/* ============================================================
   The tour cards. Two of them, split by job rather than by page: the card that
   cites a trip (`.lp-adventure-*`, the blog and the listings) and the poster
   that sells one (`.lp-poster-*`, the landing page). See `macros/cards.html`.

   These rules used to live in `landing.css`, which was correct while the card
   markup lived inline in `public/index.html`. B0 moved the markup into
   `macros/cards.html` so the blog could call it, and left the styles behind,
   so the first blog post to use a `tour` block rendered a stack of unstyled
   blue links. Markup and styles move together or the extraction is not done.

   Loaded by every page that calls `adventure_card()`. The `lp-` prefix is kept
   deliberately: renaming it would be a rename across the landing page for no
   gain, and the prefix is now simply what these classes are called.
   ============================================================ */

.lp-dot { width:4px; height:4px; border-radius:50%; background:var(--text-muted); align-self:center; flex-shrink:0; }
.lp-stars { color:#f59e0b; }

.lp-adventure-card {
    border-radius:16px; overflow:hidden;
    border:1px solid var(--border-color);
    background:var(--card-bg);
    transition:border-color .2s ease, box-shadow .2s ease;
    height:100%;
}
.lp-adventure-card:hover { border-color:var(--accent-color); box-shadow:0 8px 32px var(--accent-alpha); }
.lp-adventure-link { text-decoration:none; color:inherit; display:block; }
.lp-adventure-media { aspect-ratio:16/10; overflow:hidden; }
.lp-adventure-media img { width:100%; height:100%; object-fit:cover; display:block; transition:transform .5s ease; }
.lp-adventure-card:hover .lp-adventure-media img { transform:scale(1.04); }
.lp-adventure-info { padding:20px 20px 16px; }
.lp-adventure-name { font-size:1.15rem; font-weight:700; margin-bottom:4px; letter-spacing:-.01em; }
.lp-adventure-route { font-size:.82rem; color:var(--text-muted); margin-bottom:12px; }
.lp-adventure-meta { display:flex; align-items:center; gap:8px; font-size:.82rem; color:var(--text-secondary); flex-wrap:wrap; }
.lp-adventure-meta .lp-dot { background:var(--text-muted); }
.lp-adventure-meta strong { color:var(--text-primary); }
.lp-adventure-rating { display:flex; align-items:center; gap:4px; }
.lp-adventure-bottom { display:flex; flex-wrap:wrap; gap:8px; margin-top:14px; }
.lp-adventure-departure{
    display:inline-flex; align-items:center; gap:4px;
    font-size:.75rem; font-weight:500; color:var(--text-muted);
    background:var(--bg-secondary); padding:4px 10px; border-radius:50px;
}
/* The action row sits outside the card's main anchor, because an <a> inside an
   <a> is invalid and browsers recover by closing the outer one early. */
.lp-adventure-actions { display:flex; gap:8px; align-items:center; padding:0 20px 20px; }
.lp-adventure-cta {
    display:inline-flex; align-items:center;
    background:var(--accent-gradient);
    color:var(--white); padding:8px 20px; border-radius:50px;
    font-size:.82rem; font-weight:600;
    text-decoration:none;
    transition:all .2s ease;
}
.lp-adventure-card:hover .lp-adventure-cta { filter:brightness(1.1); transform:translateY(-1px); }

/* Booking is the harder commitment, so it is the quieter button. A second
   filled button beside the first reads as two equal choices and makes the card
   look like an advert. */
.lp-adventure-book {
    display:inline-flex; align-items:center;
    padding:8px 18px; border-radius:50px;
    border:1px solid var(--border-color);
    color:var(--text-primary); background:transparent;
    font-size:.82rem; font-weight:600; text-decoration:none;
    transition:border-color .2s ease, color .2s ease;
}
.lp-adventure-book:hover { border-color:var(--accent-color); color:var(--accent-color); }

/* What it was, before whatever applies to everybody. Muted and struck, because
   the price that counts is the one beside it. */
.lp-card-was {
    font-weight: 400; color: var(--text-muted);
    text-decoration: line-through; margin-right: 2px;
}

/* Why this price is this price. Accent-colored so it reads as a deal rather
   than as another fact about the route, and only ever one line: the engine has
   already composed every live deal into the single figure beside it. */
.lp-adventure-deal {
    color: var(--accent-color); font-weight: 600;
}

/* ============================================================
   The poster — the landing page's card.

   Photograph to all four edges, everything typeset over it. It exists because
   `.lp-adventure-card` is the card every operator we are positioned against
   also draws: white body, 16:10 photo, gray meta row. With three tabs open a
   visitor could not tell which tab they were in.

   The count at the end is the part no competitor can copy. "9 to cross off" is
   read straight off the itinerary's own bucket list, and it is the only number
   on the card that is about the trip rather than about the transaction.
   ============================================================ */

/* auto-FILL, not auto-fit. `auto-fit` collapses the empty tracks on the last
   row and stretches what is left across them, so seven posters in a three-wide
   grid drew the seventh at full width -- and at 3:4 that is a card taller than
   the viewport. `auto-fill` keeps the empty tracks and the odd one out stays a
   card. It matters here and not on a text card because these have a fixed
   aspect ratio: width is height. */
/* 210 rather than 255. Four routes in a 960 container came out as a row of
   three with the fourth on its own underneath, about 800px of grid to show four
   things; four columns of 223 complete the row and take it to about 300. The
   card is told its own width below, so this is a grid change rather than a
   second card. */
.lp-poster-grid {
    display: grid; gap: 14px;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}

/* ============================================================
   THE CARD IS TOLD ITS OWN WIDTH

   Every size on this card was a rem set for the one width it had ever been
   drawn at: a 960 grid over three columns is about 309px. Put it in a narrower
   column and nothing scales -- the name stays 24px and wraps to four lines.

   So each number below is `clamp(floor, Ncqw, today)`, where N is that number
   divided by 309. At 309 and above every one of them resolves to exactly what
   it was, so /trips, the moment page and the blog are untouched; at 223 it is
   the same card rather than a different one. `.is-small` already did this for
   the hero's square version and wins on specificity where it applies.
   ============================================================ */
.lp-poster {
    position: relative; display: block; isolation: isolate;
    container-type: inline-size;
    aspect-ratio: 3 / 4;
    border-radius: clamp(12px, 5.83cqw, 18px); overflow: hidden;
    background: var(--brand-bg); color: var(--white); text-decoration: none;
}
/* base.html sets `a:hover { color: var(--text-primary) }` on one class and one
   type, which outranks a bare class, so the poster restates its own color. */
.lp-poster, .lp-poster:hover, .lp-poster:focus-visible { color: var(--white); }
.lp-poster:focus-visible { outline: 2px solid var(--brand-highlight); outline-offset: 3px; }

/* No zoom on hover. A 1.055 scale over 600ms is the photograph itself moving
   under the type, and with the body sliding up and the call to action growing
   into place at the same time, three things were in motion at once on a card
   the size of a thumbnail. What is left is a light on the photograph: the card
   answers, and nothing on it changes position. */
.lp-poster-photo {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; transition: filter .25s ease;
}
.lp-poster:hover .lp-poster-photo,
.lp-poster:focus-visible .lp-poster-photo { filter: brightness(1.09) saturate(1.04); }
/* Weighted to the bottom, where the words are, and dark enough that white type
   holds over a bright sky. */
.lp-poster::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(to top,
        rgba(0,0,0,.88) 4%, rgba(0,0,0,.42) 44%, rgba(0,0,0,.05) 76%);
}
/* No photograph is not a broken card: the brand field carries it instead. */
.lp-poster.is-blank::after {
    background: linear-gradient(to top,
        rgba(0,0,0,.55) 4%, rgba(0,0,0,.12) 60%, transparent 100%);
}

.lp-poster-top {
    position: absolute; z-index: 2;
    top: clamp(10px, 4.53cqw, 14px); left: clamp(10px, 4.53cqw, 14px);
    right: clamp(10px, 4.53cqw, 14px);
    display: flex; align-items: flex-start; gap: clamp(6px, 2.59cqw, 8px);
}
.lp-poster-days {
    font-family: var(--font-mono); font-size: clamp(8px, 3.31cqw, 10.24px);
    font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
    white-space: nowrap;
    background: rgba(0,0,0,.42); backdrop-filter: blur(4px);
    padding: clamp(3px, 1.62cqw, 5px) clamp(6px, 3.24cqw, 10px); border-radius: 5px;
}
/* Why the price is the price. Gold rather than another gray line, because it is
   the only thing on the card that is a deal rather than a fact.

   The same badge as the length, in the other color. It was a rounded lozenge
   in bold sans holding the deal's whole sentence, which is two typographic
   languages in one corner and a banner where the card wanted a stamp: at 223px
   it wrapped to two lines, pushed the length badge into two of its own, and
   turned a row of four photographs into a row with a gold bar across the top.
   Mono, uppercase, the same size, radius and padding as the badge it sits
   beside; only the fill and the type color differ, and the text is now the
   figure alone. See the macro for what the sentence does instead. */
.lp-poster-deal {
    margin-left: auto; white-space: nowrap;
    font-family: var(--font-mono); font-size: clamp(8px, 3.31cqw, 10.24px);
    font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
    background: var(--brand-highlight); color: var(--brand-highlight-text);
    padding: clamp(3px, 1.62cqw, 5px) clamp(6px, 3.24cqw, 10px); border-radius: 5px;
}

.lp-poster-body {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
    display: block; padding: clamp(12px, 5.83cqw, 18px);
}
.lp-poster-route {
    display: block; font-family: var(--font-mono);
    font-size: clamp(8.5px, 3.42cqw, 10.56px);
    letter-spacing: .06em; opacity: .8;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lp-poster-name {
    display: block; font-size: clamp(15px, 7.77cqw, 24px); font-weight: 800;
    letter-spacing: -.032em; line-height: 1.06;
    margin: clamp(4px, 1.94cqw, 6px) 0 clamp(7px, 3.24cqw, 10px);
}
.lp-poster-foot {
    display: flex; align-items: baseline; gap: clamp(4px, 1.94cqw, 6px); flex-wrap: wrap;
    padding-top: clamp(8px, 3.56cqw, 11px); border-top: 1px solid rgba(255,255,255,.22);
}
.lp-poster-foot b { font-size: clamp(13px, 5.70cqw, 17.6px); font-weight: 800; letter-spacing: -.024em; }
.lp-poster-foot s { font-weight: 400; opacity: .6; font-size: clamp(10px, 4.45cqw, 13.76px); margin-right: 5px; }
/* The small print either side of the number: "From" in front, "pp" behind. Two
   spans rather than one trailing "from, pp", so the line reads in the order it
   is spoken. */
.lp-poster-note {
    font-family: var(--font-mono); font-size: clamp(8px, 3.21cqw, 9.92px);
    letter-spacing: .1em; text-transform: uppercase; opacity: .72;
}
.lp-poster-cross { margin-left: auto; font-size: clamp(9px, 3.88cqw, 12px); font-weight: 700; opacity: .9; }

/* The call to action holds its line whether or not it is showing, and only its
   opacity changes. It used to cost no height until hover, which meant the name
   and the price were shoved upwards every time a pointer crossed the card --
   the single largest movement on it, and on a grid of seven, seven of them.
   The line is a few pixels of gradient at rest; the shift was the whole card. */
.lp-poster-go {
    display: block; opacity: 0; margin-top: clamp(7px, 3.24cqw, 10px);
    font-size: clamp(10px, 4.14cqw, 12.8px); font-weight: 700;
    transition: opacity .2s ease;
}
.lp-poster:hover .lp-poster-go,
.lp-poster:focus-visible .lp-poster-go { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
    .lp-poster-photo, .lp-poster-go { transition: none; }
}

/* ============================================================
   THE SMALL POSTER. The same card at half the width, for the three featured
   trips in the hero.

   `.lp-poster` sets every size in rem, which is correct at the one width it
   had ever been drawn at -- a 960 grid over three columns is 309px -- and
   falls apart anywhere else. At 152 the name stayed 24px and wrapped to four
   lines and the foot wrapped to three rows.

   So `is-small` makes the card its own container and restates those sizes in
   `cqw`, a percentage of the card rather than of the root. Every number below
   is the shipped one divided by 309, so at 309px this changes nothing and the
   grid under "Ready when you are" is untouched; at 152 it is the same card
   rather than a different one.

   It is square, because height is the one thing a card this size cannot
   afford, and it drops the route line and the moment count: there is room for
   a photograph, a name, a length and a price, and nothing else.

   Settled in mockups/featured-lab.html, concept F1.
   ============================================================ */
.lp-poster.is-small {
    container-type: inline-size;
    aspect-ratio: 1 / 1;
    border-radius: clamp(10px, 4.2cqw, 18px);
}
.is-small .lp-poster-top { top: 4.5cqw; left: 4.5cqw; right: 4.5cqw; gap: 2.6cqw; }
.is-small .lp-poster-days {
    font-size: clamp(7px, 3.3cqw, 11px); padding: 1.6cqw 3.2cqw; border-radius: 1.6cqw;
}
/* No `.is-small .lp-poster-deal`: the small card has carried the ribbon in its
   corner since it stopped fitting a band, so the deal span is never drawn at
   this size and the rule sizing it was dressing something that is not there. */
.is-small .lp-poster-body { padding: 5.8cqw; }
.is-small .lp-poster-route, .is-small .lp-poster-cross { display: none; }
/* ── The deal, as a ribbon across the top-right corner ──
   It was a gold band the full width of the card, sitting directly on top of the
   trip name. On a 152px card that is the loudest element there is, it read as a
   headline the trip did not write, and it pushed the name and the price down
   into the last third. A corner is where a poster has carried a flash since
   posters existed, and it takes a part of the photograph that never has
   anything in it.

   Geometry, so the numbers below are not magic. The band is centered `k` from
   both edges, which puts its middle on the corner's diagonal:

       k = 13cqw            distance from the top edge and from the right edge
       top    = k - h/2     h is the band's own height, about 10cqw here
       right  = -(W/2 - k)  so the center lands at k from the right edge
       W      = 57cqw       long enough that both ends run past the corner and
                            are cut off by the card's own overflow:hidden

   Everything is in cqw, so it is the same ribbon at 152px in the desktop row
   and at 240px in the phone's pile. */
.is-small .lp-poster-ribbon {
    position: absolute; z-index: 3;
    top: 8cqw; right: -15.5cqw; width: 57cqw;
    transform: rotate(45deg);
    padding: 2.2cqw 0; text-align: center;
    background: var(--brand-highlight); color: var(--brand-highlight-text);
    font-size: clamp(8px, 4cqw, 12px); font-weight: 800;
    letter-spacing: .04em; text-transform: uppercase; line-height: 1.1;
    white-space: nowrap; overflow: hidden;
    box-shadow: 0 2px 9px rgba(0,0,0,.3);
}
/* The small card does not get the call to action. There is no room for a line
   of it under a name that is already the height of a third of the card, and the
   ribbon is now doing the job of catching the eye. */
.is-small .lp-poster-go { display: none; }
.is-small .lp-poster-name {
    font-size: clamp(11px, 7.8cqw, 26px); margin: 1.9cqw 0 3.2cqw;
}
.is-small .lp-poster-foot { gap: 1.9cqw; padding-top: 1.5cqw; border-top: 0; }
.is-small .lp-poster-foot b { font-size: clamp(11px, 5.7cqw, 19px); }
/* No `.is-small .lp-poster-foot s`: the small card does not draw the struck
   price. Four things in the foot -- From, the old price, the price, pp -- came
   to more than the row holds, and a seven-digit currency wrapped it onto a
   second line over the trip name. The corner ribbon carries the figure. */
.is-small .lp-poster-note { font-size: clamp(7px, 3.2cqw, 10px); }
