/* ============================================================================
   HutchConnect — Trunk-or-Treat (HC.Module #544, EPIC #534)
   Halloween theme. Joey: "i want some pictures and shit on there not a boring page"

   WHY THIS IS A GLOBAL STYLESHEET AND NOT A SCOPED .razor.css
   -----------------------------------------------------------
   A scoped `.razor.css` in this RCL does NOT aggregate into the host's
   {HostAssembly}.styles.css when the module is a cross-repo ProjectReference. The page
   returns 200 with correct HTML and every class unstyled — HC.Module #97, and the single
   most likely way this work becomes invisible. So: a plain file in wwwroot, served at
   _content/ForWardAI.HutchConnect.Module/trunk-or-treat.css, linked from the page's
   <HeadContent>, exactly the way hutchconnect.css already does it.

   NAMESPACING
   -----------
   Every selector is prefixed `tot-`. Nothing here is a bare element or utility selector,
   so it cannot collide with hutchconnect.css, app.css, or post-studio.css no matter what
   order the host loads them in. The one exception is `.tot-page` scoping the Leaflet
   overrides at the bottom, which is what keeps those off any other map on the site.

   NEW FILE, NEW URL — so there is no stale-cache problem for the CSS. ?v=1 is a starting
   point; bump it in TrunkOrTreatPage.razor's <HeadContent> on any future edit.
   ============================================================================ */

.tot-page {
    /* Local tokens only. Deliberately NOT overriding --hc-* : the seasonal theme switcher in
       HutchConnectNav writes those on :root, and stomping them here would recolour the nav
       and footer too. Halloween stays inside this page. */
    --tot-ink: #f8f5ff;
    --tot-ink-dim: #cfc4e8;
    --tot-ink-muted: #9d92b8;
    --tot-night: #140a24;
    --tot-night-2: #1e0f35;
    --tot-card: #241344;
    --tot-card-2: #2d1854;
    --tot-edge: #3d2168;
    --tot-pumpkin: #ff7a1a;
    --tot-pumpkin-dark: #e05c00;
    --tot-slime: #8ef05a;
    --tot-grape: #a855f7;
    --tot-blood: #e2344a;

    background: var(--tot-night);
    color: var(--tot-ink);
    min-height: 60vh;
}

/* ── Hero: night sky, moon, skyline, bats ───────────────────────────────── */

.tot-hero {
    position: relative;
    overflow: hidden;
    padding: 3.5rem 1.5rem 5.5rem;
    text-align: center;
    isolation: isolate;
}

.tot-hero-sky {
    position: absolute;
    inset: 0;
    z-index: 0;
    background:
        radial-gradient(1.5px 1.5px at 12% 18%, rgba(255,255,255,.85) 50%, transparent 51%),
        radial-gradient(1.5px 1.5px at 28% 42%, rgba(255,255,255,.55) 50%, transparent 51%),
        radial-gradient(2px 2px at 47% 12%, rgba(255,255,255,.75) 50%, transparent 51%),
        radial-gradient(1.5px 1.5px at 63% 33%, rgba(255,255,255,.6) 50%, transparent 51%),
        radial-gradient(1.5px 1.5px at 78% 22%, rgba(255,255,255,.8) 50%, transparent 51%),
        radial-gradient(1.5px 1.5px at 88% 48%, rgba(255,255,255,.5) 50%, transparent 51%),
        radial-gradient(2px 2px at 36% 62%, rgba(255,255,255,.45) 50%, transparent 51%),
        radial-gradient(1.5px 1.5px at 70% 66%, rgba(255,255,255,.4) 50%, transparent 51%),
        linear-gradient(180deg, #0c0518 0%, #1b0d30 45%, #3a1a4a 78%, #6b2f3f 100%);
}

.tot-hero-moon {
    position: absolute;
    top: 1.75rem;
    right: 9%;
    width: 78px;
    height: 78px;
    border-radius: 50%;
    z-index: 0;
    background: radial-gradient(circle at 36% 32%, #fffbe8 0%, #ffe9a8 58%, #f3cf72 100%);
    box-shadow: 0 0 34px 12px rgba(255, 230, 160, .32), 0 0 90px 30px rgba(255, 210, 120, .14);
}

.tot-hero-bats {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
}

.tot-bat {
    position: absolute;
    font-size: 1.1rem;
    opacity: .75;
    filter: brightness(.25) saturate(0);   /* silhouette, not a brown emoji bat */
}

.tot-bat-1 { top: 18%;  left: 14%; transform: rotate(-12deg); animation: tot-flap 6s ease-in-out infinite; }
.tot-bat-2 { top: 30%;  left: 76%; font-size: .85rem; transform: rotate(8deg); animation: tot-flap 7.5s ease-in-out infinite .8s; }
.tot-bat-3 { top: 11%;  left: 55%; font-size: .7rem; opacity: .55; animation: tot-flap 9s ease-in-out infinite 1.6s; }

@keyframes tot-flap {
    0%, 100% { transform: translateY(0) rotate(-8deg); }
    50%      { transform: translateY(-11px) rotate(6deg); }
}

/* Respect a reader who has asked the OS for less motion. */
@media (prefers-reduced-motion: reduce) {
    .tot-bat { animation: none; }
}

.tot-hero-skyline {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 74px;
    z-index: 1;
    /* A jagged rooftop line drawn with gradients — no image asset to ship or 404. */
    background: var(--tot-night);
    clip-path: polygon(
        0 100%, 0 56%, 5% 56%, 5% 34%, 9% 34%, 9% 56%, 14% 56%, 14% 70%,
        19% 70%, 19% 44%, 23% 30%, 27% 44%, 27% 70%, 33% 70%, 33% 52%,
        38% 52%, 38% 26%, 42% 26%, 42% 52%, 47% 52%, 47% 66%, 53% 66%,
        53% 40%, 58% 40%, 58% 60%, 63% 60%, 63% 32%, 67% 20%, 71% 32%,
        71% 60%, 77% 60%, 77% 46%, 82% 46%, 82% 68%, 88% 68%, 88% 38%,
        93% 38%, 93% 58%, 100% 58%, 100% 100%
    );
}

.tot-hero-inner {
    position: relative;
    z-index: 2;
    max-width: 680px;
    margin: 0 auto;
}

.tot-hero-kicker {
    margin: 0 0 .5rem;
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--tot-slime);
    text-shadow: 0 0 14px rgba(142, 240, 90, .45);
}

.tot-hero-title {
    margin: 0 0 .65rem;
    font-size: clamp(2.3rem, 9vw, 4rem);
    font-weight: 900;
    line-height: 1.02;
    letter-spacing: -.02em;
    color: var(--tot-pumpkin);
    text-shadow:
        0 2px 0 #7a2d00,
        0 0 26px rgba(255, 122, 26, .55),
        0 0 60px rgba(255, 122, 26, .25);
}

.tot-hero-pumpkin {
    display: inline-block;
    margin-right: .3rem;
    font-size: .8em;
    text-shadow: none;
    animation: tot-bob 4s ease-in-out infinite;
}

@keyframes tot-bob {
    0%, 100% { transform: translateY(0) rotate(-4deg); }
    50%      { transform: translateY(-6px) rotate(4deg); }
}

@media (prefers-reduced-motion: reduce) {
    .tot-hero-pumpkin { animation: none; }
}

.tot-hero-sub {
    margin: 0 auto;
    max-width: 520px;
    font-size: 1.05rem;
    line-height: 1.55;
    color: var(--tot-ink-dim);
}

.tot-hero-count {
    margin: .9rem 0 0;
    font-size: .95rem;
    color: var(--tot-ink);
}

.tot-hero-count strong { color: var(--tot-slime); }

.tot-hero-cta {
    display: inline-block;
    margin-top: 1.35rem;
    padding: .72rem 1.6rem;
    border-radius: 999px;
    background: linear-gradient(180deg, var(--tot-pumpkin) 0%, var(--tot-pumpkin-dark) 100%);
    color: #2a0f00;
    font-weight: 800;
    font-size: .95rem;
    text-decoration: none;
    box-shadow: 0 6px 20px rgba(255, 122, 26, .35);
    transition: transform .15s ease, box-shadow .15s ease;
}

.tot-hero-cta:hover,
.tot-hero-cta:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(255, 122, 26, .45);
}

/* ── UGC notice: the shared component is styled for a light page ─────────── */

.tot-page .tot-ugc-notice {
    max-width: 1040px;
    margin: 1.5rem auto 0;
    background: rgba(61, 33, 104, .5);
    border: 1px solid var(--tot-edge);
    border-radius: 12px;
    color: var(--tot-ink-dim);
}

.tot-page .tot-ugc-notice strong { color: var(--tot-ink); }

/* ── Body ───────────────────────────────────────────────────────────────── */

.tot-body {
    max-width: 1040px;
    margin: 0 auto;
    padding: 2rem 1.5rem 4rem;
}

.tot-loading {
    padding: 3rem 0;
    text-align: center;
    color: var(--tot-ink-muted);
}

.tot-section-heading {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: 0 0 .85rem;
    font-size: 1.15rem;
    font-weight: 800;
    color: var(--tot-ink);
}

/* ── Empty / error states ───────────────────────────────────────────────── */

.tot-empty {
    margin: 2rem 0;
    padding: 3.25rem 1.5rem;
    text-align: center;
    background: var(--tot-card);
    border: 1px solid var(--tot-edge);
    border-radius: 16px;
}

.tot-empty-icon { display: block; font-size: 2.75rem; margin-bottom: .85rem; opacity: .85; }
/* h1 as well as h2: the #628 detail page's 404 and read-failed states are the top-level heading
   of their own page, so they are an h1 there and an h2 inside the browse calendar. */
.tot-empty h1,
.tot-empty h2 { margin: 0 0 .5rem; font-size: 1.25rem; font-weight: 800; color: var(--tot-ink); }
.tot-empty p { margin: 0 auto 1.25rem; max-width: 46ch; color: var(--tot-ink-dim); font-size: .95rem; line-height: 1.55; }

/* Visually distinct from "nothing posted" on purpose — a failure must never look like a
   result (/shared-standing-guidance §1.6). Red edge, alert role, different wording. */
.tot-empty-error {
    border-color: var(--tot-blood);
    box-shadow: inset 0 0 0 1px rgba(226, 52, 74, .35);
}

.tot-empty-cta {
    display: inline-block;
    padding: .6rem 1.35rem;
    border-radius: 999px;
    background: var(--tot-pumpkin);
    color: #2a0f00;
    font-weight: 700;
    font-size: .9rem;
    text-decoration: none;
}

.tot-empty-cta:hover { background: var(--tot-pumpkin-dark); color: #fff; }

/* ── Date jump strip ────────────────────────────────────────────────────── */

.tot-datenav {
    display: flex;
    gap: .6rem;
    overflow-x: auto;
    padding: 0 0 .75rem;
    margin: 0 0 1.75rem;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}

.tot-datechip {
    position: relative;
    flex: 0 0 auto;
    display: grid;
    justify-items: center;
    gap: 1px;
    min-width: 62px;
    padding: .5rem .65rem .55rem;
    border-radius: 12px;
    background: var(--tot-card);
    border: 1px solid var(--tot-edge);
    color: var(--tot-ink-dim);
    text-decoration: none;
    line-height: 1.1;
    transition: border-color .15s ease, transform .15s ease;
}

.tot-datechip:hover,
.tot-datechip:focus-visible {
    border-color: var(--tot-pumpkin);
    transform: translateY(-2px);
}

.tot-datechip-dow { font-size: .62rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.tot-datechip-day { font-size: 1.3rem; font-weight: 900; color: var(--tot-ink); }
.tot-datechip-mon { font-size: .62rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }

.tot-datechip-n {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--tot-slime);
    color: #12300a;
    font-size: .68rem;
    font-weight: 800;
    line-height: 18px;
    text-align: center;
}

.tot-datechip-halloween {
    background: linear-gradient(180deg, var(--tot-pumpkin) 0%, var(--tot-pumpkin-dark) 100%);
    border-color: var(--tot-pumpkin);
    color: #2a0f00;
}

.tot-datechip-halloween .tot-datechip-day { color: #2a0f00; }

/* ── Map ────────────────────────────────────────────────────────────────── */

.tot-map-section { margin: 0 0 2.5rem; }

/* The height lives on the SHELL, not on .tot-map.
   Why: once Leaflet boots it stamps `leaflet-container` onto .tot-map, and the override block
   at the bottom of this file (`.tot-page .leaflet-container`) is two classes to .tot-map's one —
   so its `height:100%` wins. With the height on .tot-map, `100%` resolved against an auto-height
   parent and the map collapsed to ZERO pixels: the page still returned 200, the DOM still had a
   fully-initialised leaflet-container, and the map was simply invisible. Caught by looking at a
   screenshot, which is the only thing that would have caught it. Putting the fixed height on the
   shell makes `height:100%` on the inner element correct instead of destructive. */
.tot-map-shell {
    height: clamp(280px, 46vw, 440px);
    border-radius: 16px;
    overflow: hidden;
    border: 1px solid var(--tot-edge);
    box-shadow: 0 10px 34px rgba(0, 0, 0, .45);
}

.tot-map {
    position: relative;
    height: 100%;
    background:
        radial-gradient(circle at 30% 25%, rgba(168, 85, 247, .18), transparent 60%),
        var(--tot-night-2);
}

/* The fallback is real content, not a spinner: it is what a reader sees when JS is off, when
   Leaflet's CDN is blocked, or before the map finishes booting. hutchconnect.js hides it only
   once a map has actually rendered. */
.tot-map-fallback {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    padding: 1.5rem;
    text-align: center;
}

.tot-map-fallback-icon { font-size: 2rem; }
.tot-map-fallback-title { margin: 0; font-weight: 800; color: var(--tot-ink); }
.tot-map-fallback-note { margin: 0 auto; max-width: 42ch; font-size: .85rem; line-height: 1.5; color: var(--tot-ink-muted); }

.tot-map-fallback-cta {
    margin-top: .5rem;
    padding: .5rem 1.1rem;
    border-radius: 999px;
    background: var(--tot-grape);
    color: #fff;
    font-weight: 700;
    font-size: .85rem;
    text-decoration: none;
}

.tot-map-fallback-cta:hover { background: #9333ea; }

/* #657: the always-visible route handoff. This used to be .tot-map-fallback-cta, living
   inside the fallback that script hides the moment Leaflet starts — so the button and a
   working map could never coexist, and it was the only Google Maps link on the page.
   It sits outside the map now and nothing hides it. */
.tot-map-actions { margin: .85rem 0 0; }

.tot-map-cta {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .6rem 1.25rem;
    border-radius: 999px;
    background: var(--tot-grape);
    color: #fff;
    font-weight: 700;
    font-size: .9rem;
    text-decoration: none;
}

.tot-map-cta:hover,
.tot-map-cta:focus-visible { background: #9333ea; color: #fff; }

.tot-map-note {
    margin: .75rem 0 0;
    font-size: .82rem;
    line-height: 1.55;
    color: var(--tot-ink-muted);
}

/* ── Day groups ─────────────────────────────────────────────────────────── */

.tot-day { margin: 0 0 2.5rem; scroll-margin-top: 76px; }   /* fixed nav is 56px tall */

.tot-day-heading {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .6rem;
    margin: 0 0 1rem;
    padding-bottom: .55rem;
    border-bottom: 2px dashed var(--tot-edge);
    font-size: 1.3rem;
    font-weight: 900;
    color: var(--tot-ink);
}

.tot-day-heading-text { margin-right: auto; }

.tot-day-count {
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--tot-ink-muted);
}

/* #667: per-day route handoff, directly under its day heading. Sits above the card grid so the
   reader meets "here is this night, here is the drive" before scrolling the stops. */
.tot-day-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;      /* the truncation note drops to its own line on a phone */
    gap: .5rem .75rem;
    margin: -.35rem 0 1.15rem;
}

.tot-day-cta {
    font-size: .85rem;
    padding: .5rem 1.05rem;
}

.tot-day-actions-note {
    /* min-width:0 so a long note can shrink and wrap instead of forcing the row wider than the
       phone — a data-derived string overflowing the viewport has bitten this codebase before. */
    min-width: 0;
    flex: 1 1 14rem;
    font-size: .78rem;
    line-height: 1.45;
    color: var(--tot-ink-muted);
}

.tot-day-badge {
    padding: .2rem .6rem;
    border-radius: 999px;
    background: linear-gradient(180deg, var(--tot-pumpkin) 0%, var(--tot-pumpkin-dark) 100%);
    color: #2a0f00;
    font-size: .68rem;
    font-weight: 900;
    letter-spacing: .07em;
    text-transform: uppercase;
}

.tot-day-halloween .tot-day-heading {
    border-bottom-color: var(--tot-pumpkin);
    color: var(--tot-pumpkin);
}

.tot-day-undated .tot-day-heading { color: var(--tot-ink-muted); }

/* ── Cards ──────────────────────────────────────────────────────────────── */

.tot-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
    gap: 1.1rem;
}

.tot-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: 16px;
    background: linear-gradient(180deg, var(--tot-card-2) 0%, var(--tot-card) 100%);
    border: 1px solid var(--tot-edge);
    color: inherit;
    text-decoration: none;
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}

.tot-card:hover,
.tot-card:focus-visible {
    transform: translateY(-3px);
    border-color: var(--tot-pumpkin);
    box-shadow: 0 14px 30px rgba(255, 122, 26, .18);
}

.tot-card-media {
    position: relative;
    aspect-ratio: 16 / 10;
    background: var(--tot-night-2);
}

/* Sits ON TOP of the always-present placeholder layer, so `onerror="this.remove()"` on a dead
   photo URL uncovers the themed panel instead of leaving a broken-image box. */
.tot-card-img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.tot-card-photocount {
    position: absolute;
    right: .55rem;
    bottom: .55rem;
    padding: .12rem .5rem;
    border-radius: 999px;
    background: rgba(20, 10, 36, .82);
    color: var(--tot-ink);
    font-size: .72rem;
    font-weight: 700;
}

/* A card with no photo must still look deliberate — a themed panel, never a broken image box
   or a collapsed card (#544 directive). */
.tot-card-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background:
        repeating-linear-gradient(45deg, rgba(168, 85, 247, .09) 0 12px, transparent 12px 24px),
        radial-gradient(circle at 50% 42%, rgba(255, 122, 26, .22), transparent 66%),
        var(--tot-night-2);
}

.tot-card-placeholder-glyph {
    font-size: 2.6rem;
    filter: drop-shadow(0 3px 10px rgba(0, 0, 0, .5));
    opacity: .92;
}

.tot-card-body {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    padding: .95rem 1rem 1.05rem;
}

.tot-card-host {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 800;
    line-height: 1.25;
    color: var(--tot-ink);
}

.tot-card-when {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin: 0;
}

.tot-card-date,
.tot-card-time {
    padding: .16rem .55rem;
    border-radius: 6px;
    font-size: .76rem;
    font-weight: 700;
}

.tot-card-date { background: rgba(255, 122, 26, .16); color: var(--tot-pumpkin); }
.tot-card-time { background: rgba(142, 240, 90, .13); color: var(--tot-slime); }

.tot-card-address,
.tot-card-candy {
    margin: 0;
    font-size: .84rem;
    line-height: 1.45;
    color: var(--tot-ink-dim);
}

.tot-card-desc {
    margin: .1rem 0 0;
    font-size: .85rem;
    line-height: 1.55;
    color: var(--tot-ink-muted);
}

/* Partner badge seam (#627) — styled now so the slice that populates it needs no CSS. */
.tot-card-partners {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-top: .25rem;
}

.tot-partner-badge {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .2rem .55rem .2rem .3rem;
    border-radius: 999px;
    background: rgba(248, 245, 255, .08);
    border: 1px solid var(--tot-edge);
}

.tot-partner-logo {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    object-fit: cover;
    background: #fff;
}

.tot-partner-name {
    font-size: .73rem;
    font-weight: 700;
    color: var(--tot-ink-dim);
}

.tot-card-nomap {
    margin: .2rem 0 0;
    font-size: .76rem;
    line-height: 1.45;
    color: var(--tot-ink-muted);
    font-style: italic;
}

.tot-card-more {
    margin-top: .55rem;
    font-size: .8rem;
    font-weight: 800;
    color: var(--tot-pumpkin);
}

/* ============================================================================
   PER-EVENT DETAIL SUB-PAGE (HC.Module #628)

   Appended to THIS file rather than shipped as a second stylesheet on purpose. A new global
   CSS file would need a <link> added to App.razor in ForWardAI.Hub and
   ForWardAI.HutchConnect.Web — two repos the #628 branch cannot touch — and a scoped
   .razor.css would not aggregate across the cross-repo ProjectReference at all (#97). So the
   detail page reuses the tokens and the tot-* vocabulary already defined above, and its own
   page links this file at ?v=4.
   ============================================================================ */

.tot-detail-body { padding-top: 1.5rem; }

.tot-detail-back {
    display: inline-block;
    margin: 0 0 1.25rem;
    color: var(--tot-ink-dim);
    font-size: .88rem;
    font-weight: 700;
    text-decoration: none;
}

.tot-detail-back:hover { color: var(--tot-pumpkin); }

/* ── Header ─────────────────────────────────────────────────────────────── */

.tot-detail-header {
    padding: 0 0 1.1rem;
    margin: 0 0 1.25rem;
    border-bottom: 2px solid var(--tot-edge);
}

.tot-detail-header-halloween { border-bottom-color: var(--tot-pumpkin); }

.tot-detail-title {
    display: flex;
    align-items: center;
    gap: .55rem;
    margin: 0 0 .55rem;
    /* clamp, not a fixed size: a long host name must not overflow a 400px phone. */
    font-size: clamp(1.5rem, 5.5vw, 2.1rem);
    font-weight: 900;
    line-height: 1.15;
    color: var(--tot-ink);
    /* A host name is free text from a public form and can be one unbroken string. */
    overflow-wrap: anywhere;
}

.tot-detail-title-glyph { flex: 0 0 auto; filter: drop-shadow(0 2px 8px rgba(0, 0, 0, .5)); }

.tot-detail-when {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
    margin: 0;
}

.tot-detail-date {
    font-size: 1.02rem;
    font-weight: 800;
    color: var(--tot-pumpkin);
}

/* An unparseable event_date is shown as "Date to be confirmed" and must read as a caveat,
   not as a headline date. */
.tot-detail-date-tbc { color: var(--tot-ink-muted); font-weight: 700; }

.tot-detail-time {
    font-size: .95rem;
    font-weight: 700;
    color: var(--tot-ink-dim);
}

/* ── Photos ─────────────────────────────────────────────────────────────── */

.tot-detail-media { margin: 0 0 1.5rem; }

/* aspect-ratio + a placeholder base layer means the panel occupies the same space whether
   the host uploaded a photo, uploaded one whose URL now 404s, or uploaded none at all. */
.tot-detail-photo-main {
    position: relative;
    aspect-ratio: 16 / 9;
    max-height: 420px;
    border-radius: 16px;
    overflow: hidden;
    border: 1px solid var(--tot-edge);
    box-shadow: 0 10px 34px rgba(0, 0, 0, .45);
}

/* No photo was uploaded at all: keep the themed panel — it is what makes the page read as
   deliberate rather than broken — but at a banner height, so it does not dominate a page whose
   actual content is the address and the times. */
/* Two classes, so this beats BOTH the base `.tot-detail-photo-main` rule above and the phone media
   query at the bottom of the file, which re-declares that class's aspect-ratio AFTER this block and
   would otherwise win at equal specificity.
   `aspect-ratio: auto` is the load-bearing part, found by screenshotting at 400px rather than by
   reading the rule: with any ratio still in force, Chrome derives this box's WIDTH from its height
   instead of stretching it, and the panel rendered as a narrow tile floated against the left margin
   rather than a full-bleed banner. A definite height plus no ratio is what makes it stretch. */
.tot-detail-page .tot-detail-photo-main-empty {
    aspect-ratio: auto;
    height: clamp(140px, 16vw, 190px);
    max-height: none;
}

.tot-detail-photo-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.tot-detail-photo-strip {
    display: flex;
    gap: .5rem;
    margin: .55rem 0 0;
    flex-wrap: wrap;
}

.tot-detail-photo-thumb {
    width: 84px;
    height: 84px;
    object-fit: cover;
    border-radius: 10px;
    border: 1px solid var(--tot-edge);
}

/* ── Two-column body, collapsing to one on a phone ──────────────────────── */

.tot-detail-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
    gap: 1.5rem;
    align-items: start;
}

.tot-detail-main { min-width: 0; }

.tot-detail-block { margin: 0 0 1.5rem; }

.tot-detail-text {
    margin: 0;
    color: var(--tot-ink-dim);
    font-size: .95rem;
    line-height: 1.65;
    overflow-wrap: anywhere;
}

/* Host line breaks survive. Razor HTML-encodes the value, so this cannot render markup. */
.tot-detail-desc { white-space: pre-wrap; }

.tot-detail-candy .tot-detail-text { color: var(--tot-slime); font-weight: 600; }

.tot-detail-text a { color: var(--tot-pumpkin); font-weight: 700; }

.tot-detail-partners {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.tot-detail-partner { text-decoration: none; }

/* ── "Where it is" panel ────────────────────────────────────────────────── */

.tot-detail-side {
    min-width: 0;
    padding: 1.15rem 1.15rem 1.25rem;
    border-radius: 16px;
    background: linear-gradient(180deg, var(--tot-card-2) 0%, var(--tot-card) 100%);
    border: 1px solid var(--tot-edge);
}

.tot-detail-address {
    margin: 0 0 .85rem;
    font-size: .98rem;
    font-weight: 700;
    line-height: 1.5;
    color: var(--tot-ink);
    overflow-wrap: anywhere;
}

/* No address is an honest "the host didn't give one", never a blank line. */
.tot-detail-address-missing { font-weight: 600; color: var(--tot-ink-muted); }

/* The directions handoff is deliberately prominent and deliberately independent of the map:
   it works with zero JavaScript and with no coordinates at all (#642). */
.tot-detail-directions {
    display: inline-block;
    padding: .6rem 1.2rem;
    border-radius: 999px;
    background: var(--tot-pumpkin);
    color: #2a0f00;
    font-size: .9rem;
    font-weight: 800;
    text-decoration: none;
}

.tot-detail-directions:hover { background: var(--tot-pumpkin-dark); color: #fff; }

/* Specificity bumped above the shared .tot-map-shell rules, which are declared both before
   AND after this block (the phone media query at the bottom re-declares .tot-map-shell). At
   equal specificity the later declaration would win and the detail map would take the browse
   page height. */
.tot-detail-page .tot-detail-map-shell {
    height: clamp(220px, 34vw, 300px);
    margin: 1rem 0 0;
}

.tot-detail-nomap { margin-top: .9rem; }

.tot-detail-posted {
    margin: 1.75rem 0 0;
    font-size: .8rem;
    color: var(--tot-ink-muted);
}

.tot-detail-cta {
    margin: 2rem 0 0;
    padding: 1.5rem 1.25rem;
    text-align: center;
    border-radius: 16px;
    border: 1px dashed var(--tot-edge);
}

.tot-detail-cta-text {
    margin: 0 0 .9rem;
    color: var(--tot-ink-dim);
    font-size: .95rem;
}

/* ── Phone width. Most of this traffic is a parent outdoors in October. ──── */

@media (max-width: 640px) {
    /* Single column, and the map/address panel moves below the description rather than
       being squeezed into a column narrower than an address line. */
    .tot-detail-grid { grid-template-columns: 1fr; gap: 1.15rem; }
    .tot-detail-photo-main { aspect-ratio: 4 / 3; }
    .tot-detail-photo-thumb { width: 68px; height: 68px; }
    .tot-detail-page .tot-detail-map-shell { height: 230px; }
    .tot-detail-side { padding: 1rem; }
    .tot-hero { padding: 2.5rem 1.15rem 4.25rem; }
    .tot-hero-moon { width: 54px; height: 54px; top: 1.1rem; right: 7%; }
    .tot-hero-skyline { height: 52px; }
    .tot-hero-sub { font-size: .96rem; }
    .tot-body { padding: 1.5rem 1.15rem 3rem; }
    .tot-day-heading { font-size: 1.1rem; }
    /* One column below 640px, so a card is never squeezed under its 268px minimum. */
    .tot-grid { grid-template-columns: 1fr; gap: .9rem; }
    .tot-map-shell { height: 260px; }
    .tot-datenav { margin-bottom: 1.35rem; }
}

/* ── Leaflet overrides, scoped to this page ─────────────────────────────── */

.tot-page .leaflet-container {
    height: 100%;
    width: 100%;
    background: var(--tot-night-2);
    font: inherit;
}

/* OSM raster tiles are daylight-bright and would fight the night theme. Darken them in the
   browser rather than shipping a custom tile set.

   #657: this was `filter: brightness(.55) ...` applied directly to .leaflet-tile-pane —
   the one element Leaflet drives with translate3d. A filter on a transformed, composited
   layer forces the whole tile layer to re-rasterise on every pan and zoom. Desktop absorbs
   it; mobile GPUs frequently bail, leaving blank or half-painted tiles that never repaint.
   That is the prime suspect for the grey box on Joey's phone.

   Same look, achieved with a plain overlay that is never transformed and never touches the
   tile layer's compositing. Sits above tilePane (z 200) and below overlayPane (400) and
   markerPane (600), so pins, popups and controls stay full-brightness and clickable.

   NOTE: the phone rendering was never reproduced on a real device, so this is a strongly
   motivated change, not a confirmed fix. It is cosmetic-only and independently revertible. */
.tot-page .tot-map { position: relative; }

.tot-page .tot-map::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 350;
    pointer-events: none;
    background: rgba(10, 6, 20, .46);
}

/* No overlay before the map exists — the fallback has its own background. */
.tot-page .tot-map:not(.leaflet-container)::after { content: none; }

.tot-page .leaflet-popup-content-wrapper {
    background: var(--tot-card);
    color: var(--tot-ink);
    border: 1px solid var(--tot-pumpkin);
    border-radius: 12px;
}

.tot-page .leaflet-popup-tip { background: var(--tot-card); border: 1px solid var(--tot-pumpkin); }
.tot-page .leaflet-popup-content { margin: .6rem .8rem; font-size: .85rem; line-height: 1.5; }
.tot-page .leaflet-popup-close-button { color: var(--tot-ink-muted) !important; }
.tot-page .leaflet-control-attribution { background: rgba(20,10,36,.78); color: var(--tot-ink-muted); }
.tot-page .leaflet-control-attribution a { color: var(--tot-ink-dim); }

.tot-page .leaflet-bar a {
    background: var(--tot-card);
    color: var(--tot-ink);
    border-bottom-color: var(--tot-edge);
}

.tot-page .leaflet-bar a:hover { background: var(--tot-card-2); }

.tot-pin {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: linear-gradient(180deg, var(--tot-pumpkin) 0%, var(--tot-pumpkin-dark) 100%);
    border: 2px solid #2a0f00;
    box-shadow: 0 0 0 4px rgba(255, 122, 26, .22), 0 3px 8px rgba(0, 0, 0, .5);
    font-size: 15px;
    line-height: 1;
}

.tot-popup-host { display: block; font-weight: 800; margin-bottom: .2rem; }
.tot-popup-meta { display: block; color: var(--tot-ink-muted); font-size: .8rem; }
.tot-popup-link { display: inline-block; margin-top: .35rem; color: var(--tot-pumpkin); font-weight: 700; }
