/* Tokens (base/root.css) are linked once site-wide — see fragments/header.html. */

/* ============================================================================
   HEADER — new-design (cosplay-kingdom) look.
   Same markup/behavior as before (burger, bell, avatar menu, unread badge);
   only the visual language changed: dark translucent bar, gold logo,
   pink underline nav, solid indigo dropdowns.
   ========================================================================== */

nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: relative;
    word-break: auto-phrase;
    gap: 1.25rem;
}

header {
    background: color-mix(in srgb, var(--shadow-tint) 55%, transparent);
    backdrop-filter: blur(6px);
    padding: 0.9rem 3rem;
    z-index: 30;
    top: 0;
    position: sticky;
}

/* The header's own logo is .site-logo (below). These .logo rules are kept
   because several standalone pages still render their own text logo with this
   class (user/login, user/ranking, user/messages, item/medium) and header.css
   is linked site-wide, so removing them would change those pages. */
.logo {
    font-size: 1.35rem;
    font-weight: 800;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--color-gold);
    text-shadow: 0 0 30px var(--gold-border);
    white-space: nowrap;
}

/* SITE LOGO — the header brand mark.
   OVERFLOW FIX: this used to be a text node with white-space: nowrap. A flex
   item's automatic minimum size is its min-content width, so the full string
   was an unshrinkable floor; below ~450px the row (burger + logo + bell +
   avatar + gaps) exceeded the viewport and the header ran off the screen
   (body has overflow-x: hidden, so it clipped rather than scrolled).
   KEEP min-width: 0 — without it the automatic minimum comes straight back and
   the logo stops shrinking again. */
header .site-logo-link {
    display: flex;
    align-items: center;
    min-width: 0;
    flex: 0 1 auto;
    text-decoration: none;
}

/* HIT-AREA FIX — keep `width: fit-content`.
   These images are sized by HEIGHT and let the width follow the aspect ratio,
   but as flex items with `width: auto` Chrome takes the flex base size from the
   image's INTRINSIC width (logo.png is 1800px wide, logo-mini.png 615px), then
   only clamps it to max-width. The box therefore came out 260px wide while
   object-fit: contain drew the mark at its real ~109px (~42px for the badge)
   in the middle of it — so the <a> around it was a 260px-wide "go home" target
   with ~75px of invisible dead click area on each side of the logo.
   `fit-content` makes the base size the ratio-derived width instead, so the box
   is exactly the visible mark. Do NOT swap it for `auto` — the 260px box (and
   the oversized hit area) comes straight back.
   flex: 0 1 auto stays: fit-content is only the PREFERRED size, so the logo can
   still shrink when the row runs out of space (see the min-width note above). */
header .site-logo,
header .site-logo-mini {
    height: 48px;
    width: fit-content;
    max-width: 260px;
    min-width: 0;
    flex: 0 1 auto;
    display: block;
    object-fit: contain;   /* base/common.css sets img { object-fit: cover } */
}

/* Desktop shows the wide wordmark; the round badge is the mobile stand-in and
   is switched on in the ≤1024px block below (the same breakpoint at which the
   burger appears). Both files are small, and an <img> is fetched even when
   display:none, so this costs one extra request rather than a resize flicker. */
header .site-logo-mini { display: none; }

.nav-links {
    display: flex;
    list-style: none;
    width: 100%;
    justify-content: space-between;
}

.nav-links a {
    color: var(--color-text-muted);
    text-decoration: none;
    font-weight: 600;
    transition: color 0.2s, transform 0.2s;
    position: relative;
    padding: 0.5rem 1rem 0.6rem;
}

.nav-links a:hover {
    color: #fff;
    transform: translateY(-2px);
}

.nav-links a::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    width: 0;
    height: 3px;
    border-radius: 2px;
    background: var(--accent-tertiary);
    transition: all 0.25s ease;
    transform: translateX(-50%);
}

.nav-links a:hover::after { width: 80%; }

/* ALIGNMENT FIX: the avatar is an <img>, i.e. inline content, so this box used
   to be a line box — taller than the image itself by the font's descender gap.
   nav centers the box, the image sat at the top of it, and the avatar ended up
   a few pixels ABOVE the notification bell next to it. Centering the image in
   a flex container removes the phantom descender space and lines the two up. */
.avatar-menu-container {
    position: relative;
    cursor: pointer;
    flex: 0 1 auto;
    min-width: 60px;
    max-width: 180px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.avatar-menu-container:hover {
    transition: transform 220ms ease-out;
    transform: scale(1.1);
}

/* OVERFLOW FIX: the menu is ~15 rows tall and hangs off a sticky header, so on
   a short viewport (landscape phone, small laptop, phone with the browser
   chrome expanded) its bottom half used to run past the screen edge with no way
   to reach it — the page itself cannot scroll it into view, because the menu is
   absolutely positioned inside a position:sticky header.
   Cap the height at what is actually left below the header and let the menu
   scroll internally. --avatar-menu-offset is the distance from the top of the
   viewport to the top of the menu (header padding + avatar row + the 0.75rem
   gap above); it is re-declared per breakpoint below, where the padding and the
   avatar size change. 1rem is breathing room at the bottom.
   dvh, not vh: on mobile Safari/Chrome vh means the TALLEST viewport (chrome
   collapsed), so a vh-based cap would still overflow while the address bar is
   showing. dvh tracks the currently visible height. */
.avatar-menu {
    --avatar-menu-offset: 5rem;
    --avatar-menu-gutter: 1rem;
    position: absolute;
    top: calc(100% + 0.75rem);
    right: 0;
    background: var(--menu-bg);
    border: var(--panel-border);
    border-radius: 11px;
    min-width: 220px;
    box-shadow: var(--shadow-menu);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: all 0.3s;
    width: 300px;
    text-align-last: center;
    max-height: calc(100dvh - var(--avatar-menu-offset) - var(--avatar-menu-gutter));
    /* x hidden keeps the rounded corners clipping as before; y auto adds the
       scrollbar only when the cap above actually bites. */
    overflow: hidden auto;
    /* Don't hand the scroll to the page once the menu hits its end. */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    /* Thin, in-palette scrollbar — the default light one looks like a rendering
       glitch on the dark menu. */
    scrollbar-width: thin;
    scrollbar-color: var(--overlay-md) transparent;
}

.avatar-menu::-webkit-scrollbar { width: 6px; }
.avatar-menu::-webkit-scrollbar-track { background: transparent; }

.avatar-menu::-webkit-scrollbar-thumb {
    background: var(--overlay-md);
    border-radius: 3px;
}

.avatar-menu.active {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.avatar-menu a,
.avatar-menu button {
    display: block;
    padding: 1rem;
    color: var(--color-text-muted);
    text-decoration: none;
    transition: background 0.12s, color 0.12s;
    background: none;
    border: none;
    width: 100%;
    text-align: left;
    cursor: pointer;
    font-size: 1rem;
    font-weight: 600;
    font-family: inherit;
}

.avatar-menu a:hover {
    background: var(--overlay-sm);
    color: #fff;
}

/* logout: quiet, warm red text like the new design menu */
.avatar-menu button {
    color: #ff7b9d !important;
    font-weight: 700;
}

.avatar-menu button:hover { background: var(--overlay-sm); }

.avatar-menu div {
    padding: 0.8rem 1rem 0.2rem;
    color: var(--color-text-subtle);
    font-size: 0.8rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.8px;
}

.avatar-menu hr {
    border: none;
    border-top: 1px solid var(--overlay-md);
}

.avatar-menu form { margin: 0; }

nav ul { font-size: large; }

/* SIZE MUST MATCH THE BELL: 45px + 2px ring, same as .notification-bell in
   component/notification-bell.css (38px in the ≤1024px block below, also
   mirrored there). Change one, change the other. */
.user-avatar {
    width: 45px;
    height: 45px;
    /* Ring: base/avatar.css (site-wide). Do not re-declare it here. */
    border-radius: 50%;
    cursor: pointer;
    transition: all 0.3s;
    object-fit: cover;
    display: block;
    background: var(--avatar-empty-bg);
}

.avatar-menu-container:hover .user-avatar {
    box-shadow: 0 0 0 4px var(--overlay-lg);
}

.avatar-menu .avatar-menu-username {
    font-weight: 800;
    font-size: 1.1rem;
    text-align: center;
    color: var(--color-gold);
    word-break: break-all;
}

/* =====================================================================
   RESPONSIVE — mobile header: burger menu + collapsing nav (unchanged
   behavior, recolored).
   ===================================================================== */

.nav-burger {
    display: none;
    background: none;
    border: 1px solid var(--overlay-xl);
    border-radius: 8px;
    color: #fff;
    font-size: 1.4rem;
    line-height: 1;
    padding: 0.35rem 0.6rem;
    cursor: pointer;
    flex-shrink: 0;
}

.nav-burger:hover { border-color: var(--color-gold); color: var(--color-gold); }

@media (max-width: 1024px) {
    header { padding: 0.9rem 1rem; }

    .logo { font-size: 1.2rem; margin-right: auto; }

    /* margin-right: auto keeps the bell/avatar group pinned right. It only eats
       FREE space, so it never blocks the shrinking above — once the row is full
       the auto margin collapses to 0 and flex-shrink takes over. */
    /* MOBILE MARK: wide wordmark out, round badge in. The badge is ~1:1, so a
       34px height is only ~32px wide — it costs a fraction of the row the
       wordmark needed and stays readable instead of shrinking to a smear. */
    header .site-logo { display: none; }
    header .site-logo-mini { display: block; height: 38px; }

    /* CENTERED MARK: taking the logo out of flow and pinning it to 50% of nav
       centers it on the HEADER itself, not on the free space between the burger
       and the bell/avatar group (those two sides differ in width, so an auto
       margin would leave it visibly off-center). nav is position: relative. */
    header .site-logo-link {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        margin-right: 0;
    }

    nav { gap: 0.75rem; }
    nav ul { font-size: large; }

    /* margin-right: auto took over the job the logo's auto margin used to do:
       it eats the free space so the bell + avatar stay pinned right instead of
       being spread out by nav's justify-content: space-between. */
    .nav-burger { display: block; order: -1; margin-right: auto; }

    .nav-links {
        display: none;
        position: absolute;
        top: calc(100% + 0.9rem);
        left: 0;
        right: 0;
        flex-direction: column;
        background: var(--menu-bg);
        border: var(--panel-border);
        border-radius: 11px;
        box-shadow: var(--shadow-menu);
        padding: 0.5rem 0;
        z-index: 20;
    }

    .nav-links.open { display: flex; }

    .nav-links a {
        display: block;
        padding: 0.9rem 1.25rem;
    }

    .nav-links a::after { display: none; }

    /* min-width: 0 overrides the 60px floor above — the avatar is 38px here, so
       the extra 22px was pure dead width in the row that has to fit. */
    .avatar-menu-container { max-width: 130px; min-width: 0; }
    .user-avatar { width: 38px; height: 38px; }

    /* Offset shrinks with the avatar: 0.9rem header padding + 38px avatar
       (+2px ring) + 0.75rem gap ≈ 4.5rem. */
    .avatar-menu {
        min-width: 200px;
        max-width: calc(100vw - 2rem);
        --avatar-menu-offset: 4.5rem;
        /* The fixed mobile footer bar owns the bottom of the screen from this
           breakpoint down, so the menu has to stop above it instead of running
           underneath. --mobile-nav-h is declared in component/mobile-footer.css,
           which is only loaded when the bar is actually rendered (authenticated
           users) — hence the 0px fallback. */
        --avatar-menu-gutter: calc(var(--mobile-nav-h, 0px) + 0.75rem);
    }
}

@media (max-width: 480px) {
    header { padding: 0.75rem 0.75rem; }
    .logo { font-size: 1.05rem; }
    header .site-logo-mini { height: 34px; }
    .avatar-menu-container { max-width: 96px; }
    /* Header padding drops to 0.75rem here. */
    .avatar-menu { --avatar-menu-offset: 4.25rem; }
}

/* PHONE (≤450px) — the width at which the header row stopped fitting.
   Everything below is width recovery: tighter chrome, no item hidden. Rough
   budget at 360px: 20px padding + burger 36 + gap 8 + logo badge 32 + gap 8 +
   bell 38 + gap 8 + avatar 38 = 188px. The square badge (see the ≤1024px block)
   is what bought most of the slack the wide wordmark used to eat. */
@media (max-width: 450px) {
    header { padding: 0.6rem 0.5rem; }
    nav { gap: 0.5rem; }

    header .site-logo-mini { height: 44px;  }

    .nav-burger { font-size: 1.2rem; padding: 0.3rem 0.45rem; }

    /* Was 96px for a 38px avatar. */
    .avatar-menu-container { max-width: 60px; min-width: 0; }

    /* Header padding is 0.6rem here, and the 44px logo badge — not the 38px
       avatar — sets the row height, so the avatar sits 3px lower than it does
       above this breakpoint. */
    .avatar-menu { --avatar-menu-offset: 4rem; }
}

.header-msg-badge {
    margin-left: 8px;
    min-width: 18px;
    height: 18px;
    padding: 0 6px;
    border-radius: var(--radius-pill);
    background: var(--color-danger);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

/* ── Staff work badge ────────────────────────────────────────────────────
   The number beside the Admin / Moderator links: everything on the admin
   panel that still needs a decision, in one figure. Same treatment as
   .header-msg-badge above - same size, same red, same "hidden at zero" rule -
   because it is the same promise: a number here means somebody is waiting on
   you, and it goes away when they are not.

   A separate class rather than reusing .header-msg-badge so the nav row and
   the avatar menu can drift apart later without one of them dragging the
   other; the values are intentionally identical today. */
.nav-work-badge {
    margin-left: 6px;
    min-width: 18px;
    height: 18px;
    padding: 0 6px;
    border-radius: var(--radius-pill);
    background: var(--color-danger);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 700;
    align-items: center;
    justify-content: center;
    line-height: 1;
    vertical-align: middle;
}

/* ── Nav dropdown (Cosplay: Browse / Search) ─────────────────────────────
   ONE ENTRY, TWO PAGES. Cosplay is now two destinations - /cosplay/series,
   which lists every anime, game and show, and /search/cosplay, which filters
   characters and builds. They are different questions ("what is there?" vs
   "find me one that is easy and cheap"), but they are the same section, so
   they share one nav entry instead of widening a row that already has to fit
   on a phone.

   The toggle is a <button> and not a link: it goes nowhere, and a link that
   goes nowhere is a trap for a keyboard or screen reader. It styles itself to
   match .nav-links a exactly, underline animation included, so the row does
   not show which entry is the odd one out.

   It opens on hover AND on click. Hover alone leaves touch users unable to
   reach either page; click alone makes a mouse user work for a menu that is
   free to show. The click handler lives in fragments/header.html and joins the
   single-open group there, so opening this closes the avatar menu and the bell.

   ≤1024px (the burger breakpoint) the whole nav is already a dropdown column,
   and a submenu inside a dropdown is a menu nobody can hit with a thumb. There
   the two links simply render as indented rows of the same column - see the
   media query at the bottom of this block. */
.nav-drop { position: relative; }

.nav-drop-toggle {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font: inherit;
    font-weight: 600;
    color: var(--color-text-muted);
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.5rem 1rem 0.6rem;
    position: relative;
    transition: color 0.2s, transform 0.2s;
}

/* LIFT: every other entry in the row rises 2px under the cursor (.nav-links a
   :hover). The toggle is a <button>, so that rule never reached it and Cosplay
   sat flat while its neighbours moved. It also keeps the lift for as long as the
   entry is the active one - hovered, tabbed into, or with the flyout open -
   instead of dropping back the moment the cursor leaves the label for the menu
   hanging under it, which read as the entry deselecting itself mid-move. */
.nav-drop-toggle:hover,
.nav-drop:hover > .nav-drop-toggle,
.nav-drop:focus-within > .nav-drop-toggle,
.nav-drop.is-open > .nav-drop-toggle {
    color: #fff;
    transform: translateY(-2px);
}

.nav-drop-toggle::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    width: 0;
    height: 3px;
    border-radius: 2px;
    background: var(--accent-tertiary);
    transition: all 0.25s ease;
    transform: translateX(-50%);
}

.nav-drop-toggle:hover::after,
.nav-drop:hover > .nav-drop-toggle::after,
.nav-drop:focus-within > .nav-drop-toggle::after,
.nav-drop.is-open > .nav-drop-toggle::after { width: 80%; }

.nav-drop-caret { font-size: 0.7em; opacity: 0.8; transition: transform 0.2s; }
.nav-drop.is-open .nav-drop-caret { transform: rotate(180deg); }

.nav-drop-menu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    /* The 0.4rem breathing room used to be part of `top`, which put a strip of
       PAGE between the toggle and the panel: moving the cursor down crossed it,
       :hover was lost on the way and the menu closed before it could be aimed
       at. The offset is a margin now, and ::before below covers that strip from
       inside the menu, so the whole path from label to first link stays hovered.
       The extra 4px of height and the -8px sides also absorb the 2px lift the
       toggle takes on hover and a diagonal move towards the first link. */
    margin-top: 0.4rem;
    min-width: 250px;
    background: var(--menu-bg);
    border: var(--panel-border);
    border-radius: 11px;
    box-shadow: var(--shadow-menu);
    padding: 0.4rem;
    z-index: 30;
}

.nav-drop-menu::before {
    content: '';
    position: absolute;
    left: -8px;
    right: -8px;
    bottom: 100%;
    height: calc(0.4rem + 4px);
}

/* focus-within keeps it open while tabbing through the two links. */
.nav-drop:hover > .nav-drop-menu,
.nav-drop:focus-within > .nav-drop-menu,
.nav-drop.is-open > .nav-drop-menu { display: block; }

/* The subtitle is what makes the split obvious at the moment of choosing,
   rather than after landing on the wrong page. */
.nav-drop-menu a {
    display: block;
    padding: 0.6rem 0.8rem;
    border-radius: 8px;
    color: var(--color-text-muted);
}

.nav-drop-menu a:hover { background: var(--overlay-sm); color: #fff; transform: none; }
.nav-drop-menu a::after { display: none; }
.nav-drop-menu b { display: block; color: #fff; font-size: 0.95rem; }
.nav-drop-menu span { display: block; font-size: 0.78rem; color: var(--color-text-subtle); }

@media (max-width: 1024px) {
    /* Inside the burger column the entry keeps its name. Dropping the toggle
       left "Browse" and "Search" as two loose rows between Commission and the
       rest, with nothing saying they were the cosplay section - so the toggle
       stays and becomes a full-width row that expands the two links under it.
       Same button, same handler, same single-open group; only the shape of the
       panel it opens changes. */
    .nav-drop-toggle {
        display: flex;
        width: 100%;
        justify-content: space-between;
        padding: 0.9rem 1.25rem;
        transform: none;
    }

    /* The lift and the underline belong to a horizontal row of entries; in a
       column they just make one row jitter. */
    .nav-drop-toggle:hover,
    .nav-drop:hover > .nav-drop-toggle,
    .nav-drop:focus-within > .nav-drop-toggle,
    .nav-drop.is-open > .nav-drop-toggle { transform: none; }
    .nav-drop-toggle::after { display: none; }

    .nav-drop-menu {
        position: static;
        min-width: 0;
        margin-top: 0;
        background: none;
        border: none;
        box-shadow: none;
        padding: 0;
    }

    .nav-drop-menu::before { display: none; }

    /* Hover is meaningless on a touch screen and firing it here would leave the
       two links expanded from the moment a stray finger brushed the row, so on
       this side of the breakpoint only the explicit toggle opens the group. */
    .nav-drop:hover > .nav-drop-menu,
    .nav-drop:focus-within > .nav-drop-menu { display: none; }
    .nav-drop.is-open > .nav-drop-menu { display: block; }

    /* Indented, and against a faint ground, so the two rows read as belonging
       to the Cosplay row above rather than as two more top-level entries. */
    .nav-drop.is-open > .nav-drop-menu {
        background: var(--overlay-xs, rgba(255, 255, 255, 0.03));
    }

    .nav-drop-menu a { padding: 0.75rem 1.25rem 0.75rem 2.5rem; border-radius: 0; }
    .nav-drop-menu span { display: none; }
}
