/* Anime Compass — shell.css. The chrome every page shares: reset, base type,
   scrollbars, the sticky glass top bar, nav, buttons, and back-to-top. Loaded
   after tokens.css and before the page's own stylesheet on all three pages, so
   these rules are defined exactly once. Every colour is a token, a color-mix()
   over a token, or an accent-tinted rgba() glow. */

/* ── Reset & base ─────────────────────────────────────────────────────────── */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scrollbar-color: color-mix(in srgb, var(--accent-primary) 55%, transparent) rgba(0, 0, 0, 0.32);
}

body {
    font-family: var(--font-ui);
    color: var(--text-primary);
    background: var(--canvas);
    line-height: 1.6;
    min-height: 100vh;
}

h1 {
    color: var(--text-primary);
    font-weight: 700;
    letter-spacing: -0.02em;
}

:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

/* ── Scrollbars: traditional, always visible, wide enough to grab ──────────── */
::-webkit-scrollbar {
    width: 12px;
    height: 12px;
}

::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.32);
}

::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--accent-primary) 45%, transparent);
    border-radius: var(--radius-pill);
    border: 2px solid transparent;
    background-clip: padding-box;
}

::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--accent-primary) 75%, transparent);
    background-clip: padding-box;
}

/* ── Icons ────────────────────────────────────────────────────────────────── */
.icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    line-height: 0;
}

.icon-svg {
    display: block;
}

/* ── Top bar: the one piece of chrome on every page ───────────────────────── */
.top-bar {
    position: sticky;
    top: var(--space-2);
    z-index: 80;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    max-width: 1440px;
    margin-top: var(--space-2);
    margin-inline: max(var(--space-4), calc((100% - 1440px) / 2));
    padding: var(--space-2) var(--space-3);
    background: var(--panel-fill-raised);
    backdrop-filter: blur(var(--panel-blur));
    -webkit-backdrop-filter: blur(var(--panel-blur));
    border: var(--border) solid color-mix(in srgb, var(--accent-primary) 30%, var(--panel-border));
    border-radius: var(--radius-md);
    box-shadow: var(--panel-lift), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

.wordmark {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: var(--text-primary);
    text-decoration: none;
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    white-space: nowrap;
    transition: transform var(--motion-hover) var(--ease-standard);
}

.wordmark:hover {
    transform: translateY(-1px);
}

.wordmark-mark {
    filter: drop-shadow(0 0 8px rgba(61, 224, 232, 0.55));
    transition: filter var(--motion-hover) var(--ease-standard);
}

.wordmark:hover .wordmark-mark {
    filter: drop-shadow(0 0 14px rgba(61, 224, 232, 0.85));
}

/* Search field: recessed into the bar (darker than its host, no lift). */
.top-search {
    flex: 1;
    display: flex;
    align-items: center;
    gap: var(--space-1);
    max-width: 480px;
    background: var(--panel-fill-sunken);
    border: var(--border) solid var(--panel-border);
    border-radius: var(--radius-pill);
    padding: 8px var(--space-2);
    transition: border-color var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard);
}

.top-search:focus-within {
    border-color: var(--accent-primary);
    box-shadow: 0 0 0 3px var(--accent-primary-dim);
}

#searchBox {
    flex: 1;
    min-width: 0;
    background: transparent;
    border: none;
    color: var(--text-primary);
    font-size: 0.9rem;
    font-family: inherit;
    padding: 4px 0;
}

#searchBox::placeholder {
    color: var(--text-secondary);
}

.search-clear {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    background: transparent;
    border: none;
    padding: 2px;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--motion-hover) var(--ease-standard),
        transform var(--motion-hover) var(--ease-standard);
}

.search-clear.visible {
    opacity: 0.8;
    pointer-events: auto;
}

.search-clear:hover {
    opacity: 1;
    transform: scale(1.12);
}

.search-clear:active {
    transform: scale(0.94);
}

/* ── Nav ──────────────────────────────────────────────────────────────────── */
.site-nav {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    flex-shrink: 0;
}

.nav-link {
    display: inline-flex;
    align-items: center;
    color: var(--accent-primary);
    text-decoration: none;
    padding: 8px 18px;
    border-radius: var(--radius-pill);
    font-weight: 600;
    font-size: 0.85rem;
    white-space: nowrap;
    border: var(--border) solid color-mix(in srgb, var(--accent-primary) 55%, transparent);
    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);
}

.nav-link:hover {
    background: var(--accent-primary);
    color: var(--text-on-accent);
    border-color: var(--accent-primary);
    transform: translateY(-2px);
    box-shadow: var(--panel-lift-high), 0 0 20px rgba(61, 224, 232, 0.35);
}

.nav-link:active {
    transform: translateY(0);
}

.nav-link--active {
    background: var(--accent-primary);
    color: var(--text-on-accent);
    border-color: var(--accent-primary);
    box-shadow: 0 0 18px rgba(61, 224, 232, 0.3);
    cursor: default;
    pointer-events: none;
}

/* ── Page title band (statistics, about) ──────────────────────────────────── */
.page-head {
    text-align: center;
    padding: var(--space-6) var(--space-3) var(--space-4);
}

.page-head h1 {
    font-size: clamp(2rem, 5vw, 3.2rem);
    line-height: 1.05;
    letter-spacing: -0.03em;
    margin-bottom: var(--space-2);
}

.page-head p {
    color: var(--text-secondary);
    font-size: 1.05rem;
    max-width: 56ch;
    margin: 0 auto;
}

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-1);
    background: var(--accent-primary);
    color: var(--text-on-accent);
    padding: 12px 24px;
    border-radius: var(--radius-sm);
    border: none;
    cursor: pointer;
    font-weight: 600;
    font-size: 0.9rem;
    font-family: inherit;
    text-decoration: none;
    transition: transform var(--motion-hover) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard),
        filter var(--motion-hover) var(--ease-standard);
}

.btn:hover {
    transform: translateY(-2px);
    box-shadow: var(--panel-lift-high), 0 0 22px rgba(61, 224, 232, 0.35);
    filter: brightness(1.06);
}

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

.btn-secondary {
    background: var(--panel-fill-raised);
    color: var(--text-primary);
    border: var(--border) solid var(--panel-border);
}

.btn-secondary:hover {
    border-color: var(--panel-border-bright);
    box-shadow: var(--panel-lift-high);
}

.btn-small {
    padding: 8px 16px;
    font-size: 0.85rem;
}

/* Disabled controls read as inert rather than silently no-oping. */
.btn:disabled,
button:disabled,
select:disabled,
input:disabled {
    opacity: 0.45;
    filter: saturate(0.25);
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}

/* ── Back to top ──────────────────────────────────────────────────────────── */
.back-to-top {
    position: fixed;
    bottom: var(--space-4);
    right: var(--space-4);
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--accent-primary);
    color: var(--text-on-accent);
    border: none;
    border-radius: 50%;
    cursor: pointer;
    box-shadow: var(--panel-lift), 0 0 18px rgba(61, 224, 232, 0.3);
    opacity: 0;
    transform: translateY(12px);
    pointer-events: none;
    transition: opacity var(--motion-base) var(--ease-standard),
        transform var(--motion-base) var(--ease-standard),
        box-shadow var(--motion-hover) var(--ease-standard);
    z-index: 100;
}

.back-to-top.visible {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.back-to-top.visible:hover {
    transform: translateY(-3px);
    box-shadow: var(--panel-lift-high), 0 0 28px rgba(61, 224, 232, 0.55);
}

.back-to-top.visible:active {
    transform: translateY(0) scale(0.94);
}

/* ── Responsive ───────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
    .top-bar {
        flex-wrap: wrap;
        margin-left: var(--space-2);
        margin-right: var(--space-2);
    }

    .top-search {
        order: 3;
        flex-basis: 100%;
        max-width: none;
    }

    /* The nav and the family switcher are not in the bar at this width: they
       are in the drawer behind the hamburger, and every rule that places them
       is in the Mobile nav section below. */

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

@media (max-width: 480px) {
    .top-bar {
        margin-left: var(--space-1);
        margin-right: var(--space-1);
        gap: var(--space-2);
    }

    .nav-link {
        padding: 8px 14px;
    }

    .back-to-top {
        bottom: var(--space-2);
        right: var(--space-2);
        width: 40px;
        height: 40px;
    }
}

/* ── Site footer ────────────────────────────────────────────────────────────
   Built by site-shell.js into the empty <footer id="siteFooter"> every page
   carries. Holds the affiliate disclosure, which has to appear wherever a
   cover or title links to Amazon. */
.site-footer {
    margin-top: var(--space-8);
    border-top: var(--border) solid var(--panel-border);
    padding: var(--space-4) var(--space-3) var(--space-6);
    text-align: center;
    color: var(--text-secondary);
    font-size: 0.9rem;
    line-height: 1.7;
}

/* .back-to-top is fixed at the viewport's bottom-right, so on the pages that
   carry one the puck would otherwise float over this band. The clearance is
   derived from the puck's own offset and height: change either and change
   this. */
body[data-page="home"] .site-footer,
body[data-page="about"] .site-footer,
body[data-page="statistics"] .site-footer {
    padding-bottom: calc(var(--space-4) + 44px + var(--space-1));
}

.footer-inner {
    max-width: 860px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.footer-brand {
    color: var(--text-primary);
    font-weight: 600;
    letter-spacing: -0.01em;
}

.footer-links {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2);
}

.footer-links a {
    color: var(--accent-secondary);
    text-decoration: none;
    transition: color var(--motion-hover) var(--ease-standard);
}

.footer-links a:hover {
    color: var(--text-primary);
    text-decoration: underline;
}

.footer-link--active {
    color: var(--text-secondary);
}

/* Held at full --text-secondary rather than dimmed: knocking the token back
   with alpha lands inside the mid-grey band the legibility floor rejects. The
   measure and the size drop are what make this the quietest line here. */
.footer-disclosure {
    max-width: 62ch;
    margin: var(--space-1) auto 0;
    font-size: 0.85rem;
    color: var(--text-secondary);
}

@media (max-width: 480px) {
    .site-footer {
        margin-top: var(--space-6);
        padding: var(--space-3) var(--space-3) var(--space-4);
    }

    /* Same derivation against the 40px puck this breakpoint uses. */
    body[data-page="home"] .site-footer,
    body[data-page="about"] .site-footer,
    body[data-page="statistics"] .site-footer {
        padding-bottom: calc(var(--space-2) + 40px + var(--space-1));
    }
}

/* ── Mobile nav: hamburger and drawer ─────────────────────────────────────── */
/* Phone layout only. Every rule below sits inside a max-width query, so the
   desktop bar is exactly the flex row it always was.

   Until this existed the bar wrapped into three stacked rows at 768px and
   under (wordmark plus nav pills, then the search, then the family switcher)
   and held about a fifth of a phone screen on every page, permanently, because
   the bar is sticky. Now the nav and the switcher live in .nav-drawer behind
   one button, and the bar stows itself while the page scrolls down.

   Two things here are load-bearing:

   * The drawer is absolutely positioned, so opening it cannot change the
     header's height. The bar is sticky, which puts its flow box at the top of
     the document: grow or shrink it while the reader is 900px down and every
     element after it moves, which reads as the page lurching under the thumb.
   * Stowing is a transform for the same reason. A transform costs no layout.

   .nav-drawer is display:contents above the breakpoint, so on desktop the nav
   and the switcher stay direct flex children of .top-bar and no desktop rule
   has to know the wrapper is there. */
.nav-drawer {
    display: contents;
}

.nav-toggle {
    display: none;
}

@media (max-width: 768px) {
    .nav-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        /* Ends row one: wordmark hard left, button hard right, and the search
           (order 3, full basis) wrapping to its own row underneath. */
        margin-left: auto;
        flex-shrink: 0;
        width: 44px;
        height: 44px;
        padding: 0;
        background: transparent;
        color: var(--accent-primary);
        border: var(--border) solid color-mix(in srgb, var(--accent-primary) 55%, transparent);
        border-radius: var(--radius-pill);
        cursor: pointer;
        transition: background-color var(--motion-hover) var(--ease-standard),
            color var(--motion-hover) var(--ease-standard),
            border-color var(--motion-hover) var(--ease-standard);
    }

    /* Three bars out of one element: the middle bar is the span itself, the
       outer two are its pseudo-elements, so the button carries no markup to
       keep in sync across four sites. */
    .nav-toggle-bars,
    .nav-toggle-bars::before,
    .nav-toggle-bars::after {
        display: block;
        width: 18px;
        height: 2px;
        border-radius: 2px;
        background: currentColor;
        transition: transform var(--motion-hover) var(--ease-standard),
            background-color var(--motion-hover) var(--ease-standard);
    }

    .nav-toggle-bars {
        position: relative;
    }

    .nav-toggle-bars::before,
    .nav-toggle-bars::after {
        content: '';
        position: absolute;
        left: 0;
    }

    .nav-toggle-bars::before {
        top: -6px;
    }

    .nav-toggle-bars::after {
        top: 6px;
    }

    /* Open, the outer two bars rotate onto the middle one and the middle one
       drops its fill. Dropping the fill rather than the opacity is what keeps
       the other two visible: opacity on the span would take its pseudo-elements
       with it, since a child cannot climb back out of an ancestor's alpha. */
    .top-bar.nav-open .nav-toggle {
        background: var(--accent-primary);
        color: var(--text-on-accent);
        border-color: var(--accent-primary);
    }

    .top-bar.nav-open .nav-toggle-bars {
        background: transparent;
    }

    .top-bar.nav-open .nav-toggle-bars::before {
        transform: translateY(6px) rotate(45deg);
    }

    .top-bar.nav-open .nav-toggle-bars::after {
        transform: translateY(-6px) rotate(-45deg);
    }

    /* The drawer itself: painted opaque rather than composited. The bar's
       backdrop-filter makes it a backdrop root, so a translucent child could
       only blur the bar it sits inside and the page would read straight through
       the links; the autocomplete lists are painted for the same reason. */
    .nav-drawer {
        display: none;
        position: absolute;
        top: calc(100% + var(--space-1));
        left: 0;
        right: 0;
        flex-direction: column;
        gap: var(--space-1);
        padding: var(--space-2);
        background: linear-gradient(var(--panel-fill-raised), var(--panel-fill-raised)), var(--canvas);
        border: var(--border) solid var(--panel-border);
        border-radius: var(--radius-md);
        box-shadow: var(--panel-lift-high);
    }

    .top-bar.nav-open .nav-drawer {
        display: flex;
    }

    /* One pill per row, each the full width of the drawer: a phone tap lands on
       a target it cannot miss rather than on a 90px pill in a wrapped cluster.

       These three are scoped to .nav-drawer rather than left bare, because the
       .site-nav and .site-switcher they override are declared further down the
       file: a bare selector here loses the tie on source order, and the
       switcher keeps the left-hand hairline it wears in the desktop bar. */
    .nav-drawer .site-nav {
        flex-direction: column;
        align-items: stretch;
    }

    .nav-drawer .nav-link {
        justify-content: center;
    }

    /* The hairline dividing the two clusters moves from the left edge to the
       top, as it did when the switcher took its own row in the bar. Its gutter
       is the drawer's own gap above the rule and this padding below it. */
    .nav-drawer .site-switcher {
        flex: 0 0 auto;
        flex-wrap: wrap;
        justify-content: center;
        padding-left: 0;
        padding-top: var(--space-1);
        border-left: none;
        border-top: var(--border) solid var(--panel-border);
    }

    /* Stowed: up by its own height plus the offset it sticks at, so the shadow
       clears the top of the viewport with it. Scrolling up by 8px brings it
       back, and site-shell.js closes the drawer before it goes. */
    .top-bar {
        transition: transform var(--motion-base) var(--ease-standard);
    }

    .top-bar.is-stowed {
        transform: translateY(calc(-100% - var(--space-2) - var(--space-1)));
    }
}

/* ── Family switcher ──────────────────────────────────────────────────────── */
/* The four Marcsplained sites, rendered by site-shell.js immediately after
   .site-nav inside the top bar. Canonical text: identical on all four sites,
   resolving against whichever palette tokens.css binds, so the switcher is one
   shared control rather than four lookalikes.

   It has to read as a different kind of control from .nav-link, which is an
   accent-coloured pill offering a destination inside this site. These are plain
   text at --text-secondary, one weight lighter, with no border and no accent
   until the cursor arrives: page navigation first, sibling sites second. The
   hairline is what divides the two clusters. */
.site-switcher {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    flex-shrink: 0;
    /* Matches .top-bar's own gap, so the hairline sits centred in its gutter
       rather than 24px from the nav and 16px from the first site name. */
    padding-left: var(--space-3);
    border-left: var(--border) solid var(--panel-border);
}

.site-link {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border-radius: var(--radius-pill);
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 500;
    white-space: nowrap;
    transition: color var(--motion-hover) var(--ease-standard),
        transform var(--motion-hover) var(--ease-standard);
}

/* The same lift the rest of the shell uses, at the wordmark's amplitude rather
   than the nav pill's: this is a text link in the bar, and the nearest thing to
   it already moves 1px. */
.site-switcher a.site-link:hover {
    color: var(--accent-secondary);
    transform: translateY(-1px);
}

.site-switcher a.site-link:active {
    transform: translateY(0);
}

/* Inert: it labels where you are rather than offering a destination, so it
   never lifts and never takes an accent. Dimmed by recession rather than by
   colour: the sunken fill reads as cut into the bar, the way an input does,
   while the label itself stays at full --text-secondary. Knocking the token
   back with alpha instead would composite into the mid-grey band the legibility
   floor rejects. Held at rest rather than on hover, so it survives touch. */
.site-link--active {
    background: var(--panel-fill-sunken);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35);
    cursor: default;
}

@media (max-width: 480px) {
    /* Type size holds; only the gaps close. Below roughly 340px the four names
       wrap to a second centred row inside the drawer. */
    .site-switcher {
        flex-wrap: wrap;
        justify-content: center;
        gap: 4px;
        padding-top: var(--space-1);
    }

    .site-link {
        padding: 4px 8px;
    }
}
