/**
 * Works Facet Filter — ArtistFolio
 * ================================
 * Visitor-facing facet filters (medium / series / collections) that sit ABOVE
 * the works gallery and combine with the year sub-navigation.
 *
 * Rendered by jp-works-filter.js; only present when works_nav produced ≥1 facet.
 * Reuses the same CSS custom-props as 15-year-nav.css (--bg / --fg / --muted /
 * --border / --accent / --max-width / --t-fast) so it inherits the active theme.
 *
 * DESIGN LANGUAGE — text-links, not pills.
 *   The chips deliberately mirror the year sub-nav (.year-nav__item): plain
 *   editorial TEXT items, no resting border or fill, hover → --fg, and an ACTIVE
 *   state that is --fg + weight 600 + a thin underline indicator (the same
 *   treatment .year-nav__item.is-active uses). This keeps the two navigation
 *   rows in one quiet, museum-style visual system instead of stacking a heavy
 *   "control panel" of filled/bordered capsules under the airy year links.
 *   Type matches the year-nav exactly: 10px · uppercase · letter-spacing .1em.
 *
 * Markup:
 *   .works-filter                       (BAR wrapper; --below-year-bar when the
 *                                        year nav runs as a fixed top bar)
 *     .works-filter__inner              (max-width track, h-scroll — mirrors
 *                                        .year-nav__inner)
 *       .works-filter__group            (one per facet, inline run)
 *         .works-filter__legend         (facet label)
 *         .works-filter__chips          (chips style → row of <button>)
 *           button.works-filter__chip[aria-pressed]
 *             span.works-filter__chip-label
 *             span.works-filter__count
 *         select.works-filter__select   (dropdown style)
 *       .works-filter__status           (aria-live count, right end of bar)
 */

/* ── Wrapper — the BAR (USER-049) ─────────────────────────────────────────── */
/* Exactly the year-nav top-bar optics: full-bleed hairline bar with the same
   height, background blur and border. Sticky, so it stays available while the
   visitor scrolls the gallery; when the year nav runs as a fixed top bar the
   filter docks directly beneath it (modifier set by jp-works-filter.js). */

.works-filter {
    position: sticky;
    top: var(--header-height, 112px);
    z-index: 80;                          /* beneath the year-nav's 90 */
    /* Full-bleed out of the content column, like the fixed year bar */
    width: 100vw;
    margin: 0 calc(50% - 50vw) 28px;
    padding: 0;
    background: var(--bg);
    backdrop-filter: blur(20px) saturate(180%);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    border-bottom: var(--hairline-w) solid var(--border);
}

.works-filter--below-year-bar {
    top: calc(var(--header-height, 112px) + var(--year-nav-height, 36px));
}

/* UI-NAV-1 (Jan): die Medien-Leiste klebt IMMER bündig als zweite Zeile direkt unter
   der Jahres-Nav — null Luft, in JEDEM Scroll-Zustand. (sticky pinnt sonst erst nach
   Scrollen; am Seitenanfang klaffte ~133px Luft, weil die Jahres-Nav fixed oben
   schwebt und der Filter im Fluss unter der „Werke"-Überschrift sitzt.) Greift exakt,
   wenn die Jahres-Nav als Top-Bar sichtbar ist: jp-year-nav.js setzt body.has-year-nav,
   sobald #works im Viewport ist. Aus dem Fluss genommen schwebt der Filter im leeren
   Padding ÜBER der „Werke"-Überschrift → kein Überlapp (Header bleibt sticky/z1000
   oben, Überschrift liegt darunter). --header-height/--year-nav-height setzt
   jp-year-nav.js je Viewport → Offset stimmt auch mobil. */
body.has-year-nav .works-filter {
    position: fixed;
    top: calc(var(--header-height, 112px) + var(--year-nav-height, 36px));
    left: 0;
    margin: 0;
}
/* Klick-auf-Jahr: Scrollziel zusätzlich um die fixe Filterzeile (≈ year-nav-height)
   versetzen, damit der Jahresanfang nicht unter dem Filter verschwindet.
   SWEEP-css-scrollmargin-rule-collision: this is now the SOLE declaration for
   this selector (15-year-nav.css used to carry a second, identically-specific
   rule — same 2 classes + 1 element, so the cascade silently picked whichever
   file loaded last instead of merging the intent of either). Formula: header +
   year-nav-height (year bar) + year-nav-height (this filter bar, ≈ same height)
   + the 32px comfort padding the year-nav-only rule used to add. */
body.has-year-nav .works-year {
    scroll-margin-top: calc(var(--header-height, 112px) + (2 * var(--year-nav-height, 36px)) + 32px);
}

/* USER-FB 2026-07-25: Sticky-Pin der „Werke"-Überschrift ist zurückgenommen
   (15-year-nav.css). Damit die Überschrift im RUHEZUSTAND trotzdem unter dem
   Doppel-Turm (Jahres-Nav + gedockte Filterzeile) hervorkommt, braucht die
   Filter-Variante mehr Kopf-Luft als die Basis-Regel (die nur EINE Bar
   einrechnet). :has = gleiche Support-Annahme wie die übrigen Regeln hier. */
body.has-year-nav:has(.works-filter) #works {
    padding-top: calc((2 * var(--year-nav-height, 36px)) + 24px);
}

/* Inner track mirrors .year-nav__inner: centered max-width column, one
   horizontally scrollable row, hidden scrollbars. */
.works-filter__inner {
    display: flex;
    align-items: center;
    width: 100%;
    max-width: var(--max-width, 1100px);
    margin: 0 auto;
    min-height: var(--year-nav-height, 36px);
    gap: 0 28px;
    /* Leading/trailing inset of 14px so the first chip/legend left-aligns with the
       year-nav labels directly above (.year-nav__item padding: 0 14px) AND the
       works content column gutter (main padding-inline ~--space-md). Without it the
       filter row hung ~14px further left than the year bar it docks beneath
       (USER-FB-111). max() merges it with the iOS notch safe-area so neither is
       lost on a landscape notched device — the same shape the ≤900px rule already
       used. 0px off-notch stays byte-identical for the safe-area part.
       DES-P13B-SAFEBAR. */
    padding-inline: max(14px, var(--safe-left, 0px)) max(14px, var(--safe-right, 0px));
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.works-filter__inner::-webkit-scrollbar {
    display: none;
}

/* ── One facet group — an inline run inside the bar ───────────────────────── */

.works-filter__group {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 14px;
}

/* Hairline divider between facet groups (quiet, year-nav rhythm) */
.works-filter__group + .works-filter__group {
    border-left: var(--hairline-w) solid var(--border);
    padding-left: 28px;
}

/* Jan-Design: das sichtbare "Technik/Medium"-Label ist redundant — die Chips
   erklären sich selbst. Visually-hidden statt entfernt: die Chip-Gruppe behält
   ihren accessible name (aria-labelledby zeigt hierher, WCAG 1.3.1). */
.works-filter__legend {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.works-filter__chips {
    display: flex;
    flex-wrap: nowrap;                    /* one row — the bar scrolls instead */
    align-items: center;
    gap: 0 14px;
    border: 0;
    margin: 0;
    padding: 0;
    min-width: 0;
}

/* ── Chip (toggle) — text-link language mirroring .year-nav__item ──────────── */

.works-filter__chip {
    /* Inline text item with NO visible box. A min-height floor keeps the tap
       target ≥24px (the contract the e2e a11y check asserts) even though the
       chip reads as plain text; the label centers within that height. */
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    min-height: 26px;
    padding: 4px 1px;
    font: inherit;
    font-size: 10px;
    letter-spacing: var(--af-track-caps-lg);
    text-transform: uppercase;
    line-height: 1;
    color: var(--muted);
    background: transparent;
    border: 0;
    border-radius: 0;
    cursor: pointer;
    white-space: nowrap;
    transition: color var(--t-fast, 0.15s ease);
    -webkit-appearance: none;
    appearance: none;
}

.works-filter__chip:hover {
    color: var(--fg);
}

.works-filter__chip:focus-visible {
    /* --accent matches the site-wide focus ring (00-base.css). index.php now emits
       --accent with a 3:1 contrast guard, so it stays visible in both themes. */
    outline: 2px solid var(--accent, var(--fg));
    outline-offset: 3px;
    border-radius: 2px;
}

/* The label carries the underline indicator so it hugs the TEXT (not the
   centered tap-target box) — the same way .year-nav__item's underline tracks
   its label width. */
.works-filter__chip-label {
    position: relative;
}

/* Pressed / selected — --fg text + weight 600 + thin underline indicator,
   exactly like .year-nav__item.is-active (no fill, no pill). */
.works-filter__chip[aria-pressed="true"] {
    color: var(--fg);
    font-weight: 600;
}

.works-filter__chip[aria-pressed="true"] .works-filter__chip-label::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -4px;              /* a hair below the text, like the year-nav line */
    height: 1.5px;
    /* --accent is the SAME token the year-nav active underline uses, so both nav
       rows share one indicator colour (the artist's brand accent). index.php emits
       it with a 3:1 contrast guard, so it stays visible on every preset incl. dark
       — where the old static #111 accent used to vanish. */
    background: var(--accent, var(--fg));
    border-radius: 1px;
}

.works-filter__count {
    opacity: 0.5;
    font-weight: 400;
    letter-spacing: var(--af-track-snug);    /* numerals don't need the wide tracking */
    font-variant-numeric: tabular-nums;
}

.works-filter__chip[aria-pressed="true"] .works-filter__count {
    opacity: 0.6;
}

/* ── Dropdown (select style) ──────────────────────────────────────────────── */
/* The <select> keeps a light affordance (it genuinely needs to read as a
   control), but trimmed to the minimal palette: hairline border, no fill. */

.works-filter__select {
    font: inherit;
    font-size: 11px;
    letter-spacing: var(--af-track-snug);
    color: var(--fg);
    background: transparent;
    border: 0;
    border-bottom: var(--hairline-w) solid var(--border);
    border-radius: 0;
    padding: 5px 22px 5px 2px;
    min-height: 28px;          /* comfortable tap target */
    cursor: pointer;
    max-width: 100%;
    -webkit-appearance: none;
    appearance: none;
    /* Caret */
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                      linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: calc(100% - 8px) center, calc(100% - 4px) center;
    background-size: 4px 4px, 4px 4px;
    background-repeat: no-repeat;
    transition: border-color var(--t-fast, 0.15s ease);
}

.works-filter__select:hover {
    border-bottom-color: var(--fg);
}

.works-filter__select:focus-visible {
    outline: 2px solid var(--accent, var(--fg));
    outline-offset: 3px;
    border-radius: 2px;
}

/* ── Live status / count — rides at the end of the bar ────────────────────── */

.works-filter__status {
    font-size: 10px;
    letter-spacing: var(--af-track-wide);
    color: var(--muted);
    margin: 0 0 0 auto;       /* push to the right end of the bar */
    padding-left: 16px;
    white-space: nowrap;
    flex-shrink: 0;
}

/* Hide the status when it carries no message (avoids an empty gap) */
.works-filter__status:empty {
    display: none;
}

/* Year groups the filter emptied out are hidden via [hidden]; nothing to style,
   but make sure forced display rules elsewhere don't override the attribute. */
.works-year[hidden] {
    display: none !important;
}

/* ── Responsive ───────────────────────────────────────────────────────────── */

@media (max-width: 900px) {
    .works-filter {
        margin-bottom: 22px;
    }

    .works-filter__inner {
        gap: 0 18px;
        /* breathing room at the bleed edges, merged with the notch safe-area so
           neither is lost (logical padding — keeps the base rule's padding-inline
           semantics instead of the physical shorthand). DES-P13B-SAFEBAR. */
        padding-block: 0;
        padding-inline: max(14px, var(--safe-left, 0px)) max(14px, var(--safe-right, 0px));
    }

    .works-filter__group {
        gap: 10px;
    }

    .works-filter__group + .works-filter__group {
        padding-left: 18px;
    }

    .works-filter__chips {
        gap: 0 12px;
    }

    .works-filter__chip {
        font-size: 9px;
    }
}

@media (max-width: 600px) {
    /* Chips WRAP onto multiple lines on narrow screens so every chip stays inside
       the viewport. A previous horizontal-scroll strip (flex-wrap:nowrap;
       overflow-x:auto) pushed later chips off-screen — unreachable without
       sideways scrolling and flagged as a critical offscreen defect. Wrapping
       keeps the whole facet visible and tappable. */
    .works-filter__chips {
        flex-wrap: wrap;
        gap: 2px 12px;
    }
    .works-filter__chip { flex-shrink: 0; }

    /* Stack the legend above its chips so the row reads like a labelled list. */
    .works-filter__group {
        flex-direction: column;
        align-items: stretch;
        gap: 3px;
    }
    .works-filter__select { width: 100%; }
}

/* ── Dark mode ────────────────────────────────────────────────────────────── */
/* All chip styling is token-driven (--muted / --fg / --accent), so it flips with
   the theme automatically — no per-mode overrides needed for the text links.
   These only firm up the <select> option list, which some browsers render with
   the UA palette regardless of the control colors. */

[data-theme="dark"] .works-filter__select option,
.dark-mode .works-filter__select option {
    color: var(--fg);
    background: var(--bg);
}

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

@media (prefers-reduced-motion: reduce) {
    .works-filter__chip,
    .works-filter__select {
        transition: none !important;
    }
}
