/*
 * util.css — the three utility surfaces, light system.
 *   page.php   (Privacy Policy + any page with no template of its own)  body.apex-pg
 *   search.php (search results)                                          body.apex-pg
 *   404.php                                                              body.error404
 *
 * These were the last dark surfaces on the site. Privacy Policy is the one
 * that mattered: it is linked from the footer of every page, so a visitor
 * could jump from a white page straight onto a navy one. Search and 404 are
 * reachable from anywhere for the same reason.
 *
 * Replaces pg-night.css and nf-404.css (both archived 2026-08-14). One sheet
 * owns all three: they already shared `.apex-page-band` markup, and `:is()`
 * takes the specificity of its single most-specific argument, so
 * `body:is(.apex-pg, .error404)` scores exactly what `body.apex-pg` did — the
 * widening shifts no cascade.
 *
 * `.apex-page-band` is styled by main.css at (0,1,0); every rule here is
 * (0,2,0) or better, so nothing needs !important. The two exceptions are
 * marked: Elementor/Gutenberg-authored content carries inline `style="color:…"`
 * which only !important can reach.
 *
 * Palette lifted verbatim from pst3.css so these match the rest of the site.
 */

body:is(.apex-pg, .error404) {
    --u-ink: #0a1730;
    --u-body: #33415e;
    --u-soft: #4d5b74;
    --u-brand: #22458a;
    --u-brand-deep: #16305f;
    --u-line: var(--a-line);
    --u-hair: var(--a-hair);
    --u-paper: #f2f6fb;
    --u-sans: "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
    --u-ease: cubic-bezier(.22, 1, .36, 1);
    background: #fff;
}

body:is(.apex-pg, .error404) .site-shell,
body:is(.apex-pg, .error404) .site-main { background: #fff }

/* main.css carries `h1, h2, h3 { font-family: var(--font-display) }`, and a
   type selector beats inheritance however low its specificity — declaring the
   face on a wrapper alone leaves every heading in Source Serif. */
body:is(.apex-pg, .error404) .apex-page-band :is(h1, h2, h3, h4, h5, h6) {
    font-family: var(--u-sans);
}


/* ════════ The band ═══════════════════════════════════════════════════════ */

body:is(.apex-pg, .error404) .apex-page-band {
    position: relative;
    background: #fff;
    color: var(--u-body);
    font-family: var(--u-sans);
    -webkit-font-smoothing: antialiased;
    padding-block: clamp(7rem, 16vh, 11rem) clamp(4rem, 9vh, 6.5rem);
}

/* the night field's starfield overlay */
body:is(.apex-pg, .error404) .apex-page-band::before { content: none }

body:is(.apex-pg, .error404) .apex-page-band > .wrap {
    position: relative;
    z-index: 1;
    width: var(--a-shell);
    margin-inline: auto;
}

/* Privacy and Search are read, not scanned, so they narrow to the measure
   itself. They used to set a 725px reading column inside an 1180px wrap, which
   left 585px of nothing beside every paragraph: not a narrow page, a wide page
   with the text pushed against one wall. The band is the column now, so the
   heading and the prose share an edge and the whole thing sits centred. 46rem
   is the reading width the app pages already use. */
body.apex-pg .apex-page-band > .wrap { width: min(46rem, 92vw) }

body:is(.apex-pg, .error404) .apex-page-band h1 {
    margin: 0 0 1.75rem;
    font-size: var(--a-t-h1);
    line-height: 1.06;
    letter-spacing: -.028em;
    font-weight: 600;
    color: var(--u-ink);
    text-wrap: balance;
}


/* ════════ Authored content (Privacy Policy et al) ════════════════════════
   The measure is the band's now, set above, so the heading sits on it too. */

body.apex-pg .apex-page-band__content { max-width: none }

body.apex-pg .apex-page-band__content p,
body.apex-pg .apex-page-band__content li {
    font-size: var(--a-t-body);   /* was 17px; every other page reads at 16 */
    line-height: 1.68;
    color: var(--u-body) !important;   /* beats inline style="color:…" */
}

body.apex-pg .apex-page-band__content p { margin: 0 0 1.15rem }

body.apex-pg .apex-page-band__content ul {
    margin: 0 0 1.4rem;
    padding-left: 1.15rem;
}
body.apex-pg .apex-page-band__content li { margin-bottom: .5rem }

body.apex-pg .apex-page-band__content strong {
    color: var(--u-ink) !important;    /* beats inline style="color:…" */
    font-weight: 600;
}

/* The two below need !important for the same reason the rest of this block
   does, and they are the ones that actually bit. The authored content was
   written against the dark design and carries inline colours that a light page
   cannot live with: every heading is `style="color:#357ded"`, which measures
   3.96:1 on white, and every link is `style="color:#ffffff"` — literally
   invisible the moment the page stopped being navy. Neither is reachable
   without out-ranking the inline declaration. */
body.apex-pg .apex-page-band__content :is(h2, h3, h4, h5, h6) {
    margin: 2.4rem 0 .85rem;
    font-size: var(--a-t-sub);
    line-height: 1.25;
    letter-spacing: -.014em;
    font-weight: 600;
    color: var(--u-ink) !important;
}
body.apex-pg .apex-page-band__content :is(h2, h3, h4, h5, h6):first-child { margin-top: 0 }

body.apex-pg .apex-page-band__content a {
    color: var(--u-brand) !important;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
}
body.apex-pg .apex-page-band__content a:hover { color: var(--u-brand-deep) !important }


/* ════════ Search ═════════════════════════════════════════════════════════ */

body.apex-pg .pg-search {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    margin: 0 0 2.25rem;
    max-width: 34rem;
}

body.apex-pg .pg-search input[type="search"] {
    flex: 1 1 16rem;
    min-width: 0;
    padding: .8rem 1rem;
    border: 1px solid var(--u-line);
    border-radius: var(--a-r-sm);
    background: #fff;
    font: 400 1rem/1.4 var(--u-sans);
    color: var(--u-ink);
}
body.apex-pg .pg-search input[type="search"]::placeholder { color: var(--u-soft) }
body.apex-pg .pg-search input[type="search"]:focus-visible {
    outline: var(--a-focus);
    outline-offset: 2px;
    border-color: var(--u-brand);
}

body.apex-pg .pg-search button {
    padding: var(--a-btn-pad);
    border: 1px solid var(--a-brand);
    border-radius: var(--a-btn-r);
    background: var(--a-brand);
    box-shadow: var(--a-btn-glow);
    color: #fff;
    font: var(--a-btn-font);
    cursor: pointer;
    transition: background .25s var(--u-ease), transform .25s var(--u-ease);
}
body.apex-pg .pg-search button:hover { background: var(--u-brand-deep); transform: translateY(-1px) }
body.apex-pg .pg-search button:active { transform: translateY(0) }

/* the count is information, not a label above a heading. It was set as a
   tracked uppercase eyebrow, which is the one thing this site does not do. */
body.apex-pg .pg-results__count {
    margin: 0 0 1.5rem;
    font-size: var(--a-t-mark);
    font-weight: 600;
    color: var(--u-soft);
}

body.apex-pg .pg-result {
    padding: 1.5rem 0;
    border-bottom: 1px solid var(--u-hair);
    max-width: 68ch;
}
body.apex-pg .pg-result:last-child { border-bottom: 0 }

body.apex-pg .pg-result h2 {
    margin: 0 0 .35rem;
    font-size: var(--a-t-sub);   /* a result title is a sub, not a section head */
    line-height: 1.25;
    letter-spacing: -.014em;
    font-weight: 600;
}
body.apex-pg .pg-result h2 a { color: var(--u-ink); text-decoration: none }
body.apex-pg .pg-result h2 a:hover { color: var(--u-brand); text-decoration: underline; text-underline-offset: 4px }

body.apex-pg .pg-result__meta {
    margin: 0 0 .5rem;
    font-size: var(--a-t-mark);
    color: var(--u-soft);
}

body.apex-pg .pg-result__excerpt {
    margin: 0;
    font-size: var(--a-t-body);
    line-height: 1.6;
    color: var(--u-body);
}

/* Neither of these was styled at all before — the markup shipped and the dark
   sheet never covered it, so both fell back to main.css. */
body.apex-pg .pg-pagination {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-top: 2.25rem;
}
body.apex-pg .pg-pagination :is(a, span) {
    display: inline-grid;
    place-items: center;
    min-width: 2.5rem;
    padding: .55rem .8rem;
    border: 1px solid var(--a-card-line);
    border-radius: var(--a-btn-r);
    font: var(--a-btn-font);
    color: var(--u-ink);
    text-decoration: none;
}
body.apex-pg .pg-pagination a:hover { border-color: var(--u-brand); background: var(--u-paper) }
body.apex-pg .pg-pagination .current {
    background: var(--a-brand);
    border-color: var(--a-brand);
    color: #fff;
}

body.apex-pg .pg-empty-links {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem .75rem;
    margin: 1.25rem 0 0;
    padding: 0;
}
body.apex-pg .pg-empty-links a {
    display: inline-flex;
    padding: .5rem 1rem;
    border: 1px solid var(--u-line);
    border-radius: 999px;
    font-size: .9375rem;
    font-weight: 600;
    color: var(--u-brand);
    text-decoration: none;
    transition: border-color .25s var(--u-ease), background .25s var(--u-ease);
}
body.apex-pg .pg-empty-links a:hover { border-color: var(--u-brand); background: var(--u-paper) }


/* ════════ 404 ════════════════════════════════════════════════════════════ */

body.error404 .apex-page-band { padding-block: clamp(8rem, 20vh, 13rem) clamp(5rem, 12vh, 9rem) }

body.error404 .nf-inner { max-width: 40rem }

body.error404 .not-found-page .nf-inner h1 {
    margin: 0 0 1rem;
    font-size: var(--a-t-h1);
    line-height: 1.06;
    letter-spacing: -.028em;
    font-weight: 600;
    color: var(--u-ink);
}

body.error404 .nf-lede {
    margin: 0 0 2.25rem;
    font-size: var(--a-t-lede);
    line-height: 1.5;
    color: var(--u-soft);
    max-width: 46ch;
}

body.error404 .nf-links {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem .75rem;
}

body.error404 .nf-links a {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: var(--a-btn-pad);
    border: 1px solid var(--a-card-line);
    border-radius: var(--a-btn-r);
    background: #fff;
    font: var(--a-btn-font);
    color: var(--u-ink);
    text-decoration: none;
    transition: border-color .25s var(--u-ease), background .25s var(--u-ease), transform .25s var(--u-ease);
}
body.error404 .nf-links a span { transition: transform .25s var(--u-ease) }
body.error404 .nf-links a:hover {
    border-color: var(--u-brand);
    background: var(--u-paper);
    transform: translateY(-2px);
}
body.error404 .nf-links a:hover span { transform: translateX(3px) }
body.error404 .nf-links a:focus-visible {
    outline: var(--a-focus);
    outline-offset: var(--a-focus-off);
}


/* ════════ Focus ══════════════════════════════════════════════════════════ */

body:is(.apex-pg, .error404) .apex-page-band :is(a, button, input):focus-visible {
    outline: var(--a-focus);
    outline-offset: var(--a-focus-off);
    border-radius: 6px;
}


/* ════════ Reveals ════════════════════════════════════════════════════════
   These templates use the shared motion script (apex_enqueue_shared_motion),
   which adds .is-revealed. The start state is gated on html.apex-anim, which
   that script adds, so without scripts the content simply shows (it used to
   leave the whole Privacy page at opacity 0). */

html.apex-anim body:is(.apex-pg, .error404) [data-reveal] {
    opacity: 0;
    transform: translateY(var(--a-rev-y));
    filter: blur(var(--a-rev-blur));
    transition: opacity var(--a-rev-fade) var(--a-ease), transform var(--a-rev-move) var(--a-ease),
                filter var(--a-rev-fade) var(--a-ease);
    transition-delay: calc(var(--i, 0) * var(--a-rev-step));
}
html.apex-anim body:is(.apex-pg, .error404) [data-reveal].is-revealed { opacity: 1; transform: none; filter: none }

@media (prefers-reduced-motion: reduce) {
    body:is(.apex-pg, .error404) [data-reveal] { opacity: 1; transform: none; transition: none }
    body:is(.apex-pg, .error404) :is(.nf-links a, .pg-search button) { transition: none }
}


/* ════════════════════════════════════════════════════════════════════════
   THE SHARED FOOTER, RE-SKINNED
   Same treatment as every other light page: the ridge is swapped for the
   ice-shelf plate with the page's white fading into it. Scoped per body class
   everywhere it appears, so each new surface has to opt in.
   ════════════════════════════════════════════════════════════════════════ */

body:is(.apex-pg, .error404) .nx-footer {
    position: relative;
    background: linear-gradient(to bottom, var(--footer-fade, #fff) 0, var(--footer-fade, #fff) 4px, #02122f 4px); /* the top 4px match the page, so a fractional footer edge never shows a grey seam */
    padding-top: 0;
    overflow: hidden;
}

body:is(.apex-pg, .error404) .nx-footer__ridge { display: none }

body:is(.apex-pg, .error404) .nx-footer::before {
    content: "";
    display: block;
    width: 100%;
    aspect-ratio: 2172 / 374;
    /* the top of the shelf dissolves into the page above (Lachlan, 29 Oct:
       the hard top edge read as cut off); the ledge and icicles stay crisp */
    background:
        linear-gradient(to bottom, var(--footer-fade, #fff) 0%, var(--footer-fade, #fff) 4%, rgba(255, 255, 255, 0) 55%) top center / 100% 100% no-repeat,
        url("../media/fx/fx-ice-shelf.webp") top center / 100% auto no-repeat;
}

/* the footer's own shell rule owns position, z-index, padding and font now */

/* ════════ 4 NOV: THE 404 STRIKES OUT THE ADDRESS THEY ASKED FOR ═════════════ */
body.error404 .nf-inner { max-width: 44rem }
.nf-bar { display: flex; align-items: center; gap: .6rem; max-width: 100%; padding: .7rem 1.1rem; background: #fff; border: 1px solid var(--a-card-line); border-radius: 999px; box-shadow: var(--a-card-shadow); font-size: 1.05rem; color: #33415e }
.nf-bar__lock { flex: none; width: 1rem; height: 1rem; color: #7f8da6 }
.nf-bar__lock svg { display: block; width: 100%; height: 100% }
.nf-bar__addr { position: relative; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis }
.nf-bar__strike { position: absolute; left: 0; top: 50%; width: 100%; height: .75rem; margin-top: -.35rem; fill: none; stroke: #cf2a27; stroke-width: 2.4; stroke-linecap: round; vector-effect: non-scaling-stroke }
.nf-bar__strike path { vector-effect: non-scaling-stroke }
body.error404 .nf-pen { margin: .55rem 0 1.6rem 1.2rem; font: 400 2.4rem/1 "Apex Hand", cursive; color: #cf2a27; transform: rotate(-2deg); transform-origin: 0 50% }
body.error404 .nf-links { display: block; margin-top: 1.4rem; border-top: 1px solid var(--a-card-line) }
body.error404 .nf-links a { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; width: auto; min-height: 0; padding: .95rem 0; font-size: 1.22rem; font-weight: 500; color: #0a1730; background: none; border: 0; border-bottom: 1px solid var(--a-card-line); border-radius: 0; box-shadow: none }
body.error404 .nf-links a span { color: var(--a-brand) }
body.error404 .nf-links a:hover { color: var(--a-brand); background: none; transform: none; box-shadow: none; border-color: var(--a-card-line) }

/* 6 Nov: the 404 pen offers the nearest page */
body.error404 .nf-pen a { color: inherit; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: .15em }
body.error404 .nf-pen a:hover { color: #a91f1c }
body.error404 .nf-pen a:focus-visible { outline: var(--a-focus); outline-offset: 3px }
