/* ═══════════════════════════════════════════════════════════════════════════
   /bucket-list and /bucket-list/<moment>

   Descended from /static/mockups/bucket-page-lab.html, concepts S1, Q1, Q2 and
   M1, with two deliberate departures from the lab:

   **Q1 and Q2 are one module.** The lab drew them as separate concepts and the
   first build shipped them as separate sections with a chip bar wedged between,
   which put a seam through the middle of one idea. Searching and browsing are
   the same act on the same list.

   **S1 is not the hero and is not a score.** The scratch card was thirty-five
   tiles with a progress bar over them, asking a returning-visitor question of a
   first-time visitor. What was good about it was the scratching, so it survives
   at the foot of the page as a way of finding three moments at random.

   `bucket-badges.css` is the album on the landing and trip pages. This is the
   place that album links to.
   ═══════════════════════════════════════════════════════════════════════════ */



/* ── the hero, which is the search ────────────────────────────────────────
   Everybody's search answers "where do you want to go". This one answers what
   you want to do, which is what a bucket list is already an answer to. */

.bl-hero {
    position: relative; isolation: isolate; overflow: hidden;
    background: var(--brand-bg); color: var(--brand-text);
    padding: clamp(26px, 3vw, 44px) 0 clamp(24px, 2.8vw, 38px);
}
/* The pine glow is what the hero has when there is no photograph. With one it
   would be a wash over a wash, so it is only drawn on the plain version. */
.bl-hero:not(.has-shot)::before {
    content: ""; position: absolute; inset: -30%; z-index: -2;
    background:
        radial-gradient(50% 56% at 80% 8%, var(--brand-bg-light) 0%, transparent 70%),
        radial-gradient(44% 50% at 5% 95%, var(--brand-bg-light) 0%, transparent 68%);
}
/* The picture is one of the moments. The wash is heavier on the left, where
   the words are, and lets the right-hand side of the photograph through behind
   the covered cards -- so the gold sits on a picture rather than on a flat
   field, which is what made the panel look like it had been pasted on. */
.bl-shot { position: absolute; inset: 0; z-index: -2; }
.bl-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bl-shot-veil {
    position: absolute; inset: 0;
    background: linear-gradient(to right,
        rgba(4, 26, 18, .93) 0%, rgba(4, 26, 18, .82) 42%,
        rgba(4, 26, 18, .55) 74%, rgba(4, 26, 18, .42) 100%);
}
/* Two halves: the question on the left, six of the answers covered on the
   right. A search box on its own asks a reader to already know what they want,
   and the whole premise of this page is that they might not. */
.bl-hero-grid {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 40%);
    gap: clamp(24px, 3.4vw, 48px); align-items: center;
}
.bl-hero-copy { min-width: 0; }
/* Capped. At 46% of a wide container the cards came out around 250px each and
   the panel was taller than the question beside it, which is the panel
   arguing with the thing it is meant to support. */
.bl-hero-reveal { min-width: 0; max-width: 460px; margin-left: auto; }

.bl-crumb {
    font-family: var(--font-mono); font-size: .66rem; letter-spacing: .14em;
    text-transform: uppercase; color: var(--brand-text-muted);
}
/* One line at every width the hero is two columns at. It wrapped to "What do
   you want to / do?" because 14ch is narrower than the question, and a
   two-line question on a page whose whole job is to ask it reads as an
   accident. */
.bl-h1 {
    margin: 12px 0 0; font-size: clamp(1.75rem, 3.1vw, 2.6rem); font-weight: 800;
    letter-spacing: -.042em; line-height: 1.04;
    /* No max-width. It was 14ch, which is narrower than the question, so the
       one thing this page exists to ask broke across two lines. The column is
       the constraint and it is wide enough. */
}
.bl-sub {
    margin: 12px 0 0; font-size: .96rem; line-height: 1.5;
    color: var(--brand-text-muted); max-width: 50ch;
}

/* ── the control ───────────────────────────────────────────────────────────
   `filter.css` draws it, shared with /trips and the journal. What is here is
   only what this page adds: the field sits on the brand ground rather than on
   the page, so it reads as a control rather than as part of the picture, and
   the pills under it inherit the light-on-dark the hero is set in. */
.bl-hero .bt-filter { margin: 18px 0 0; max-width: 620px; }
.bl-hero .bt-field { background: var(--bg-primary); border-color: transparent; }
.bl-hero .bt-field:focus-within {
    border-color: var(--brand-highlight); box-shadow: 0 0 0 3px rgba(212, 175, 55, .22);
}
.bl-hero .bt-pills:not(:empty) { margin-top: 10px; }
.bl-hero .bt-tok {
    background: color-mix(in srgb, currentColor 12%, transparent);
    border-color: color-mix(in srgb, currentColor 26%, transparent);
    color: var(--brand-text);
}
.bl-hero .bt-field .bt-tok { background: var(--bg-secondary); color: var(--text-primary); }
.bl-hero .bt-dim { color: var(--brand-text-muted); }

.bl-tries { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 14px; align-items: center; }
.bl-tries span {
    font-family: var(--font-mono); font-size: .62rem; letter-spacing: .11em;
    text-transform: uppercase; color: var(--brand-text-muted);
}
.bl-tries a {
    font-size: .78rem; font-weight: 600; padding: 5px 12px; border-radius: 50px;
    text-decoration: none; background: transparent; color: var(--brand-text-muted);
    border: 1px solid color-mix(in srgb, var(--brand-text) 26%, transparent);
}
.bl-tries a:hover { border-color: var(--brand-highlight); color: var(--brand-highlight); }
.bl-tries a.is-on {
    background: var(--brand-highlight); border-color: transparent;
    color: var(--brand-highlight-text);
}


/* ── the results, which are also the browse ───────────────────────────────
   Nine shelves, in `position` order and never in size order. The heading is
   full width above its own moments rather than in a column beside them: the
   tagline is a sentence, and a 150px column turned it into six lines.

   Nothing sits between the hero and the first heading except the count. What
   used to be here was two rows of country and trip chips, and they are the
   shared control's job now -- on this page as on the other two, nothing shows
   until something is chosen. */
.bl-browse { padding: clamp(22px, 2.6vw, 34px) 0 10px; }
.bl-count-line {
    display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
    font-size: .9rem; color: var(--text-secondary);
    padding-bottom: 14px; border-bottom: 1px solid var(--border-color);
}
.bl-count-line strong { color: var(--text-primary); }
.bl-in b { color: var(--text-primary); font-weight: 600; }
.bl-all {
    margin-left: auto; font-size: .82rem; font-weight: 600;
    color: var(--accent-color); text-decoration: none; white-space: nowrap;
}
.bl-all:hover { text-decoration: underline; }
.bl-g { min-width: 0; }
/* A category starts with room above it, so its heading reads as the start of
   what follows and not as the caption of the row of photographs before it. */
.bl-g + .bl-g { margin-top: clamp(34px, 4vw, 54px); }
/* A heading that is also the control. It reads as a heading until the pointer
   is on it, because a page whose rule is that nothing shows until something is
   chosen cannot have nine controls announcing themselves at rest. */
.bl-v {
    display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
    text-decoration: none; color: inherit; margin-bottom: 18px; max-width: 72ch;
}
/* A short bar of the accent opens each category, where a rule the width of
   the page used to underline it like a table header. */
.bl-v::before {
    content: ''; width: 28px; height: 3px; border-radius: 2px;
    background: var(--accent-color); margin-bottom: 8px; transition: width .25s ease;
}
.bl-v .bl-n {
    font-family: var(--font-mono); font-size: .66rem; font-weight: 600;
    letter-spacing: .1em; text-transform: uppercase; color: var(--accent-color);
    font-variant-numeric: tabular-nums;
}
.bl-v b {
    display: inline-flex; align-items: center; gap: 10px;
    font-size: clamp(1.4rem, 2.5vw, 1.95rem); font-weight: 800;
    letter-spacing: -.035em; line-height: 1.08; color: var(--text-primary);
}
.bl-v-go {
    width: .8em; height: .8em; flex-shrink: 0; fill: none; stroke: currentColor;
    stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
    opacity: 0; transform: translateX(-6px); transition: opacity .2s ease, transform .2s ease;
}
.bl-v em {
    font-style: normal; font-size: .95rem; line-height: 1.5; color: var(--text-secondary);
}
.bl-v:hover, .bl-v:focus-visible { color: inherit; }
.bl-v:hover b, .bl-v.is-on b { color: var(--accent-color); }
.bl-v:hover::before, .bl-v.is-on::before { width: 56px; }
.bl-v:hover .bl-v-go, .bl-v:focus-visible .bl-v-go, .bl-v.is-on .bl-v-go { opacity: 1; transform: none; }

/* ── the moment, as a photograph with its sentence on it ──────────────────
   It was a 52px thumbnail beside eleven words until 2026-09-06, which on a
   phone is a sentence in a column two thirds of a screen wide with the picture
   too small to be the reason anybody presses it. The photograph is the reason
   anybody presses it. */
.bl-tiles {
    --bl-tile-min: 232px;
    display: grid; gap: 10px;
    grid-template-columns: repeat(auto-fill, minmax(var(--bl-tile-min), 1fr));
}
.bl-t {
    position: relative; display: block; aspect-ratio: 4 / 3.1; overflow: hidden;
    border-radius: 13px; background: var(--bg-tertiary); color: var(--white);
    isolation: isolate; text-decoration: none;
}
/* base.html darkens every link on hover; the words on a photograph stay white,
   as the covered cards' do (.bl-card below). */
.bl-t:hover, .bl-t:focus, .bl-t:focus-visible { color: var(--white); }
.bl-t.is-flat:hover, .bl-t.is-flat:focus, .bl-t.is-flat:focus-visible { color: var(--brand-text); }
.bl-t img {
    position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
    z-index: -2; transition: transform .5s ease;
}
.bl-t:hover img { transform: scale(1.05); }
/* The shade the words sit on, measured from the bottom in pixels, where the
   words are, rather than as a share of the tile: three lines of the sentence
   and the place reach about 90px up, and over all of that the shade holds at
   .62 or more, which keeps white at 4.5:1 on a white photograph. As a share it
   thinned to .44 halfway up, and on a light photograph the first line went. */
.bl-t-veil {
    position: absolute; inset: 0; z-index: -1;
    background: linear-gradient(to top, rgba(0, 0, 0, .86) 0, rgba(0, 0, 0, .62) 100px,
                rgba(0, 0, 0, .14) 160px, rgba(0, 0, 0, 0) 100%);
}
.bl-t.is-flat { background: var(--brand-bg); color: var(--brand-text); }
.bl-t-text {
    position: absolute; left: 13px; right: 13px; bottom: 27px;
    font-size: .92rem; font-weight: 650; line-height: 1.28; letter-spacing: -.014em;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
    overflow: hidden; text-shadow: 0 1px 8px rgba(0, 0, 0, .5);
}
.bl-t-place {
    position: absolute; left: 13px; right: 13px; bottom: 10px;
    font-family: var(--font-mono); font-size: .6rem; letter-spacing: .07em;
    opacity: .8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.bl-none {
    padding: 44px 0; color: var(--text-muted); font-size: .95rem;
    display: flex; gap: 16px; align-items: center; flex-wrap: wrap; max-width: 68ch;
}
.bl-none p { margin: 0; }
.bl-none .bl-all { margin-left: 0; }

.bl-tail {
    margin: 0; padding-top: 20px; border-top: 1px solid var(--border-color);
    font-size: .88rem; color: var(--text-muted); max-width: 68ch; line-height: 1.6;
}
.bl-tail a { color: var(--text-secondary); font-weight: 600; }
.bl-tail a:hover { color: var(--accent-color); }


/* ── the scratch panel ────────────────────────────────────────────────────
   The scratch card, doing the job it is good at. Six moments face down and
   taking the foil off is how you find out what they are: a reveal, not a
   record. Nothing is stored and the page claims to know nothing about anybody.

   Without scripting there is nothing to reveal, so the panel is not there and the
   hero is one column. */

html:not(.js) .bl-hero-reveal { display: none; }
html:not(.js) .bl-hero-grid { grid-template-columns: 1fr; }

.bl-reveal-grid { display: grid; gap: 8px; grid-template-columns: repeat(3, 1fr); }
/* Three across at every width. On a phone that is one row rather than two,
   which is `bucket-reveal.js` laying three cards instead of six -- the grid
   itself never changes, so the two cannot disagree about the shape. */
.bl-reveal-foot {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 12px;
}
.bl-reveal-hint {
    font-family: var(--font-mono); font-size: .6rem; letter-spacing: .11em;
    text-transform: uppercase; color: var(--brand-text-muted);
}
.bl-reveal-again {
    margin-left: auto; display: inline-flex; align-items: center; gap: 8px;
    font-size: .78rem; font-weight: 600; padding: 8px 15px; border-radius: 50px;
    cursor: pointer; font-family: var(--font-sans);
    background: transparent; color: var(--brand-text-muted);
    border: 1px solid color-mix(in srgb, var(--brand-text) 26%, transparent);
}
.bl-reveal-again svg {
    width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2.2;
    stroke-linecap: round; stroke-linejoin: round;
}
.bl-reveal-again:hover { border-color: var(--brand-highlight); color: var(--brand-highlight); }

.bl-card {
    position: relative; display: block; aspect-ratio: 1; border-radius: 11px;
    overflow: hidden; background: var(--brand-bg-light); text-decoration: none;
    cursor: crosshair;
    /* The gestures that used to eat the scratch. `touch-action` stops the page
       scrolling under a finger; the rest stop the browser deciding that
       dragging a link or a photograph is what was meant. The JS sets
       `draggable="false"` as well, because engines disagree about which of
       these is enough on its own. */
    touch-action: none; user-select: none; -webkit-user-select: none;
    -webkit-user-drag: none; -webkit-touch-callout: none;
}
/* base.html sets `a:hover { color: var(--text-primary) }`, one type and one
   pseudo-class, which outranks a bare class. Without this the caption turned
   near-black on a dark photograph the instant the card was revealed, because
   after a scratch the cursor is by definition sitting on the card. Restated
   rather than fought, exactly as `.bt-slot-link` in bucket-badges.css already
   had to: the same collision, the second time. */
.bl-card,
.bl-card:hover,
.bl-card:focus,
.bl-card:focus-visible { color: var(--white); }

.bl-card-shot, .bl-card-shot img {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; display: block;
}
.bl-card-shot img { -webkit-user-drag: none; pointer-events: none; }

/* A plate rather than a wash. A sentence over a photograph is only legible if
   something under it is doing the work, and these photographs are bright: half
   of them are snow and water. The gradient runs most of the height of the tile
   and the text carries a shadow on top of that. */
.bl-card-face {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
    padding: 30px 12px 12px; opacity: 0; transform: translateY(8px);
    transition: opacity .3s ease .12s, transform .35s cubic-bezier(.2,.7,.3,1) .12s;
    background: linear-gradient(to top,
        rgba(0,0,0,.94) 0%, rgba(0,0,0,.78) 38%, rgba(0,0,0,.3) 72%, transparent 100%);
    pointer-events: none;
}
.bl-card-face .t {
    display: block; font-size: .8rem; font-weight: 700; line-height: 1.3;
    letter-spacing: -.01em; text-shadow: 0 1px 6px rgba(0,0,0,.75);
    /* Four lines is the longest sentence in the catalog at this width. Any
       more and the plate would cover the photograph it is captioning. */
    display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
    overflow: hidden;
}
.bl-card-face .m {
    display: block; margin-top: 5px; font-family: var(--font-mono);
    font-size: .58rem; letter-spacing: .06em; color: var(--brand-highlight);
    text-shadow: 0 1px 5px rgba(0,0,0,.8);
}
/* Hover does nothing until the foil is off. Before that the cursor is a
   crosshair over gold and there is nothing to preview. */
.bl-card.is-open:hover .bl-card-face { background: linear-gradient(to top,
    rgba(0,0,0,.96) 0%, rgba(0,0,0,.84) 38%, rgba(0,0,0,.34) 72%, transparent 100%); }
.bl-card-foil {
    position: absolute; inset: 0; width: 100%; height: 100%; z-index: 4; display: block;
    -webkit-user-drag: none;
}

/* The invitation. Over the foil rather than painted into it, so scratching does
   not tear the words up, and `pointer-events: none` so it never intercepts the
   gesture it is asking for. It leaves on the first pointerdown: by then it has
   been understood and it is standing on the thing it pointed at. */
.bl-card-hint {
    position: absolute; inset: 0; z-index: 5; pointer-events: none;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px; color: var(--brand-highlight-text);
    transition: opacity .25s ease, transform .25s ease;
}
.bl-card-hint svg { width: 64px; height: 24px; overflow: visible; }
/* The brush, at the shape it actually is. `bucket-reveal.js` scratches with a
   round cap `w / 7` wide, so the gesture is a circle dragged across the tile:
   a dot travels and a rounded trail opens behind it. The instruction and the
   thing it describes are one picture, which is why this beats an arrow. */
.bl-card-hint .trail {
    fill: none; stroke: currentColor; stroke-width: 9; stroke-linecap: round;
    stroke-dasharray: 100; stroke-dashoffset: 100; opacity: .2;
}
.bl-card-hint .brush { fill: currentColor; opacity: .55; }
.bl-card-hint span {
    font-family: var(--font-mono); font-size: .6rem; font-weight: 700;
    letter-spacing: .14em; text-transform: uppercase; opacity: .72;
}
/* Sweep, hold, clear, wait. The dot and the trail run on one duration and one
   easing so they stay together and the dot looks like it is doing the opening.
   The pause is most of the cycle, so it reads as an occasional prompt rather
   than a spinner. */
@media (prefers-reduced-motion: no-preference) {
    /* Linear, not eased. The keyframes already carry the shape of the motion
       -- they are the curve walked at constant speed -- and an easing function
       on top would stretch them unevenly and pull the dot off the trail. */
    .bl-card-hint .trail { animation: bl-wipe 3.2s linear infinite; }
    .bl-card-hint .brush { animation: bl-drag 3.2s linear infinite; }
}
/* Still, and showing the finished swipe rather than nothing: a reader who
   asked for less movement should still be told what the gesture is. */
@media (prefers-reduced-motion: reduce) {
    .bl-card-hint .trail { stroke-dashoffset: 0; }
    .bl-card-hint .brush { transform: translate(46px, -9px); }
}
@keyframes bl-wipe {
    0%        { stroke-dashoffset: 100; opacity: .2; }
    42%, 78%  { stroke-dashoffset: 0;   opacity: .2; }
    95%, 100% { stroke-dashoffset: 0;   opacity: 0; }
}
/* The dot has to sit where the trail has just opened. `stroke-dashoffset`
   reveals by ARC length and a cubic moves faster through its middle, so
   sampling the curve at equal `t` would let the dot drift ahead and then fall
   behind. These stops are the bezier walked at equal fractions of its length,
   computed rather than eyeballed, which is why they are not round numbers. */
@keyframes bl-drag {
    0%        { transform: translate(0, 0);            opacity: .55; }
    5.25%     { transform: translate(4.9px, -3.5px); }
    10.5%     { transform: translate(10.9px, -4.7px); }
    15.75%    { transform: translate(16.9px, -4.6px); }
    21%       { transform: translate(23px, -4px); }
    26.25%    { transform: translate(29.1px, -3.6px); }
    31.5%     { transform: translate(35.1px, -4px); }
    36.75%    { transform: translate(40.9px, -5.7px); }
    42%, 78%  { transform: translate(46px, -9px);      opacity: .55; }
    95%, 100% { transform: translate(46px, -9px);      opacity: 0; }
}
.bl-card.is-scratching .bl-card-hint,
.bl-card.is-open .bl-card-hint { opacity: 0; animation: none; }
/* The reveal, exactly as the lab has it: what is left of the foil fades and the
   sentence comes up under it. No lift, no scale, nothing turning over. The
   scraping is the animation. Everything the eye is doing has already happened
   by the time this runs, because half the tile is gone by then, and adding a
   flourish on top of that reads as the interface taking over at the moment the
   reader had just finished doing the work. */
.bl-card.is-open { cursor: pointer; }
.bl-card.is-open .bl-card-foil {
    opacity: 0; pointer-events: none; transition: opacity .4s ease;
}
.bl-card.is-open .bl-card-face { opacity: 1; transform: none; }
.bl-card:focus-visible { outline: 2px solid var(--brand-highlight); outline-offset: 3px; }

/* 980px is also where `bucket-reveal.js` lays three cards instead of six. Once
   the panel is under the field rather than beside it, it has the whole width,
   and six cards at three hundred pixels each is two rows of something enormous
   pushing the browse off the screen. One row of three is the panel in the
   height of one card. Same number in two files on purpose: a media query is
   not readable from script without matching the string back. */
@media (max-width: 980px) {
    .bl-hero-grid { grid-template-columns: 1fr; gap: 26px; }
    /* Stacked, the panel is the full column: the cap and the right-alignment
       above are there to stop a wide screen giving it 250px cards, and a
       narrow one has the opposite problem. */
    .bl-hero-reveal { max-width: none; margin-left: 0; }
    .bl-shot-veil { background: linear-gradient(to bottom,
        rgba(4, 26, 18, .92) 0%, rgba(4, 26, 18, .86) 55%, rgba(4, 26, 18, .8) 100%); }
}

@media (max-width: 700px) {
    /* The tagline goes: at 375px it is four lines under a heading and it is a
       definition rather than something a reader needs before pressing. The
       tiles go two across, which is what a photograph with a sentence on it
       needs to still be readable at that width. */
    .bl-v em { display: none; }
    .bl-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; }
    .bl-t-text { font-size: .8rem; bottom: 24px; left: 10px; right: 10px; }
    .bl-t-place { font-size: .55rem; left: 10px; right: 10px; bottom: 8px; }
    .bl-count-line { font-size: .84rem; }
    .bl-all { margin-left: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .bl-card-face, .bl-card.is-open .bl-card-foil { transition: none; }
    .bl-card-face { transform: none; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   /bucket-list/<moment> — one moment, one page

   No banner. A cover crop at a fixed height decides for itself what leaves the
   frame and decides differently on every screen, and these 35 photographs run
   from 1.01 to 1.78 in aspect — so the page about a geyser could show steam and
   sky with the column outside the box. The photograph is the evidence here, so
   it is never cropped.

   One column throughout. There is no rail, because the trip stopped being a
   sidebar and became the site's own card at the foot, and no full-bleed
   element.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 960 to match `.lp-adventures .container`, which is what makes the poster grid
   resolve to three tracks at the size the posters are on the landing page
   rather than two fatter ones. The reading parts are held to a measure inside
   it and left-aligned, so every left edge on the page lines up and only the
   cards use the full width. The blog does the same thing with `is-railed`. */
.bm { max-width: 960px; margin: 0 auto; padding: clamp(6px, 2vw, 22px) 0 0; }
.bm-head, .bm-shot, .bm-prose, .bm-go-also { max-width: 680px; }

.bm-head { margin-bottom: clamp(20px, 3vw, 30px); }

.bm-crumb {
    display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
    font-family: var(--font-mono); font-size: .64rem; letter-spacing: .12em;
    text-transform: uppercase;
}
.bm-crumb a { color: var(--text-secondary); text-decoration: none; }
.bm-crumb a:hover { color: var(--accent-color); }
.bm-sep { color: var(--text-muted); }
/* Sized in em so it is the size of the words beside it. A fixed 16px flag in a
   0.64rem line reads as a bullet with a sentence after it, which is what the
   first attempt at this looked like. */
.bm-flag {
    width: 1.15em; height: 1.15em; border-radius: 50%;
    vertical-align: -.2em; margin-right: .45em;
}

.bm-h1 {
    margin: 14px 0 0; font-size: clamp(1.7rem, 4.2vw, 2.6rem); font-weight: 800;
    letter-spacing: -.038em; line-height: 1.1; color: var(--text-primary);
    /* No max-width. The sentences run to 82 characters and the last word is
       usually the point, so the headline wraps rather than being held to a
       measure that would orphan it. */
}

/* Where a blog post puts its byline. Three signals, none of them possible on an
   article: the place, which one of the set this is, and how soon it could be
   done. The vacancy here was most of why the page read as derivative. */
.bm-sig {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin-top: 16px; font-family: var(--font-mono); font-size: .7rem;
    color: var(--text-secondary); font-variant-numeric: tabular-nums;
}
.bm-sig > span + span::before {
    content: ""; display: inline-block; width: 3px; height: 3px; border-radius: 50%;
    background: var(--text-muted); vertical-align: .2em; margin-right: 11px;
}
/* The one signal that is an invitation rather than a description. */
.bm-sig .is-soon { color: var(--accent-color); font-weight: 700; }

/* The photograph, at its own aspect. Full width when it is wide; height-capped
   and narrower than the column when it is tall. Never cropped, never stretched,
   and the same on every screen. */
.bm-shot {
    margin: 0 0 clamp(24px, 3.4vw, 34px);
    display: flex; flex-direction: column; align-items: flex-start;
}
.bm-shot img {
    max-width: 100%; max-height: 68vh; width: auto; height: auto;
    display: block; border-radius: 14px; background: var(--bg-tertiary);
}
.bm-shot figcaption {
    margin-top: 9px; font-family: var(--font-mono); font-size: .6rem;
    letter-spacing: .06em; color: var(--text-muted);
}

/* The writing, which is the reason the page exists. Everything else on it is a
   field that already existed. */
.bm-prose { font-size: 1.06rem; line-height: 1.68; color: var(--text-primary); }
.bm-prose p { margin: 0 0 21px; }
.bm-prose p:first-child { font-size: 1.18rem; line-height: 1.56; }
.bm-prose p:last-child { margin-bottom: 0; }
.bm-prose h2, .bm-prose h3 {
    font-size: 1.1rem; font-weight: 800; letter-spacing: -.02em; margin: 30px 0 10px;
}
.bm-prose ul, .bm-prose ol { margin: 0 0 21px; padding-left: 22px; }
.bm-prose li { margin-bottom: 6px; }
.bm-prose a { color: var(--accent-color); }

/* The two questions a reader has after the writing: which trips let me do this,
   and what else could I do. In that order, because the version of this that was
   cut put eight related cards above the only block that sells anything. */
.bm-go, .bm-more {
    margin: clamp(32px, 3.8vw, 44px) 0 0; padding-top: 26px;
    border-top: 1px solid var(--border-color);
}
.bm-go-k {
    font-family: var(--font-mono); font-size: .62rem; letter-spacing: .12em;
    text-transform: uppercase; color: var(--text-secondary);
    font-weight: 700; margin: 0 0 14px;
}
/* The trips use `.lp-poster-grid` from cards.css, unchanged. `auto-fill`
   rather than `auto-fit` is why a single poster stays a card instead of
   stretching across the row: at 3/4 a full-width poster is taller than the
   viewport. That is the grid's own note and it is the reason not to write a
   new one here. */
.bm-go-also {
    margin: 0; font-size: .9rem; color: var(--text-secondary); line-height: 1.55;
}
.bm-go-also a { font-weight: 600; }

/* The tiles are `partials/bucket_index_row.html`, the index's own component, so
   a moment looks the same wherever it is listed, and `.bl-tiles` lays them out
   here as it does there. Only the track is this page's own: six tiles in a 960
   column at the browse's 232 resolve to four and a stranded two, and the wider
   track makes it three and three. The variable is all that changes, so the
   two-across phone rule below 700px still applies unaltered. */
.bm-more-tiles { --bl-tile-min: 282px; }
.bm-more-all {
    display: inline-block; margin-top: 16px; font-size: .86rem; font-weight: 600;
}

.bm-back { padding: clamp(30px, 3.6vw, 44px) 0 clamp(20px, 3vw, 34px); }
.bm-back a { font-weight: 600; font-size: .9rem; }
