/* ============================================================
   Buckettrips — Landing Page
   Mobile-first. Uses CSS vars from base.html. No Playfair.
   ============================================================ */

/* ── PAGE ── */
html:has(.lp-page) { overflow-x:hidden; }
.lp-page { overflow-x:hidden; min-width:0; max-width:100vw; }

/* ── NAVBAR ── */
.lp-page .navbar {
    position:fixed; top:0; left:0; right:0; z-index:100;
    transition:background .4s ease, border .4s ease;
}
.lp-page .navbar.lp-nav-solid {
    background:var(--bg-primary) !important;
    border-bottom:1px solid var(--border-color) !important;
}

@keyframes lpFadeUp { to { opacity:1; transform:translateY(0); } }

/* ════════════════════════════════════════════════════════════════
   HERO — text left, phone mockup right (desktop)
   ════════════════════════════════════════════════════════════════ */
.lp-hero {
    position:relative; width:100%;
    background:var(--bg-primary);
    /* 104 rather than 70: the bar is 51 of it, and a hero that starts straight
       under the bar reads as a page pushed up rather than one that begins. */
    padding:104px 20px 40px;
    overflow:hidden; z-index:10;
}

/* ── THE PHOTOGRAPH BEHIND IT ──
   A ghost of the lead trip rather than a picture: the page keeps its own
   background and the photograph comes through one corner at a fifth. The two
   stronger treatments were tried and both force the hero into permanent dark
   in either mode -- white copy, and a navbar with no fill and a white wordmark,
   which is a change to base.html rather than to this page. This one costs
   neither. mockups/featured-lab.html, F1.

   It is the 1024, not the 1920: at a fifth behind a gradient nobody can tell,
   and it is the same file the poster above it already asked for. */
.lp-hero-photo { position:absolute; inset:0; overflow:hidden; pointer-events:none; z-index:0; }
.lp-hero-photo img {
    position:absolute; inset:0; width:100%; height:100%;
    object-fit:cover; opacity:.20;
}
.lp-hero-photo::after {
    content:""; position:absolute; inset:0;
    background:linear-gradient(100deg, var(--bg-primary) 6%, rgba(0,0,0,0) 78%);
}

.lp-hero-inner {
    position:relative; z-index:1;
    max-width:1100px; margin:0 auto;
    display:flex; flex-direction:column; gap:40px;
}
.lp-hero-text {
    max-width:540px;
}
.lp-hero-title {
    font-size:clamp(2rem,6vw,3.2rem);
    font-weight:800;
    letter-spacing:-.03em;
    line-height:1.1;
    margin-bottom:16px;
    opacity:0; transform:translateY(20px);
    animation:lpFadeUp .7s .1s ease forwards;
}
.lp-hero-sub {
    font-size:.95rem; line-height:1.6;
    color:var(--text-muted);
    margin-bottom:28px;
    max-width:420px;
    opacity:0; animation:lpFadeUp .7s .25s ease forwards;
}

/* ── SEARCH ──
   The field, the dropdown and its rows moved to public-search.css when /trips
   needed the same box. What stays here is the hero's entrance, which is this
   page's alone: nothing else fades a search field in on a delay. */
.lp-search-wrapper { opacity:0; animation:lpFadeUp .7s .4s ease forwards; }

/* ── PHONE MOCKUP — hidden on mobile ── */
.lp-phone { display:none; position:relative; z-index:60; }

/* ── FEATURED (inside hero text) ──
   Three posters where three thin rows used to be. The rows carried a 44px
   thumbnail, a name and a gray line, which is the shape of a search result:
   the hero's last word about the trips was a list. A poster carries a
   photograph, a name, a length and a price, which is one more fact in a shape
   somebody looks at rather than reads.

   The same `.lp-poster` the grid under "Ready when you are" draws, in its
   `is-small` size. Not a second card. mockups/featured-lab.html, F1.

   Mobile first, and the two layouts are genuinely different: a pile you swipe
   here, three across in the desktop block at the foot of this file. */
.lp-featured {
    margin-top:20px;
    opacity:0; animation:lpFadeUp .7s .6s ease forwards;
}

/* Three posters down the page. That is what a phone gets without the script,
   and it is what the desktop block at the foot of this file turns into a row.
   The pile below is the enhancement on top of it. */
.lp-featured-set { display:flex; flex-direction:column; gap:12px; }
.lp-featured-hint {
    display:none; margin:16px 0 0; text-align:center;
    font-family:var(--font-mono); font-size:.6rem;
    letter-spacing:.11em; text-transform:uppercase; color:var(--text-muted);
}
.lp-featured-hint svg {
    width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2;
    vertical-align:-1px; margin:0 5px;
}

/* ── THE PILE, and it exists only on a phone ──
   Inside the media query rather than behind `.is-pile` alone, because a rule
   that turns three cards into one stacked on top of two others must not be one
   specificity accident away from the desktop row. Below 768 it applies; above
   it, it is not in the stylesheet at all. `is-pile` is the script saying it is
   driving; without the script the set stays the plain column above.

   Three routes cloned to six, so it is still a pile after four swipes and never
   runs out. Two thirds of the column rather than all of it: at full width it
   reads as a page element you scroll past, at two thirds as an object on the
   page with room for the corners underneath to show. */
@media (max-width:767px) {
    .lp-featured-set.is-pile {
        display:block; position:relative;
        width:min(67%, 240px); aspect-ratio:1/1;
        margin:4px auto 0;
    }
    .lp-featured-set.is-pile .lp-poster {
        position:absolute; inset:0;
        transform-origin:50% 100%;
        /* The card is a link wrapped round a photograph and the browser wants
           to drag both, which eats the pointermove stream and stops it
           following the finger. */
        touch-action:pan-y; user-select:none; -webkit-user-select:none;
        -webkit-user-drag:none;
        box-shadow:0 16px 34px rgba(0,0,0,.34);
        transition:transform .34s cubic-bezier(.2,.85,.28,1), opacity .34s ease;
    }
    .lp-featured-set.is-pile .lp-poster img { -webkit-user-drag:none; }
    .lp-featured-set.is-pile .lp-poster.is-dragging { transition:none; }
    .lp-featured-set.is-pile .lp-poster.is-gone {
        transition:transform .3s ease-in, opacity .3s ease-in;
    }
    /* No position indicator. A pile does not need to say how deep it is, and a
       reader who swipes twice has worked out that it comes round. */
    .lp-featured-set.is-pile ~ .lp-featured-hint { display:block; }
}
.lp-featured-more {
    display:inline-block; margin-top:14px;
    font-size:.78rem; font-weight:600;
    color:var(--accent-color); text-decoration:none;
    padding-left:4px;
}
.lp-featured-more:hover { text-decoration:underline; }


/* ════════════════════════════════════════════════════════════════
   BUCKET LIST
   ════════════════════════════════════════════════════════════════ */
/* ════════════════════════════════════════════════════════════════
   ONE FIELD, TWO SLABS

   No section on this page owns a background any more.

   The old arrangement was a fill per section, primary then brand then
   secondary then primary then primary, which read at scrolling speed as a
   stripe pattern. Alternating two grays is the answer everybody reaches for
   and nobody notices. So the page is a single field: one gradient across the
   whole document, warmed toward the brand where it dips, so the middle of the
   page sits on a green you can just about name. It was 5% and 4% of the brand
   over the second gray, which is a cast nobody can see on a screen that is not
   the one it was tuned on: the three sections it runs under were being read as
   white. These two numbers are the dial for that, and they are the only ones on
   the page that decide how warm the middle third is. Every
   section between the slabs is transparent and sits on it.

   The only two colored things left are the out of office and the deals,
   and they are drawn as slabs laid on the field rather than as bands cut
   through it: rounded away from the edges they do not meet, a hairline of gold
   round the cut, and a shadow under them. Two objects on a surface, which is
   what the rest of this page is already made of. (There were two pine washes
   bleeding out of the slabs as well. They went with the gold light, for being
   faint things doing nothing you could point at; the shadow is what pays for
   them, and it is one thing rather than three.)

   The field itself is paper rather than white. The same grain the slabs carry,
   over the whole document at about a third of their strength: on its own it
   is not a thing anybody sees, which is the point -- three sections in a row
   with no fill of their own were reading as the browser's own background, and
   what fixes that is a material, not another color.

   Nothing here declares a color. Every value is a palette token or a mix of
   two of them, which is the rule docs/PALETTE.md sets.
   ════════════════════════════════════════════════════════════════ */
.lp-page {
    /* One gap, everywhere. Five sections at five paddings between 34 and 104
       is most of what reads as untidy before anybody looks at a single
       element. */
    --lp-gap:clamp(58px, 6.4vw, 104px);
    --lp-slab-gap:clamp(40px, 4.4vw, 68px);
    background:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.065'/%3E%3C/svg%3E")
            0 0 / 150px 150px repeat,
        linear-gradient(180deg,
            var(--bg-primary) 0%,
            var(--bg-primary) 26%,
            color-mix(in srgb, var(--brand-bg) 10%, var(--bg-secondary)) 48%,
            color-mix(in srgb, var(--brand-bg) 8%, var(--bg-secondary)) 62%,
            var(--bg-primary) 84%,
            var(--bg-primary) 100%);
}
/* Transparent, all of them. The field is underneath. */
.lp-hero, .lp-match, .lp-bucket, .lp-adventures { background:transparent; }

.lp-match, .lp-bucket, .lp-adventures { padding:var(--lp-gap) 0; }
/* Except across this one join, and it is deliberate that it beats the 100px
   override in the desktop block below on specificity rather than on order.
   The matcher and the moments under it are a single argument: the cards ask
   about twelve, and the heading answers "none of those, there are forty-seven,
   here are twelve more". A full gap at each end of that put 200px between the
   question and its answer, which is enough to read them as two sections about
   different things. Every other join keeps the page's one gap. */
.lp-match:has(+ .lp-bucket) { padding-bottom:clamp(22px, 2.4vw, 38px); }
.lp-match + .lp-bucket { padding-top:clamp(22px, 2.4vw, 38px); }
/* There was a gold light here and two pine washes bleeding out of the slabs,
   and together they were three faint things doing nothing you could point at.
   Faint layers stacked up read as mess, not as depth. They are gone, and what
   pays for them is the two slabs being at full strength and a size of type
   that is not apologizing. The three sections between the slabs carry their own
   color anyway: a photograph the size of a card, twelve photographs and four
   posters. */
/* ── THE PICTURES BREAK THE COLUMN ────────────────────────────────────────
   The slabs put their content in 1120 and the three sections between them put
   theirs in 960, which is 80px of nothing down each side of the middle third of
   the page and most of why that stretch reads as empty. It is not that those
   sections have no color of their own -- they are twelve photographs and four
   posters -- it is that the photographs were being drawn in a narrower column
   than everything above and below them.

   So the pictures take the page's measure and the words do not. Headings, leads
   and the matcher's question stay in the 960 column, which keeps one text edge
   running the whole way down the page; the album and the poster grid step out
   to the 1120 the slabs use. Widening the containers instead was the first
   version of this, and it moved every heading in the run 80px left of the one
   above it: three left edges where the page had one.

   The margin is `(1120 - 100%) / -2` rather than a number, so it is the same
   arithmetic whatever the container comes to. Only above 1200, because below
   that the step-out is wider than the window it is in.

   What steps out of the moments section is the sheet, not the album inside it.
   The link under it does not: "See all 47 moments" is the page talking again
   rather than part of the object, so it goes back to the text edge every other
   line on this page starts from. */
.lp-bucket .container,
.lp-adventures .container { max-width:960px; }
@media (min-width:1200px) {
    .lp-bucket .bt-sheet,
    .lp-adventures .lp-poster-grid { margin-inline:calc((1120px - 100%) / -2); }
    /* Four across, told rather than fitted. Both grids size their own columns
       from a floor -- 190px for the prints, 210 for the posters -- which lands
       on four at 960 and on five at 1120. Five columns is twelve moments drawn
       as two rows and an orphan pair, and four posters drawn as a row of four
       with a fifth column of nothing beside them. Below 1200 the floors are
       still what draw both, and they still land on four. */
    .lp-bucket .bt-album,
    .lp-adventures .lp-poster-grid { grid-template-columns:repeat(4, minmax(0,1fr)); }
}
.lp-bucket-header { margin-bottom:clamp(22px,2.6vw,32px); }
/* There was an uppercase eyebrow over every heading here -- Away, Bucket list,
   The trips, On now -- with a little rule in front of it. Four captions doing
   the job the headings were already doing better, in the smallest type on the
   page, which is the opposite of what this page is for. They are gone. The
   headings and the marks are the pop. */
.lp-deals .lp-bucket-title { color:var(--brand-text); }
/* Bigger, and with room for a line under it. These headings carry the page's
   narrative now, one handing off to the next, and at 1.6rem in a 700 weight
   they were captions on top of modules rather than the thing being said. */
/* 30ch, not 24. Every heading on this page is one spoken sentence rather than a
   paragraph, and at 24ch the shortest of them was breaking with two thirds of
   the container still empty beside it: "None of those 12? There" / "are 47." is
   a measure fighting a line that had room to finish. 30ch of this face is about
   660px inside a 960 container, still a comfortable measure, and it lets the
   two one-line headings stay one line now that both have grown a word.

   `balance` for what still wraps. The deals heading is the long one and it
   would otherwise leave a stub on its last line; balanced, it breaks into even
   lines wherever the viewport puts it. */
.lp-bucket-title {
    font-size:clamp(1.6rem,4.2vw,2.65rem);
    font-weight:800;
    letter-spacing:-.036em;
    line-height:1.14;
    margin:0;
    max-width:30ch;
    text-wrap:balance;
}
/* ── the mark ────────────────────────────────────────────────────────────
   The out-of-office sentence has always had a highlighter on it, with an
   irregular radius so it reads as drawn on rather than as a rounded rectangle.
   It is the best-looking thing on the page and it was doing it in one section.

   Now it is the page's. A headline gets it on the word the sentence is about,
   in the gold this brand announces things in, with near-black type on it, which
   is 9.67:1 and legal anywhere. Two of them on the page and one number: any
   more and it stops being emphasis. */
/* Tight. At 2.65rem a .3em pad and a 16px radius is a lozenge with a word in
   it, and two of them on consecutive lines nearly touch. Half the padding, a
   quarter of the radius: still drawn on rather than boxed, and it stops
   reading as a button. */
.lp-mark {
    font-weight:800; padding:.01em .2em .05em;
    background:var(--brand-highlight); color:var(--brand-highlight-text);
    border-radius:4px 9px 5px 8px;
    -webkit-box-decoration-break:clone; box-decoration-break:clone;
}
.lp-mark.is-big {
    font-size:1.2em; line-height:1; letter-spacing:-.05em;
    padding:.02em .18em .08em; border-radius:5px 11px 6px 10px;
}

.lp-bucket-lead {
    margin:11px 0 0;
    font-size:clamp(.92rem,1.25vw,1.02rem);
    line-height:1.5;
    color:var(--text-secondary);
    max-width:54ch;
}
/* On a slab the quiet text is the brand's, not the page's. */
.bl-mad .lp-bucket-lead, .lp-deals .lp-bucket-lead { color:var(--brand-text-muted); }
.bl-mad .lp-bucket-title, .lp-deals .lp-bucket-title { color:var(--brand-text); }

/* The framing line the out-of-office section went without. */
.bl-mad .mad-head { margin-bottom:clamp(22px,2.6vw,34px); position:relative; }

/* ════════════════════════════════════════════════════════════════
   FEATURED ADVENTURES
   ════════════════════════════════════════════════════════════════ */
.lp-adventures-header { margin-bottom:clamp(22px,2.6vw,32px); }

/* The card itself now lives in `cards.css`, shared with the blog. */

/* ════════════════════════════════════════════════════════════════
   SOCIAL PROOF MARQUEE
   ════════════════════════════════════════════════════════════════ */
.lp-proof {
    padding:48px 0;
    background:var(--bg-secondary);
    overflow:hidden;
}
.lp-proof-header { text-align:center; margin-bottom:24px; }
.lp-proof-rating {
    display:inline-flex; align-items:center; gap:8px;
    font-size:.9rem; color:var(--text-secondary);
}
.lp-proof-rating strong { color:var(--text-primary); font-size:1rem; }
.lp-proof-marquee { position:relative; width:100%; overflow:hidden; }
.lp-proof-track {
    display:flex; gap:16px;
    animation:lpMarquee 40s linear infinite;
    width:max-content;
}
.lp-proof-track:hover { animation-play-state:paused; }
@keyframes lpMarquee { from { transform:translateX(0); } to { transform:translateX(-50%); } }
.lp-proof-card {
    flex:0 0 280px;
    background:var(--card-bg); border:1px solid var(--card-border);
    border-radius:14px; padding:20px;
    transition:border-color .2s ease;
}
.lp-proof-card:hover { border-color:var(--accent-color); }
.lp-proof-stars { color:#f59e0b; font-size:.85rem; letter-spacing:2px; margin-bottom:8px; }
.lp-proof-text { font-size:.85rem; line-height:1.55; color:var(--text-secondary); margin-bottom:10px; }
.lp-proof-author { font-size:.75rem; color:var(--text-muted); font-weight:600; }

/* ════════════════════════════════════════════════════════════════
   CLOSE CTA
   ════════════════════════════════════════════════════════════════ */

/* ════════════════════════════════════════════════════════════════
   PHONE MOCKUP — premium iPhone-style frame
   ════════════════════════════════════════════════════════════════ */
.lp-phone {
    position:relative; flex-shrink:0;
}
.lp-phone-glow {
    position:absolute;
    top:50%; left:50%; transform:translate(-50%,-50%);
    width:300px; height:420px;
    background:radial-gradient(ellipse, var(--accent-alpha) 0%, transparent 70%);
    opacity:.5; pointer-events:none;
    filter:blur(40px);
}
.lp-phone-frame {
    position:relative;
    width:240px; height:500px;
    border-radius:40px;
    background:#1a1a1a;
    border:2.5px solid #3a3a3a;
    box-shadow:
        0 0 0 1px rgba(255,255,255,.06) inset,
        0 30px 80px rgba(0,0,0,.4),
        0 8px 24px rgba(0,0,0,.2);
    overflow:hidden;
}
/* Dynamic island */
.lp-phone-island {
    position:absolute; top:12px; left:50%; transform:translateX(-50%);
    width:90px; height:28px;
    background:#000;
    border-radius:20px;
    z-index:3;
}
/* Side buttons */
.lp-phone-btn-volume1, .lp-phone-btn-volume2, .lp-phone-btn-power {
    position:absolute; background:#2a2a2a; border-radius:2px; z-index:4;
}
.lp-phone-btn-volume1 { left:-4px; top:140px; width:4px; height:28px; }
.lp-phone-btn-volume2 { left:-4px; top:180px; width:4px; height:28px; }
.lp-phone-btn-power { right:-4px; top:160px; width:4px; height:48px; }

.lp-phone-screen {
    position:absolute; inset:4px;
    overflow:hidden;
    border-radius:40px;
    background:#000;
}

/* 2-column gallery inside phone — photos go edge-to-edge behind the island */
.lp-phone-gallery {
    display:flex; gap:5px;
    padding:5px;
    height:100%;
}
.lp-phone-col {
    flex:1; min-width:0;
    display:flex; flex-direction:column; gap:5px;
    will-change:transform;
}

.lp-phone-photo {
    position:relative; flex-shrink:0;
    border-radius:6px; overflow:hidden;
    cursor:pointer;
    transition:opacity .2s ease;
}
.lp-phone-photo img {
    width:100%; display:block;
    border-radius:6px;
    filter:saturate(1.05) contrast(1.02);
}
/* A clip is treated exactly like a still here: full width, its own height, same
   rounding and grade. The roll is a vertical scroll of natural-height tiles, so
   forcing object-fit would crop clips that the photos beside them do not. */
.lp-phone-photo video {
    width:100%; display:block;
    border-radius:6px;
    filter:saturate(1.05) contrast(1.02);
}
/* Dim other photos when one is selected */
.lp-phone-photo.lp-photo-active { outline:2px solid var(--accent-color); outline-offset:-2px; z-index:1; }

/* ── DETAIL CARD — floats beside the phone, positioned by JS ── */
.lp-detail-card {
    position:absolute;
    top:0; /* set dynamically by JS */
    width:200px;
    background:var(--card-bg);
    border:1px solid var(--border-color);
    border-radius:12px;
    overflow:hidden;
    opacity:0; pointer-events:none;
    transition:opacity .2s ease, transform .25s cubic-bezier(.16,1,.3,1);
    box-shadow:0 12px 40px rgba(0,0,0,.2);
    z-index:10;
}
.lp-detail-card.lp-detail-left {
    right:calc(100% + 20px); left:auto;
    transform:translateX(10px);
}
.lp-detail-card.lp-detail-right {
    left:calc(100% + 20px); right:auto;
    transform:translateX(-10px);
}
.lp-detail-card.visible {
    opacity:1; pointer-events:all;
    transform:translateX(0);
}
.lp-detail-img {
    width:100%; aspect-ratio:4/3; object-fit:cover; display:block;
}
.lp-detail-body { padding:10px 12px 12px; }
.lp-detail-caption {
    font-family:var(--font-mono);
    font-size:.62rem; color:var(--text-muted);
    margin-bottom:3px;
}
.lp-detail-tour {
    font-size:.82rem; font-weight:700; margin-bottom:10px;
    letter-spacing:-.01em;
}
.lp-detail-cta {
    display:inline-flex; align-items:center;
    background:var(--accent-gradient);
    color:var(--white); padding:5px 13px; border-radius:50px;
    font-size:.72rem; font-weight:600;
    text-decoration:none;
    transition:all .2s ease;
}
.lp-detail-cta:hover { filter:brightness(1.1); transform:translateY(-1px); color:var(--white); }

/* ════════════════════════════════════════════════════════════════
   DESKTOP (>=768px)
   ════════════════════════════════════════════════════════════════ */
@media (min-width:768px) {
    .lp-hero { padding:88px 32px 48px; }
    .lp-hero-inner {
        flex-direction:row;
        align-items:center;
        justify-content:space-between;
        gap:60px;
    }
    .lp-hero-text { flex:1; max-width:520px; }
    .lp-hero-title { font-size:clamp(2.2rem,4vw,3.4rem); }

    .lp-phone { display:block; flex-shrink:0; }

    /* Three across, and as wide as three cards rather than as wide as the
       column: at 91.5% of a 520px column each is 152px and the search field
       above stays visibly longer than the row under it. Nothing is a pixel,
       so the same rule holds whatever the column comes to.

       `!important` on the transform because the pile below 768px sets one
       inline on every card. The script clears them on the way up; this is what
       happens if the script is not there to. */
    .lp-featured-set {
        display:grid; grid-template-columns:repeat(3,1fr); gap:2%;
        width:91.5%; margin:4px 0 0;
    }
    /* Only to wipe a transform the pile left inline on the way up past 768.
       Everything else the pile does is inside its own media query and cannot
       reach this far. */
    .lp-featured-set .lp-poster { transform:none !important; }
    /* The pile's duplicates are the same three routes said twice. On a phone
       that is depth; in a three-wide row it is a second row of repeats. */
    .lp-featured-set .lp-poster.is-dup { display:none; }
    .lp-featured-hint { display:none; }

    .lp-bucket { padding:100px 0; }
    .lp-adventures { padding:100px 0; }

    .lp-proof { padding:80px 0; }
    .lp-proof-card { flex:0 0 320px; padding:24px; }
}

/* ════════════════════════════════════════════════════════════════
   LARGE DESKTOP (>=1200px)
   ════════════════════════════════════════════════════════════════ */
@media (min-width:1200px) {
    .lp-hero-inner { gap:60px; }
    .lp-phone-glow { width:350px; height:500px; }
    .lp-phone-frame { width:270px; height:550px; border-radius:44px; }
    .lp-phone-island { width:100px; height:32px; top:14px; }
    .lp-phone-screen { inset:5px; border-radius:43px; }
    .lp-phone-gallery { padding:7px; gap:7px; }
    .lp-phone-col { gap:7px; }
    .lp-phone-photo { border-radius:8px; }
    .lp-phone-photo img { border-radius:8px; }
    .lp-detail-card { width:220px; }
    .lp-detail-card.lp-detail-left { right:calc(100% + 28px); }
    .lp-detail-card.lp-detail-right { left:calc(100% + 28px); }

    .lp-adventure-card { flex:0 0 480px; }
}

/* ════════════════════════════════════════════════════════════════
   FAB HIDE ON LANDING
   ════════════════════════════════════════════════════════════════ */
.lp-page .settings-fab { display:none !important; }

/* ════════════════════════════════════════════════════════════════
   BUCKET MADLIB — "out of office" section (section 2)

   The section is the email. No card, no headline, no brand block: those
   made it the hero a second time, on the page's own background, which is
   why it read as more page rather than as a section.

   It carries its own color instead of the site's. A saturated field is
   the one section that needs no light and no dark version, because it is
   its own mode, and it is the only thing on this page that says whose
   page it is before a word is read. The palette is decided (see
   docs/PALETTE.md and /static/mockups/palette-lab.html); "pine" is here
   because it is the only candidate along with night that passes AA on
   every pair, and because acid lime, which is the obvious choice, is
   Contiki's brand color and Contiki is who we are positioned against.
   ════════════════════════════════════════════════════════════════ */
/* ════════════════════════════════════════════════════════════════
   THE PLATE — the page's two brand sections, drawn once

   Out of office near the top and the deals near the bottom. They bracket
   the middle of the page rather than stacking, which is what the old warning
   about "a third brand band directly under the first" was protecting against:
   two are a pair, three in a row are a stripe.

   A flat color is a swatch. The second light and the grain are what stop it
   looking like a div with a background set on it, and both sections get them
   from here rather than from a copy each.
   ════════════════════════════════════════════════════════════════ */
/* Two slabs, two colors. It was pine at the top and pine at the bottom, which
   is one color doing a job twice; the brand has two and the second one has
   been spending its life on badges. The deals are the loudest thing anybody
   says on this page, so they get the loud color. */
.bl-mad, .lp-deals {
    position:relative; isolation:isolate; overflow:hidden;
    background:var(--brand-bg); color:var(--brand-text);
    border-radius:clamp(20px, 3.2vw, 44px);
    /* A hairline of the gold each slab already announces things in, round the
       cut. One pixel, and it is what stops a large flat shape reading as a div
       with a background set on it. On the slab itself rather than on the grain
       layer, which is at 45% and would take the gold down with it. */
    /* And a shadow, because the note at the top of this block calls these two
       objects laid on a field and nothing underneath them has ever said so.
       Wide, soft and pulled up well short of its own edge so it reads as a lift
       rather than as a border; in the pine rather than in gray, because a gray
       shadow on a warmed field is how a slab goes back to looking like a div.
       The band up top only shows it along its top and bottom edges, which is
       the whole of what it has -- it meets the sides. */
    --slab-lift:0 26px 54px -30px color-mix(in srgb, var(--brand-bg) 55%, transparent);
    box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--brand-highlight) 30%, transparent),
               var(--slab-lift);
}
/* One of the two is a band and one is an object, and the corners are how you
   tell. The out of office runs edge to edge, square top and bottom: it is the
   hero continuing, and a curve under it put a lip between the promise and the
   payoff. The deals slab is rounded on all four and inset from the sides,
   because it is the aside at the end and it should look like one. */
.bl-mad { border-radius:0; }
/* The grain and the light follow the cut too, or they square off the corners
   the slab just rounded. */
.bl-mad::before, .bl-mad::after,
.lp-deals::before, .lp-deals::after { border-radius:inherit; }
.bl-mad::before, .lp-deals::before {
    content:""; position:absolute; inset:-30%; z-index:-2;
    background:
        radial-gradient(50% 55% at 78% 10%, var(--brand-bg-light) 0%, transparent 70%),
        radial-gradient(46% 50% at 5% 94%, var(--brand-bg-light) 0%, transparent 68%);
}
.bl-mad::after, .lp-deals::after {
    content:""; position:absolute; inset:0; z-index:-1; opacity:.45; pointer-events:none;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.4'/%3E%3C/svg%3E");
}
/* ── the gold slab ───────────────────────────────────────────────────────
   Everything below is the deals saying the same things in the other brand
   color. Near-black on gold is 9.67:1, the tickets become pine cards with a
   paper stub, and the notches are bitten out in the plate's own gold.

   Both tokens in the pair are fixed across light and dark on purpose (see
   palette.css), so this section looks the same whichever way the toggle is set,
   which is the whole point of having a brand color. */
.lp-deals {
    background:var(--brand-highlight); color:var(--brand-highlight-text);
    box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--brand-highlight-text) 22%, transparent),
               var(--slab-lift);
}
/* The second light, in gold rather than pine, and from the other corner so the
   pair are the same object rather than the same picture twice. */
.lp-deals::before {
    transform:scaleX(-1);
    background:
        radial-gradient(50% 55% at 78% 10%,
            color-mix(in srgb, var(--brand-highlight) 74%, var(--brand-text)) 0%, transparent 70%),
        radial-gradient(46% 50% at 5% 94%,
            color-mix(in srgb, var(--brand-highlight) 78%, var(--brand-text)) 0%, transparent 68%);
}
.lp-deals::after { opacity:.28; }
.lp-deals .lp-bucket-title { color:var(--brand-highlight-text); }
.lp-deals .lp-deals-note {
    color:color-mix(in srgb, var(--brand-highlight-text) 74%, transparent);
}
/* The handoff to /deals, in this slab's ink. `.bt-all` is the site's see-all
   button and it is drawn in the page's grays, which on gold is a hairline
   nobody can find. Same shape and same gesture as the one under the moments;
   only the two colors change, which is the point of having a brand color. */
.lp-deals .bt-all {
    border-color:color-mix(in srgb, var(--brand-highlight-text) 32%, transparent);
    color:var(--brand-highlight-text);
}
.lp-deals .bt-all:hover, .lp-deals .bt-all:focus-visible {
    border-color:var(--brand-highlight-text); color:var(--brand-highlight-text);
    background:color-mix(in srgb, var(--brand-highlight-text) 8%, transparent);
}


.bl-mad {
    padding:var(--lp-slab-gap) 0;
    /* The white card is the only thing local to this section, because a card
       floating on the brand background is a property of this layout rather
       than of the palette. */
    --mad-card-bg:          var(--white);
    --mad-card-text:        #0c1f16;
    --mad-card-text-muted:  #566258;

}
.bl-mad .container { max-width:1120px; position:relative; }
/* Top aligned, and the heading lives in the left column with the reply. The
   header used to run full width above the grid, so the photographs began level
   with the email and there was a photograph-shaped hole beside the title. */
.bl-mad .mad-grid {
    display:grid; grid-template-columns:minmax(0,1fr) clamp(210px,22vw,280px);
    gap:clamp(22px,3.4vw,44px); align-items:start;
}
.bl-mad .mad-head { margin-bottom:clamp(20px,2.2vw,30px); }

/* ── the reply, as a reply ───────────────────────────────────────────────
   It was set at 2.6rem in an 800 weight with every swapped-in phrase wearing
   its own rounded translucent block, which on a five-clause sentence is six
   overlapping blobs and one very loud paragraph. Nobody writes an email in
   display type. This is reading size in a normal weight, the marks are a tint
   and a gold rule rather than a shape, and the whole thing is about a third of
   the height it was. */
/* A frame round it, and a tinted strip at the top holding the two header
   lines. That is the whole of a compose window and it is as far as this goes:
   any more chrome and it stops being a joke about an email and starts being a
   drawing of one. */
.bl-mad .mad-say {
    border:1px solid color-mix(in srgb, var(--brand-text) 15%, transparent);
    border-radius:14px; overflow:hidden;
    background:color-mix(in srgb, var(--brand-text) 4%, transparent);
}
.bl-mad .mad-meta {
    display:flex; gap:26px; flex-wrap:wrap; align-items:baseline;
    margin:0; padding:11px clamp(15px,1.7vw,21px);
    background:color-mix(in srgb, var(--brand-text) 5%, transparent);
    border-bottom:1px solid color-mix(in srgb, var(--brand-text) 13%, transparent);
    font-family:var(--font-mono, ui-monospace, monospace);
    font-size:.68rem; letter-spacing:.03em; color:var(--brand-text-muted);
}
.bl-mad .mad-body { padding:clamp(15px,1.7vw,21px); }
.bl-mad .mad-meta b {
    /* SUBJECT is wider than the 52px floor, so the floor was doing nothing on
       that row and the live dot sat against the T. The margin is the gap. */
    display:inline-block; min-width:52px; margin-right:11px; font-weight:500;
    font-size:.58rem; letter-spacing:.19em; text-transform:uppercase;
    color:color-mix(in srgb, var(--brand-text) 45%, transparent);
}
.bl-mad .mad-meta .is-subject { color:var(--brand-text); }
/* The live dot the pill used to carry, now riding on the subject. */
.bl-mad .mad-meta i {
    display:inline-block; width:6px; height:6px; border-radius:50%; margin-right:8px;
    background:var(--brand-highlight); vertical-align:1px;
    animation:mad-blink 2.4s ease-in-out infinite;
}
@keyframes mad-blink { 0%,100% { opacity:1 } 50% { opacity:.28 } }

.bl-mad .mad-sentence {
    margin:0; min-height:6.4em;
    font-size:clamp(1.02rem,1.5vw,1.32rem); font-weight:500; line-height:1.62;
    letter-spacing:-.008em; color:var(--brand-text); max-width:50ch;
}
.bl-mad .mad-corp {
    color:color-mix(in srgb, var(--brand-text) 52%, transparent);
    text-decoration:line-through; text-decoration-thickness:2px;
}
/* The swapped-in phrase. A tint to say it is a token and a gold rule under it
   to say it is the good bit, and no radius worth noticing: a word set on a
   rounded slab is a button, and there are no buttons in an email. */
.bl-mad .mad-mark {
    font-weight:650; padding:.06em .26em .1em; border-radius:3px;
    background:color-mix(in srgb, var(--brand-text) 11%, transparent);
    box-shadow:inset 0 -2px 0 color-mix(in srgb, var(--brand-highlight) 78%, transparent);
    -webkit-box-decoration-break:clone; box-decoration-break:clone;
}
/* The quiet half of the section. Composited against the field this is
   6.7:1, which is the pair that ruled out three of the five candidates. */
.bl-mad .mad-sign {
    margin:15px 0 0; padding-top:13px; font-size:.86rem; color:var(--brand-text-muted);
    border-top:1px solid color-mix(in srgb, var(--brand-text) 12%, transparent);
}
.bl-mad .mad-place { font-weight:700; color:var(--brand-text); }

/* RIGHT — photographs as slabs, not thumbnails */
.bl-mad .mad-shots { display:grid; gap:9px; align-content:start; }
.bl-mad .mad-shot {
    position:relative; margin:0; overflow:hidden; border-radius:14px; aspect-ratio:3 / 2;
    background-size:cover; background-position:center; background-color:var(--brand-bg-light);
    box-shadow:0 16px 40px rgba(0,22,11,.38);
}
.bl-mad .mad-shot::after {
    content:""; position:absolute; inset:0;
    background:linear-gradient(to top, rgba(0,0,0,.72) 0%, rgba(0,0,0,.04) 60%, transparent 100%);
}
.bl-mad .mad-shot figcaption {
    position:absolute; left:12px; right:12px; bottom:10px; z-index:2; color:var(--white);
    font-size:.74rem; font-weight:700; text-shadow:0 1px 6px rgba(0,0,0,.7);
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

/* The trip, the width of the section */
.bl-mad .mad-bar {
    display:flex; gap:16px; align-items:center;
    margin:clamp(18px,2.2vw,26px) 0 0;
    background:var(--mad-card-bg); color:var(--mad-card-text);
    border-radius:16px; padding:14px 16px; text-decoration:none;
    box-shadow:0 24px 60px rgba(0,22,11,.45);
    transition:transform .16s ease, box-shadow .16s ease;
}
.bl-mad .mad-bar:hover {
    transform:translateY(-2px); box-shadow:0 28px 66px rgba(0,22,11,.55);
    color:var(--mad-card-text);
}
.bl-mad .mad-bar img {
    width:88px; height:60px; object-fit:cover; border-radius:10px; flex:0 0 88px;
    background:var(--brand-bg-light);
}
.bl-mad .mad-bar-name {
    font-size:1.15rem; font-weight:800; letter-spacing:-.02em; line-height:1.2;
}
.bl-mad .mad-bar-meta { font-size:.86rem; color:var(--mad-card-text-muted); }
.bl-mad .mad-bar-cta {
    margin-left:auto; background:var(--brand-highlight); color:var(--brand-highlight-text);
    font-weight:800; font-size:.88rem; padding:12px 22px; border-radius:50px; white-space:nowrap;
}

/* nav dots */
.bl-mad .mad-nav {
    /* The bar above throws a 60px shadow, so 15px put the dots inside it and
       they read as part of the card rather than as the control under it. */
    display:flex; justify-content:center; align-items:center; gap:9px;
    margin-top:clamp(26px,2.8vw,36px);
}
.bl-mad .mad-nav button {
    width:8px; height:8px; padding:0; border:none; border-radius:50px;
    background:color-mix(in srgb, var(--brand-text) 30%, transparent); cursor:pointer;
    transition:background .25s ease, width .25s ease, transform .2s ease;
}
.bl-mad .mad-nav button:hover {
    background:color-mix(in srgb, var(--brand-text) 60%, transparent); transform:scale(1.25);
}
.bl-mad .mad-nav button.on { background:var(--brand-highlight); width:26px; transform:none; }

@media (max-width:860px) {
    .bl-mad .mad-grid { grid-template-columns:1fr; gap:30px; }
    .bl-mad .mad-shots { grid-template-columns:1fr 1fr; }
    .bl-mad .mad-bar { flex-wrap:wrap; }
    .bl-mad .mad-bar-cta { margin-left:0; width:100%; text-align:center; }
}

/* ════════════════════════════════════════════════════════════════
   THE MATCHER — twelve moments, yes or no, then the trip that fits.

   On the page's own background rather than the brand field. Out-of-office above
   is pine and the ticket stubs below are pine, and a third band between them
   would leave the page more green than not. The cards are photographs to all
   four edges, so the section carries plenty of color without one.
   ════════════════════════════════════════════════════════════════ */
/* The same measure as the bucket list above it and the posters below, so the
   three read as one column rather than three widths. */
.lp-match .container { max-width: 960px; }
/* The deck on the left and the words on the right, which is the other way
   round from every other two-column section on this page. The out of office
   above it reads words-then-photographs and the section under it is a full
   width grid, so a page that never changes hands starts to feel like one long
   column with pictures stapled to the right of it.

   Flipped with `order` rather than by moving the markup: the words are what a
   screen reader and a no-JS visitor should meet first, and on a phone the
   single column has to come out in that order too. */
.lp-match-stage {
    display: grid; grid-template-columns: minmax(280px, 360px) 1fr;
    /* Centered, the question floated halfway down a 480px card and the section
       had no top edge to read from. Every other section on this page starts its
       words at the top and so does this one now.

       The gap went up because the shadow under the card is 56px of blur and it
       was reaching into the first word of the heading: the two columns measured
       58px apart and looked about twenty. */
    gap: clamp(34px,5.4vw,84px); align-items: start;
}
.lp-match-say { order: 2; }
.lp-match-side { order: 1; }
/* Every one of these is toggled with the `hidden` property, and an author
   `display` beats the browser's own `[hidden] { display: none }` — so the rule
   has to be restated here or `el.hidden = true` does nothing at all. The same
   trap is already documented on `.tour-fs[hidden]`. */
.lp-match-stage[hidden],
.lp-match-result[hidden],
.lp-match-ctrls[hidden],
.lp-match-card[hidden] { display: none; }
/* A rule and a word, not a pill. YOUR TRIP in a pale gray capsule was a
   caption for a heading that captions itself, and it was the quietest thing on
   a block that has just told somebody where they are going. The block throws
   confetti as it arrives instead; the label only has to name what follows it. */
.lp-match-eyebrow {
    display: inline-flex; align-items: center; gap: 10px;
    font-family: var(--font-mono); font-size: .66rem; font-weight: 700;
    letter-spacing: .14em; text-transform: uppercase;
    color: var(--accent-color);
}
.lp-match-eyebrow::before {
    content: ""; width: 24px; height: 2px; border-radius: 2px;
    background: var(--accent-color);
}
.lp-match-ask {
    margin: 15px 0 0; font-size: clamp(1.7rem,3.6vw,2.8rem); font-weight: 800;
    letter-spacing: -.038em; line-height: 1.04; max-width: 14ch;
}
.lp-match-lead {
    margin: 14px 0 0; font-size: .98rem; color: var(--text-secondary); max-width: 46ch;
}
.lp-match-prog { display: flex; align-items: center; gap: 12px; margin-top: 22px; flex-wrap: wrap; }
.lp-match-bar {
    flex: 1; min-width: 110px; max-width: 220px; height: 3px; border-radius: 3px;
    background: var(--border-color); overflow: hidden;
}
.lp-match-bar i {
    display: block; height: 100%; width: 0; border-radius: 3px;
    background: var(--brand-highlight); transition: width .35s ease;
}
.lp-match-n {
    font-family: var(--font-mono); font-size: .74rem; color: var(--text-muted);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.lp-match-lean { margin: 14px 0 0; font-size: .86rem; color: var(--text-muted); min-height: 1.4em; }
.lp-match-lean b { color: var(--text-primary); font-weight: 800; }

/* the deck */
.lp-match-deck { position: relative; aspect-ratio: 3/4; }
.lp-match-card {
    position: absolute; inset: 0; border-radius: 18px; overflow: hidden;
    background: var(--brand-bg); color: var(--white); touch-action: none;
    /* Was 0 24px 56px at .28, which put a gray wash across the two buttons
       directly underneath and made them look disabled. Shorter throw, tighter
       blur, and a hairline to keep the card's edge now that the shadow is not
       doing that job on its own. */
    box-shadow: 0 14px 30px rgba(0,0,0,.2), 0 2px 6px rgba(0,0,0,.1);
    /* A fan, not a stack. Straight down and scaled meant the shrink took the
       bottom edge up by about as much as the offset pushed it down, so the two
       cards behind sat inside the outline of the top one and the deck read as a
       single card. The offsets and the tilt come from the script, the way the
       pile on the hero fans, so the corners underneath show. */
    transform-origin: 50% 100%;
    transform: translate3d(calc(var(--dx,0) * 1px), calc(var(--d,0) * 11px), 0)
               rotate(calc(var(--dr,0) * 1deg))
               scale(calc(1 - var(--d,0) * .04));
    transition: transform .32s cubic-bezier(.2,.7,.3,1), opacity .3s ease;
}
.lp-match-card.is-top { cursor: grab; }

/* ── the card shows you the gesture ──────────────────────────────────────
   There was a line of 10px mono under the deck reading "or drag the card",
   which asks a reader to imagine a movement. This performs it: a nudge right
   with the Yes stamp coming up, a nudge left with Not for me, then a long
   pause, on a loop until the first time anybody answers. The same bet as the
   foil on /bucket-list, where you learn what the control is by watching it
   work once.

   Only ever on the top card, whose own transform is the identity, so the
   animation has nothing to fight. It is pulled the moment a pointer goes down
   or a button is pressed, because a running animation outranks the inline
   transform the drag handler writes. */
@keyframes lp-match-nudge {
    0%, 60%, 100% { transform: translate3d(0,0,0) rotate(0deg); }
    68%           { transform: translate3d(34px,0,0) rotate(5deg); }
    76%           { transform: translate3d(0,0,0) rotate(0deg); }
    84%           { transform: translate3d(-34px,0,0) rotate(-5deg); }
    92%           { transform: translate3d(0,0,0) rotate(0deg); }
}
@keyframes lp-match-peek-yes { 0%, 62%, 74%, 100% { opacity: 0; } 67%, 70% { opacity: 1; } }
@keyframes lp-match-peek-no  { 0%, 78%, 90%, 100% { opacity: 0; } 83%, 86% { opacity: 1; } }
.lp-match-card.is-nudge { animation: lp-match-nudge 4.6s cubic-bezier(.4,0,.3,1) infinite; }
.lp-match-card.is-nudge .lp-match-mark.is-yes {
    animation: lp-match-peek-yes 4.6s cubic-bezier(.4,0,.3,1) infinite;
}
.lp-match-card.is-nudge .lp-match-mark.is-no {
    animation: lp-match-peek-no 4.6s cubic-bezier(.4,0,.3,1) infinite;
}
.lp-match-card.is-dragging { transition: none; cursor: grabbing; }
.lp-match-card.is-gone {
    transition: transform .42s cubic-bezier(.3,.6,.3,1), opacity .42s ease; opacity: 0;
}
.lp-match-card img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.lp-match-card::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(to top, rgba(0,0,0,.88) 2%, rgba(0,0,0,.36) 46%, rgba(0,0,0,.04) 78%);
}
.lp-match-no {
    position: absolute; top: 14px; left: 15px; z-index: 3;
    font-family: var(--font-mono); font-size: .64rem; font-weight: 700;
    letter-spacing: .12em; color: var(--brand-highlight);
}
.lp-match-body { position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; padding: 20px; }
.lp-match-t {
    display: block; font-size: 1.2rem; font-weight: 800;
    letter-spacing: -.026em; line-height: 1.18;
}
.lp-match-m {
    display: block; margin-top: 8px;
    font-family: var(--font-mono); font-size: .66rem; opacity: .78;
}
/* The two stamps ride on the card and fade in with the drag. */
.lp-match-mark {
    position: absolute; top: 22px; z-index: 4; opacity: 0;
    font-family: var(--font-mono); font-size: .86rem; font-weight: 700;
    letter-spacing: .16em; text-transform: uppercase;
    padding: 8px 14px; border-radius: 8px; border: 2.5px solid;
}
.lp-match-mark.is-yes {
    left: 18px; color: var(--brand-highlight); border-color: var(--brand-highlight);
    transform: rotate(-11deg);
}
.lp-match-mark.is-no { right: 18px; color: #ff8f7a; border-color: #ff8f7a; transform: rotate(11deg); }

/* Clear of the card, not tucked under its edge. */
.lp-match-ctrls {
    display: flex; gap: 11px; align-items: center; justify-content: center;
    margin-top: clamp(24px,2.6vw,34px);
}
.lp-match-btn {
    display: inline-flex; align-items: center; gap: 9px; cursor: pointer;
    font: inherit; font-size: .9rem; font-weight: 800; line-height: 1;
    padding: 13px 24px; border-radius: 50px; border: 1.5px solid;
}
.lp-match-btn.is-no { background: transparent; color: var(--text-primary); border-color: var(--border-color); }
.lp-match-btn.is-no:hover { border-color: var(--text-secondary); }
.lp-match-btn.is-yes {
    background: var(--brand-highlight); border-color: var(--brand-highlight);
    color: var(--brand-highlight-text);
}
.lp-match-btn.is-yes:hover { filter: brightness(1.06); }
/* With no JavaScript the deck is a stack of photographs and this is the way
   out of it, so it is not hidden once the script runs. */
/* Under the words now, so it reads as the end of that column rather than as a
   fourth thing stacked below the deck. */
.lp-match-fallback { margin: 20px 0 0; font-size: .85rem; }
.lp-match-fallback a { color: var(--accent-color); font-weight: 600; text-decoration: none; }
.lp-match-fallback a:hover { text-decoration: underline; }

/* the result, in the poster language the trips grid uses */
.lp-match-result {
    position: relative;
    display: grid; grid-template-columns: minmax(0,290px) 1fr;
    gap: clamp(28px,4.4vw,64px); align-items: start;
}
/* The confetti, for the two and a half seconds it exists. Sized to the block
   and drawn in the palette by the script, which reads the tokens off the
   document rather than naming a color. Anything thrown past an edge is simply
   not drawn, so it can never widen the page. */
.lp-match-confetti {
    position: absolute; inset: 0; z-index: 6;
    width: 100%; height: 100%; pointer-events: none;
}
.lp-match-poster {
    position: relative; display: block; aspect-ratio: 3/4;
    border-radius: 18px; overflow: hidden; background: var(--brand-bg); color: var(--white);
    box-shadow: 0 24px 56px rgba(0,0,0,.28);
}
.lp-match-poster, .lp-match-poster:hover { color: var(--white); }
.lp-match-poster img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.lp-match-poster::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(to top, rgba(0,0,0,.9) 4%, rgba(0,0,0,.4) 46%, rgba(0,0,0,.04) 78%);
}
.lp-match-poster-body { position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; padding: 18px; }
.lp-match-poster-route {
    display: block; font-family: var(--font-mono); font-size: .62rem; letter-spacing: .08em;
    opacity: .8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lp-match-poster-name {
    display: block; font-size: 1.5rem; font-weight: 800; letter-spacing: -.032em;
    line-height: 1.06; margin: 6px 0 9px;
}
.lp-match-poster-foot {
    display: flex; align-items: baseline; gap: 9px; font-size: .86rem;
    padding-top: 10px; border-top: 1px solid rgba(255,255,255,.22);
}
.lp-match-poster-foot b { font-size: 1.08rem; font-weight: 800; letter-spacing: -.022em; }
.lp-match-poster-days { margin-left: auto; }

.lp-match-win {
    margin: 11px 0 0; font-size: clamp(1.5rem,3.2vw,2.4rem); font-weight: 800;
    letter-spacing: -.036em; line-height: 1.05;
}
/* The name of the trip is the trip. Nothing about it said so. */
.lp-match-win a { color: inherit; text-decoration: none; }
.lp-match-win a:hover {
    text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 5px;
}
.lp-match-because { margin: 18px 0 0; display: grid; gap: 9px; }
.lp-match-because-h {
    font-family: var(--font-mono); font-size: .64rem; letter-spacing: .12em;
    text-transform: uppercase; color: var(--text-muted); margin-bottom: 2px;
}
.lp-match-b { display: flex; gap: 10px; align-items: flex-start; font-size: .94rem; line-height: 1.36; }
.lp-match-b svg {
    flex: 0 0 auto; width: 16px; height: 16px; margin-top: 2px; fill: none;
    stroke: var(--brand-highlight); stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round;
}
.lp-match-rank { margin: 20px 0 0; display: grid; gap: 8px; max-width: 420px; }
.lp-match-r {
    display: grid; grid-template-columns: 1fr 84px 34px; gap: 11px; align-items: center;
    font-size: .82rem; color: var(--text-muted);
}
.lp-match-r.is-top { color: var(--text-primary); font-weight: 700; }
/* The three under the winner are trips too, and until now the only way to
   reach one of them was to answer twelve more cards and hope. */
.lp-match-r a {
    display: block; min-width: 0; color: inherit; text-decoration: none;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lp-match-r a:hover {
    color: var(--accent-color); text-decoration: underline; text-underline-offset: 3px;
}
.lp-match-fit { height: 5px; border-radius: 5px; background: var(--border-color); overflow: hidden; }
.lp-match-fit i { display: block; height: 100%; background: var(--brand-highlight); border-radius: 5px; }
.lp-match-v { font-family: var(--font-mono); font-size: .72rem; text-align: right; font-variant-numeric: tabular-nums; }
.lp-match-again { margin: 22px 0 0; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.lp-match-go {
    display: inline-flex; align-items: center; text-decoration: none;
    background: var(--brand-highlight); color: var(--brand-highlight-text);
    font-weight: 800; font-size: .88rem; padding: 12px 22px; border-radius: 50px;
}
.lp-match-go:hover { color: var(--brand-highlight-text); filter: brightness(1.06); }
.lp-match-restart {
    font-family: var(--font-mono); font-size: .7rem; font-weight: 600; cursor: pointer;
    color: var(--text-muted); background: transparent;
    border: 1px solid var(--border-color); border-radius: 999px; padding: 8px 15px;
}
.lp-match-restart:hover { border-color: var(--accent-color); color: var(--accent-color); }
.lp-match-none { max-width: 52ch; }

@media (max-width: 860px) {
    .lp-match-stage { grid-template-columns: 1fr; gap: 26px; }
    /* One column, and the question comes before the cards that ask it. */
    .lp-match-say { order: 1; }
    .lp-match-side { order: 2; }
    .lp-match-deck { max-width: 340px; margin: 0 auto; width: 100%; }
    .lp-match-result { grid-template-columns: 1fr; }
    .lp-match-poster { max-width: 290px; }
}
@media (prefers-reduced-motion: reduce) {
    .lp-match-card, .lp-match-bar i { transition: none; }
    /* No demonstration for somebody who asked for no motion. The two buttons
       under the deck say the same thing and they are always there. */
    .lp-match-card.is-nudge,
    .lp-match-card.is-nudge .lp-match-mark { animation: none; }
}

/* ── What is on offer ──────────────────────────────────────────────────────
   Tickets, because of what the data is. Every live deal has a headline and,
   between them, no photograph, no standfirst and no page. The cards this
   replaced were built for all three, so what they drew was four tinted boxes
   with a line of gray text in each -- which is the cookie-notice problem this
   section has now had twice.

   A ticket needs nothing but a number and a sentence, and it carries its own
   interest as an object rather than borrowing it from a picture we do not have.
   The perforation is two radial notches biting into the same edge, so it holds
   its shape at any width and loads nothing.

   The second brand field on the page, and the last one: the out-of-office
   section opens on pine and this closes on it. The bucket list between them
   deliberately does not, or the three would merge into one green block. */
/* The section is the plate (see THE PLATE above) and the tickets on it are
   paper. It was the other way round: four pine tickets on the page's own
   background, which is four tinted boxes with a gold number in each, and the
   whole strip read as a coupon rail. Turning it over costs nothing and changes
   what the thing is -- a board with tickets pinned to it, which is what a
   deal actually is here, and it gives the page a second brand plate to
   balance the out-of-office one near the top. */
/* Inset from the edges, where the out of office is not. That difference is the
   difference between the two slabs: the first is part of the page's spine and
   runs into the hero above it, the second is an aside at the end and floats. */
.lp-deals {
    padding: clamp(38px,4vw,60px) 0 clamp(42px,4.4vw,66px);
    margin: clamp(10px,1.6vw,24px) clamp(12px,3vw,40px) 0;
}
.lp-deals-inner { max-width: 1200px; margin: 0 auto; padding: 0 20px; position: relative; }
/* Centered, and the only heading on the page that is. The other three are part
   of the left-hand spine the whole page reads down; this one is an aside at the
   end, on a plate of its own, over a row of four objects that fills the width
   beneath it. A 30ch line pinned to the left of a 1200px plate reads as the top
   of a column that is not there, and the note under the tickets was doing the
   same thing to the other corner. */
.lp-deals .lp-adventures-header { margin-bottom: 22px; text-align: center; }
.lp-deals .lp-bucket-title { margin-inline: auto; }

/* auto-FILL for the same reason the poster grid uses it: a fifth deal on a
   four-wide row would otherwise be drawn a whole row wide on its own. */
.lp-deals-grid {
    display: grid; gap: 14px;
    grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
}

.lp-ticket {
    position: relative; display: grid; grid-template-columns: 92px 1fr;
    align-items: stretch; min-height: 126px;
    background: var(--brand-bg); color: var(--brand-text);
    border-radius: 14px; overflow: hidden; text-decoration: none;
    box-shadow: 0 12px 28px rgba(0,18,10,.3);
    transition: transform .16s ease, box-shadow .16s ease;
}
a.lp-ticket:hover { transform: translateY(-3px); box-shadow: 0 20px 40px rgba(0,18,10,.38); }
.lp-ticket, .lp-ticket:hover, .lp-ticket:focus-visible { color: var(--brand-text); }
.lp-ticket:focus-visible { outline: 2px solid var(--brand-highlight); outline-offset: 3px; }
/* The notches are painted in the plate behind, so the tear reads as a tear
   rather than as two gray dots. They moved with the stub: the notch has to sit
   on the perforation, and the perforation is now the gold edge. */
.lp-ticket::before, .lp-ticket::after {
    content: ""; position: absolute; left: 80px; width: 24px; height: 13px;
    background: var(--brand-highlight); border-radius: 13px; z-index: 4;
}
.lp-ticket::before { top: -7px; }
.lp-ticket::after { bottom: -7px; }

/* The stub is the torn-off end and it carries the number, which is the only
   thing on a ticket anybody reads first. Gold on near-black is 9.67:1; the
   figure used to be gold type on pine, which is the same two colors doing
   half the work. */
.lp-ticket-stub {
    display: grid; place-items: center; padding: 12px 6px;
    background: var(--brand-text); color: var(--brand-bg);
    border-right: 2px dashed color-mix(in srgb, var(--brand-bg) 26%, transparent);
}
.lp-ticket-big {
    font-size: 1.78rem; font-weight: 800; letter-spacing: -.04em; line-height: 1;
    color: var(--brand-bg); text-align: center;
}
.lp-ticket-big small {
    display: block; margin-top: 6px;
    font-family: var(--font-mono); font-size: .56rem; font-weight: 700;
    letter-spacing: .14em; text-transform: uppercase;
    color: color-mix(in srgb, var(--brand-bg) 72%, transparent);
}

/* A deal with a page usually has a photograph worth showing, so it sits
   behind the sentence under enough of a wash that the type holds. The stub is
   opaque over it, because a number on a picture is a number you cannot read. */
.lp-ticket-photo {
    position: absolute; left: 92px; top: 0; right: 0; bottom: 0;
    width: auto; height: 100%; object-fit: cover; z-index: 0;
}
/* A deal with a page usually has a photograph worth showing, so it sits
   behind the sentence under enough of a wash that the type holds. The card is
   paper now, so the wash is the card's own color rather than the brand's. */
.lp-ticket.has-photo .lp-ticket-say::before {
    content: ""; position: absolute; left: 0; top: 0; right: 0; bottom: 0; z-index: 1;
    background: linear-gradient(to right,
        var(--brand-bg) 14%, color-mix(in srgb, var(--brand-bg) 76%, transparent) 100%);
}
.lp-ticket.has-photo .lp-ticket-stub { position: relative; z-index: 2; }
/* More room above the sentence and a bigger sentence in it. Cutting the figure
   off the front of the headline gave this half of the ticket a line or two of
   its height back, and the way to spend that is on the words rather than on the
   gap under them: the copy used to start hard against the top edge while the
   stub's figure sat optically centered beside it, so the two halves of one
   object began at different heights. */
.lp-ticket-say { position: relative; z-index: 2; padding: 20px 17px 16px; display: flex; flex-direction: column; gap: 7px; }
.lp-ticket-head { font-size: 1.08rem; font-weight: 700; line-height: 1.3; letter-spacing: -.016em; }
.lp-ticket-sub { font-size: .8rem; line-height: 1.4; color: var(--brand-text-muted); }
.lp-ticket-foot {
    margin-top: auto; display: flex; align-items: baseline; gap: 10px;
    font-family: var(--font-mono); font-size: .68rem; color: var(--brand-text-muted);
}
.lp-ticket-foot b {
    margin-left: auto; font-family: var(--font-sans); font-size: .78rem;
    font-weight: 700; color: var(--brand-highlight);
}

/* THE PRINT ON THE TICKET
   A real ticket carries the operator's name faintly in a corner, and this card
   has been a ticket since the four tinted boxes went. So the wordmark, white on
   the pine at a quarter, in the corner the layout leaves empty.

   Only on `.is-plain`, which the template sets for a deal with no
   photograph, no end date and no page. The other two shapes have that corner
   spoken for -- a picture behind the sentence, or "Until 30 September · Read
   why" along the foot -- and a wordmark under either is a smudge rather than a
   print. It is drawn behind the type either way (`z-index:-1` inside the say
   panel's own stacking context, so it sits above the card and below every word
   on it), which is the belt to that braces.

   The white file rather than `currentColor`: the ticket is pine in both themes,
   because the plate under it is the brand's gold in both themes. */
.lp-ticket.is-plain .lp-ticket-say::after {
    content: ""; position: absolute; z-index: -1; pointer-events: none;
    right: 17px; bottom: 14px; width: 86px; height: 16px;
    background: url("/static/brand/logo-white.svg") right bottom / contain no-repeat;
    opacity: .25;
}

/* On the plate, so it takes the plate's quiet color rather than the page's.
   Centered and measured, under a centered heading. */
.lp-deals-note {
    margin: 20px auto 0; max-width: 64ch; text-align: center;
    font-size: .8rem; color: var(--brand-text-muted);
    position: relative;
}
/* Centered under a centered note, the way the moments sheet's is centered under
   the sheet. Its colors are with the rest of the gold slab, further up. */
.lp-deals-more { margin-top: 16px; display: flex; justify-content: center; position: relative; }

@media (prefers-reduced-motion: reduce) {
    a.lp-ticket:hover { transform: none; }
}
