/* site-chrome.css — Navbar redesign Step 4
 *
 * Shared design tokens and styles for the public site navbar.
 * Loaded AFTER base.css so its tokens can override anything earlier.
 * Tokens are namespaced `--nav-*` / `--site-*` to avoid collision.
 *
 * Mobile breakpoint: <=720px switches to hamburger + right-side drawer.
 * The hamburger button itself is JS-injected by site-nav.js at
 * DOMContentLoaded (keeps the server-rendered HTML unchanged and
 * avoids a dead button for no-JS desktop users).
 *
 * CSS minification is deferred (TODO #5); this file ships unminified.
 */

:root {
    --nav-bg: #0a0a0c;
    --nav-fg: #ececec;
    --nav-fg-dim: #a7a7a7;
    --nav-accent: #8b7355;          /* warm tan (spec decision) */
    --nav-hover-bg: #1a1a1e;
    --nav-border: #2a2a2e;
    --nav-dropdown-bg: #111115;
    --nav-dropdown-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
    --nav-radius: 3px;
    --nav-pad-x: 14px;
    --nav-pad-y: 10px;
    --nav-gap: 4px;
    --nav-font-stack: "Open Sans", system-ui, -apple-system, "Segoe UI",
                      Helvetica, Arial, sans-serif;
    --nav-drawer-width: 300px;
    --nav-z-header: 900;
    --nav-z-dropdown: 910;
    --nav-z-drawer: 920;

    /* Contact form tokens (step 5) */
    --form-bg: #000;
    --form-field-bg: #0a0a0c;
    --form-border: #2a2a2e;
    --form-fg: #ececec;
    --form-fg-dim: #a7a7a7;
    --form-accent: #8b7355;

    /* Photo-comment lightbox tokens (step 6) — layered depth: card
     * floats over the blurred page behind it. Inputs are slightly
     * lighter than the card to read as nested surfaces. */
    --lightbox-bg: #141416;
    --lightbox-field-bg: #1c1c20;
}

/* =====================================================================
 * Header wrapper — #header-wrapper is read by updateContentBoxPadding
 * JS in base.html, so the ID must stay intact.
 * ===================================================================== */
#header-wrapper {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    background: var(--nav-bg);
    color: var(--nav-fg);
    font-family: var(--nav-font-stack);
    border-bottom: 1px solid var(--nav-border);
    z-index: var(--nav-z-header);
}

.site-nav-csrf {
    /* template-tag CSRF sentinel — never displayed */
    display: none !important;
}

/* .site-nav-wrapper width tracks the legacy #contentBox column so the
 * header band visually aligns with the content below it (base.css owns
 * #contentBox at 70% / 812px / 100%). Default = wide desktop: 70%,
 * menu LEFT / title RIGHT via row-reverse. Stacked + mobile regimes
 * override below.
 */
.site-nav-wrapper {
    display: flex;
    flex-direction: row-reverse;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 8px 0;
    width: 70%;
    margin: 0 auto;
    position: relative;
    box-sizing: border-box;
}

.site-nav-logo-link {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    line-height: 0;
}

.site-nav-logo-link img,
#logo {
    display: block;
    width: 315px;
    height: 55px;
}

/* =====================================================================
 * Top-level nav list (desktop default)
 * ===================================================================== */
.site-nav {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: var(--nav-gap);
}

.site-nav-item {
    position: relative;
    display: flex;
    align-items: center;
}

.site-nav-item > a,
.site-nav-dropdown-toggle {
    display: inline-block;
    padding: var(--nav-pad-y) var(--nav-pad-x);
    color: var(--nav-fg);
    text-decoration: none;
    background: transparent;
    border: 0;
    font: inherit;
    font-size: 14px;
    letter-spacing: 0.02em;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    border-radius: var(--nav-radius) var(--nav-radius) 0 0;
}

.site-nav-item > a:hover,
.site-nav-item > a:focus,
.site-nav-dropdown-toggle:hover,
.site-nav-dropdown-toggle:focus {
    background: var(--nav-hover-bg);
    color: var(--nav-fg);
    outline: none;
}

/* Active indicator: scope the warm-tan underline to the text itself,
 * not the whole <li>/button cell. Using text-decoration means the line
 * is drawn under the glyphs only (not under the horizontal padding),
 * which was the bug in review #73. The transparent border-bottom on
 * .site-nav-item > a above stays as-is to preserve baseline spacing. */
.site-nav-item.active > a,
.site-nav-item.active > .site-nav-dropdown-toggle {
    color: var(--nav-fg);
    text-decoration: underline;
    text-decoration-color: var(--nav-accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
}

/* Push the admin menu to the right end */
.site-nav-admin-menu,
.site-nav-item.site-nav-dropdown:has(.site-nav-admin-menu) {
    margin-left: auto;
}

/* =====================================================================
 * Desktop dropdowns — CSS :hover is the primary mechanism.
 * ===================================================================== */
.site-nav-dropdown-menu {
    list-style: none;
    margin: 0;
    padding: 6px 0;
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 200px;
    background: var(--nav-dropdown-bg);
    border: 1px solid var(--nav-border);
    box-shadow: var(--nav-dropdown-shadow);
    display: none;
    z-index: var(--nav-z-dropdown);
}

/* :hover / :focus-within only fire for real mouse devices. Touch
 * devices use click-driven .open (site-nav.js) and fall through to
 * the .open rule below. This prevents iOS "first tap hovers, second
 * tap clicks" disambiguation from corrupting the open/close state. */
@media (hover: hover) and (pointer: fine) {
    .site-nav-dropdown:hover > .site-nav-dropdown-menu,
    .site-nav-dropdown:focus-within > .site-nav-dropdown-menu {
        display: block;
    }
}

.site-nav-dropdown.open > .site-nav-dropdown-menu {
    display: block;
}

.site-nav-dropdown-item > a,
.site-nav-location-node > a {
    display: block;
    padding: 8px 16px;
    color: var(--nav-fg);
    text-decoration: none;
    font-size: 14px;
    white-space: nowrap;
}

.site-nav-dropdown-item > a:hover,
.site-nav-dropdown-item > a:focus,
.site-nav-location-node > a:hover,
.site-nav-location-node > a:focus {
    background: var(--nav-hover-bg);
    color: var(--nav-accent);
    outline: none;
}

/* Active indicator for children inside dropdowns and for location-tree
 * nodes. Uses a left border in the warm-tan accent so the currently
 * viewed gallery stands out inside the flyout. Distinct from the
 * top-level underline but visually cohesive. */
.site-nav-dropdown-item.active > a,
.site-nav-location-node.active > a {
    color: var(--nav-accent);
    border-left: 3px solid var(--nav-accent);
    padding-left: 13px;  /* 16px - 3px border to keep text aligned */
    background: var(--nav-hover-bg);
}

/* Photo count suffix on themes dropdown entries (task #59 redux).
 * Dim, slightly smaller than the label so the count is readable but
 * doesn't fight the theme name for attention. */
.site-nav-dropdown-item-count {
    color: #888;
    font-size: 0.85em;
    margin-left: 2px;
}
.site-nav-dropdown-item.active > a .site-nav-dropdown-item-count {
    color: var(--nav-accent);
}
/* Same dim treatment when the count appears inside the location tree
 * (task #71). Active node inherits the warm-tan accent. */
.site-nav-location-node.active > a .site-nav-dropdown-item-count {
    color: var(--nav-accent);
}

/* =====================================================================
 * Location tree — nested flyouts on desktop.
 * ===================================================================== */
.site-nav-location-tree {
    /* same base as .site-nav-dropdown-menu */
}

.site-nav-location-node {
    position: relative;
    list-style: none;
}

.site-nav-location-children {
    list-style: none;
    margin: 0;
    padding: 6px 0;
    position: absolute;
    top: 0;
    left: 100%;
    min-width: 200px;
    /* Cap nested flyout column width so very long labels don't push the
     * column wider than the parent dropdown. Combined with the JS
     * .flipped-left logic below, this keeps deep chains inside the
     * viewport on narrow desktops (task pass5f bug 2). */
    max-width: 280px;
    background: var(--nav-dropdown-bg);
    border: 1px solid var(--nav-border);
    box-shadow: var(--nav-dropdown-shadow);
    display: none;
    z-index: calc(var(--nav-z-dropdown) + 1);
}

/* Viewport-edge flip: site-nav.js adds .flipped-left to any flyout
 * whose right edge would exceed window.innerWidth. The flipped flyout
 * positions itself to the left of its parent <li> instead of to the
 * right. Re-evaluated on each open/hover (task pass5f bug 2). */
.site-nav-location-children.flipped-left {
    left: auto;
    right: 100%;
}

/* Nested flyouts: hover-driven on mouse devices only. On touch,
 * the stack-drawer path (site-nav.js handleLocationNodeClick)
 * replaces panel contents instead of opening nested flyouts. */
@media (hover: hover) and (pointer: fine) {
    .site-nav-location-node.has-children:hover > .site-nav-location-children,
    .site-nav-location-node.has-children:focus-within > .site-nav-location-children {
        display: block;
    }
}

.site-nav-location-node.has-children.open > .site-nav-location-children {
    display: block;
}

/* Has-children rows reserve a fixed-width chevron slot at the right
 * edge via padding-right + an absolutely positioned `::after`. Pre-fix
 * used `float: right` + `white-space: nowrap`, which bumped the floated
 * chevron to a hidden second line whenever the label text was wide
 * enough to leave less than chevron-width of room (e.g. "Republic of
 * Ireland (60)" inside a 200px-min-width column). Padding-right
 * reserves the slot up front so the row stays single-line regardless
 * of label length. (task pass5f bug 1) */
.site-nav-location-node.has-children > a {
    position: relative;
    padding-right: 28px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.site-nav-location-node.has-children > a::after {
    content: "\203A";  /* single right-pointing angle */
    color: var(--nav-fg-dim);
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    line-height: 1;
    pointer-events: none;
}

/* "Show All" row — server-rendered as the first <li> inside
 * every .site-nav-location-children <ul>. On desktop flyouts it sits at
 * the top of the column and must share the same left padding as the
 * other child rows (task #79). */
.site-nav-location-show-all {
    list-style: none;
}
.site-nav-location-show-all > a {
    display: block;
    padding: 8px 16px;
    color: var(--nav-accent);
    text-decoration: none;
    font-size: 14px;
    white-space: nowrap;
    border-bottom: 1px solid var(--nav-border);
}
.site-nav-location-show-all > a:hover,
.site-nav-location-show-all > a:focus {
    background: var(--nav-hover-bg);
    outline: none;
}

/* =====================================================================
 * Hamburger (JS-injected on DOMContentLoaded)
 * ===================================================================== */
.site-nav-hamburger {
    display: none;
    margin-left: auto;
    background: transparent;
    color: var(--nav-fg);
    border: 1px solid var(--nav-border);
    border-radius: var(--nav-radius);
    font-size: 22px;
    line-height: 1;
    padding: 6px 12px;
    cursor: pointer;
}

.site-nav-hamburger:hover,
.site-nav-hamburger:focus {
    background: var(--nav-hover-bg);
    outline: none;
}

/* =====================================================================
 * Stacked horizontal regime — narrower desktop / tablet / landscape
 * phones. Title on top row, menu row beneath it, both left-aligned.
 * Width tracking matches base.css #contentBox breakpoints:
 *   812-1150px -> width: 812px (matches base.css #header rule)
 *   <=999px    -> width: 100% (same fallback base.css uses)
 * Above the hamburger breakpoint (<=720px) the mobile drawer rules
 * below take over.
 * ===================================================================== */
/* Stacked range: 721-1599. Title row + menu row, both left-aligned.
 * Width rules mirror base.css #header breakpoints so the header band
 * continues to line up with the content column.
 *   >1599px              -> 70% single-row (default rules above)
 *   1151-1599px          -> 70% stacked
 *   812-1150px           -> 812px stacked
 *   721-811px / <=999px  -> 100% stacked (base.css uses 100% at <=999)
 */
@media screen and (max-width: 1599px) and (min-width: 721px) {
    .site-nav-wrapper {
        flex-direction: column;
        align-items: flex-start;
        justify-content: flex-start;
        gap: 6px;
        padding: 8px 12px;
    }
    .site-nav {
        width: 100%;
        flex-wrap: wrap;
        /* Pull the menu row left by one link's horizontal padding so
         * the first link's TEXT left edge lines up with the logo img's
         * left edge (task #80). Without this the menu row appears
         * indented relative to the title row. */
        margin-left: calc(-1 * var(--nav-pad-x));
    }
}

@media screen and (min-width: 812px) and (max-width: 1150px) {
    .site-nav-wrapper {
        width: 812px;
    }
}

@media screen and (max-width: 999px) and (min-width: 721px) {
    .site-nav-wrapper {
        width: 100%;
    }
}

/* =====================================================================
 * Location stack-drawer — layout rules
 *
 * These rules are unconditional (no media query) so they apply to both
 * the narrow-viewport hamburger drawer AND the wide-viewport touch
 * device path. The narrow-viewport block below layers on padding/font
 * overrides tailored to the full-height hamburger drawer; the rules
 * here describe the core "which ul is visible" layout that is
 * identical in both contexts.
 *
 * JS (site-nav.js handleLocationNodeClick) adds .stack-mode to the
 * .site-nav-location-tree root and .stack-active to the currently-
 * visible nested <ul> whenever the device is narrow OR touch.
 * ===================================================================== */

/* Every descendant children ul is hidden by default in stack mode. */
.site-nav-location-tree.stack-mode .site-nav-location-children {
    display: none;
}

/* Ancestor uls on the path to the stack-active descendant render as
 * display: contents — they contribute no box of their own, so the
 * stack-active panel (a nested descendant) isn't hidden by an
 * ancestor's display:none. */
.site-nav-location-tree.stack-mode .site-nav-location-children:has(.stack-active) {
    display: contents;
}

/* The currently-visible stack level. `position: static` overrides
 * the desktop nested-flyout absolute positioning so the panel
 * replaces the dropdown contents inline instead of opening to the
 * right. */
.site-nav-location-tree.stack-mode .site-nav-location-children.stack-active {
    display: block;
    position: static;
    padding: 6px 0;
    background: var(--nav-dropdown-bg);
    border: 0;
    box-shadow: none;
    min-width: 0;
    max-width: none;
}

/* Root-level <li>s: only the one on the path to the stack-active
 * panel stays visible. */
.site-nav-location-tree.stack-mode > .site-nav-location-node {
    display: none;
}
.site-nav-location-tree.stack-mode > .site-nav-location-node:has(.stack-active) {
    display: block;
}

/* Hide the parent node's own <a> along the whole path so the visible
 * level is just the stack-active ul's contents, not a breadcrumb of
 * ancestor rows stacked above it. */
.site-nav-location-tree.stack-mode .site-nav-location-node:has(.stack-active) > a {
    display: none;
}

/* In an ancestor children ul (display:contents pass-through), hide
 * every sibling <li> except the single one on the path to the
 * stack-active panel. Also hide the ancestor's Show All and Back
 * rows — only the stack-active level's own chrome should show. */
.site-nav-location-tree.stack-mode .site-nav-location-children:has(.stack-active) > .site-nav-location-node:not(:has(.stack-active)) {
    display: none;
}
.site-nav-location-tree.stack-mode .site-nav-location-children:has(.stack-active) > .site-nav-location-show-all,
.site-nav-location-tree.stack-mode .site-nav-location-children:has(.stack-active) > .site-nav-location-back {
    display: none;
}

/* Back chevron — injected by JS at the top of each .stack-active ul.
 * Base styling (desktop dropdown panel context); the narrow block
 * below overrides padding/font-size for the full-height hamburger
 * drawer. */
.site-nav-location-back,
.site-nav-location-show-all {
    list-style: none;
}
.site-nav-location-back-btn {
    display: block;
    width: 100%;
    background: transparent;
    color: var(--nav-fg);
    border: 0;
    border-bottom: 1px solid var(--nav-border);
    padding: 8px 16px;
    text-align: left;
    font-size: 14px;
    cursor: pointer;
    font-family: inherit;
}
.site-nav-location-back-btn:hover,
.site-nav-location-back-btn:focus {
    background: var(--nav-hover-bg);
    color: var(--nav-accent);
    outline: none;
}

/* Wide-viewport touch devices: the Location dropdown panel stays
 * anchored to the Location button (desktop dropdown chrome) but
 * uses the stack-drawer content-replacement pattern. The panel must
 * be vertically scrollable — this is the original iPhone landscape
 * bug that motivated the touch pivot. */
/* Wide-viewport touch devices: dropdown panels become vertically
 * scrollable via overflow-y: auto + max-height. This is the same
 * mechanism the shelved portal branch used successfully on iOS.
 * Applied to .site-nav-dropdown-menu so every dropdown (themes,
 * location) scrolls when the content exceeds the viewport.
 *
 * The normal position:absolute anchoring is preserved — the
 * dropdown still opens anchored under its toggle button. The
 * overflow just caps the max height and lets the user scroll
 * internally.
 *
 * Gated on (hover: none) / (pointer: coarse) so the rule does
 * NOT fire on desktop mouse devices, where nested hover flyouts
 * (.site-nav-location-children) are position:absolute descendants
 * that an overflow:auto parent would clip.
 *
 * The two queries are split because Level 4 "( ... or ... )"
 * nesting has spotty parser support. */
@media (min-width: 721px) and (hover: none) {
    .site-nav-dropdown-menu {
        max-height: calc(100vh - 110px);
        overflow-y: auto;
    }
}
@media (min-width: 721px) and (pointer: coarse) {
    .site-nav-dropdown-menu {
        max-height: calc(100vh - 110px);
        overflow-y: auto;
    }
}

/* =====================================================================
 * Mobile drawer (<=720px)
 * ===================================================================== */
@media screen and (max-width: 720px) {
    .site-nav-wrapper {
        padding: 6px 12px;
        gap: 10px;
        width: 100%;
        flex-direction: row;
    }

    .site-nav-hamburger {
        display: inline-block;
    }

    .site-nav {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        width: var(--nav-drawer-width);
        max-width: 85vw;
        background: var(--nav-dropdown-bg);
        border-left: 1px solid var(--nav-border);
        box-shadow: var(--nav-dropdown-shadow);
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        padding: 64px 0 24px;
        overflow-y: auto;
        transform: translateX(100%);
        transition: transform 180ms ease-out;
        z-index: var(--nav-z-drawer);
    }

    .site-nav-wrapper.site-nav-drawer-open .site-nav {
        transform: translateX(0);
    }

    .site-nav-item {
        display: block;
        width: 100%;
        border-bottom: 1px solid var(--nav-border);
    }

    .site-nav-item > a,
    .site-nav-dropdown-toggle {
        display: block;
        width: 100%;
        border-bottom: 0;
        border-left: 3px solid transparent;
        padding: 14px 20px;
        text-align: left;
    }

    .site-nav-item.active > a,
    .site-nav-item.active > .site-nav-dropdown-toggle {
        border-bottom-color: transparent;
        border-left-color: var(--nav-accent);
        /* Mobile drawer uses a left-border on the cell, not the desktop
         * text underline. Clear the underline inherited from the
         * unscoped rule above. */
        text-decoration: none;
    }

    /* Mobile: disable CSS :hover — JS toggles an `open` class instead. */
    .site-nav-dropdown-menu,
    .site-nav-location-children {
        position: static;
        display: none;
        border: 0;
        box-shadow: none;
        background: #0e0e12;
        min-width: 0;
        padding: 0 0 6px 0;
    }

    .site-nav-dropdown:hover > .site-nav-dropdown-menu,
    .site-nav-dropdown:focus-within > .site-nav-dropdown-menu,
    .site-nav-location-node.has-children:hover > .site-nav-location-children,
    .site-nav-location-node.has-children:focus-within > .site-nav-location-children {
        display: none;
    }

    .site-nav-dropdown.open > .site-nav-dropdown-menu,
    .site-nav-location-node.has-children.open > .site-nav-location-children {
        display: block;
    }

    .site-nav-dropdown-item > a,
    .site-nav-location-node > a {
        padding: 12px 32px;
        white-space: normal;
    }

    /* =================================================================
     * Mobile Location stack drawer (task #62)
     *
     * When JS puts the tree in stack-mode, the root <ul> stays visible
     * but all .site-nav-location-children lists are hidden EXCEPT the
     * one marked .stack-active, which fills the drawer as a full-width
     * replacement panel (not indented). A JS-injected back chevron and
     * "Show All" row live at the top of each level.
     *
     * In non-stack-mode (the default), everything collapses back to the
     * root list — child lists stay hidden by the display:none rule
     * above. This gives a clean reset when the drawer closes.
     * ================================================================= */
    .site-nav-location-tree.stack-mode .site-nav-location-node.has-children > a::after {
        /* Keep the chevron for affordance on stack-mode too. */
        content: " \203A";
    }

    /* Children uls that are neither stack-active nor on the path to a
     * stack-active descendant: hidden entirely. */
    .site-nav-location-tree.stack-mode .site-nav-location-children {
        display: none;
    }

    /* Ancestor children uls on the path to the stack-active level stay
     * in the layout so the stack-active panel (a nested descendant of
     * them) is not hidden by an ancestor display:none. They render as
     * display:contents so they contribute no box of their own — only
     * their allowed descendants show. */
    .site-nav-location-tree.stack-mode .site-nav-location-children:has(.stack-active) {
        display: contents;
    }

    .site-nav-location-tree.stack-mode .site-nav-location-children.stack-active {
        display: block;
        position: static;
        padding: 0 0 6px 0;
        background: #0e0e12;
    }

    /* Root-level <li>s: only the one on the path to the stack-active
     * panel stays visible. */
    .site-nav-location-tree.stack-mode > .site-nav-location-node {
        display: none;
    }
    .site-nav-location-tree.stack-mode > .site-nav-location-node:has(.stack-active) {
        display: block;
    }
    /* Hide the parent node's own <a> along the whole path so we don't
     * see "USA > Arizona > children" breadcrumbs stacked at the top. */
    .site-nav-location-tree.stack-mode .site-nav-location-node:has(.stack-active) > a {
        display: none;
    }
    /* In an ancestor children ul (display:contents pass-through), hide
     * everything except the single <li> that contains the stack-active
     * descendant. That means: hide sibling <li>s that do NOT lead to
     * the stack-active panel, and hide the ancestor ul's Show All row
     * (we only want the Show All for the currently-visible level, which
     * lives inside the stack-active ul itself). */
    .site-nav-location-tree.stack-mode .site-nav-location-children:has(.stack-active) > .site-nav-location-node:not(:has(.stack-active)) {
        display: none;
    }
    .site-nav-location-tree.stack-mode .site-nav-location-children:has(.stack-active) > .site-nav-location-show-all,
    .site-nav-location-tree.stack-mode .site-nav-location-children:has(.stack-active) > .site-nav-location-back {
        display: none;
    }

    /* Stack chrome rows injected by JS. */
    .site-nav-location-back,
    .site-nav-location-show-all {
        list-style: none;
    }
    .site-nav-location-back-btn {
        display: block;
        width: 100%;
        background: transparent;
        color: var(--nav-fg);
        border: 0;
        border-bottom: 1px solid var(--nav-border);
        padding: 14px 20px;
        text-align: left;
        font-size: 14px;
        cursor: pointer;
    }
    .site-nav-location-back-btn:hover,
    .site-nav-location-back-btn:focus {
        background: var(--nav-hover-bg);
        color: var(--nav-accent);
        outline: none;
    }
    .site-nav-location-show-all > a {
        display: block;
        padding: 12px 20px;
        color: var(--nav-accent);
        text-decoration: none;
        font-size: 14px;
        border-bottom: 1px solid var(--nav-border);
    }
    .site-nav-location-show-all > a:hover,
    .site-nav-location-show-all > a:focus {
        background: var(--nav-hover-bg);
        outline: none;
    }

    /* In stack-mode, stacked children use the same flat padding as the
     * root level — no indentation (we're replacing the panel, not
     * nesting visually). */
    .site-nav-location-tree.stack-mode .site-nav-location-children.stack-active .site-nav-location-node > a {
        padding: 12px 20px;
        padding-left: 20px;
    }

    .site-nav-location-children .site-nav-location-node > a {
        padding-left: 48px;
    }

    /* Mobile: active-child indicator as a left border, matching the
     * top-level active style. Overrides the desktop left-border rule so
     * padding lines up with the mobile drawer layout. */
    .site-nav-dropdown-item.active > a,
    .site-nav-location-node.active > a {
        border-left: 3px solid var(--nav-accent);
        padding-left: 29px;  /* 32px - 3px */
    }

    .site-nav-location-children .site-nav-location-node.active > a {
        padding-left: 45px;  /* 48px - 3px */
    }

    .site-nav-admin-menu,
    .site-nav-item.site-nav-dropdown:has(.site-nav-admin-menu) {
        margin-left: 0;
        margin-top: auto;
    }
}

/* =====================================================================
 * Contact form — Navbar redesign Step 5 / task #68 spec audit
 *
 * Full-page /contact/. Per docs/contact-navbar-redesign.md View 2, this
 * form sits directly on the page background — no card wrapper. The
 * darker `#0a0a0c` inputs provide contrast against `#000` without a
 * card shade (the lightbox uses `#1c1c20` on `#141416` instead — that
 * intentional split is called out in the spec).
 * ===================================================================== */
.site-contact {
    background: var(--form-bg);
    color: var(--form-fg);
    font-family: var(--nav-font-stack);
    min-height: 70vh;
    display: flex;
    justify-content: center;
}

.site-contact-main {
    width: 100%;
    max-width: 640px;
    padding: 56px 32px 80px;
    box-sizing: border-box;
}

.site-contact-title {
    font-family: "Cormorant Garamond", "Palatino", Georgia, serif;
    font-weight: 400;
    font-style: italic;
    font-size: 1.8rem;
    color: var(--form-fg);
    margin: 0 0 8px 0;
    letter-spacing: 0.01em;
}

.site-contact-lede {
    color: #6b665f;
    font-size: 0.88rem;
    line-height: 1.5;
    letter-spacing: 0.01em;
    margin: 0 0 40px 0;
}

.site-contact-form {
    display: flex;
    flex-direction: column;
    gap: 22px;
}

.site-contact-row {
    display: flex;
    flex-direction: column;
}

.site-contact-label {
    color: #8a857e;
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    margin-bottom: 8px;
}

.site-contact-required {
    color: var(--form-accent);
    font-style: normal;
    margin-left: 1px;
    font-weight: 400;
}

.site-contact-form input[type="text"],
.site-contact-form input[type="email"],
.site-contact-form input[type="url"],
.site-contact-form select,
.site-contact-form textarea {
    background: var(--form-field-bg);
    border: 1px solid #1e1e22;
    color: var(--form-fg);
    font-family: var(--nav-font-stack);
    font-size: 0.88rem;
    padding: 12px 14px;
    border-radius: 6px;
    width: 100%;
    box-sizing: border-box;
    outline: none;
    letter-spacing: 0.01em;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.site-contact-form input[type="text"]::placeholder,
.site-contact-form input[type="email"]::placeholder,
.site-contact-form input[type="url"]::placeholder,
.site-contact-form textarea::placeholder {
    color: #333338;
    font-weight: 300;
}

.site-contact-form input[type="text"]:hover,
.site-contact-form input[type="email"]:hover,
.site-contact-form input[type="url"]:hover,
.site-contact-form select:hover,
.site-contact-form textarea:hover {
    border-color: #2a2a30;
}

.site-contact-form input[type="text"]:focus,
.site-contact-form input[type="email"]:focus,
.site-contact-form input[type="url"]:focus,
.site-contact-form select:focus,
.site-contact-form textarea:focus {
    border-color: var(--form-accent);
    box-shadow: 0 0 0 3px rgba(139, 115, 85, 0.08);
}

.site-contact-form textarea {
    min-height: 150px;
    resize: vertical;
    line-height: 1.6;
}

/* cc_self inline checkbox row — the <label> wraps the checkbox and the
 * visible text so clicking anywhere in the row toggles it. */
.site-contact-checkbox {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    user-select: none;
    margin: 0;
}

.site-contact-checkbox input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    border-radius: 4px;
    border: 1px solid #1e1e22;
    background: var(--form-field-bg);
    cursor: pointer;
    position: relative;
    flex-shrink: 0;
    margin: 0;
    transition: background 0.2s, border-color 0.2s;
}

.site-contact-checkbox input[type="checkbox"]:checked {
    background: var(--form-accent);
    border-color: var(--form-accent);
}

.site-contact-checkbox input[type="checkbox"]:checked::after {
    content: '';
    position: absolute;
    left: 5.5px;
    top: 2.5px;
    width: 5px;
    height: 9px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.site-contact-checkbox span {
    font-size: 0.84rem;
    color: #6b665f;
    letter-spacing: 0.02em;
}

.site-contact-help {
    color: var(--form-fg-dim);
    font-size: 0.72rem;
    margin-top: 6px;
    letter-spacing: 0.01em;
}

.site-contact-error {
    color: #d78a6c;
    font-size: 0.78rem;
    margin-top: 6px;
    padding: 8px 12px;
    background: rgba(215, 138, 108, 0.06);
    border-left: 2px solid #d78a6c;
    border-radius: 2px;
}

.site-contact-recaptcha {
    padding-top: 4px;
}

.site-contact-actions {
    display: flex;
    justify-content: flex-start;
    padding-top: 4px;
}

.site-contact-submit {
    background: var(--form-accent);
    color: #ffffff;
    font-family: var(--nav-font-stack);
    font-size: 0.84rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    padding: 13px 40px;
    border: 0;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.2s ease, box-shadow 0.2s ease;
}

.site-contact-submit:hover {
    background: #a0896b;
    box-shadow: 0 2px 16px rgba(139, 115, 85, 0.2);
}

@media (max-width: 720px) {
    .site-contact-main {
        padding: 32px 20px 60px;
    }
    .site-contact-title {
        font-size: 1.5rem;
    }
    .site-contact-actions {
        justify-content: stretch;
    }
    .site-contact-submit {
        width: 100%;
    }
}

@media (min-width: 1600px) {
    .site-contact-main {
        padding: 64px 32px 100px;
    }
}

/* =====================================================================
 * Photo-comment lightbox (step 6 / tasks #66+#67)
 *
 * All lightbox rules — including the jquery-ui 1.12 base-theme
 * overrides (.ui-dialog.commentForm, .ui-dialog-titlebar, etc.) and
 * the initial `#dialog { display: none }` rule that prevents the
 * snippet from flashing at the bottom of gallery pages before jQuery
 * UI boots — live inline inside
 * templates/contact/contactAjaxSnippet.html. The snippet is both
 * server-rendered into `<div id="dialog">` on gallery pages AND
 * AJAX-reloaded into that same host via gallery.js resetDialog(), so
 * co-locating the styles guarantees they are always present whichever
 * path delivers the markup. See that template for the full rule set.
 * ===================================================================== */
