/* ============================================================================
   Departures v5 — the locator. (2026-07-29)

   The loyalty-app grammar: titled band, live map, two floating controls, one
   drag sheet, the app's tab bar. (The band went transparent 2026-07-29 — see
   the note on it below.) Everything is scoped under
   body.dep-v5 — with the flag off this stylesheet is inert and v4/v3/v2/v1
   render untouched.

   The sheet is WHITE, not the dark glass the other Departures surfaces used.
   That's deliberate and it's most of why this reads cleaner: all four
   benchmarks put a paper-white list under a light map, and a dark sheet over
   a light map is two unrelated worlds stacked.
   ========================================================================== */

/* Retire the surfaces v5 replaces. Kept in the DOM (they're the fallback). */
body.dep-v5 #dep-sheet,
body.dep-v5 #dep-cadence-rail,
body.dep-v5 #dep-rail,
body.dep-v5 #dep-pager,
body.dep-v5 #dep4 { display: none !important; }

/* ── 1 · the band ────────────────────────────────────────────────────────
   Transparent, not white. The solid band was ~56px of nothing — the app header
   sits directly above it and the tab bar already names this surface, so the
   only thing it carried was the title. It now floats on a cream-to-nothing
   fade that continues the header above it, and the map runs all the way up.
   (The benchmark rule was "never float a title over a moving map"; the fade
   plus the halo below is what buys the exception — the title sits in the top
   ~50px, which is the calmest part of a pitched 3D map.) */
body.dep-v5 #dep5-band {
    position: fixed;
    top: calc(var(--header-height, 72px) + var(--safe-top, 0px));
    left: 0;
    right: 0;
    z-index: 8;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 10px 15px 14px;
    pointer-events: none;
    /* No scrim. The cream-to-transparent fade that used to sit here read as a
       glow bleeding out of the app header, which is worse than the problem it
       solved: the Standard 'day' basemap is light everywhere (cream buildings,
       pale roads, light water), so ink text holds up on it unaided. If a dark
       lightPreset ever ships, this is where the scrim comes back. */
    background: none;
}
body.dep-v5 #dep5-band > * { pointer-events: auto; }
body.dep-v5 #dep5-band { justify-content: center; }

/* ── the mode switch ─────────────────────────────────────────────────────
   MAP | TERMINAL. Replaced the DEPARTURES title 2026-08-02 (see MODES in
   departures-v5.js for why). A standard segmented control — grey track, white
   raised thumb — because that is the one control every phone user already
   reads as "two views of the same thing, pick one", and this surface genuinely
   is two views. It is deliberately NOT gold: gold is currency and reward in
   this app, and navigation that dresses as a reward is the single cheapest
   thing an interface can do.

   It's opaque, so it earns its place over the map on its own (the band's
   exception for floating a title doesn't have to stretch to cover it), and it
   stays up over the dark storefront — same control, same place, both modes, so
   the way back is always the way in. */
body.dep-v5 #dep5-modes {
    display: flex;
    gap: 2px;
    padding: 3px;
    border-radius: 100px;
    background: rgba(238, 236, 230, 0.94);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.16), inset 0 0 0 1px rgba(0, 0, 0, 0.05);
}
body.dep-v5 #dep5-modes button {
    appearance: none;
    border: none;
    cursor: pointer;
    min-width: 104px;
    padding: 8px 20px;
    border-radius: 100px;
    background: transparent;
    color: rgba(26, 26, 26, 0.55);
    font-family: var(--font-ui, 'Figtree', sans-serif);
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1.15;
    transition: background 160ms ease, color 160ms ease, box-shadow 160ms ease;
    -webkit-tap-highlight-color: transparent;
}
body.dep-v5 #dep5-modes button[aria-selected="true"] {
    background: #fff;
    color: var(--ink, #1a1a1a);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.16);
}

/* Over the storefront the track has to sit on near-black instead of a cream
   map. Same control, inverted — anything else would read as a different
   button doing a different job. */
body.dep-v5.dep5-terminal-open #dep5-modes {
    background: rgba(255, 255, 255, 0.11);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.09);
}
body.dep-v5.dep5-terminal-open #dep5-modes button { color: rgba(255, 255, 255, 0.62); }
body.dep-v5.dep5-terminal-open #dep5-modes button[aria-selected="true"] {
    background: #fff;
    color: #12141b;
}


/* ── 2 · the map ─────────────────────────────────────────────────────────
   Nothing to do — it's the live shared canvas already behind this tab. It
   simply gets to be visible between the band and the sheet, which is the
   whole point. The heavy vignette the globe-landing used has to go, though:
   a locator map is read, not admired. */
body.dep-v5 .departures-globe.dep-globe-live::after {
    background: linear-gradient(180deg, rgba(5, 5, 15, 0.1) 0%, transparent 22%);
}

/* Mapbox's own chrome — geolocate, zoom +/-, compass — is off here. There is
   already one locate button, and the +/- pair does nothing a pinch doesn't.
   Scoped to .departures-globe so the Travel Map overlay keeps all of it: that
   surface is browsed rather than acted on, and the controls earn their place
   there. (The bottom-corner groups were already hidden in
   departures-tiles.css; these are the top ones.) */
body.dep-v5 .departures-globe .mapboxgl-ctrl-top-right,
body.dep-v5 .departures-globe .mapboxgl-ctrl-top-left { display: none !important; }

/* ── 3 · the one floating control ────────────────────────────────────────
   Locate. Nothing else is allowed to float over the map — every benchmark
   holds this line and it's why their maps stay readable. */
body.dep-v5 #dep5-locate {
    position: fixed;
    right: 12px;
    top: calc(var(--header-height, 72px) + var(--safe-top, 0px) + 52px);
    z-index: 7;
    width: 42px;
    height: 42px;
    border-radius: 10px;
    border: none;
    cursor: pointer;
    background: #fff;
    color: #3d3d3d;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.22);
    display: flex;
    align-items: center;
    justify-content: center;
    -webkit-tap-highlight-color: transparent;
}
/* ── 4 · the sheet ───────────────────────────────────────────────────────
   Costa's: grab handle, one row of tabs, a flat list. ONE axis — how much
   list. That single fact is what separates it from the v2 sheet this replaces,
   which also held which-pane-am-I-on and a glance strip and a drag hint. */
body.dep-v5 #dep5-sheet {
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(56px + var(--safe-bottom, 0px));
    z-index: 9;
    max-width: 560px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    background: #fff;
    border-radius: 15px 15px 0 0;
    box-shadow: 0 -5px 22px rgba(0, 0, 0, 0.17);
    overflow: hidden;
    transition: height 300ms cubic-bezier(0.22, 0.9, 0.3, 1);
}
body.dep-v5 #dep5-sheet.is-dragging { transition: none; }
@media (prefers-reduced-motion: reduce) {
    body.dep-v5 #dep5-sheet { transition: none; }
}
body.dep-v5 #dep5-sheet[data-snap="peek"] { height: 224px; }
body.dep-v5 #dep5-sheet[data-snap="half"] { height: 58vh; }
body.dep-v5 #dep5-sheet[data-snap="full"] {
    height: calc(100vh - var(--header-height, 72px) - var(--safe-top, 0px)
                 - var(--safe-bottom, 0px) - 56px - 54px);
}

body.dep-v5 #dep5-grab {
    flex: 0 0 auto;
    padding: 9px 0 6px;
    display: flex;
    justify-content: center;
    cursor: grab;
    touch-action: none;
    -webkit-tap-highlight-color: transparent;
}
body.dep-v5 #dep5-grab i {
    display: block;
    width: 40px;
    height: 4px;
    border-radius: 100px;
    background: rgba(26, 26, 26, 0.2);
}

/* The tab row — where Costa keeps Nearby / Favourites. This is the ONLY
   navigation the surface has, and it sits where the thumb already is. */
body.dep-v5 #dep5-tabs {
    flex: 0 0 auto;
    display: grid;
    /* TWO. Was 4 (with Terminal), then 3 (with Pass) — both left on
       2026-08-02 for surfaces that suit them. Keep this in step with TABS in
       departures-v5.js: a stale column count leaves the row bunched to one
       side with the remainder empty, which is exactly how the 4→3 step showed
       up on device. */
    grid-template-columns: repeat(2, 1fr);
    border-bottom: 1px solid rgba(26, 26, 26, 0.1);
}
/* Passes trial (2026-08-03) adds a THIRD tab. Exactly the stale-column-count
   failure the note above warns about: without this the row keeps two columns
   and "Passes" wraps onto a line of its own. Scoped to body.passes-on, so
   ?passes=off restores two columns with no other change. */
body.dep-v5.passes-on #dep5-tabs {
    grid-template-columns: repeat(3, 1fr);
}
body.dep-v5 #dep5-tabs button {
    appearance: none;
    border: none;
    background: none;
    cursor: pointer;
    padding: 10px 1px 12px;
    position: relative;
    white-space: nowrap;
    font-family: var(--font-ui, 'Figtree', sans-serif);
    font-weight: 600;
    /* 13.5px was the largest that kept FOUR labels on one line at 360px. With
       two, the constraint is gone entirely — this is now sized to be read
       rather than to fit, and it's the largest that still sits below the row
       titles ("TODAY", "THIS WEEK") it introduces. */
    font-size: 16.5px;
    letter-spacing: -0.01em;
    color: rgba(26, 26, 26, 0.52);
    -webkit-tap-highlight-color: transparent;
}
@media (max-width: 359px) {
    body.dep-v5 #dep5-tabs button { font-size: 15px; }
}
body.dep-v5 #dep5-tabs button[aria-selected="true"] {
    color: var(--ink, #1a1a1a);
    font-weight: 700;
}
/* The label carries the underline, not the column — see the span in
   departures-v5.js. The 6px overhang each side is the optical bit: an
   indicator flush to the glyphs reads as an underline on a word, one that
   clears them reads as a tab. */
body.dep-v5 #dep5-tabs button > span {
    position: relative;
    display: inline-block;
}
body.dep-v5 #dep5-tabs button[aria-selected="true"] > span::after {
    content: "";
    position: absolute;
    left: -6px;
    right: -6px;
    /* The button's own 12px bottom padding, plus 1px, so the bar lands on the
       row's border exactly where it did when it hung off the button. */
    bottom: -13px;
    height: 3px;
    border-radius: 3px 3px 0 0;
    background: var(--gold-deep, #b38728);
}

body.dep-v5 .dep5-sec:first-child { padding-top: 10px; }

body.dep-v5 #dep5-list {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    padding: 0 0 calc(14px + var(--safe-bottom, 0px));
}

/* ── the row ─────────────────────────────────────────────────────────────
   Costa's grammar exactly: leading pin, bold name, ONE grey context line, ONE
   grey distance line, at most ONE action on the right. The eye gets one job
   per row, which is the entire reason their lists scan so fast. */
body.dep-v5 .dep5-row {
    display: flex;
    align-items: flex-start;
    gap: 13px;
    width: 100%;
    padding: 15px 16px;
    border: none;
    border-bottom: 1px solid rgba(26, 26, 26, 0.1);
    background: #fff;
    text-align: left;
    cursor: pointer;
    font-family: var(--font-ui, 'Figtree', sans-serif);
    -webkit-tap-highlight-color: transparent;
}
body.dep-v5 .dep5-row:last-child { border-bottom: none; }
body.dep-v5 .dep5-row.is-focus { background: rgba(255, 217, 61, 0.11); }
body.dep-v5 .dep5-row-pin {
    flex: 0 0 auto;
    width: 22px;
    margin-top: 2px;
    display: flex;
    justify-content: center;
}
body.dep-v5 .dep5-row-b {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
body.dep-v5 .dep5-row-t {
    font-size: 15.5px;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.005em;
    color: var(--ink, #1a1a1a);
}
body.dep-v5 .dep5-row-c,
body.dep-v5 .dep5-row-d {
    font-size: 13px;
    font-weight: 500;
    color: rgba(26, 26, 26, 0.52);
    line-height: 1.35;
}
body.dep-v5 .dep5-row-go {
    flex: 0 0 auto;
    align-self: center;
    border-radius: 100px;
    padding: 9px 17px;
    background: var(--accent-gold, #FFD93D);
    color: #1a1a1a;
    font-weight: 800;
    font-size: 12.5px;
    white-space: nowrap;
}
body.dep-v5 .dep5-row-go.is-claim {
    background: var(--accent-green, #27ae60);
    color: #fff;
}
body.dep-v5 .dep5-row.is-done .dep5-row-t { color: rgba(26, 26, 26, 0.45); }
body.dep-v5 .dep5-row.is-done .dep5-row-go {
    background: rgba(26, 26, 26, 0.06);
    color: rgba(26, 26, 26, 0.52);
}

/* ── the expandable row ──────────────────────────────────────────────────
   "Visit a pub" is ONE challenge with three pubs inside it, not three rows.
   The chevron is the promise that there's something under there; it rotates so
   the open state is readable without reading. */
body.dep-v5 .dep5-row-chev {
    flex: 0 0 auto;
    align-self: center;
    color: rgba(26, 26, 26, 0.35);
    display: flex;
    transition: transform 220ms cubic-bezier(0.22, 0.9, 0.3, 1);
}
body.dep-v5 .dep5-row.is-open .dep5-row-chev {
    transform: rotate(180deg);
    color: var(--gold-deep, #b38728);
}
body.dep-v5 .dep5-row.is-open {
    background: rgba(255, 217, 61, 0.11);
    border-bottom-color: transparent;
}
@media (prefers-reduced-motion: reduce) {
    body.dep-v5 .dep5-row-chev { transition: none; }
}

body.dep-v5 .dep5-exp {
    background: rgba(255, 217, 61, 0.055);
    border-bottom: 1px solid rgba(26, 26, 26, 0.1);
    padding: 2px 0 8px;
    animation: dep5-open 240ms cubic-bezier(0.22, 0.9, 0.3, 1);
}
@keyframes dep5-open {
    from { opacity: 0; transform: translateY(-5px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    body.dep-v5 .dep5-exp { animation: none; }
}

/* Sub-row: one real place. Indented under the pin column so the hierarchy is
   spatial, not just typographic. */
body.dep-v5 .dep5-sub {
    display: flex;
    align-items: center;
    gap: 11px;
    width: 100%;
    padding: 10px 16px 10px 51px;
    border: none;
    background: none;
    text-align: left;
    cursor: pointer;
    font-family: var(--font-ui, 'Figtree', sans-serif);
    -webkit-tap-highlight-color: transparent;
}
body.dep-v5 .dep5-sub-pin { flex: 0 0 auto; display: flex; }
body.dep-v5 .dep5-sub-b { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
body.dep-v5 .dep5-sub-t {
    font-size: 14.5px;
    font-weight: 600;
    color: var(--ink, #1a1a1a);
    line-height: 1.3;
}
body.dep-v5 .dep5-sub-d { font-size: 12.5px; color: rgba(26, 26, 26, 0.5); }
body.dep-v5 .dep5-sub-go {
    flex: 0 0 auto;
    font-size: 12px;
    font-weight: 800;
    color: #1a1a1a;
    background: var(--accent-gold, #FFD93D);
    border-radius: 100px;
    padding: 7px 14px;
}
body.dep-v5 .dep5-sub-empty {
    padding: 10px 16px 12px 51px;
    font-size: 13px;
    color: rgba(26, 26, 26, 0.5);
}

/* MOVE / PLAY — the answer to "how close am I?" as a bar, because a fraction
   buried in a sentence is a number you have to do arithmetic on. */
body.dep-v5 .dep5-prog { padding: 8px 16px 10px 51px; }
body.dep-v5 .dep5-prog-bar {
    height: 8px;
    border-radius: 100px;
    background: rgba(26, 26, 26, 0.09);
    overflow: hidden;
}
body.dep-v5 .dep5-prog-bar i {
    display: block;
    height: 100%;
    border-radius: 100px;
    background: linear-gradient(90deg, #bf953f, #fcf6ba 60%, #b38728);
    transition: width 420ms cubic-bezier(0.22, 0.9, 0.3, 1);
}
body.dep-v5 .dep5-prog-txt {
    display: flex;
    align-items: baseline;
    gap: 5px;
    margin-top: 6px;
    font-size: 13px;
    font-weight: 500;
    color: rgba(26, 26, 26, 0.55);
}
body.dep-v5 .dep5-prog-txt b { font-size: 15px; font-weight: 800; color: var(--ink, #1a1a1a); }
body.dep-v5 .dep5-prog-txt span { margin-left: auto; font-weight: 700; color: var(--gold-deep, #b38728); }

/* PLAY's one extra affordance — the genre library that already exists. */
body.dep-v5 .dep5-more {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 2px 16px 4px 51px;
    padding: 9px 15px;
    border: 1px solid rgba(179, 135, 40, 0.35);
    border-radius: 100px;
    background: rgba(255, 255, 255, 0.7);
    color: #6d4f10;
    font-family: var(--font-ui, 'Figtree', sans-serif);
    font-weight: 700;
    font-size: 12.5px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

body.dep-v5 .dep5-sec {
    position: sticky;
    top: 0;
    z-index: 3;
    background: #fff;
    border-bottom: 1px solid rgba(26, 26, 26, 0.07);
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 12px 16px 9px;
    font-family: var(--font-display, 'Archivo Black', sans-serif);
    font-size: 12px;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--ink, #1a1a1a);
}
body.dep-v5 .dep5-sec i {
    margin-left: auto;
    font-style: normal;
    font-family: var(--font-ui, 'Figtree', sans-serif);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: rgba(26, 26, 26, 0.45);
}

/* ── the Terminal: a storefront, not a pane ──────────────────────────────
   Built to the Xbox Store's shape. The point of that shape is commercial, not
   decorative: a marquee plus lanes gives four sellable positions at four price
   points, where a vertical list gives one (the top).

   It's DARK, and it's the only dark surface in the app. Art pops on dark —
   which is why every storefront is (Xbox, Steam, PS Store, Netflix) — and it
   makes "browsing the shop" feel unmistakably unlike "doing my challenges", so
   the commercial surface can never be mistaken for the earning one.

   It's a PAGE, not a sheet pane: the marquee is invisible at peek height, and
   this is the one tab where the map behind is irrelevant. */
body.dep-v5 #dep5-terminal { display: none; }
/* Starts BELOW the band, not under the app header — the mode switch stays up
   over this page (it's how you leave), so the storefront can't be allowed to
   cover it. --dep5-band-h is the switch (38px) plus the band's 10/14 padding. */
body.dep-v5 { --dep5-band-h: 62px; }
body.dep-v5.dep5-terminal-open #dep5-terminal {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: calc(var(--header-height, 72px) + var(--safe-top, 0px) + var(--dep5-band-h));
    bottom: calc(56px + var(--safe-bottom, 0px));
    left: 0;
    right: 0;
    z-index: 28;
    background: #0f1117;
    color: #fff;
}
/* The dark page runs up UNDER the band too, so the switch sits on the
   storefront's own colour rather than on a strip of leftover map. */
body.dep-v5.dep5-terminal-open #dep5-band::before {
    content: '';
    position: absolute;
    inset: 0;
    background: #0f1117;
    z-index: -1;
}
/* The storefront owns the screen — the sheet and the map control stand down
   while it's up. The BAND does not: it holds the only way out. */
body.dep-v5.dep5-terminal-open #dep5-sheet,
body.dep-v5.dep5-terminal-open #dep5-locate { display: none !important; }
body.dep-v5.dep5-terminal-open #dep5-band { z-index: 29; }
body.dep-v5 #dep5-terminal-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 24px;
}

/* SLOT 0 — the pinned Boarding Pass. Above the marquee, never inside it.
   See passCardHTML() in departures-v5.js for why it's pinned rather than
   rotated in. SQUARE, against the marquee's 16:10 — the shape is what says
   "this is not one of the things on sale, this is the shop's own product",
   and it says it before a word is read.

   Cream and gold, not the storefront's dark card stock: it's the one object
   here made of the same material as the physical pass it represents, and on a
   near-black page that reads as the premium thing on the shelf. max-height
   stops it eating a tall phone whole — a hero you have to scroll past to see
   the shop isn't a hero, it's a wall. */
body.dep-v5 .dt5-pass {
    position: relative;
    display: block;
    width: calc(100% - 30px);
    margin: 0 15px 16px;
    aspect-ratio: 1 / 1;
    max-height: 300px;
    border: none;
    border-radius: 18px;
    padding: 18px;
    overflow: hidden;
    cursor: pointer;
    text-align: left;
    color: #2a2113;
    background:
        radial-gradient(120% 90% at 85% 8%, rgba(255, 255, 255, 0.75), transparent 60%),
        linear-gradient(150deg, #fcf6ba 0%, #e8d79a 42%, #d8bf75 100%);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.42), inset 0 0 0 1px rgba(179, 135, 40, 0.5);
    -webkit-tap-highlight-color: transparent;
}
/* The perforation, so it reads as a ticket rather than a gold rectangle. Same
   device as the runway's .bp-tear. */
body.dep-v5 .dt5-pass::after {
    content: "";
    position: absolute;
    left: 18px;
    right: 18px;
    bottom: 62px;
    border-top: 2px dashed rgba(140, 105, 30, 0.38);
}
body.dep-v5 .dt5-pass-plane {
    position: absolute;
    right: -10px;
    top: 2px;
    font-size: 132px;
    line-height: 1;
    color: rgba(140, 105, 30, 0.13);
    transform: rotate(-18deg);
    pointer-events: none;
}
body.dep-v5 .dt5-pass-tag {
    position: absolute;
    top: 16px;
    left: 18px;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 5px 9px;
    border-radius: 6px;
    background: rgba(26, 26, 26, 0.86);
    color: var(--accent-gold, #FFD93D);
}
body.dep-v5 .dt5-pass-b {
    position: absolute;
    left: 18px;
    right: 18px;
    bottom: 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
body.dep-v5 .dt5-pass-t {
    font-family: var(--font-display, 'Archivo Black', sans-serif);
    font-size: 25px;
    letter-spacing: 0.02em;
    line-height: 1.05;
    color: #241c0f;
    text-transform: uppercase;
}
body.dep-v5 .dt5-pass-s {
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.35;
    color: rgba(60, 46, 18, 0.82);
}
body.dep-v5 .dt5-pass-bar {
    display: block;
    height: 5px;
    border-radius: 100px;
    background: rgba(120, 92, 26, 0.25);
    overflow: hidden;
}
body.dep-v5 .dt5-pass-bar > i {
    display: block;
    height: 100%;
    border-radius: 100px;
    background: #6d4f10;
}
body.dep-v5 .dt5-pass-cta {
    margin-top: 2px;
    font-size: 13px;
    font-weight: 800;
    color: #6d4f10;
}
body.dep-v5 .dt5-pass-cta b { font-weight: 800; }
/* Held, not sold — the tag flips to ink-on-gold and the plane brightens. Same
   card, different sentence. */
body.dep-v5 .dt5-pass.is-mine .dt5-pass-tag {
    background: #6d4f10;
    color: #fcf6ba;
}

/* SLOT 1 — the marquee. A brand's own artwork, seen first. */
body.dep-v5 .dt5-marq {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding: 0 14px 8px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
body.dep-v5 .dt5-marq::-webkit-scrollbar { display: none; }
body.dep-v5 .dt5-m {
    position: relative;
    flex: 0 0 86%;
    scroll-snap-align: center;
    aspect-ratio: 16 / 10;
    border: none;
    border-radius: 16px;
    overflow: hidden;
    cursor: pointer;
    padding: 15px;
    display: flex;
    align-items: flex-end;
    text-align: left;
    background: linear-gradient(140deg, #2b3f6b, #101728);
    background-size: cover;
    background-position: center;
    -webkit-tap-highlight-color: transparent;
}
body.dep-v5 .dt5-m::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0,0,0,0) 30%, rgba(0,0,0,0.78) 100%);
}
body.dep-v5 .dt5-m-ico {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 64px;
    opacity: 0.35;
}
body.dep-v5 .dt5-m-b {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 3px;
}
body.dep-v5 .dt5-m-t {
    font-family: var(--font-display, 'Archivo Black', sans-serif);
    font-size: 18px;
    letter-spacing: 0.02em;
    color: #fff;
}
body.dep-v5 .dt5-m-s { font-size: 12.5px; font-weight: 600; color: rgba(255, 255, 255, 0.82); }
body.dep-v5 .dt5-m-tag {
    position: absolute;
    top: 12px;
    left: 12px;
    z-index: 1;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 5px 9px;
    border-radius: 6px;
    background: var(--accent-gold, #FFD93D);
    color: #1a1a1a;
}
/* Sponsored is ALWAYS labelled. Not only for the law: the moment a user can't
   tell what's here on merit, the editorial lanes stop being worth reading —
   and then the sponsored slots stop being worth buying. The label is what
   protects the inventory. */
body.dep-v5 .dt5-m-tag.is-spon {
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.3);
}
body.dep-v5 .dt5-dots { display: flex; justify-content: center; gap: 6px; padding: 2px 0 16px; }
body.dep-v5 .dt5-dots i {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.25);
    transition: width 200ms ease, background 200ms ease;
}
body.dep-v5 .dt5-dots i.on { width: 18px; border-radius: 100px; background: var(--accent-gold, #FFD93D); }

/* SLOTS 2 & 3 — lanes. A lane is editorial or bought outright; a single card
   inside an editorial lane is the entry tier. */
body.dep-v5 .dt5-lane-hd {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 0 15px 9px;
}
body.dep-v5 .dt5-lane-hd h2 {
    margin: 0;
    font-size: 17px;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: #fff;
    /* Sentence case, like every storefront's lane titles ("Game deals", "New
       games"). The global heading rule was forcing SHOUTING. */
    text-transform: none;
    font-family: var(--font-ui, 'Figtree', sans-serif);
}
body.dep-v5 .dt5-lane-by {
    font-size: 11px;
    font-weight: 700;
    color: var(--accent-gold, #FFD93D);
    background: rgba(255, 217, 61, 0.13);
    border: 1px solid rgba(255, 217, 61, 0.3);
    padding: 3px 8px;
    border-radius: 5px;
}
body.dep-v5 .dt5-lane {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    padding: 0 15px 22px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
body.dep-v5 .dt5-lane::-webkit-scrollbar { display: none; }

/* Card anatomy is theirs: art, ONE corner badge, ONE footer line. Their footer
   holds price; ours holds the reward — the same question, "what do I get". */
body.dep-v5 .dt5-c {
    flex: 0 0 132px;
    border: none;
    background: none;
    padding: 0;
    text-align: left;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    -webkit-tap-highlight-color: transparent;
}
body.dep-v5 .dt5-c-art {
    position: relative;
    aspect-ratio: 3 / 4;
    border-radius: 11px;
    overflow: hidden;
    background: linear-gradient(150deg, #2a3145, #161a24);
    background-size: cover;
    background-position: center;
    display: flex;
    align-items: center;
    justify-content: center;
}
body.dep-v5 .dt5-c-ico { font-size: 34px; opacity: 0.4; }
body.dep-v5 .dt5-c-badge {
    position: absolute;
    top: 0;
    right: 0;
    font-size: 10.5px;
    font-weight: 800;
    padding: 4px 7px;
    border-radius: 0 11px 0 8px;
    background: var(--accent-gold, #FFD93D);
    color: #1a1a1a;
}
body.dep-v5 .dt5-c-badge.is-urgent { background: #d35400; color: #fff; }
body.dep-v5 .dt5-c-badge.is-new { background: var(--accent-green, #27ae60); color: #fff; }
body.dep-v5 .dt5-c-badge.is-spon {
    background: rgba(10, 12, 18, 0.86);
    color: #fff;
    font-size: 9.5px;
    letter-spacing: 0.06em;
}
body.dep-v5 .dt5-c-t {
    margin: 8px 0 2px;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.25;
    color: #fff;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
body.dep-v5 .dt5-c-f { font-size: 11.5px; font-weight: 700; color: rgba(255, 255, 255, 0.55); }

/* SLOT 4 — browse everything, pinned tile first. Also the only home a stamp
   without coordinates will ever have. */
body.dep-v5 .dt5-all {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    margin: 0 15px 16px;
    padding: 16px;
    border-radius: 12px;
    background: #1e222c;
    border: 1px solid rgba(255, 255, 255, 0.09);
    font-size: 15px;
    font-weight: 700;
}
body.dep-v5 .dt5-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    padding: 0 15px;
}
body.dep-v5 .dt5-g {
    position: relative;
    border-radius: 12px;
    padding: 13px;
    min-height: 82px;
    cursor: pointer;
    border: 1px solid rgba(255, 255, 255, 0.09);
    background: linear-gradient(140deg, #1f2735, #151922);
    color: #fff;
    text-align: left;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 2px;
    -webkit-tap-highlight-color: transparent;
}
body.dep-v5 .dt5-g b { font-size: 14px; font-weight: 700; }
body.dep-v5 .dt5-g span { font-size: 11.5px; font-weight: 600; color: rgba(255, 255, 255, 0.55); }
body.dep-v5 .dt5-g.is-pinned {
    border-color: rgba(255, 217, 61, 0.4);
    background: linear-gradient(140deg, #2b2716, #191712);
}
body.dep-v5 .dt5-g-pin {
    position: absolute;
    top: 9px;
    left: 13px;
    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.08em;
    color: var(--accent-gold, #FFD93D);
}
body.dep-v5 #dep5-terminal .dep5-empty b { color: #fff; }
body.dep-v5 #dep5-terminal .dep5-empty span { color: rgba(255, 255, 255, 0.5); }

body.dep-v5 .dep5-empty {
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 34px 22px;
    text-align: center;
    font-family: var(--font-ui, 'Figtree', sans-serif);
}
body.dep-v5 .dep5-empty b { font-size: 14.5px; color: var(--ink, #1a1a1a); }
body.dep-v5 .dep5-empty span { font-size: 13px; color: rgba(26, 26, 26, 0.5); }

/* Skeleton rows while the trophy cache fills — the list has a known shape, so
   showing it beats showing a spinner. */
body.dep-v5 .dep5-skel { pointer-events: none; }
body.dep-v5 .dep5-skel .dep5-row-pin,
body.dep-v5 .dep5-skel .s1,
body.dep-v5 .dep5-skel .s2 {
    background: rgba(26, 26, 26, 0.07);
    border-radius: 6px;
    animation: dep5-pulse 1.4s ease-in-out infinite;
}
body.dep-v5 .dep5-skel .dep5-row-pin { height: 26px; border-radius: 100px 100px 40% 40%; }
body.dep-v5 .dep5-skel .s1 { height: 15px; width: 62%; }
body.dep-v5 .dep5-skel .s2 { height: 12px; width: 40%; }
@keyframes dep5-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
@media (prefers-reduced-motion: reduce) {
    body.dep-v5 .dep5-skel .dep5-row-pin,
    body.dep-v5 .dep5-skel .s1,
    body.dep-v5 .dep5-skel .s2 { animation: none; }
}

/* The Pass pane's rules (#dep5-list.is-pass) went 2026-08-02 with the tab.
   The runway now only ever renders in its own full-screen overlay, which
   carries .bp-host itself. */

/* ── the scoped series view ──────────────────────────────────────────────
   departures-series-view.js injects .dt-series-view into #departures-content
   and gives it a panel background ONLY under body.dt-tiles-mode — a class this
   surface doesn't set. So on v5 it rendered transparently over the live map,
   and because there is no idle/hidden rule anywhere in the base stylesheet, it
   stayed there after close() too: the content just sat on the map with no way
   to get rid of it.

   Fixed here rather than in departures-tiles.css so the old surfaces keep the
   exact behaviour they have today. Two rules: hidden by default, and a real
   full-screen panel when active. */
/* #departures-content is `position: relative; z-index: 1`, which makes it a
   STACKING CONTEXT — so .dt-series-view's z-index below only competes with its
   siblings inside that container, and the whole subtree sits at effective z:1
   against anything outside it. #dep5-terminal is z:28 and a sibling of
   #departures-content, so once Terminal stayed mounted behind the series view
   (so that "← Terminal" could work) it covered the series view completely and
   nothing appeared to happen on a tile tap.
   Raising the CONTAINER is the fix; raising the child can't work. Kept under
   200 so the tab bar (--z-sticky) still wins. */
body.dep-v5.dt-series-active #departures-content { z-index: 40; }

body.dep-v5 .dt-series-view { display: none; }
body.dep-v5.dt-series-active .dt-series-view {
    display: block;
    position: fixed;
    top: calc(var(--header-height, 72px) + var(--safe-top, 0px));
    bottom: calc(56px + var(--safe-bottom, 0px));
    left: 0;
    right: 0;
    z-index: 30;                       /* above the sheet, below the tab bar */
    min-height: 0;
    max-height: none;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    padding: 0 0 calc(24px + var(--safe-bottom, 0px));
    background: linear-gradient(180deg, #15152a, #0f0f23);
}
/* The back strip is the only way out, so it must never scroll away. */
body.dep-v5.dt-series-active .dt-back-strip {
    position: sticky;
    top: 0;
    z-index: 2;
}
/* The lane title and count were written for a light panel (`color: var(--ink)`
   and `rgba(0,0,0,0.55)` in departures-tiles.css) but the panel is dark, so
   they read as dark-on-dark. Same class of bug as the Terminal headings: a
   colour set for one background, inherited onto another. */
body.dep-v5.dt-series-active .dt-series-lane-title { color: #fff; }
body.dep-v5.dt-series-active .dt-series-lane-count { color: rgba(255, 255, 255, 0.55); }
body.dep-v5.dt-series-active .dt-series-desc { color: rgba(255, 255, 255, 0.7); }

/* Anything that takes over the screen hides the surface wholesale. */
body.dep-v5.dt-series-active #dep5,
body.dep-v5.dep-finding #dep5,
body.dep-v5.dep-challenge-focus #dep5,
body.dep-v5.poi-card-open #dep5-sheet { display: none; }

/* The landing notice sat above the v2 sheet; here the sheet owns the bottom,
   so it moves above the sheet's peek height. */
body.dep-v5 #dep-landing-notice { bottom: calc(56px + 224px + var(--safe-bottom, 0px) + 10px); }
