/*
=======================================
THOSE WHO PLAY THE GAME — the court's NPCs
npcs.css
=======================================

One card per figure: portrait in an arched niche, then who they are,
what they said, and how they stand with the heirs.

Shape and colour follow BRANDING.md: square, 1px gold hairlines, gold
for structure, crimson for the current thing, parchment for speech.
*/

:root {
    /* How a figure stands with the heirs. Court metals and crimson only —
       the old palette reached for the main site's purple and a teal. */
    --relation-ally: var(--royal-gold);
    --relation-friendly: var(--royal-silver);
    --relation-neutral: var(--court-secondary);
    --relation-hostile: var(--crimson-light);
    --relation-unknown: var(--court-secondary);

    --card-appear-duration: .5s;
    --card-transition: .24s;
    --filter-transition: .18s;
}

.npcs-page { overflow-x: hidden; }

/* styles.css gives bare `section` overflow:hidden, which clips the cards. */
.npcs-section,
section.npcs-section,
.npcs-section .container {
    overflow: visible !important;
}

.npcs-section .container {
    max-width: 100%;
    margin: 0;
    padding: 0;
}

/*
======================
FILTER CONTROLS
======================
*/
.filter-controls {
    background: var(--court-raised);
    border: 1px solid var(--court-line);
    border-radius: 0;
    padding: 18px;
    margin-bottom: 30px;
    position: relative;
    box-shadow: none;
}

.npc-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px 18px;
    margin-bottom: 14px;
}

/* The search box: the masthead's court search, sized for the toolbar. */
.npc-search {
    position: relative;
    flex: 1 1 260px;
    display: block;
    margin: 0;
}

.npc-search i {
    position: absolute;
    top: 50%;
    left: 13px;
    transform: translateY(-50%);
    color: var(--court-secondary);
    font-size: 14px;
    pointer-events: none;
}

.npc-search input {
    width: 100%;
    height: 42px;
    padding: 8px 12px 8px 38px;
    border: 1px solid var(--court-border);
    border-radius: 2px;
    background: var(--court-surface);
    color: var(--parchment);
    font: 17px 'EB Garamond', Georgia, serif;
    transition: border-color var(--filter-transition) ease;
}

.npc-search input::placeholder { color: var(--court-secondary); }

.npc-search input:focus {
    outline: none;
    border-color: var(--royal-gold);
}

.npc-search input::-webkit-search-cancel-button { cursor: pointer; }

.primary-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 18px;
}

.filter-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 18px;
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: 2px;
    font-family: 'Cinzel', Georgia, serif;
    font-size: 12px;
    letter-spacing: .12em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background var(--filter-transition) ease,
                border-color var(--filter-transition) ease,
                color var(--filter-transition) ease;
}

.filter-btn i { font-size: 13px; }

.filter-btn:hover,
.filter-btn:focus {
    background: var(--court-hover);
    border-color: var(--court-border);
    transform: none;
    box-shadow: none;
}

.filter-btn.active {
    background: var(--crimson-dark);
    border-color: var(--crimson-blood);
    color: var(--parchment);
    box-shadow: none;
}

/* Tag filters */
.tag-filters {
    background: var(--court-surface);
    border: 1px solid var(--court-line);
    border-radius: 0;
    padding: 16px;
    margin-top: 0;
}

.tag-filter-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px 16px;
    margin-bottom: 12px;
    color: var(--crimson-light);
    font-family: 'Cinzel', Georgia, serif;
    font-size: 12px;
    letter-spacing: .16em;
    text-transform: uppercase;
}

.tag-filter-header i { margin-right: 6px; }

/* "All 102 tags" / "Fewer tags": the rare tags wait behind it. */
.tag-more {
    padding: 4px 10px;
    background: transparent;
    color: var(--court-secondary);
    border: 1px solid var(--court-line);
    border-radius: 2px;
    font-family: 'Cinzel', Georgia, serif;
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background var(--filter-transition) ease, color var(--filter-transition) ease;
}

.tag-more:hover,
.tag-more[aria-expanded="true"] {
    background: var(--court-hover);
    color: var(--parchment);
}

/* A tag fewer than three people carry (js/npcs.js, COMMON_TAG_MIN) shows
   only with the toggle open, or while it is the active filter. */
.tag-btn--rare:not(.active) { display: none; }

.show-all-tags .tag-btn--rare:not(.active) { display: inline-block; }

.tag-btn small {
    margin-left: 7px;
    font-size: 12px;
    color: var(--court-secondary);
}

.tag-btn.active small { color: var(--parchment); opacity: .75; }

.tag-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}

.tag-btn {
    padding: 5px 12px;
    background: none;
    color: var(--court-secondary);
    border: 1px solid var(--court-line);
    border-radius: 2px;
    font-family: 'EB Garamond', Georgia, serif;
    font-size: 16px;
    cursor: pointer;
    transition: background var(--filter-transition) ease,
                border-color var(--filter-transition) ease,
                color var(--filter-transition) ease;
}

.tag-btn:hover {
    background: var(--court-hover);
    color: var(--parchment);
}

.tag-btn.active {
    background: var(--crimson-dark);
    border-color: var(--crimson-blood);
    color: var(--parchment);
    box-shadow: none;
}

/* Active filters */
.active-filters {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    padding-top: 14px;
    border-top: 1px solid var(--court-line);
}

.filter-label {
    color: var(--royal-gold);
    font-family: 'Cinzel', Georgia, serif;
    font-size: 11px;
    letter-spacing: .14em;
    text-transform: uppercase;
}

.active-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    flex-grow: 1;
}

.active-tag {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 4px 11px;
    background: var(--crimson-dark);
    color: var(--parchment);
    border: 1px solid var(--crimson-blood);
    border-radius: 2px;
    font-family: 'EB Garamond', Georgia, serif;
    font-size: 15px;
}

.active-tag i {
    cursor: pointer;
    opacity: .7;
    transition: opacity .2s ease;
}

.active-tag i:hover { opacity: 1; }

.npc-count {
    color: var(--court-secondary);
    font-family: 'EB Garamond', Georgia, serif;
    font-size: 15px;
    white-space: nowrap;
}

.clear-filters {
    padding: 5px 12px;
    background: transparent;
    color: var(--court-secondary);
    border: 1px solid var(--court-line);
    border-radius: 2px;
    font-family: 'Cinzel', Georgia, serif;
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background var(--filter-transition) ease, color var(--filter-transition) ease;
}

.clear-filters:hover {
    background: var(--court-hover);
    color: var(--parchment);
}

/*
======================
NPC CARDS
======================
*/
.npc-list {
    display: flex;
    flex-direction: column;
    gap: 26px;
    margin-bottom: 30px;
    width: 100%;
    max-width: 100%;
    padding: 0;
}

.npc-card {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 28px;
    background: var(--court-raised);
    border: 1px solid var(--court-border);
    border-radius: 0;
    padding: 26px;
    position: relative;
    box-shadow: none;
    transition: transform var(--card-transition) ease,
                border-color var(--card-transition) ease,
                box-shadow var(--card-transition) ease,
                opacity var(--card-transition) ease;
    animation: cardAppear var(--card-appear-duration) ease forwards;
    opacity: 0;
    transform: translateY(20px);
}

.npc-card:hover {
    transform: translateY(-4px);
    border-color: var(--royal-gold);
    box-shadow: none;
}

/*
The card a link asked for, marked so it is obvious which of thirty-odd it
meant. Gold down both edges rather than a flood fill, which the Court reserves
for nothing at all.

Deliberately not an `animation`: a card is invisible until `cardAppear` runs
(see `.npc-card` above, which starts at `opacity: 0`), and an animation
declared here would replace that one and leave the card the link pointed at
as the only one on the page that never fades in. It is a plain state instead,
transitioned by the base rule, and js/npcs.js drops the class after a few
seconds so it fades out the same way it came in.
*/
.npc-card.npc-targeted {
    border-color: var(--royal-gold);
    box-shadow: inset 3px 0 0 var(--royal-gold), inset -3px 0 0 var(--royal-gold);
}

.npc-card.npc-targeted:focus { outline: none; }

/*
======================
PORTRAIT
======================
*/
.npc-portrait {
    display: flex;
    align-items: flex-start;
    justify-content: center;
}

/* The arched niche every portrait in the court sits in. */
.portrait-frame {
    position: relative;
    width: 100%;
    max-width: 260px;
    aspect-ratio: 1 / 1.2;
    background: var(--royal-black);
    border: 1px solid var(--court-border);
    border-bottom: 0;
    border-radius: 50% 50% 0 0 / 22% 22% 0 0;
    overflow: hidden;
    box-shadow: none;
    transition: border-color var(--card-transition) ease;
}

.portrait-frame img {
    position: relative;
    z-index: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
}

.npc-card:hover .portrait-frame { border-color: var(--royal-gold); }

/* With a portrait, the frame opens it full size (js/court-lightbox.js). */
.portrait-frame.has-art { cursor: zoom-in; }

.portrait-frame.has-art:focus-visible {
    outline: none;
    border-color: var(--royal-gold-light);
    box-shadow: 0 0 0 2px var(--royal-gold);
}

/* The ornament corners carry no art; the arch is the frame now. */
.frame-ornament { display: none; }

/*
======================
DETAILS
======================
*/
.npc-details {
    color: var(--parchment);
    font-family: 'EB Garamond', Georgia, serif;
}

.npc-name {
    color: var(--royal-gold-light);
    font-family: 'Cinzel', Georgia, serif;
    font-size: 24px;
    margin-bottom: 10px;
    line-height: 1.3;
    text-shadow: none;
}

/* Importance */
.npc-importance {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 14px;
}

.importance-label,
.meta-label {
    color: var(--royal-gold);
    font-family: 'Cinzel', Georgia, serif;
    font-size: 11px;
    letter-spacing: .14em;
    text-transform: uppercase;
    opacity: 1;
}

.importance-stars {
    color: var(--royal-gold);
    display: flex;
    gap: 3px;
}

.importance-stars .fa-star { filter: none; }

/* Meta */
.npc-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 24px;
    margin-bottom: 16px;
}

.npc-appearance,
.npc-relation,
.npc-last-seen {
    display: flex;
    align-items: center;
    gap: 9px;
}

/* The last session that tags them (js/npcs.js, from the who-appears tags,
   stopping at the reader's spoiler shield). */
.npc-last-seen a.appearance-value {
    text-decoration: none;
    border-bottom: 1px solid var(--court-line);
}

.npc-last-seen a.appearance-value:hover {
    border-bottom-color: var(--royal-gold);
}

.appearance-value {
    color: var(--parchment);
    font-family: 'EB Garamond', Georgia, serif;
    font-size: 17px;
}

/* Relationship */
.relation-value {
    padding: 3px 12px;
    border-radius: 2px;
    background: var(--court-surface);
    border: 1px solid var(--court-line);
    font-family: 'Cinzel', Georgia, serif;
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
}

.relation-ally     { color: var(--relation-ally); border-color: var(--court-border); }
.relation-friendly { color: var(--relation-friendly); }
.relation-neutral  { color: var(--relation-neutral); }
.relation-hostile  { color: var(--relation-hostile); border-color: var(--crimson-blood); }
.relation-unknown  { color: var(--relation-unknown); border-style: dashed; }

/* Description */
.npc-description {
    margin-bottom: 18px;
    font-size: 19px;
    line-height: 1.7;
}

.npc-description p { margin: 0; }

/* The story so far: the development notes the reader has reached, newest
   first, and one line counting what the spoiler shield still holds. */
.npc-developments {
    margin-bottom: 18px;
    padding: 14px 18px;
    border: 1px solid var(--court-line);
    border-left: 2px solid var(--royal-gold);
    background: var(--court-surface);
}

.npc-developments-title {
    margin: 0 0 10px;
    font: 12px 'Cinzel', Georgia, serif;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--court-secondary);
}

.npc-development-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.npc-development {
    display: grid;
    grid-template-columns: minmax(96px, auto) 1fr;
    gap: 4px 14px;
    padding: 8px 0;
    border-top: 1px solid var(--court-line);
    font-size: 17px;
    line-height: 1.6;
}

.npc-development:first-child { border-top: 0; padding-top: 0; }

.npc-development:last-child { padding-bottom: 0; }

.npc-development-when {
    font-family: 'EB Garamond', Georgia, serif;
    color: var(--parchment);
    text-decoration: none;
    border-bottom: 1px solid var(--court-line);
    align-self: start;
    justify-self: start;
    white-space: nowrap;
}

.npc-development-when:hover { border-bottom-color: var(--royal-gold); }

.npc-development-text { color: var(--court-secondary); }

.npc-developments-held {
    margin: 10px 0 0;
    padding-top: 8px;
    border-top: 1px dashed var(--court-line);
    font-size: 15px;
    font-style: italic;
    color: var(--court-secondary);
}

.npc-developments-held i { color: var(--crimson-light); margin-right: 6px; }

/* Quote */
.npc-quote {
    background: var(--court-surface);
    border: 1px solid var(--court-line);
    border-left: 2px solid var(--crimson-blood);
    border-radius: 0;
    padding: 16px 20px;
    margin-bottom: 18px;
    position: relative;
}

.npc-quote blockquote {
    font-family: 'EB Garamond', Georgia, serif;
    font-style: italic;
    font-size: 19px;
    color: var(--parchment);
    margin: 0;
    line-height: 1.6;
}

/* The oversized quote glyphs fought the text; the crimson rule says enough. */
.quote-icon { display: none; }

/* Tags */
.npc-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* Under the tags: the person's own page, and the share button. */
.npc-share {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 16px;
    margin-top: 14px;
}

.npc-page-link {
    font: 600 11px 'Cinzel', Georgia, serif;
    letter-spacing: .12em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--royal-gold);
    transition: color .18s ease;
}

.npc-page-link i { margin-right: 6px; }

.npc-page-link:hover,
.npc-page-link:focus-visible { color: var(--royal-gold-light); }

.tag {
    padding: 4px 12px;
    background: none;
    color: var(--court-secondary);
    border: 1px solid var(--court-line);
    border-radius: 2px;
    font-family: 'EB Garamond', Georgia, serif;
    font-size: 15px;
    transition: background var(--filter-transition) ease, color var(--filter-transition) ease;
}

.tag:hover {
    background: var(--court-hover);
    color: var(--parchment);
    cursor: pointer;
}

/*
======================
LOADING & EMPTY STATES
======================
*/
.loading-indicator {
    text-align: center;
    padding: 40px;
    display: none;
}

.loading-indicator .spinner-inner { border-top-color: var(--royal-gold); }

.loading-indicator p {
    color: var(--court-secondary);
    margin-top: 14px;
    font-family: 'EB Garamond', Georgia, serif;
    font-style: italic;
    font-size: 18px;
}

.no-results-message {
    padding: 48px 26px;
    text-align: center;
    background: var(--court-raised);
    border: 1px solid var(--court-border);
    border-radius: 0;
    margin: 26px 0;
}

.message-content {
    max-width: 540px;
    margin: 0 auto;
}

.no-results-message i {
    font-size: 34px;
    color: var(--royal-gold);
    margin-bottom: 16px;
}

.no-results-message h3 {
    color: var(--royal-gold-light);
    font-family: 'Cinzel', Georgia, serif;
    font-size: 23px;
    margin-bottom: 14px;
}

.no-results-message p {
    color: var(--parchment);
    font-family: 'EB Garamond', Georgia, serif;
    font-size: 18px;
    margin-bottom: 22px;
}

.clear-filters-btn {
    padding: 10px 20px;
    background: var(--crimson-dark);
    color: var(--parchment);
    border: 1px solid var(--crimson-blood);
    border-radius: 2px;
    font-family: 'Cinzel', Georgia, serif;
    font-size: 12px;
    letter-spacing: .12em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background var(--filter-transition) ease;
}

.clear-filters-btn:hover {
    background: var(--crimson-blood);
    transform: none;
    box-shadow: none;
}

/*
======================
ANIMATIONS & FILTER STATES
======================
*/
@keyframes cardAppear {
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.npc-card.filtered { display: none; }

/* Past the reader's spoiler shield (js/court-shield.js). */
.npc-card.spoiled { display: none; }

.npc-card.filtering {
    animation: none;
    opacity: 0;
    transform: translateY(20px);
    transition: opacity .3s ease, transform .3s ease;
}

.npc-card.filtering-in {
    opacity: 1;
    transform: translateY(0);
}

/*
======================
RESPONSIVE
======================
*/
@media (max-width: 1200px) {
    .npc-card,
    .npc-card:nth-child(even) {
        grid-template-columns: 1fr;
        gap: 22px;
    }

    .npc-card:nth-child(even) .npc-portrait { grid-column: 1; }

    .npc-card:nth-child(even) .npc-details {
        grid-column: 1;
        grid-row: 2;
    }

    .npc-portrait { justify-content: center; }

    .portrait-frame { max-width: 230px; }
}

@media (max-width: 768px) {
    .npc-meta {
        flex-direction: column;
        align-items: flex-start;
        gap: 10px;
    }

    .npc-name { font-size: 21px; }

    .npc-card { padding: 20px; }

    .npc-description { font-size: 18px; }
    .npc-development { grid-template-columns: 1fr; gap: 2px; font-size: 16px; }
}

@media (max-width: 576px) {
    .npc-card { padding: 16px; }

    .portrait-frame { max-width: 180px; }

    .npc-quote { padding: 14px; }

    .npc-quote blockquote { font-size: 18px; }

    .filter-controls { padding: 14px; }

    .tag-filters { padding: 14px; }
}
