/* ===================== 
    CSS Variables                 
   ===================== */

:root {
    --sidebar-width: 265px;
    --header-height: 280px;
    --page-padding: 40px;
    --background: #FCFBF8;
    --panel: #ffffff;
    --border-color: rgba(0, 0, 0, 0.08);
    --text: #222;
    --text-muted: #7B7772;
    --text-subtle: #5E5A55;
    --text-faint: #9c9c9c;
    --accent: #6D5CE7;
    --accent-muted: #8B7EF0;
    --accent-soft: rgba(109, 92, 231, 0.10);
    --hover-border: rgba(109, 92, 231, 0.35);
    /* Centers the whole layout past 1680px viewport width instead of letting
       the sidebar/hero stretch to the edges; stays 0 below that width. */
    --outer-margin: max(0px, (100vw - 1680px) / 2);
    --footer-height: 36px;
    --sidebar-inset: 10px;
    --hex-pattern: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12.47' height='21.6' viewBox='0 0 12.47 21.6'%3E%3Cg fill='none' stroke='rgba(0,0,0,0.04)' stroke-width='1'%3E%3Cpolygon points='0,7.2 6.235,3.6 6.235,-3.6 0,-7.2 -6.235,-3.6 -6.235,3.6'/%3E%3Cpolygon points='0,28.8 6.235,25.2 6.235,18 0,14.4 -6.235,18 -6.235,25.2'/%3E%3Cpolygon points='12.47,7.2 18.706,3.6 18.706,-3.6 12.47,-7.2 6.235,-3.6 6.235,3.6'/%3E%3Cpolygon points='12.47,28.8 18.706,25.2 18.706,18 12.47,14.4 6.235,18 6.235,25.2'/%3E%3Cpolygon points='6.235,18 12.47,14.4 12.47,7.2 6.235,3.6 0,7.2 0,14.4'/%3E%3C/g%3E%3C/svg%3E");
}

/* ===================== 
    Reset                 
   ===================== */

*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* ===================== 
    Body                 
   ===================== */

html,
body {
    height: 100%;
}

body {
    font-family: 'Alegreya Sans', sans-serif;
    background-color: var(--background);
    background-image: var(--hex-pattern);
    background-size: 12.47px 21.6px;
    color: var(--text);
    overflow: hidden;
}

/* ===================== 
    Mobile Warning
   =====================  */

.mobile-warning {
    display: none;
}

@media (max-width: 1280px) {

    .mobile-warning {
        position: fixed;
        inset: 0;
        z-index: 999999;
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 38px;
        background-color: var(--background);
        background-image: var(--hex-pattern);
    }

    .mobile-warning img {
        display: block;
        max-width: 100%;
        max-height: 22vh;
        object-fit: contain;
        scale: 80%;
        margin: 0 auto;
    }

    .mobile-warning-content {
        max-width: 560px;
        width: 100%;
        padding: 0 28px 20px 28px;
        background:rgba(95, 77, 234, 0.08);
        border: 1px solid var(--border-color);
        border-radius: 14px;
        text-align: center;
        box-shadow:
            0 12px 12px rgba(234, 227, 239, 0.15);
    }

    .mobile-warning-content h1 {
        margin: 0 0 14px;
        font-family: "Newsreader", serif;
        font-size: 1.6rem;
        font-weight: 600;   
        color: var(--text);
        padding-bottom: 10px;
    }

    .mobile-warning-content p {
        margin: 0 0 16px;
        line-height: 1.7;
        color: var(--text-subtle)
    }

    body:not(.mobile-override) > :not(.mobile-warning) {
        display: none !important;
    }

    body.mobile-override .mobile-warning {
        display: none;
    }
}

/* ===================== 
    Sidebar                 
   ===================== */

.sidebar {
    position: fixed;
    top: 0;
    right: var(--outer-margin);
    height: 100vh;
    width: var(--sidebar-width);
    background: linear-gradient(
        90deg,
        #F5F4F1 0%,
        #F2F2F3 100%
    );
    border-left: 1px solid rgba(0, 0, 0, 0.05);
    display: flex;
    flex-direction: column;
    padding: 48px 36px var(--sidebar-inset);
    z-index: 250;
}

.sidebar-logo {
    display: flex;
    align-items: center;
    gap: 14px;
}

.sidebar-logo-mark {
    flex: none;
    height: 71.28px;
    width: auto;
    aspect-ratio: 41.799 / 78.86;
    object-fit: contain;
}

.sidebar-logo-text {
    font-size: 22px;
    font-weight: 600;
    line-height: 1.08;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    font-family: "Cormorant Garamond", serif;
    color: #000;
}

.sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 18px;
    flex: 1;
    margin-top: 72px;
}

.sidebar-nav a {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    color: var(--text);
    font-size: 14px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: 8px 12px;
    margin: 0 -12px;
    border-radius: 8px;
    transition: color .2s, background-color .2s;
}

.sidebar-nav a:hover {
    background: rgba(0, 0, 0, 0.05);
}

.sidebar-nav a.active {
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 600;
}

.sidebar-nav i {
    width: 15px;
    height: 15px;
    stroke-width: 1.8;
    color: var(--text-faint);
    flex-shrink: 0;
    transition: color .2s;
}

.sidebar-nav a:hover i {
    color: var(--text-subtle);
}

.sidebar-nav a.active i {
    color: var(--accent);
}

/*  Marks a deliberately-hidden department (see sidebar generator's :hidden flag):
    the link stays in the DOM and clickable, but its text/icon render invisible
    until the department becomes the active page, so it can't be discovered by
    browsing the sidebar. */
.sidebar-nav a.hidden-nav:not(.active),
.sidebar-nav a.hidden-nav:not(.active) i {
    color: transparent;
}

/* Suppresses the hover background too, so a hidden link can't be spotted by
   sweeping the mouse down the nav. */
.sidebar-nav a.hidden-nav:not(.active):hover {
    background: transparent;
}

.sidebar-worlds {
    margin-top: auto;
    padding-top: 24px;
}

.sidebar-worlds a {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 17px 14px;
    background: rgba(109, 88, 214, 0.06);
    border-radius: 10px;
    overflow: hidden;
    text-decoration: none;
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
}

.sidebar-worlds a::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 40%;
    background-image: url("../imgs/visit-other-worlds-button.webp");
    background-size: 80%;
    background-position: 55% 25%;
    background-repeat: no-repeat;
    /*  Fades the background image's opposite (bottom-left) corner to
        transparent via mask rather than the image's own alpha, so it blends
        into the link's solid background without needing a pre-faded asset. */
    filter: grayscale(65%) contrast(85%);
    -webkit-mask-image: linear-gradient(315deg, black 0%, transparent 100%);
    mask-image: linear-gradient(315deg, black 0%, transparent 100%);
}

.sidebar-worlds a span {
    position: relative;
    z-index: 1;
    white-space: nowrap;
}

    /* RESPONSIVENESS */

        /* Small heights */
        @media (max-height: 780px) {
            .sidebar {
                padding-top: 35px;
            }
        }

        /*  Tightens the nav's vertical rhythm so Visit Other Worlds
        (.sidebar-worlds, pinned to the bottom via margin-top: auto) stays
        inside the sidebar instead of being pushed off the bottom edge. */
        .sidebar-nav {
            margin-top: 40px;
            gap: 10px;
        }


/* ===================== 
    Main Frame                 
   ===================== */

.main {
    margin-right: var(--sidebar-width);
    height: 100vh;
}

.page-content {
    position: fixed;
    top: var(--header-height);
    left: var(--outer-margin);
    right: calc(var(--sidebar-width) + var(--outer-margin));
    bottom: calc(var(--sidebar-inset) + var(--footer-height));
    overflow-y: auto;
    padding: var(--page-padding);
    background: var(--background);
    container-type: inline-size;
}

.page-slot {
    width: 100%;
    min-height: 100%;
}

/* =====================
    Site Footer
   ===================== */

.site-footer {
    position: fixed;
    left: var(--outer-margin);
    right: calc(var(--sidebar-width) + var(--outer-margin));
    bottom: var(--sidebar-inset);
    height: var(--footer-height);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: var(--background);
    z-index: 150;
}

.site-footer::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    height: var(--sidebar-inset);
    background: var(--background);
}

.site-footer p {
    font-size: 11px;
    color: var(--text-faint);
    text-align: center;
    padding: 0 24px;
}

.site-footer-icon {
    width: 10px;
    height: 10px;
    vertical-align: -1px;
    margin-right: 1px;
}

/* ===================== 
    Breadcrumbs                 
   ===================== */

.breadcrumbs {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 48px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.breadcrumbs a {
    color: var(--text-faint);
    text-decoration: none;
    transition: color .2s;
}

.breadcrumbs a:hover {
    color: var(--accent);
}

.breadcrumbs span {
    color: var(--text-muted);
}

.breadcrumbs .current {
    color: var(--accent);
}

/* ===================== 
    Hero Slot               
   ===================== */

.hero {
    position: fixed;
    top: 0;
    left: var(--outer-margin);
    right: calc(var(--sidebar-width) + var(--outer-margin));
    height: var(--header-height);
    --hero-padding-right: 48px;
    --hero-padding-bottom: 40px;
    padding: 28px var(--hero-padding-right) var(--hero-padding-bottom) 48px;
    background: var(--background);
    border-bottom: 1px solid rgba(0, 0, 0, .05);
    z-index: 100;
}

.hero-artwork {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: clamp(680px, 48vw, 900px);
    background-size: cover;
    background-position: center top;
}

.hero-artwork::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        /* Large atmospheric wash */
        radial-gradient(
            ellipse 120% 140% at top left,
            rgba(252,251,248,0.98) 0%,
            rgba(252,251,248,0.85) 18%,
            rgba(252,251,248,0.55) 35%,
            rgba(252,251,248,0.20) 55%,
            transparent 80%
        ),
        /* Soft left fade */
        linear-gradient(
            to right,
            var(--background) 0%,
            rgba(252,251,248,0.95) 10%,
            rgba(252,251,248,0.65) 22%,
            rgba(252,251,248,0.30) 35%,
            transparent 50%
        ),
        /* Subtle top fade */
        linear-gradient(
            to bottom,
            rgba(252,251,248,0.30) 0%,
            rgba(252,251,248,0.12) 12%,
            transparent 28%
        );
    pointer-events: none;
}

.hero-slot {
    position: relative;
    z-index: 1;
    display: flex;
    width: 100%;
    height: 100%;
}

.hero-slot > *:not(.hero-artwork) {
    position: relative;
    z-index: 1;
}

.hero-text {
    display: flex;
    flex-direction: column;
    max-width: 620px;
}

.hero-text h1 {
    font-family: "Newsreader", serif;
    font-size: 48px;
    font-weight: 500;
    letter-spacing: -0.02em;
    line-height: 1;
    margin-bottom: 22px;
}

.hero-text p {
    font-size: 15px;
    line-height: 1.8;
    color: var(--text-muted);
}

    /* RESPONSIVENESS */

        /* -- Small widths -- */

        @media (max-width: 1370px) {
            .hero-text {
                max-width: 360px;
            }
            
            .hero-text h1 {
                font-size: 46px;
            }
        }

        @media (min-width: 1371px) and (max-width: 1580px) {
            .hero-text {
                max-width: 420px;
            }

            .hero-text h1 {
                font-size: 46px;
            }
        }

        /* -- Normal widths -- */

        @media (min-width: 1581px) {
            .hero-text {
                max-width: 420px;
            }
        }

        /* -- Small heights -- */

        @media (max-height: 900px) {
            
            .hero-text h1 {
                margin-bottom: 14px;
                font-size: 46px;
            }
}

/* =====================
    Shared Components
   ===================== */

    /* SEARCH BAR */

.search-toolbar {
    display: flex;
    gap: 16px;
    align-items: center;
}

.search-toolbar select {
    width: 180px;
}

.search-box {
    display: flex;
    flex: 1;
    align-items: center;
    gap: 12px;
    padding: 0 18px;
    height: 52px;
    border: 1px solid var(--border-color);
    border-radius: 12px;
    background: white;
}

.search-box input {
    flex: 1;
    border: none;
    outline: none;
    background: transparent;
    font: inherit;
}

.search-box i {
    width: 18px;
    height: 18px;
    color: var(--accent-muted);
    flex-shrink: 0;
}

.search-box input::placeholder {
    color: var(--accent-muted);
    opacity: 0.75;
}

    /* DROPDOWNS */

.dropdown {
    position: relative;
    width: 170px;
}

/*  .toolbar-select (used by the Data Flag toolbar) is the same generic
    panel-style select button as .dropdown-button under a different class
    name; they share their base look here so a redesign doesn't have to touch
    both independently. */
.dropdown-button,
.toolbar-select {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 42px;
    background: var(--panel);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    cursor: pointer;
    font: inherit;
    color: var(--text);
    transition: border-color .2s;
}

.dropdown-button:hover,
.toolbar-select:hover {
    border-color: var(--hover-border);
}

.dropdown-button {
    width: 100%;
    padding: 0 16px;
}

.dropdown-button svg {
    width: 18px;
    height: 18px;
    color: var(--accent-muted);
    stroke: var(--accent-muted);
    transition:
        transform .2s,
        color .2s,
        stroke .2s;
}

.dropdown-menu {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    width: max-content;
    padding: 16px;
    background: var(--panel);
    border: 1px solid var(--border-color);
    border-radius: 14px;
    box-shadow: 0 12px 32px rgba(0,0,0,.08);
    z-index: 100;
}

/* .open is toggled by setupDropdownGroup (script-list-filter.js); the menu is
   display:none otherwise so it's unreachable by keyboard/AT when closed. */
.dropdown.open .dropdown-menu {
    display: grid;
    grid-template-columns: auto auto;
    justify-content: start;
    justify-items: start;
    column-gap: 10px;
    row-gap: 8px;
}

/* Flips the chevron icon to point up while the dropdown is open. */
.dropdown.open .dropdown-button i {
    transform: rotate(180deg);
}

/* Collapses the two-column option grid to one column when there's only a
   single option, so it doesn't leave an empty second column. */
.dropdown.open .dropdown-menu:has(.dropdown-option:only-child) {
    grid-template-columns: max-content;
}

.filter-search {
    grid-column: 1 / -1;
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: var(--panel);
    font: inherit;
    font-size: 13px;
    outline: none;
    transition: border-color .2s;
    margin-bottom: 6px;
}

.filter-search:focus {
    border-color: var(--accent);
}

/*  Overrides the generic .dropdown.open layout above specifically for the year
    filter, which has many more options than other filters and reads better as
    a compact 3-column grid than the default 2-column one. */
#year-filter.open .dropdown-menu {
    display: grid;
    grid-template-columns: repeat(3, max-content);
    justify-content: center;
    column-gap: 10px;
    row-gap: 8px;
    min-width: 230px;
}

#year-filter.open .dropdown-menu:has(.dropdown-option:only-child) {
    grid-template-columns: max-content;
    min-width: 0;
}

.dropdown-option {
    padding: 6px 12px;
    white-space: nowrap;
    background: #F6F6F6;
    border: 1px solid transparent;
    border-radius: 999px;
    cursor: pointer;
    font: inherit;
    font-size: 12px;
    font-weight: 500;
    color: var(--text);
    transition:
        background .2s,
        border-color .2s,
        color .2s;
}

/* Set by setupFilterDropdown when an option doesn't match the current search
   text typed into .filter-search. */
.dropdown-option.hidden {
    display: none;
}

.dropdown-option:hover {
    border-color: var(--accent);
}

/* Marks the currently active filter value, toggled by setupFilterDropdown /
   setupWorldFilterDropdown when the user picks an option. */
.dropdown-option.selected {
    background: var(--accent-soft);
    color: var(--accent);
    border-color: transparent;
    font-weight: 600;
}

    /* META ROW */

.meta-item {
    display: flex;
    align-items: center;
}

.meta-item i {
    width: 16px;
    height: 16px;
    stroke-width: 2;
    color: var(--accent);
}

.meta-divider {
    color: var(--accent);
    font-size: 13px;
    line-height: 1;
    opacity: .75;
}

    /* HEADER IMAGE */

.header-image {
    width: clamp(280px, 32vw, 420px);
    height: auto;
    aspect-ratio: 420 / 250;
    margin-top: 8px;
    background: #ECECEC;
    border-radius: 14px;
}

    /* BACK LINK */

.back-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    color: var(--text-muted);
    text-decoration: none;
    transition: color .18s ease;
    padding-bottom: 10px;
}

.back-link:hover {
    color: var(--accent);
}

.back-link svg {
    width: 13px;
    height: 13px;
    stroke-width: 2;
}

    /* BACK TO TOP */

.back-to-top {
    position: fixed;
    right: calc(var(--sidebar-width) + var(--outer-margin) + 32px);
    bottom: calc(var(--sidebar-inset) + var(--footer-height) + 32px);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: none;
    border-radius: 999px;
    background: var(--accent);
    color: white;
    cursor: pointer;
    opacity: 0;
    transform: translateY(8px);
    pointer-events: none;
    transition:
        opacity .2s ease,
        transform .2s ease,
        background .2s ease;
    z-index: 200;
}

/* Toggled by setupBackToTop based on scroll position past `threshold`. */
.back-to-top.visible {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.back-to-top:hover {
    color: white;
    background: var(--accent-muted);
}

.back-to-top i {
    width: 18px;
    height: 18px;
}

    /* DOTTED LINK */

.dotted-link {
    color: inherit;
    text-decoration: underline dotted;
    text-underline-offset: 3px;
}

.dotted-link:hover {
    color: var(--accent);
}

    /* HEX BADGE */

/*  Shared hexagon clip: these four unrelated elements (timeline node, world
    logo frame, recovery icon, BBS avatar) all use the same hex badge shape,
    so the polygon points live in one place instead of being repeated per file. */
.timeline-node,
.world-hex,
.recovery-option-icon,
.thread-avatar {
    clip-path: polygon(
        50% 0%,
        100% 25%,
        100% 75%,
        50% 100%,
        0% 75%,
        0% 25%
    );
}

    /* ACTION CARDS */

.recovery-options {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 16px;
}

.recovery-option {
    display: flex;
    align-items: center;
    gap: 16px;
    height: 100%;
    padding: 20px;
    background: var(--panel);
    border: 1px solid var(--border-color);
    border-radius: 14px;
    cursor: pointer;
    text-align: left;
    font: inherit;
    color: var(--text);
    text-decoration: none;
    transition: border-color .2s ease, background .2s ease;
}

.recovery-option:hover {
    border-color: var(--hover-border);
}

/* Marks the option whose drawer panel is currently open (set by openDrawer). */
.recovery-option.active {
    background: var(--accent-soft);
    border-color: var(--accent);
}

.recovery-option-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 46px;
    flex-shrink: 0;
    background: var(--accent-soft);
    color: var(--accent);
}

.recovery-option-icon svg {
    width: 18px;
    height: 18px;
    stroke-width: 1.8;
}

.recovery-option-label {
    flex: 1;
    font-weight: 500;
    font-size: 0.95rem;
    line-height: 1.3;
}

.recovery-option-arrow {
    width: 16px;
    height: 16px;
    color: var(--text-faint);
    flex-shrink: 0;
    stroke-width: 2;
}

    /* COLLAPSIBLE SECTIONS */

.detail-heading-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.detail-heading-toggle .detail-heading {
    margin-bottom: 0;
}

.detail-toggle-icon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    margin-left: 16px;
    color: var(--text-muted);
    stroke-width: 1.8;
    transition: transform 0.2s ease;
}

/* toggleDetailSection flips aria-expanded rather than a class, since it's
   the accessibility state driving this; the chevron just follows it. */
.detail-heading-toggle[aria-expanded="true"] .detail-toggle-icon {
    transform: rotate(180deg);
}

/*  The 1fr/0fr grid-template-rows swap below is the "animate to auto height"
    trick: a single grid track can be transitioned smoothly, unlike height:auto,
    so this fakes a collapsible section without knowing its content's height. */
.detail-collapse {
    display: grid;
    grid-template-rows: 1fr;
    transition: grid-template-rows 0.25s ease;
}

/* min-height: 0 lets the grid item actually shrink to 0fr instead of being
   clamped to its content's intrinsic height. */
.detail-collapse > * {
    overflow: hidden;
    min-height: 0;
    padding-top: 18px;
}

/* .collapsed is toggled by toggleDetailSection. */
.detail-section-collapsible.collapsed .detail-collapse {
    grid-template-rows: 0fr;
}

.detail-section-collapsible.collapsed .detail-collapse > * {
    padding-top: 0;
}

    /* DRAWER */

/* --drawer-top is set inline by openDrawer to align the drawer with the
   layout it was triggered from, rather than always starting at the top. */
.recovery-drawer {
    position: absolute;
    top: var(--drawer-top, 0);
    right: 0;
    width: min(460px, 40%);
    padding-left: 32px;
    border-left: 1px solid var(--border-color);
    transition: opacity 0.3s ease, transform 0.3s ease;
}

/*  Deliberately overrides the site-wide .hidden (display:none) utility with a
    fade+slide-out instead, so closing the drawer animates rather than snapping
    away; display stays "block" and pointer-events is disabled to compensate. */
.recovery-drawer.hidden {
    display: block;
    opacity: 0;
    transform: translateX(24px);
    pointer-events: none;
}

.drawer-header {
    display: flex;
    justify-content: flex-start;
    margin-bottom: 22px;
}

.drawer-toggle {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    color: var(--text-muted);
    transition: color .18s ease;
}

.drawer-toggle:hover {
    color: var(--accent);
}

.drawer-toggle svg {
    width: 13px;
    height: 13px;
    stroke-width: 2;
}

.drawer-section {
    padding: 28px 0;
    border-bottom: 1px solid var(--border-color);
}

.drawer-section:last-child {
    border-bottom: none;
}

.drawer-section-content {
    line-height: 1.8;
    color: var(--text-subtle);
}

.drawer-section-content p {
    margin: 0 0 16px 0;
    line-height: 1.8;
    color: var(--text-subtle);
}

.drawer-section-content li {
    line-height: 1.7;
    color: var(--text-subtle);
}

.drawer-section-content ul {
    margin: 0;
    padding-left: 20px;
}

.drawer-section-content > :last-child {
    margin-bottom: 0;
}

/* Shared "section title" idiom for a drawer or detail-page heading; each
   consuming page keeps only its own margin as a local override. */
.detail-heading,
.drawer-title,
.drawer-section h3 {
    font-family: "Newsreader", serif;
    font-weight: 500;
}

.detail-heading,
.drawer-title {
    font-size: 1.5rem;
}

.drawer-section h3 {
    font-size: 1.4rem;
}

    /* IMAGE MODAL */

button.dotted-link {
    border: none;
    padding: 0;
    font: inherit;
    cursor: pointer;
    background: none;
}

.artifact-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Uses the native hidden attribute (set/cleared directly by script-common.js)
   rather than a class, since the modal has no other state to combine it with. */
.artifact-modal[hidden] {
    display: none;
}

.artifact-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(20, 18, 15, 0.55);
}

.artifact-modal-carousel {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    max-width: 100%;
}

.artifact-modal-nav {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: var(--panel);
    border: 1px solid var(--border-color);
    border-radius: 50%;
    cursor: pointer;
    color: var(--text-muted);
    transition: border-color .2s ease,
                color .2s ease;
}

.artifact-modal-nav:hover {
    border-color: var(--hover-border);
    color: var(--accent);
}

.artifact-modal-nav i {
    width: 15px;
    height: 15px;
    stroke-width: 1.8;
}

.artifact-modal-nav[hidden] {
    display: none;
}

.artifact-modal-content {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    max-width: min(92vw, 1200px);
    max-height: 92vh;
    background: var(--panel);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 28px;
}

.artifact-modal-image-wrap {
    position: relative;
    max-width: 100%;
    max-height: 76vh;
    overflow: auto;
}

.artifact-modal-content img {
    display: block;
    max-width: 100%;
    max-height: 76vh;
    object-fit: contain;
}

.artifact-modal-image-wrap img {
    cursor: zoom-in;
}

/* .zoomed is toggled by setZoom (script-common.js) whenever zoomLevel > 1;
   it drops the max-width/height clamp so the JS-set width can exceed the frame. */
.artifact-modal-content.zoomed .artifact-modal-image-wrap img {
    max-width: none;
    max-height: none;
    cursor: grab;
    user-select: none;
}

/* .dragging is toggled on mousedown/mouseup so the cursor reflects an active
   pan drag instead of the idle "grab" affordance. */
.artifact-modal-image-wrap.dragging img {
    cursor: grabbing;
}

.artifact-modal-caption {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.artifact-modal-page-count {
    text-align: center;
    font-size: 14px;
    padding-bottom: 2px;
}

.artifact-modal-caption-text {
    text-align: center;
    font-size: 13px;
    color: var(--text-muted);
}

.artifact-modal-close {
    position: absolute;
    top: -18px;
    right: -18px;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--panel);
    border: 1px solid var(--border-color);
    border-radius: 50%;
    cursor: pointer;
    color: var(--text);
}

.artifact-modal-close i {
    width: 16px;
    height: 16px;
    stroke-width: 1.8;
}

.artifact-modal-lang {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}

/* Hidden when the panel has no English source and no "experience" link, so
   there's nothing for the language toggle to switch between. */
.artifact-modal-lang[hidden] {
    display: none;
}

.artifact-modal-lang-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.artifact-modal-lang-options {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 8px;
    font-family: "Alegreya Sans", sans-serif;
    font-size: 12px;
}

.artifact-modal-lang-options .artifact-modal-lang-btn:first-child {
    justify-self: end;
}

.artifact-modal-lang-options .artifact-modal-lang-btn:last-child {
    justify-self: start;
}

.artifact-modal-lang-btn {
    /* Flex so "Translation" and the info icon center against each other
       directly, immune to baseline/vertical-align drift. */
    display: inline-flex;
    align-items: center;
    font-family: inherit;
    font-size: inherit;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    border: none;
    background: none;
    padding: 0;
    color: var(--text-muted);
    cursor: pointer;
    transition: color .18s ease;
}

/* Hovers toward full text color rather than the site's usual accent hover,
   since accent is reserved for .active to mark the selected language. */
.artifact-modal-lang-btn:hover {
    color: var(--text);
}

/* Marks the currently displayed language, set by setLang. */
.artifact-modal-lang-btn.active {
    color: var(--accent);
}

/*  .disabled mirrors the disabled attribute (both set together by openModal)
    so the same dimmed state applies whether or not the button element itself
    supports :disabled styling in a given context. */
.artifact-modal-lang-btn:disabled,
.artifact-modal-lang-btn.disabled {
    color: var(--text-faint);
    cursor: not-allowed;
}

.artifact-modal-lang-btn:disabled:hover,
.artifact-modal-lang-btn.disabled:hover {
    color: var(--text-faint);
}

.artifact-modal-lang-divider {
    width: 1px;
    height: 12px;
    background: var(--border-color);
}

/* Pure-CSS tooltip reading its text from the data-tooltip attribute,
   same pattern as .header-action in style-data-flag.css.
   Centers against "Translation" via the button's flex layout. */
.artifact-modal-lang-btn .artifact-modal-lang-info {
    position: relative;
    display: inline-flex;
    margin-left: 4px;
    cursor: help;
}

/* icons.js replaces the <i> placeholder with <svg data-lucide="info">, so
   target the rendered element. Sized to the word's cap height (~8.4px at
   the 12px label size); Lucide's info circle spans ~83% of its box, so a
   10px box draws it level with "Translation". */
.artifact-modal-lang-info svg[data-lucide="info"] {
    width: 12px;
    height: 12px;
    stroke-width: 2;
    color: var(--text-faint);
}

.artifact-modal-lang-info::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translate(-50%, 4px);
    width: max-content;
    max-width: 220px;
    padding: 8px 10px;
    background: var(--text);
    color: var(--panel);
    border-radius: 6px;
    font-size: 12px;
    font-weight: 500;
    line-height: 1.5;
    text-align: left;
    text-transform: none;
    letter-spacing: normal;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease, transform .2s ease;
    z-index: 1;
}

.artifact-modal-lang-info:hover::after {
    opacity: 1;
    transform: translate(-50%, 0);
}

/* =====================
    Explore Grid
   ===================== */

.explore-section {
    padding-bottom: 56px;
}

.explore-heading {
    margin-bottom: 28px;
    font-family: "Alegreya Sans", sans-serif;
    font-size: 0.92rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent);
}

.explore-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 20px;
}

.explore-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    width: 100%;
    max-width: 170px;
    margin: 0 auto;
    padding: 28px 16px 24px;
    background: var(--background);
    border: 1px solid var(--border-color);
    border-radius: 14px;
    text-align: center;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.explore-card:hover {
    border-color: var(--hover-border);
    transform: translateY(-4px);
    box-shadow: 0 12px 24px rgba(76, 52, 130, 0.14);
}

.explore-card--disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

.explore-card--disabled[title] {
    pointer-events: auto;
}

.explore-card--disabled:hover {
    border-color: var(--border-color);
    transform: none;
    box-shadow: none;
}

.explore-card-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 55px;
    background: var(--accent-soft);
    color: var(--accent);
}

.explore-card-icon i {
    width: 22px;
    height: 22px;
    stroke-width: 1.8;
}

.explore-card-title {
    font-family: "Alegreya Sans", sans-serif;
    font-size: 0.85rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text);
}

.explore-card-desc {
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.explore-card-arrow {
    align-self: flex-start;
    margin-top: auto;
    width: 16px;
    height: 16px;
    color: var(--accent);
    stroke-width: 2;
}

@media (max-width: 1100px) {
    .explore-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media (max-width: 640px) {
    .explore-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* =====================
    Chapter Section
   ===================== */

.chapter-section {
    padding-bottom: 48px;
}

.chapter-section + .chapter-section {
    padding-top: 40px;
    border-top: 1px solid var(--border-color);
}

.chapter-heading {
    margin-bottom: 10px;
    font-family: "Newsreader", serif;
    font-size: 26px;
    font-weight: 500;
    letter-spacing: -0.01em;
}

.chapter-section .card-grid {
    margin-top: 20px;
}


/* =====================
    List Card
   ===================== */

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(560px, 100%), 1fr));
    gap: 28px;
    margin-top: 40px;
}

.list-card {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 24px;
    min-height: 180px;
    padding: 20px;
    background: var(--panel);
    border: 1px solid rgba(0,0,0,.05);
    border-radius: 14px;
}

.list-card.list-card-plain {
    grid-template-columns: 1fr;
    min-height: 0;
}

.list-card-thumbnail {
    display: block;
    width: 100%;
    overflow: hidden;
    border-radius: 10px;
    border: none;
    background: none;
    padding: 0;
    font: inherit;
    text-align: inherit;
}

button.list-card-thumbnail {
    cursor: pointer;
}

.list-card-thumbnail img {
    width: 100%;
    height: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: 10px;
    background: #EAEAEA;
    transition: transform .3s ease;
}

.list-card-thumbnail:hover img {
    transform: scale(1.05);
}

.list-card-content {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
}

.list-card-tag {
    align-self: flex-start;
    margin-bottom: 14px;
    padding: 4px 10px;
    background: var(--accent-soft);
    color: var(--accent);
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.list-card-title {
    margin-bottom: 12px;
    font-family: "Newsreader", serif;
    font-size: 20px;
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: -0.02em;
}

.list-card-title a {
    color: inherit;
    text-decoration: none;
    transition: color .2s ease;
}

.list-card-title a:hover {
    color: var(--accent);
}

.list-card-description {
    margin-bottom: 18px;
    color: var(--text-muted);
    font-size: 16px;
    line-height: 1.6;
}

.list-card-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 16px;
    margin-top: auto;
    padding-top: 24px;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-muted);
}

/* =====================
    Poster Card

    A vertical alternative to .list-card: cover image on top, a small
    category label, and a centered title only (no description or meta row).
   ===================== */

.card-grid--posters {
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

.poster-card {
    display: block;
    background: var(--panel);
    border: 1px solid rgba(0, 0, 0, .05);
    border-radius: 14px;
    overflow: hidden;
    color: inherit;
    text-decoration: none;
    transition: border-color .2s ease, transform .2s ease;
}

.poster-card:hover {
    border-color: var(--hover-border);
    transform: translateY(-4px);
}

.poster-card-cover img {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    background: #EAEAEA;
}

.poster-card-tag {
    display: inline-block;
    margin-bottom: 8px;
    color: var(--accent);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.poster-card-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 6px 18px 0px;
    text-align: center;
}

.poster-card-title {
    font-family: "Newsreader", serif;
    font-size: 20px;
    font-weight: 500;
    letter-spacing: -0.02em;
    line-height: 1;
}

/* =====================
    Info Table
   ===================== */

.info-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--border-color);
    border-radius: 14px;
}

.info-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--panel);
}

.info-table th,
.info-table td {
    padding: 16px 20px;
    text-align: left;
    vertical-align: middle;
    font-size: 14px;
    line-height: 1.6;
}

.info-table thead th {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent);
    border-bottom: 1px solid var(--border-color);
}

.info-table tbody tr + tr {
    border-top: 1px solid var(--border-color);
}

/* =====================
    Empty State
   ===================== */

.empty-state {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 60px 20px;
    color: var(--text-faint);
    text-align: center;
}

.empty-state i {
    width: 28px;
    height: 28px;
    stroke-width: 1.5;
}

/* =====================
    Utilities
   ===================== */

/*  The generic show/hide toggle used throughout the site's JS (list filters,
    panels, tabs, etc. all do classList.toggle("hidden", ...)); components that
    need a different hidden treatment (e.g. .recovery-drawer.hidden's animated
    variant above) override it explicitly instead of relying on this rule. */
.hidden {
    display: none;
}
