/* Anime Compass — main.css. The browse surface: hero, filter rail, popovers,
   results grid and the anime card, over the glass/token system in tokens.css and
   the shared chrome in shell.css. Reset, body, scrollbars, buttons and the top
   bar live in shell.css and are deliberately absent here.

   Region colour, one hue per region and never reused:
     pink     (--accent-secondary)  filters: rail, popovers, chips, pills, links
     tangerine(--accent-curator)    curator ratings and stars, and only those
     yellow   (--accent-quaternary) discovery: Surprise me, the sheet, Similar
     green    (--accent-tertiary)   viewing guidance: the age recommendation
     aqua     (--accent-primary)    results state: active view, count, focus,
                                    title, Watch Together

   Every colour is a token, a color-mix() over a token, or an accent-tinted
   rgba() glow. No literal hex. */

/* ── Layout shell ─────────────────────────────────────────────────────────── */
/* Panels are islands: the container never fills the window, and the gaps run
   several space units so the canvas reads as one continuous field behind them.
   Nothing here may take transform, filter or backdrop-filter — any of the three
   would make .container the containing block for the fixed discovery sheet. */
.container {
    max-width: 1440px;
    margin-inline: max(var(--space-4), calc((100% - 1440px) / 2));
    padding-block: var(--space-3) var(--space-8);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

/* ── Hero: the visual anchor, sat in its own air above the working chrome ──── */
.hero {
    position: relative;
    padding: var(--space-6) var(--space-3) var(--space-4);
    text-align: center;
}

/* Wide aqua bloom behind the display type: atmosphere where there is no data to
   protect. Horizontal insets stay at 0, since an absolutely positioned child
   still counts toward overflow and a negative one adds a scrollbar. */
.hero::before {
    content: '';
    position: absolute;
    inset: -28% 0 -22%;
    z-index: -1;
    pointer-events: none;
    background: radial-gradient(56% 60% at 50% 45%, rgba(61, 224, 232, 0.15), transparent 72%);
}

.hero-title {
    font-size: clamp(2.2rem, 6vw, 4.2rem);
    font-weight: 700;
    line-height: 0.98;
    letter-spacing: -0.035em;
    margin-bottom: var(--space-2);
}

.hero-sub {
    color: var(--text-secondary);
    font-size: 1.05rem;
    line-height: 1.6;
    max-width: 64ch;
    margin: 0 auto var(--space-2);
}

.hero-count {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    color: var(--accent-primary);
    font-weight: 700;
    font-size: 0.95rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.hero-count strong {
    font-size: 1.35rem;
    font-weight: 700;
}

/* ── Filter rail ──────────────────────────────────────────────────────────── */
/* The rail's own backdrop-filter makes it a stacking context, so row two's
   similar-to dropdown cannot escape it however high its own z-index. The rail is
   lifted above the panels that follow it and left below the popover layer (60)
   and the sticky top bar (80). */
.filter-rail {
    position: relative;
    z-index: 40;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-2);
    background: var(--panel-fill);
    backdrop-filter: blur(var(--panel-blur));
    -webkit-backdrop-filter: blur(var(--panel-blur));
    border: var(--border) solid color-mix(in srgb, var(--accent-secondary) 35%, var(--panel-border));
    border-radius: var(--radius-md);
    box-shadow: var(--panel-lift);
}

/* Row one: the popover buttons and discovery. Row two: the refinements, shown at
   rest so the rail states what it can do unopened. */
.rail-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.rail-row--refine {
    gap: var(--space-3);
    padding-top: var(--space-2);
    border-top: var(--border) solid var(--panel-border);
}

.rail-inline-field {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

.rail-inline-field label {
    color: var(--text-secondary);
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
}

.rail-inline-field select,
.rail-inline-field input[type="text"] {
    padding: 8px 12px;
    font-size: 0.85rem;
}

/* Grows into the space the select leaves, but stops: it is the least-reached
   control on the rail and should not end up the widest thing in the panel. */
.rail-inline-field--grow {
    flex: 0 1 380px;
    min-width: 180px;
}

.filter-autocomplete-wrapper {
    position: relative;
    flex: 1;
}

.rail-inline-field--grow input[type="text"] {
    width: 100%;
}

/* Row two carries no badge, so the control itself has to show it is set. The pink
   stays on the chrome and the label; the value it holds is the thing being read,
   so it keeps full text contrast. */
.rail-inline-field.is-set label {
    color: var(--accent-secondary);
}

.rail-inline-field.is-set select,
.rail-inline-field.is-set input[type="text"] {
    background: var(--accent-secondary-dim);
    border-color: var(--accent-secondary);
    color: var(--text-primary);
}

/* The similar-to chip sits on row two beside the field that sets it, and would
   otherwise take a flex gap of its own while holding nothing. */
.rail-row--refine .person-pills {
    margin-top: 0;
}

.rail-row--refine .person-pills:empty {
    display: none;
}

.rail-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 10px 18px;
    background: var(--panel-fill-sunken);
    color: var(--text-secondary);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-pill);
    font-size: 0.9rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard),
        color var(--motion-hover) var(--ease-standard);
}

.rail-btn:hover {
    transform: translateY(-2px);
    box-shadow: var(--panel-lift-high);
    border-color: var(--panel-border-bright);
    color: var(--text-primary);
}

.rail-btn:active {
    transform: translateY(0) scale(0.98);
    box-shadow: var(--panel-lift);
}

/* Open, or carrying a selection: the filters region blooms pink. */
.rail-btn.active,
.rail-btn[aria-expanded="true"] {
    background: var(--accent-secondary-dim);
    border-color: var(--accent-secondary);
    color: var(--accent-secondary);
    box-shadow: var(--panel-lift), 0 0 18px rgba(255, 95, 168, 0.24);
}

/* Curator ratings keep their own hue wherever they surface, the rail included. */
.rail-btn[data-popover="pop-rating"].active,
.rail-btn[data-popover="pop-rating"][aria-expanded="true"] {
    background: var(--accent-curator-dim);
    border-color: var(--accent-curator);
    color: var(--accent-curator);
    box-shadow: var(--panel-lift), 0 0 18px rgba(255, 154, 60, 0.24);
}

.rail-btn[data-popover="pop-rating"] .rail-badge {
    background: var(--accent-curator);
}

.rail-btn--discover {
    border-color: color-mix(in srgb, var(--accent-quaternary) 60%, transparent);
    color: var(--accent-quaternary);
}

.rail-btn--discover:hover {
    background: var(--accent-quaternary-dim);
    border-color: var(--accent-quaternary);
    color: var(--accent-quaternary);
    box-shadow: var(--panel-lift-high), 0 0 22px rgba(255, 216, 77, 0.38);
}

.rail-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    background: var(--accent-secondary);
    color: var(--text-on-accent);
    border-radius: var(--radius-pill);
    font-size: 0.85rem;
    font-weight: 700;
}

.rail-caret {
    opacity: 0.6;
    transition: transform var(--motion-hover) var(--ease-standard);
}

.rail-btn[aria-expanded="true"] .rail-caret {
    transform: rotate(180deg);
    opacity: 1;
}

/* ── Popovers ─────────────────────────────────────────────────────────────── */
/* The layer is a zero-height positioning context directly under the rail, so a
   popover floats over the results rather than pushing them down. */
.popover-layer {
    position: relative;
    height: 0;
    z-index: 60;
}

.filter-popover {
    position: absolute;
    top: 0;
    left: 0;
    display: none;
    min-width: 300px;
    max-width: min(460px, calc(100vw - 32px));
    max-height: min(70vh, 580px);
    overflow-y: auto;
    padding: var(--space-3);
    /* Opaque base under the glass tint. A popover floats over the cover grid,
       and an 8.5% white fill over a bright cover leaves its labels unreadable
       however much the backdrop is blurred. Dialog-level elevation, per the
       depth model: more fill, not more blur. */
    background:
        linear-gradient(var(--panel-fill-raised), var(--panel-fill-raised)),
        linear-gradient(165deg, var(--anchor) 0%, var(--canvas) 70%);
    border: var(--border) solid color-mix(in srgb, var(--accent-secondary) 30%, var(--panel-border));
    border-radius: var(--radius-md);
    box-shadow: var(--panel-lift-high);
}

.filter-popover.open {
    display: block;
    animation: popover-in var(--motion-base) var(--ease-entrance);
}

@keyframes popover-in {
    from {
        opacity: 0;
        transform: translateY(-6px) scale(0.98);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

.filter-popover--wide {
    min-width: 440px;
}

/* The panel's own header: the title on the left, an explicit close on the
   right, sticky inside the panel's scroll box so it stays put however far the
   list below has scrolled. On a phone the panel is a bottom sheet and this
   button is the only exit the screen shows, Escape and a tap on the page
   behind being invisible affordances on a touch device.

   The panel gives up its top padding to the head, which supplies it instead: a
   sticky box cannot leave its containing block, so a head reaching the panel's
   top edge on a negative margin is pinned below the padding and the content
   scrolls through the gap that leaves. */
.filter-popover.has-popover-head {
    padding-top: 0;
}

.popover-head {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0 calc(var(--space-3) * -1) var(--space-2);
    padding: var(--space-2) var(--space-3) var(--space-1);
    /* Opaque, or the content scrolling under it reads straight through. The
       panel's own corners clip this one, so the head takes no radius. */
    background:
        linear-gradient(var(--panel-fill-raised), var(--panel-fill-raised)),
        linear-gradient(var(--anchor), var(--anchor));
    border-bottom: var(--border) solid var(--panel-border);
}

.popover-head .popover-title {
    flex: 1;
    min-width: 0;
    margin-bottom: 0;
}

.popover-close {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    margin-right: calc(var(--space-1) * -1);
    padding: 0;
    background: transparent;
    color: var(--text-secondary);
    border: none;
    border-radius: var(--radius-sm);
    line-height: 0;
    cursor: pointer;
    transition: color var(--motion-hover) var(--ease-standard),
        transform var(--motion-hover) var(--ease-standard);
}

.popover-close:hover {
    color: var(--text-primary);
    transform: scale(1.12) rotate(90deg);
}

.popover-close:active {
    transform: scale(0.94) rotate(90deg);
}

.popover-title {
    color: var(--accent-secondary);
    font-size: 0.95rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: var(--space-1);
}

#pop-rating {
    border-color: color-mix(in srgb, var(--accent-curator) 40%, var(--panel-border));
}

#pop-rating .popover-title {
    color: var(--accent-curator);
}

/* Two filters in one popover are two groups, and the rule between them is a
   real divider rather than implied space. */
.popover-group + .popover-group {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: var(--border) solid var(--panel-border);
}

.filter-label {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    margin-bottom: var(--space-1);
    color: var(--text-secondary);
    font-size: 0.85rem;
    font-weight: 600;
}

.chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin-bottom: var(--space-2);
}

.chip-row:last-child {
    margin-bottom: 0;
}

/* ── Chip buttons: popular genres, quick age ranges, flags ───────────────── */
.chip-btn {
    padding: 7px 15px;
    background: var(--panel-fill-sunken);
    color: var(--text-secondary);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-pill);
    font-size: 0.85rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard),
        color var(--motion-hover) var(--ease-standard);
}

.chip-btn:hover {
    transform: translateY(-2px);
    box-shadow: var(--panel-lift);
    border-color: var(--panel-border-bright);
    color: var(--text-primary);
}

.chip-btn:active {
    transform: translateY(0) scale(0.97);
}

.chip-btn.active,
.chip-btn[aria-pressed="true"] {
    background: var(--accent-secondary-dim);
    border-color: var(--accent-secondary);
    color: var(--accent-secondary);
}

/* ── Popover fields: one labelled block, one job ──────────────────────────── */
.popover-field {
    margin-bottom: var(--space-2);
}

.popover-field:last-child {
    margin-bottom: 0;
}

.popover-field > label {
    display: block;
    margin-bottom: var(--space-1);
    color: var(--text-secondary);
    font-size: 0.85rem;
    font-weight: 600;
}

.popover-field select {
    width: 100%;
}

.popover-field--pair .field-pair {
    display: flex;
    gap: var(--space-1);
}

.field-pair select {
    flex: 1;
    min-width: 0;
}

/* ── Rating: one row per level, the stars carrying the whole label ────────── */
.rating-checkbox-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.rating-checkbox-group .genre-checkbox {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    border-radius: var(--radius-sm);
    padding: 8px 12px;
}

/* Tangerine owns the ratings region on every page, so the selected row cannot
   take the pink the other checkbox pills use. */
.rating-checkbox-group .genre-checkbox:hover {
    border-color: var(--accent-curator);
}

.rating-checkbox-group .genre-checkbox.selected,
.rating-checkbox-group .genre-checkbox:has(input:checked) {
    background: var(--accent-curator-dim);
    border-color: var(--accent-curator);
    color: var(--accent-curator);
}

.rating-gloss {
    color: var(--text-secondary);
    font-size: 0.8rem;
}

/* ── The star scale ───────────────────────────────────────────────────────── */
/* The tier names are storage and never reach a viewer. One <symbol id="star-mark">
   per page carries the path; starsHTML_() in app.js is the only thing that writes
   the markup, always STAR_MAX_ marks wide with the unearned ones hollow, so one
   star and three stars are the same object at two fills rather than two objects
   of different widths. */
.svg-sprite {
    display: none;
}

.star-rating {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    color: var(--accent-curator);
    line-height: 0;
}

.star-rating .star {
    flex: none;
    width: 16px;
    height: 16px;
}

.star-rating .star--on {
    fill: currentColor;
    filter: drop-shadow(0 0 5px rgba(255, 154, 60, 0.5));
}

.star-rating .star--off {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    opacity: 0.4;
}

.star-rating--chip .star {
    width: 13px;
    height: 13px;
}

/* ── The genre popover is a chip row over a scrolling list ────────────────── */
/* Without the flex column the list keeps its own cap and the panel scrolls
   around it, giving one popover two nested scrollbars. */
#pop-genre {
    flex-direction: column;
    overflow: hidden;
}

#pop-genre.open {
    display: flex;
}

#pop-genre .popover-field:last-child {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

#pop-genre .genre-filter {
    flex: 1 1 auto;
    max-height: none;
    min-height: 120px;
}

/* ── AND/OR mode toggle ───────────────────────────────────────────────────── */
/* A joined segmented control: two states of one filter, so the segments sit in
   a shared recessed well and brighten in place rather than lifting apart. */
.logic-compact {
    display: inline-flex;
    gap: 3px;
    padding: 3px;
    background: var(--panel-fill-sunken);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-pill);
}

.logic-compact-btn {
    padding: 3px 12px;
    background: transparent;
    color: var(--text-secondary);
    border: none;
    border-radius: var(--radius-pill);
    font-size: 0.85rem;
    font-weight: 700;
    font-family: inherit;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: box-shadow var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard),
        color var(--motion-hover) var(--ease-standard);
}

.logic-compact-btn:hover {
    background: var(--panel-fill-raised);
    color: var(--text-primary);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

.logic-compact-btn:active {
    box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.45);
}

.logic-compact-btn.active {
    background: var(--accent-secondary);
    color: var(--text-on-accent);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3),
        0 0 14px rgba(255, 95, 168, 0.32);
}

/* ── Form elements: recessed, never raised ────────────────────────────────── */
input[type="text"],
input[type="number"],
select {
    padding: 10px 12px;
    background: var(--panel-fill-sunken);
    color: var(--text-primary);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-sm);
    font-size: 0.9rem;
    font-family: inherit;
    transition: border-color var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard);
}

input[type="text"]::placeholder,
input[type="number"]::placeholder {
    color: var(--text-secondary);
}

input[type="text"]:focus,
input[type="number"]:focus,
select:focus,
.person-search-wrapper:focus-within input,
.crew-search-wrap:focus-within input,
.year-inputs:focus-within input:focus {
    outline: none;
    border-color: var(--accent-primary);
    box-shadow: 0 0 0 3px var(--accent-primary-dim);
}

/* The popup list is native chrome: `color-scheme: dark` in tokens.css is what
   stops the OS painting it white, and this keeps each row on the canvas black
   rather than the browser's own dark grey. */
select option {
    background: var(--canvas);
    color: var(--text-primary);
}

.year-inputs {
    display: flex;
    gap: var(--space-1);
}

.year-inputs input {
    flex: 1;
    min-width: 0;
}

/* ── Autocomplete: search wrapper, dropdown, pills ────────────────────────── */
.person-search-wrapper,
.crew-search-wrap {
    position: relative;
    margin-bottom: var(--space-1);
}

.person-search-wrapper input,
.crew-search-wrap input {
    width: 100%;
}

.person-dropdown,
.crew-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    z-index: 200;
    margin-top: 4px;
    max-height: 260px;
    overflow-y: auto;
    background: var(--panel-fill-raised);
    backdrop-filter: blur(var(--panel-blur));
    -webkit-backdrop-filter: blur(var(--panel-blur));
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-sm);
    box-shadow: var(--panel-lift-high);
}

.person-dropdown.open,
.crew-dropdown.open {
    display: block;
}

/* A list row cannot lift without disturbing the rows around it, so the hover
   payload here is a pink edge sliding in from the left. */
.person-dropdown-item,
.crew-dropdown-item {
    padding: 9px 12px;
    color: var(--text-secondary);
    border-bottom: var(--border) solid var(--panel-border);
    font-size: 0.9rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    box-shadow: inset 0 0 0 0 var(--accent-secondary);
    transition: background-color var(--motion-hover) var(--ease-standard),
        color var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        padding-left var(--motion-hover) var(--ease-standard);
}

.person-dropdown-item:last-child,
.crew-dropdown-item:last-child {
    border-bottom: none;
}

.person-dropdown-item:hover,
.crew-dropdown-item:hover {
    background: var(--accent-secondary-dim);
    color: var(--text-primary);
    box-shadow: inset 3px 0 0 0 var(--accent-secondary);
    padding-left: 16px;
}

/* The role qualifier is context for the name, not the name itself. */
.crew-dropdown-role,
.similar-year {
    color: var(--text-secondary);
    opacity: 0.8;
}

.genre-pills-filter,
.genre-filter {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
}

.genre-pills-filter,
.genre-filter.scrollable {
    max-height: 280px;
    overflow-y: auto;
}

/* The checkbox pill: the native box is redundant once the pill itself carries
   the selected state, so it is hidden and the label does the work. */
.genre-checkbox {
    padding: 5px 14px;
    background: var(--panel-fill-sunken);
    color: var(--text-secondary);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-pill);
    font-size: 0.85rem;
    cursor: pointer;
    user-select: none;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard),
        color var(--motion-hover) var(--ease-standard);
}

.genre-checkbox input[type="checkbox"] {
    display: none;
}

.genre-checkbox label {
    cursor: pointer;
}

.genre-checkbox:hover {
    transform: translateY(-2px);
    box-shadow: var(--panel-lift);
    border-color: var(--accent-secondary);
    color: var(--text-primary);
}

.genre-checkbox:active {
    transform: translateY(0) scale(0.97);
}

.genre-checkbox.selected,
.genre-checkbox:has(input:checked) {
    background: var(--accent-secondary-dim);
    border-color: var(--accent-secondary);
    color: var(--accent-secondary);
}

/* Keyboard focus reaches the hidden box, so the pill has to show it. */
.genre-checkbox:focus-within {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

.person-pills,
.crew-selected-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin-top: var(--space-1);
}

.person-filter-pill,
.crew-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 8px 5px 14px;
    background: var(--accent-secondary-dim);
    color: var(--accent-secondary);
    border: var(--border) solid var(--accent-secondary);
    border-radius: var(--radius-pill);
    font-size: 0.85rem;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard);
}

.person-filter-pill:hover,
.crew-chip:hover {
    transform: translateY(-2px);
    box-shadow: var(--panel-lift), 0 0 16px rgba(255, 95, 168, 0.28);
}

.crew-chip-role {
    opacity: 0.75;
}

.person-pill-remove,
.crew-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    background: transparent;
    color: inherit;
    border: none;
    border-radius: 50%;
    font-size: 1rem;
    line-height: 1;
    font-family: inherit;
    cursor: pointer;
    opacity: 0.75;
    transition: opacity var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard),
        transform var(--motion-hover) var(--ease-standard);
}

.person-pill-remove:hover,
.crew-chip-remove:hover {
    opacity: 1;
    background: var(--accent-secondary);
    color: var(--text-on-accent);
    transform: scale(1.12);
}

/* ── Active filters ───────────────────────────────────────────────────────── */
.active-filters {
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    background: var(--panel-fill);
    backdrop-filter: blur(var(--panel-blur));
    -webkit-backdrop-filter: blur(var(--panel-blur));
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-md);
    box-shadow: var(--panel-lift);
}

.active-filters-label {
    color: var(--text-secondary);
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
}

.active-filters-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    flex: 1;
    min-width: 0;
}

.active-filter-chip,
.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 8px 6px 14px;
    background: var(--accent-secondary-dim);
    color: var(--accent-secondary);
    border: var(--border) solid var(--accent-secondary);
    border-radius: var(--radius-pill);
    font-size: 0.85rem;
    cursor: pointer;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard);
}

.active-filter-chip:hover,
.filter-chip:hover {
    transform: translateY(-2px);
    box-shadow: var(--panel-lift), 0 0 16px rgba(255, 95, 168, 0.28);
}

.chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    background: transparent;
    color: inherit;
    border: none;
    border-radius: 50%;
    font-size: 1rem;
    line-height: 1;
    font-family: inherit;
    cursor: pointer;
    opacity: 0.75;
    transition: opacity var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard),
        transform var(--motion-hover) var(--ease-standard);
}

.chip-remove:hover {
    opacity: 1;
    background: var(--accent-secondary);
    color: var(--text-on-accent);
    transform: scale(1.12);
}

/* Clearing everything is the destructive end of the strip, so it sits quiet at
   rest and only takes the filters hue when reached for. */
.clear-all-btn {
    margin-left: auto;
    padding: 6px 14px;
    background: var(--panel-fill-sunken);
    color: var(--text-secondary);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-pill);
    font-size: 0.85rem;
    font-weight: 600;
    font-family: inherit;
    white-space: nowrap;
    cursor: pointer;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard),
        color var(--motion-hover) var(--ease-standard);
}

.clear-all-btn:hover {
    transform: translateY(-2px);
    background: var(--accent-secondary-dim);
    border-color: var(--accent-secondary);
    color: var(--accent-secondary);
    box-shadow: var(--panel-lift), 0 0 16px rgba(255, 95, 168, 0.28);
}

.clear-all-btn:active {
    transform: translateY(0) scale(0.97);
}

/* ── Controls bar: view, sort, count ──────────────────────────────────────── */
.controls {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    background: var(--panel-fill);
    backdrop-filter: blur(var(--panel-blur));
    -webkit-backdrop-filter: blur(var(--panel-blur));
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-md);
    box-shadow: var(--panel-lift);
}

/* A joined segmented control: segments brighten in place rather than lifting,
   since lifting one segment out would break the object it belongs to. */
.view-controls {
    display: flex;
    gap: 4px;
    padding: 4px;
    background: var(--panel-fill-sunken);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-sm);
}

.view-controls button {
    padding: 7px 16px;
    background: transparent;
    color: var(--text-secondary);
    border: none;
    border-radius: 6px;
    font-size: 0.85rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: color var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard);
}

.view-controls button:hover {
    color: var(--text-primary);
    background: var(--panel-fill-raised);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

.view-controls button:active {
    box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.45);
}

.view-controls button.active {
    background: var(--accent-primary);
    color: var(--text-on-accent);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35),
        0 0 14px rgba(61, 224, 232, 0.32);
}

.sort-controls {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

.sort-controls label {
    color: var(--text-secondary);
    font-size: 0.85rem;
}

.sort-dir-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 9px 14px;
    background: var(--panel-fill-sunken);
    color: var(--text-primary);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-sm);
    font-size: 0.9rem;
    font-family: inherit;
    line-height: 1;
    cursor: pointer;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard);
}

.sort-dir-btn:hover {
    transform: translateY(-2px);
    box-shadow: var(--panel-lift);
    border-color: var(--panel-border-bright);
}

.sort-dir-btn:active {
    transform: translateY(0) scale(0.96);
}

/* Similarity ranking owns the order while it is set, so the sort controls read
   as inert rather than silently no-oping. */
.sort-controls.sort-disabled #sortBy,
.sort-controls.sort-disabled #sortDirBtn {
    opacity: 0.4;
    filter: saturate(0.2);
    pointer-events: none;
}

.sort-disabled-hint {
    display: inline-flex;
    align-items: center;
    color: var(--accent-quaternary);
    font-size: 0.85rem;
    font-style: italic;
}

.sort-disabled-hint[hidden] {
    display: none;
}

.results-info {
    margin-left: auto;
}

#resultsCount {
    color: var(--accent-primary);
    font-size: 1rem;
    font-weight: 700;
}

/* ── Results grid / list ──────────────────────────────────────────────────── */
.anime-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--space-3);
}

.anime-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

/* ── Anime card ───────────────────────────────────────────────────────────── */
.anime-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--panel-fill);
    backdrop-filter: blur(var(--panel-blur));
    -webkit-backdrop-filter: blur(var(--panel-blur));
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-md);
    box-shadow: var(--panel-lift);
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard);
}

.anime-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--panel-lift-high);
    border-color: var(--panel-border-bright);
    background: var(--panel-fill-raised);
}

/* Cover above information, which is the shape the grid wants; list view flips
   this to a row below. */
.anime-header {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.anime-header > a {
    display: block;
    text-decoration: none;
}

.anime-cover-container {
    position: relative;
    overflow: hidden;
    background: var(--panel-fill-sunken);
}

.anime-cover {
    display: block;
}

/* The ratio is held by CSS rather than by the image, so a missing or slow cover
   cannot collapse the grid row. */
.anime-cover img {
    display: block;
    width: 100%;
    aspect-ratio: 2 / 3;
    object-fit: cover;
    transition: transform var(--motion-base) var(--ease-standard);
}

.anime-card:hover .anime-cover img {
    transform: scale(1.04);
}

.anime-info {
    display: flex;
    flex-direction: column;
    flex: 1;
    gap: var(--space-1);
    padding: var(--space-2);
}

.anime-title {
    color: var(--text-primary);
    text-decoration: none;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.3;
    transition: color var(--motion-hover) var(--ease-standard),
        text-shadow var(--motion-hover) var(--ease-standard);
}

.anime-title:hover {
    color: var(--accent-primary);
    text-shadow: 0 0 18px rgba(61, 224, 232, 0.45);
}

/* ── Card metadata ────────────────────────────────────────────────────────── */
.anime-studio {
    align-self: flex-start;
    color: var(--text-secondary);
    font-size: 0.85rem;
    line-height: 1.7;
}

.anime-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    color: var(--text-secondary);
    font-size: 0.85rem;
}

.anime-year {
    padding: 3px 10px;
    background: var(--panel-fill-sunken);
    color: var(--text-secondary);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-sm);
}

/* Format is a fact about the work and carries no judgement, so it takes no
   accent at all. */
.medium-badge {
    display: inline-block;
    padding: 3px 10px;
    background: var(--panel-fill-raised);
    color: var(--text-secondary);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-sm);
    font-size: 0.85rem;
    white-space: nowrap;
}

/* Green is the curator's viewing guidance: what a work asks of a viewer. Shown
   at rest, never hover-gated. */
.anime-age-rec {
    align-self: flex-start;
    padding: 3px 12px;
    background: var(--accent-tertiary-dim);
    color: var(--accent-tertiary);
    border: var(--border) solid color-mix(in srgb, var(--accent-tertiary) 55%, transparent);
    border-radius: var(--radius-pill);
    font-size: 0.85rem;
    font-weight: 600;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard);
}

.anime-age-rec:hover {
    transform: translateY(-2px);
    border-color: var(--accent-tertiary);
    box-shadow: 0 4px 14px rgba(93, 232, 140, 0.28);
}

.watch-together-badge {
    align-self: flex-start;
    padding: 3px 12px;
    background: var(--accent-primary-dim);
    color: var(--accent-primary);
    border: var(--border) solid color-mix(in srgb, var(--accent-primary) 55%, transparent);
    border-radius: var(--radius-pill);
    font-size: 0.85rem;
    font-weight: 600;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard);
}

.watch-together-badge:hover {
    transform: translateY(-2px);
    border-color: var(--accent-primary);
    box-shadow: 0 4px 14px rgba(61, 224, 232, 0.28);
}

.anime-genres {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* Genre and theme tags load themselves into the filters when clicked, so they
   read pink, the filters region's hue. */
.genre-tag,
.theme-tag {
    padding: 3px 12px;
    background: var(--panel-fill-sunken);
    color: var(--text-secondary);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-pill);
    font-size: 0.85rem;
    cursor: pointer;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard),
        color var(--motion-hover) var(--ease-standard);
}

.genre-tag:hover,
.theme-tag:hover {
    transform: translateY(-2px);
    background: var(--accent-secondary-dim);
    border-color: var(--accent-secondary);
    color: var(--accent-secondary);
    box-shadow: 0 4px 14px rgba(255, 95, 168, 0.3);
}

.genre-tag:active,
.theme-tag:active {
    transform: translateY(0) scale(0.97);
}

.anime-synopsis {
    padding: 0 var(--space-2);
    color: var(--text-secondary);
    font-size: 0.9rem;
    line-height: 1.55;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Expanding the card releases the clamp, so no text is unreachable. */
.anime-card:has(.more-details[open]) .anime-synopsis {
    -webkit-line-clamp: unset;
    line-clamp: unset;
    overflow: visible;
}

/* ── Expanded detail: themes and crew ─────────────────────────────────────── */
.more-details {
    margin: var(--space-1) var(--space-2) 0;
    padding-top: var(--space-2);
    border-top: var(--border) solid var(--panel-border);
    color: var(--text-secondary);
    font-size: 0.85rem;
    line-height: 1.7;
}

.more-details-summary,
.crew-summary {
    display: inline-block;
    padding: 4px 0;
    color: var(--text-secondary);
    font-weight: 600;
    list-style: none;
    cursor: pointer;
    transition: color var(--motion-hover) var(--ease-standard);
}

.more-details-summary::-webkit-details-marker,
.crew-summary::-webkit-details-marker {
    display: none;
}

.more-details-summary::before,
.crew-summary::before {
    content: '\25B8';
    display: inline-block;
    margin-right: 6px;
    transition: transform var(--motion-hover) var(--ease-standard);
}

.more-details[open] .more-details-summary::before,
.crew-details[open] .crew-summary::before {
    transform: rotate(90deg);
}

.more-details-summary:hover,
.crew-summary:hover {
    color: var(--text-primary);
}

.more-details-content {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding-top: var(--space-1);
}

.card-detail-section {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.card-detail-label {
    color: var(--text-secondary);
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.card-theme-list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.crew-details {
    margin-top: var(--space-1);
    color: var(--text-secondary);
    font-size: 0.85rem;
}

.crew-entries {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding-top: var(--space-1);
}

.crew-entry {
    line-height: 1.6;
}

.crew-role-label {
    color: var(--text-secondary);
    font-weight: 700;
}

/* Any metadata that loads itself into the filters when clicked reads pink, the
   filters region's hue, and carries a dotted edge at rest so the affordance is
   not gated on hover. */
.clickable-filter,
.crew-name-link {
    display: inline-block;
    color: inherit;
    cursor: pointer;
    transition: transform var(--motion-hover) var(--ease-standard),
        color var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard);
}

.clickable-filter:hover,
.crew-name-link:hover {
    transform: translateY(-2px);
    color: var(--accent-secondary);
}

/* In prose the affordance needs its own edge; the tags above already have a
   border to recolour, so they are excluded. */
.anime-studio.clickable-filter,
.list-meta .clickable-filter,
.crew-name-link {
    border-bottom: 1px dotted color-mix(in srgb, var(--accent-secondary) 55%, transparent);
}

.anime-studio.clickable-filter:hover,
.list-meta .clickable-filter:hover,
.crew-name-link:hover {
    border-bottom-color: var(--accent-secondary);
}

/* ── Card actions ─────────────────────────────────────────────────────────── */
.anime-footer {
    display: flex;
    gap: var(--space-1);
    margin-top: auto;
    padding: var(--space-1) var(--space-2) var(--space-2);
}

/* "Similar" is a discovery act, so it carries the discovery hue the Surprise me
   button and the sheet carry. */
.btn-similar,
.btn-similar-filter {
    padding: 7px 16px;
    background: var(--panel-fill-sunken);
    color: var(--text-secondary);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-sm);
    font-size: 0.85rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard),
        color var(--motion-hover) var(--ease-standard);
}

.btn-similar:hover,
.btn-similar-filter:hover {
    transform: translateY(-2px);
    background: var(--accent-quaternary-dim);
    border-color: var(--accent-quaternary);
    color: var(--accent-quaternary);
    box-shadow: var(--panel-lift), 0 0 18px rgba(255, 216, 77, 0.3);
}

.btn-similar:active,
.btn-similar-filter:active {
    transform: translateY(0) scale(0.97);
}

.similar-panel {
    margin: 0 var(--space-2) var(--space-2);
    padding-top: var(--space-1);
    border-top: var(--border) solid var(--panel-border);
    color: var(--text-secondary);
    font-size: 0.85rem;
    line-height: 1.7;
}

.similar-panel .btn-similar-filter {
    margin-top: var(--space-1);
}

/* ── List view ────────────────────────────────────────────────────────────── */
.anime-list .anime-card {
    flex-direction: row;
    align-items: stretch;
}

.anime-list .anime-header {
    flex-direction: row;
    align-items: stretch;
}

.anime-list .anime-cover-container {
    flex: 0 0 104px;
    width: 104px;
}

.anime-list .anime-info {
    padding: var(--space-2) var(--space-3);
}

.anime-list .anime-synopsis {
    -webkit-line-clamp: 2;
    line-clamp: 2;
    /* .anime-info already carries the horizontal padding in list view, so the
       card-view inset would indent the synopsis away from the title above it. */
    padding-inline: 0;
}

.list-item {
    display: flex;
    align-items: stretch;
    gap: var(--space-2);
    overflow: hidden;
    background: var(--panel-fill);
    backdrop-filter: blur(var(--panel-blur));
    -webkit-backdrop-filter: blur(var(--panel-blur));
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-md);
    box-shadow: var(--panel-lift);
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        border-color var(--motion-hover) var(--ease-standard),
        background-color var(--motion-hover) var(--ease-standard);
}

.list-item:hover {
    transform: translateY(-2px);
    box-shadow: var(--panel-lift-high);
    border-color: var(--panel-border-bright);
    background: var(--panel-fill-raised);
}

.list-cover {
    flex: 0 0 76px;
    background: var(--panel-fill-sunken);
}

.list-cover img {
    display: block;
    width: 100%;
    aspect-ratio: 2 / 3;
    object-fit: cover;
}

.list-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    padding: var(--space-2) var(--space-2) var(--space-2) 0;
}

.list-title {
    color: var(--text-primary);
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.3;
}

.list-meta,
.list-genres {
    color: var(--text-secondary);
    font-size: 0.85rem;
}

/* ── Empty state ──────────────────────────────────────────────────────────── */
/* No working data to protect here, so this is where the atmosphere goes. */
.no-results {
    position: relative;
    overflow: hidden;
    text-align: center;
    padding: var(--space-8) var(--space-3);
    background: var(--panel-fill);
    backdrop-filter: blur(var(--panel-blur));
    -webkit-backdrop-filter: blur(var(--panel-blur));
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--panel-lift), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

.no-results::before {
    content: '';
    position: absolute;
    inset: -40% 20% 40%;
    pointer-events: none;
    background: radial-gradient(50% 60% at 50% 60%, rgba(61, 224, 232, 0.16), transparent 70%);
}

.no-results .icon {
    position: relative;
    margin-bottom: var(--space-3);
    color: var(--accent-primary);
    filter: drop-shadow(0 6px 18px rgba(61, 224, 232, 0.4));
}

.no-results h3 {
    position: relative;
    color: var(--text-primary);
    font-size: 1.4rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin-bottom: var(--space-1);
}

.empty-hint {
    position: relative;
    color: var(--text-secondary);
    font-size: 0.95rem;
    max-width: 46ch;
    margin: 0 auto var(--space-3);
}

.no-results .btn {
    position: relative;
}

/* ── Loading: skeleton cards, not a bare spinner ──────────────────────────── */
/* A skeleton shows the shape of what is coming (Doherty / Labor Illusion) and
   keeps the page from jumping when the real cards land. app.js sets this
   wrapper's display inline, which wins over the default below. */
.loading {
    display: none;
}

.skeleton-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--space-3);
}

.skeleton-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    overflow: hidden;
    padding-bottom: var(--space-2);
    background: var(--panel-fill);
    backdrop-filter: blur(var(--panel-blur));
    -webkit-backdrop-filter: blur(var(--panel-blur));
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-md);
    box-shadow: var(--panel-lift);
}

.skeleton-poster {
    width: 100%;
    aspect-ratio: 2 / 3;
}

.skeleton-line {
    height: 12px;
    margin: 0 var(--space-2);
    border-radius: var(--radius-pill);
}

.skeleton-line.short {
    width: 45%;
}

/* One shared sweep: a genuine work-in-progress indicator, which is the permitted
   case for continuous motion. Reduced-motion flattens it via tokens.css. */
.skeleton-poster,
.skeleton-line {
    background: linear-gradient(
        100deg,
        var(--panel-fill-sunken) 30%,
        color-mix(in srgb, var(--accent-primary) 14%, var(--panel-fill-sunken)) 50%,
        var(--panel-fill-sunken) 70%
    );
    background-size: 300% 100%;
    animation: skeleton-sweep 1.6s var(--ease-standard) infinite;
}

@keyframes skeleton-sweep {
    from { background-position: 180% 0; }
    to   { background-position: -80% 0; }
}

/* ── Discovery sheet ──────────────────────────────────────────────────────── */
/* Fixed to the viewport. This works only because .container carries no
   transform, filter or backdrop-filter (see the layout shell above). */
.discovery-sheet {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1002;
    width: min(460px, calc(100vw - 32px));
    max-height: min(80vh, 660px);
    overflow-y: auto;
    padding: var(--space-3);
    /* Opaque base, as on .filter-popover: the sheet lands over whatever covers
       happen to be under it, and a bright one showed straight through the
       translucent fill and swallowed the Roll again button. */
    background:
        linear-gradient(var(--panel-fill-raised), var(--panel-fill-raised)),
        linear-gradient(165deg, var(--anchor) 0%, var(--canvas) 70%);
    border: var(--border) solid var(--accent-quaternary);
    border-radius: var(--radius-lg);
    box-shadow: var(--panel-lift-high), 0 0 60px rgba(255, 216, 77, 0.22);
    animation: sheet-in var(--motion-base) var(--ease-entrance);
}

.discovery-sheet[hidden] {
    display: none;
}

@keyframes sheet-in {
    from {
        opacity: 0;
        transform: translate(-50%, -46%) scale(0.97);
    }
    to {
        opacity: 1;
        transform: translate(-50%, -50%) scale(1);
    }
}

.discovery-sheet-header {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    margin-bottom: var(--space-2);
}

.discovery-sheet-label {
    flex: 1;
    color: var(--accent-quaternary);
    font-size: 0.95rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.discovery-sheet-close {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    padding: 4px;
    background: transparent;
    color: var(--text-secondary);
    border: none;
    line-height: 0;
    cursor: pointer;
    transition: color var(--motion-hover) var(--ease-standard),
        transform var(--motion-hover) var(--ease-standard);
}

.discovery-sheet-close:hover {
    color: var(--text-primary);
    transform: scale(1.15) rotate(90deg);
}

.discovery-sheet-close:active {
    transform: scale(0.94) rotate(90deg);
}

/* Sheet content is styled by structure rather than by class, so it holds
   whatever markup the roll renders. */
#discoveryContent {
    display: flex;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
}

#discoveryContent img {
    flex-shrink: 0;
    width: 140px;
    aspect-ratio: 2 / 3;
    object-fit: cover;
    border-radius: var(--radius-sm);
    box-shadow: var(--panel-lift);
}

/* One work, alone on the surface, so its title is the anchor rather than a card
   headline. The column stacks on its own rhythm instead of inheriting the
   card's tighter one. */
.discovery-info {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
    min-width: 0;
    flex: 1;
}

.discovery-info .anime-title {
    font-size: 1.35rem;
    line-height: 1.15;
    margin: 0;
}

.discovery-info .anime-meta,
.discovery-info .anime-genres {
    margin: 0;
}

#discoveryContent a {
    color: var(--text-primary);
    text-decoration: none;
    font-weight: 700;
    transition: color var(--motion-hover) var(--ease-standard);
}

#discoveryContent a:hover {
    color: var(--accent-quaternary);
}

.discovery-sheet .genre-tag:hover,
.discovery-sheet .theme-tag:hover {
    background: var(--accent-quaternary-dim);
    border-color: var(--accent-quaternary);
    color: var(--accent-quaternary);
    box-shadow: 0 4px 14px rgba(255, 216, 77, 0.3);
}

.discovery-sheet .btn-similar:hover {
    box-shadow: var(--panel-lift), 0 0 18px rgba(255, 216, 77, 0.42);
}

/* Rolling again is what the sheet is for, so it carries the region hue rather
   than sitting quieter than the pick it is offering to replace. */
#discoveryReroll {
    background: var(--accent-quaternary-dim);
    border-color: color-mix(in srgb, var(--accent-quaternary) 55%, transparent);
    color: var(--accent-quaternary);
    font-weight: 600;
}

#discoveryReroll:hover {
    background: var(--accent-quaternary);
    border-color: var(--accent-quaternary);
    color: var(--text-on-accent);
    box-shadow: var(--panel-lift), 0 0 18px rgba(255, 216, 77, 0.42);
}

/* ── Responsive ───────────────────────────────────────────────────────────── */
@media (max-width: 1024px) {
    .anime-grid,
    .skeleton-grid {
        grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    }

    .filter-popover--wide {
        min-width: 320px;
    }
}

@media (max-width: 768px) {
    .container {
        margin-inline: var(--space-2);
    }

    .hero {
        padding: var(--space-4) var(--space-2) var(--space-3);
    }

    /* Only row one scrolls sideways: every filter stays reachable rather than
       being buried behind an overflow menu. Row two is left to wrap instead,
       because an overflow container would clip the similar-to dropdown. */
    .rail-row--primary {
        flex-wrap: nowrap;
        overflow-x: auto;
        scroll-snap-type: x proximity;
        padding: 2px 0;
    }

    .rail-btn {
        flex: 0 0 auto;
        scroll-snap-align: start;
    }

    .filter-popover,
    .filter-popover--wide {
        position: fixed;
        top: auto;
        left: 0;
        right: 0;
        bottom: 0;
        min-width: 0;
        max-width: none;
        /* A phone gives the sheet less room than the 80vh it used to take:
           at that height the panel read as a page of its own and buried the
           rail that opened it. Everything past the cap scrolls. */
        max-height: min(62vh, 440px);
        /* A flick that runs out of list must not scroll the page underneath,
           which is what made the sheet feel stuck rather than scrollable. */
        overscroll-behavior: contain;
        padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom));
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    }

    /* Thumb-sized rather than pointer-sized on the sheet, and the head tightens
       round it so the taller button costs the list nothing. */
    .popover-close {
        width: 40px;
        height: 40px;
    }

    .popover-head {
        padding-top: var(--space-1);
    }

    /* The genre panel gives the chip row a fixed slot and hands the list the
       rest, which only works while the panel is tall. On a phone the Popular
       row alone runs to four or five lines, and the list it was sharing with
       fell off the bottom of a panel that clips rather than scrolls. So on a
       phone the panel scrolls as one piece and the list keeps its full height
       inside it. */
    #pop-genre {
        overflow-y: auto;
    }

    #pop-genre .popover-field:last-child {
        flex: 0 0 auto;
    }

    #pop-genre .genre-filter {
        max-height: none;
        min-height: 0;
        overflow: visible;
    }

    .controls {
        gap: var(--space-2);
    }

    .results-info {
        margin-left: 0;
    }

    .anime-grid,
    .skeleton-grid {
        grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
        gap: var(--space-2);
    }

    .anime-list .anime-cover-container {
        flex: 0 0 76px;
        width: 76px;
    }
}

@media (max-width: 480px) {
    .container {
        margin-inline: var(--space-1);
        gap: var(--space-2);
    }

    .hero-sub {
        font-size: 0.95rem;
    }

    /* Two inline fields side by side leave each of them too narrow to read the
       value it holds, so they stack and take the full width instead. */
    .rail-row--refine {
        flex-direction: column;
        align-items: stretch;
    }

    .rail-inline-field--grow {
        flex: 1 1 auto;
    }

    .anime-info {
        padding: var(--space-1) var(--space-2) var(--space-2);
    }
}

/* ── Touch fallback: region colour at rest, not gated on hover ────────────── */
/* Any state whose only trigger is hover is invisible to half the users, so every
   hue that blooms under a cursor above is shown outright here. */
@media (hover: none) {
    .genre-tag,
    .theme-tag {
        background: var(--accent-secondary-dim);
        border-color: color-mix(in srgb, var(--accent-secondary) 60%, transparent);
        color: var(--accent-secondary);
    }

    .clickable-filter,
    .crew-name-link {
        color: var(--accent-secondary);
    }

    .anime-studio.clickable-filter,
    .list-meta .clickable-filter,
    .crew-name-link {
        border-bottom-style: solid;
        border-bottom-color: var(--accent-secondary);
    }

    .anime-age-rec {
        border-color: var(--accent-tertiary);
    }

    .watch-together-badge {
        border-color: var(--accent-primary);
    }

    .btn-similar,
    .btn-similar-filter {
        border-color: color-mix(in srgb, var(--accent-quaternary) 60%, transparent);
        color: var(--accent-quaternary);
    }

    .genre-checkbox,
    .chip-btn {
        border-color: color-mix(in srgb, var(--accent-secondary) 30%, var(--panel-border));
    }

    .rating-checkbox-group .genre-checkbox {
        border-color: color-mix(in srgb, var(--accent-curator) 30%, var(--panel-border));
    }

    /* Cards cannot lift on hover here, so their edge carries the identity. */
    .anime-card,
    .list-item {
        border-color: color-mix(in srgb, var(--accent-primary) 18%, var(--panel-border));
    }
}

/* Utility: must win any display-property tie against a same-specificity rule
   declared earlier (.rail-badge is display:inline-flex), so it stays last and
   carries !important. */
.js-hidden {
    display: none !important;
}
