/* ==========================================================================
   Buckettrips — the filter control

   A port of `app/static/mockups/final.html`, the drawing that settled this.
   Every number below — the paddings, the radii, the type sizes, the two-handled
   track, the calendar's cells — is that file's, moved across and namespaced.
   It is not a second derivation from the prose in `docs/FILTERING.md`: the
   mockup is the artifact, the document is why.

   Two things changed in the move, both because the mockup draws itself inside a
   375px or 900px box on a lab page and this draws itself on the real site:

     * the modal is `position:fixed` rather than absolute in a frame, so the
       mockup's `min-height` floor under `.stage:has(.modal)` is gone with it.
       That rule existed to stop a one-route page being shorter than the
       calendar it had to hold; a fixed modal measures against the viewport.
     * the phone drawing arrives at `max-width:700px` rather than on a `.ph`
       class. 700/701 is the pair `trips.css` already uses, and a breakpoint
       pair has to meet.

   Color comes from the palette tokens and from nowhere else. See
   `app/static/css/palette.css`, which is the only file that declares one.
   ========================================================================== */

/* ══════════════════════════════════════════════════════════════════
   THE FIELD
   Exactly one row, always: an icon, somewhere to type, and the button
   that opens the modal. It never changes height, because the pills it
   used to grow now live in their own row underneath. The mockup keeps
   them inside; on a real catalog that made the box jump a line high
   the moment the first filter was chosen, and at phone width it left
   `+ Filter` stranded on a line of its own beside nothing.
   ══════════════════════════════════════════════════════════════════ */
.bt-filter { margin:14px 0 0; }

.bt-field {
    display:flex; align-items:center; gap:8px; flex-wrap:nowrap;
    background:var(--bg-secondary);
    border:1.5px solid var(--border-color); border-radius:12px;
    padding:0 14px;
    color:var(--text-primary);
    position:relative; min-width:0;
}
.bt-field:focus-within { border-color:var(--accent-color); box-shadow:0 0 0 3px var(--accent-alpha); }

.bt-ico {
    width:16px; height:16px; flex:0 0 auto;
    fill:none; stroke:var(--text-muted); stroke-width:2.2;
    stroke-linecap:round; stroke-linejoin:round;
}

.bt-field .bt-q {
    flex:1 1 auto; min-width:0; width:100%;
    border:0; background:none; outline:none;
    color:var(--text-primary);
    font-family:var(--font-sans); font-size:.9rem;
    padding:11px 4px;
}
.bt-field .bt-q::placeholder { color:var(--text-muted); }
/* The type-to-search widget Safari and Chrome add sits on top of the pills. */
.bt-field .bt-q::-webkit-search-decoration,
.bt-field .bt-q::-webkit-search-cancel-button { -webkit-appearance:none; }

/* The real submit, off screen: pressing Enter is not the only way in. */
.bt-submit {
    position:absolute; width:1px; height:1px; padding:0; margin:-1px;
    overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* ── the pills, in a row of their own ───────────────────────────── */
/* Not there until there is something to put in it, which is the rule the whole
   design rests on: nothing shows until something is chosen. `:empty` does the
   deciding, so the server renders the row unconditionally and never has to
   know whether it is about to be visible. */
.bt-pills { display:flex; flex-wrap:wrap; gap:6px; align-items:center; margin-top:9px; }
.bt-pills:empty { display:none; }

.bt-anchor { position:relative; display:inline-block; max-width:100%; min-width:0; }
/* In the field's single row the button holds its size; only the input gives. */
.bt-field > .bt-anchor { flex:0 0 auto; }

/* The mockup's fixture data is short words. The catalog's is not: "Museo de
   Sitio y Santuario Arqueológico de Pachacámac" is a real place a reader can
   filter by, and at 320px a pill carrying it whole is wider than the field it
   sits in. `.tl` clips rather than scrolls, so the overflow would take the
   cross with it and the filter could not be removed. The value ellipses; the
   dimension, the flag and the cross never shrink. */
.bt-tok { max-width:100%; }
.bt-tok .bt-dim, .bt-tok .bt-fl, .bt-tok .bt-x { flex:0 0 auto; }
.bt-tok .bt-val { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.bt-tok {
    display:inline-flex; align-items:center; gap:5px;
    padding:3px 4px 3px 9px; border-radius:999px;
    font-family:var(--font-sans); font-size:.74rem; line-height:1.4;
    border:1px solid var(--border-color); background:var(--bg-primary);
    color:var(--text-primary); cursor:pointer; position:relative;
}
.bt-tok:hover { border-color:var(--accent-color); }
/* The pill is a button and a link side by side, so the pill itself is only the
   shell that draws the border. */
.bt-tok .bt-body {
    display:inline-flex; align-items:center; gap:5px; min-width:0;
    border:0; background:none; padding:0; margin:0;
    font:inherit; font-family:var(--font-sans); font-size:.74rem; line-height:1.4;
    color:inherit; cursor:pointer; text-align:left;
}
.bt-tok.bt-qtok .bt-body { cursor:default; }
.bt-tok .bt-body:focus-visible, .bt-tok .bt-x:focus-visible {
    outline:2px solid var(--accent-color); outline-offset:2px; border-radius:50px;
}
.bt-tok .bt-dim {
    font-family:var(--font-mono); font-size:.62rem; letter-spacing:.04em;
    color:var(--text-muted);
}
.bt-tok .bt-val { font-weight:600; }
/* The search pill opens nothing: what was typed has no screen of alternatives,
   so it does not wear a cursor that promises one. */
.bt-tok.bt-qtok { cursor:default; }
.bt-tok.bt-qtok:hover { border-color:var(--border-color); }
.bt-tok.bt-qtok .bt-val { font-style:italic; font-weight:500; }

.bt-tok .bt-x {
    display:inline-flex; align-items:center; justify-content:center;
    width:16px; height:16px; border-radius:50%;
    font-size:.9rem; line-height:1; font-family:inherit;
    border:0; background:none; padding:0; cursor:pointer;
    text-decoration:none;
}
/* base.html sets `a:hover { color: var(--text-primary) }`, which outranks one
   class, so every link-shaped thing here restates its own color. */
.bt-tok .bt-x, .bt-tok .bt-x:focus-visible { color:var(--text-muted); }
.bt-tok .bt-x:hover { background:var(--error-color); color:var(--white); }

/* `.bt-tok` already sets the face and the size; only what makes it dashed and
   quiet belongs here, as in the mockup. */
.bt-tok.bt-add {
    border-style:dashed; color:var(--text-muted);
    padding:4px 11px; background:transparent;
    flex:0 0 auto; white-space:nowrap;
}
.bt-tok.bt-add:hover { color:var(--accent-color); border-color:var(--accent-color); }

/* One size for every circle flag the control draws. */
.bt-fl { width:16px; height:16px; border-radius:50%; flex:0 0 auto; display:block; }

/* ══════════════════════════════════════════════════════════════════
   THE TYPEAHEAD

   Two sections. Content on top -- a moment, a route, an article, each
   of which takes you off the page -- and the filters below, each of
   which narrows the page you are on. Two rows that do opposite things
   have to look like two kinds of row, so the content rows are taller,
   carry a photograph and a second line, and sit under their own quiet
   heading.

   Below that, unchanged: a facet match carries its facet's glyph, and a
   country falls back to its flag. A place carries a pin rather than the
   flag of the country it is in, or Samarkand and Uzbekistan read alike.
   ══════════════════════════════════════════════════════════════════ */
/* Fixed, and drawn at the end of the document: see the note in `filter.js`.
   Above the page and the settings FAB, below the modal it can never be open
   at the same time as. */
.bt-drop {
    position:fixed; z-index:1140;
    background:var(--bg-elevated); color:var(--text-primary);
    border:1px solid var(--border-color); border-radius:12px;
    box-shadow:0 16px 48px var(--card-shadow);
    text-align:left;
    /* Fixed means the page cannot scroll to reach it, so it scrolls itself.
       `--bt-drop-room` is what `placeDrop` measured between the field and the
       edge of the screen; the fallback is for the frame before it runs. */
    max-height:var(--bt-drop-room, 60vh);
    overflow-y:auto; overscroll-behavior:contain;
}
.bt-drop .bt-di {
    display:flex; align-items:center; gap:10px;
    padding:9px 14px; font-size:.84rem; cursor:pointer;
    border-bottom:1px solid var(--border-color);
    width:100%; border-left:0; border-right:0; border-top:0;
    background:none; color:inherit; font-family:var(--font-sans); text-align:left;
}
/* The direct child, not the last row of a section: a section's last row is
   followed by the next section's heading, and the line between them is what
   says one list has ended. Only the row at the very bottom of the dropdown has
   nothing under it, and that is always the free-text row. */
.bt-drop > .bt-di:last-child { border-bottom:0; }
.bt-drop .bt-di:hover, .bt-drop .bt-di.is-active { background:var(--accent-alpha); }
.bt-drop .bt-di .bt-gly {
    width:15px; height:15px; flex:0 0 auto;
    fill:none; stroke:currentColor; stroke-width:1.9;
    stroke-linecap:round; stroke-linejoin:round; color:var(--text-muted);
}
.bt-drop .bt-di:hover .bt-gly, .bt-drop .bt-di.is-active .bt-gly { color:var(--accent-color); }
.bt-drop .bt-di .bt-dim {
    margin-left:auto; font-family:var(--font-mono); font-size:.62rem;
    letter-spacing:.06em; color:var(--text-muted); white-space:nowrap;
}
.bt-drop .bt-di.bt-all {
    background:var(--bg-secondary); color:var(--accent-color);
    font-weight:600; font-size:.78rem; justify-content:center;
}
.bt-drop .bt-di.bt-all svg { width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:2.2; flex:0 0 auto; }
/* The label itself may be long; the facet name on the right may not shrink. A
   flex item defaults to `min-width:auto`, which refuses to shrink below its
   content, so the ellipsis needs the zero as well as the overflow. */
.bt-drop .bt-di .bt-lbl { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* ── the section heading ──────────────────────────────────────────────
   Quiet on purpose. It is there to say that the rows under it are a
   different kind of thing from the rows under the next one, which needs
   a word and nothing else: a heading with any weight to it would read as
   a row, and a row is the one thing it must not be. Sticky, so the two
   halves stay named once the list is long enough to scroll inside
   itself. */
.bt-drop .bt-sh {
    position:sticky; top:0; z-index:1;
    padding:7px 14px 5px;
    background:var(--bg-secondary);
    border-bottom:1px solid var(--border-color);
    font-family:var(--font-mono); font-size:.6rem;
    letter-spacing:.1em; text-transform:uppercase;
    color:var(--text-muted);
}

/* ── a content row ────────────────────────────────────────────────────
   Taller than a filter row, with the photograph doing the identifying
   and a second line under the label carrying where it goes, how long it
   is, what it costs. It is an anchor, so it has to restate the color
   `base.html` gives every link on hover. */
.bt-drop .bt-di.bt-go { text-decoration:none; align-items:center; padding:8px 14px; }
.bt-drop .bt-di.bt-go,
.bt-drop .bt-di.bt-go:hover,
.bt-drop .bt-di.bt-go:focus-visible { color:var(--text-primary); }

/* Two classes deep, the same reason `.lp-sr-item .lp-sr-thumb` is: a page
   wrapper carrying a `.wrapper img` safety rule ties a one-class selector and
   wins on source order. */
.bt-drop .bt-di .bt-th {
    width:38px; height:38px; border-radius:8px;
    object-fit:cover; flex:0 0 auto; display:block;
}
.bt-drop .bt-di .bt-th-none {
    display:flex; align-items:center; justify-content:center;
    background:var(--bg-secondary); color:var(--text-muted);
}
.bt-drop .bt-di .bt-th-none .bt-gly { width:17px; height:17px; }
/* The label and its hint stack, and the column is what shrinks when the row
   runs out of width -- not the flag on the end of it. */
.bt-drop .bt-di .bt-cb { min-width:0; flex:1 1 auto; display:block; }
.bt-drop .bt-di .bt-hint {
    display:block; margin-top:1px;
    font-size:.7rem; color:var(--text-muted);
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.bt-drop .bt-di.bt-go .bt-lbl { display:block; font-weight:600; }

/* ══════════════════════════════════════════════════════════════════
   THE MODAL, ONE SCREEN DEEP

   `.bt-mbox`, not `.bt-modal`: that name has belonged to the site's own
   confirm dialog since long before this file, from `modal.js` by way
   of `settings-fab.css`. Sharing it inherited a `max-width:420px` that
   squeezed the two-month calendar to 27px day cells, an `overflow-y`
   that made the box a scroller, and a `modalIn` keyframe that animates
   `transform` -- which threw away the centering `translateX(-50%)` for
   200ms on every redraw, so the modal jumped sideways on every pick.
   In the other direction it broke the currency picker and every
   confirm dialog on this page, pinning them top-left of their overlay.
   The root is a list of facets, never a wall of controls. Pressing a row
   pushes that facet's own screen, which has the whole modal to itself,
   so When can be a calendar without crowding Where.
   ══════════════════════════════════════════════════════════════════ */
/* Above Bootstrap's fixed bars at 1030/1040 and above the settings FAB at 1100,
   and below the toasts at 9999, which should still be readable over a sheet. */
.bt-scrim { position:fixed; inset:0; z-index:1150; background:rgba(0,0,0,.45); }
.bt-mbox {
    position:fixed; z-index:1151;
    left:50%; top:28px; transform:translateX(-50%);
    width:min(520px,calc(100% - 36px)); max-height:calc(100% - 56px);
    display:flex; flex-direction:column;
    background:var(--bg-elevated); color:var(--text-primary);
    border:1px solid var(--border-color); border-radius:16px;
    box-shadow:0 26px 70px rgba(0,0,0,.34);
    font-family:var(--font-sans);
}

.bt-chev {
    width:14px; height:14px; flex:0 0 auto;
    fill:none; stroke:currentColor; stroke-width:2.4;
    stroke-linecap:round; stroke-linejoin:round;
}

.bt-mhead {
    display:flex; align-items:center; gap:9px; flex:0 0 auto;
    padding:13px 15px; border-bottom:1px solid var(--border-color);
}
.bt-mhead b { font-size:.95rem; font-weight:700; letter-spacing:-.018em; }
.bt-mhead .bt-mcount {
    display:grid; place-items:center; min-width:19px; height:19px; padding:0 5px;
    border-radius:19px; background:var(--accent-color); color:var(--accent-text);
    font-family:var(--font-mono); font-size:.62rem; font-weight:700;
}
.bt-mback {
    width:28px; height:28px; border-radius:50%; border:0; margin-left:-3px; flex:0 0 auto;
    background:var(--bg-secondary); color:var(--text-primary);
    display:grid; place-items:center; cursor:pointer;
}
.bt-mback:hover { color:var(--accent-color); }
.bt-mclr {
    margin-left:auto; border:0; background:none; color:var(--accent-color);
    font:inherit; font-size:.76rem; font-weight:600; cursor:pointer; padding:0;
}
/* Both carry `margin-left:auto`, so whichever comes first takes the gap: with a
   clear button the cross sits beside it, without one the cross goes right. */
.bt-mx {
    margin-left:auto; border:0; flex:0 0 auto;
    background:var(--bg-secondary); color:var(--text-primary);
    width:26px; height:26px; border-radius:50%;
    font-size:1rem; line-height:1; cursor:pointer;
}

.bt-mbody { overflow:auto; scrollbar-gutter:stable; padding:4px 8px 8px; flex:1 1 auto; min-height:0; }
.bt-mrows > * + * { border-top:1px solid var(--border-color); }
.bt-mrow {
    display:flex; align-items:center; gap:9px; width:100%;
    padding:13px 8px; border:0; background:none;
    font:inherit; font-family:var(--font-sans); font-size:.88rem;
    color:var(--text-primary); cursor:pointer; text-align:left;
}
.bt-mrow:hover { background:var(--bg-secondary); }
.bt-mrow .bt-ml { font-weight:600; flex:0 0 auto; }
.bt-mrow .bt-ml em {
    display:block; font-style:normal; font-size:.7rem; font-weight:400;
    color:var(--text-muted); margin-top:2px; letter-spacing:0;
}
.bt-mrow .bt-mut { margin-left:auto; color:var(--text-muted); font-size:.82rem; text-align:right; }
.bt-mrow {
    /* So a long chosen value ellipses rather than shoving the chevron off. */
    min-width:0;
}
.bt-mrow .bt-has {
    margin-left:auto; display:inline-flex; align-items:center; gap:5px;
    color:var(--accent-color); font-size:.82rem; font-weight:600; text-align:right;
    min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.bt-mrow .bt-has .bt-fl { width:15px; height:15px; }
.bt-mrow .bt-has .bt-plus { font-family:var(--font-mono); font-size:.66rem; font-weight:400; }
.bt-mrow > .bt-n { font-family:var(--font-mono); font-size:.62rem; color:var(--text-muted); flex:0 0 auto; }
.bt-mrow.is-switch, .bt-mrow.is-switch:hover { cursor:default; background:none; }

.bt-swb {
    margin-left:auto; display:inline-flex; align-items:center; gap:9px;
    border:0; background:none; padding:0; cursor:pointer; font:inherit;
}
.bt-swb .bt-n { font-family:var(--font-mono); font-size:.62rem; color:var(--text-muted); }
.bt-sw {
    position:relative; width:34px; height:20px; border-radius:20px; flex:0 0 auto;
    background:var(--bg-tertiary); border:1px solid var(--border-color);
}
.bt-sw::after {
    content:""; position:absolute; top:2px; left:2px;
    width:14px; height:14px; border-radius:50%;
    background:var(--text-muted); transition:left .15s ease;
}
.bt-sw.is-on { background:var(--accent-color); border-color:var(--accent-color); }
.bt-sw.is-on::after { left:16px; background:var(--white); }

.bt-mnone { padding:20px 10px; text-align:center; font-size:.82rem; color:var(--text-muted); }

/* ── a facet's own screen ───────────────────────────────────────── */
.bt-mbody .bt-find {
    width:100%; border:1px solid var(--border-color); border-radius:9px;
    padding:8px 10px; margin:5px 0 6px;
    font:inherit; font-family:var(--font-sans); font-size:.82rem;
    background:var(--bg-primary); color:var(--text-primary); outline:none;
}
.bt-mbody .bt-find:focus { border-color:var(--accent-color); }
.bt-mbody .bt-mg {
    font-family:var(--font-mono); font-size:.58rem; letter-spacing:.12em;
    text-transform:uppercase; color:var(--text-muted); padding:11px 8px 4px;
}
/* A heading that is itself a pick: a continent, over the countries under it.
   It stays a heading to look at -- same face, same size, same color -- and
   only says it is pressable by carrying a count and lighting when it is on. */
.bt-mbody .bt-mg.bt-mgb {
    display:flex; align-items:center; gap:8px; width:100%;
    border:0; background:none; cursor:pointer; text-align:left;
    border-radius:8px; margin-top:4px;
}
.bt-mbody .bt-mg.bt-mgb:hover { background:var(--bg-secondary); color:var(--text-secondary); }
.bt-mbody .bt-mg.bt-mgb.is-on { color:var(--accent-color); }
.bt-mbody .bt-mg.bt-mgb .bt-n {
    margin-left:auto; font-family:var(--font-mono); font-size:.62rem;
    letter-spacing:0; color:var(--text-muted);
}
.bt-mbody .bt-mg.bt-mgb.is-on .bt-n { color:var(--accent-color); }
.bt-mopt {
    display:flex; align-items:center; gap:10px; width:100%;
    padding:11px 8px; border:0; background:none; border-radius:9px;
    font:inherit; font-family:var(--font-sans); font-size:.87rem;
    color:var(--text-primary); cursor:pointer; text-align:left;
    text-decoration:none;
}
/* A row may be a link -- the sort's orders are, so they still work when the
   sheet is not there -- and base.html's `a:hover` outranks a single class. */
.bt-mopt, .bt-mopt:hover, .bt-mopt:visited, .bt-mopt:focus-visible { color:var(--text-primary); }
.bt-mopt:hover { background:var(--bg-secondary); }
.bt-mopt:focus-visible { outline:2px solid var(--accent-color); outline-offset:-2px; }
.bt-mopt.is-on, .bt-mopt.is-on:hover, .bt-mopt.is-on:visited { color:var(--accent-color); font-weight:600; }
.bt-mopt .bt-bx {
    width:17px; height:17px; border-radius:5px; flex:0 0 auto;
    border:1.5px solid var(--border-color); display:grid; place-items:center;
}
.bt-mopt .bt-bx.is-radio { border-radius:50%; }
.bt-mopt.is-on .bt-bx { background:var(--accent-color); border-color:var(--accent-color); }
.bt-mopt .bt-bx svg { width:10px; height:10px; fill:none; stroke:var(--white); stroke-width:3; stroke-linecap:round; stroke-linejoin:round; }
.bt-mopt .bt-fl { width:18px; height:18px; }
.bt-mopt .bt-lbl { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bt-mopt .bt-n { margin-left:auto; font-family:var(--font-mono); font-size:.66rem; color:var(--text-muted); font-weight:400; }

.bt-mpane { padding:6px 2px 2px; }

.bt-mfoot {
    display:flex; align-items:center; gap:10px; flex:0 0 auto;
    padding:11px 14px; border-top:1px solid var(--border-color);
}
.bt-mfoot .bt-done {
    margin-left:auto; border:0; border-radius:10px; padding:10px 18px;
    background:var(--accent-gradient); color:var(--accent-text);
    font:inherit; font-family:var(--font-sans); font-size:.82rem; font-weight:700; cursor:pointer;
}
.bt-mfoot .bt-mreset {
    border:0; background:none; color:var(--text-secondary);
    font:inherit; font-family:var(--font-sans); font-size:.78rem; cursor:pointer; padding:0;
    text-decoration:underline; text-underline-offset:3px;
}
.bt-mfoot .bt-mreset:hover { color:var(--text-secondary); }

/* ══════════════════════════════════════════════════════════════════
   THE RANGE CALENDAR
   As `booking.css` draws the checkout's, which is the argument that this
   becomes one component with two callers. The price on the day becomes
   the route on the day. Two presses set a range; the band behind the
   days is the range you chose, not one bar per departure.
   ══════════════════════════════════════════════════════════════════ */
.bt-cal-pager { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:6px; }
.bt-cal-range { font-family:var(--font-mono); font-size:.74rem; font-weight:600; color:var(--text-muted); letter-spacing:.02em; }
.bt-cal-nav {
    width:26px; height:26px; border-radius:50%; flex-shrink:0;
    border:1.5px solid var(--border-color); background:transparent;
    color:var(--text-secondary); font-family:inherit; font-size:.9rem;
    cursor:pointer; transition:all .16s ease;
}
.bt-cal-nav:hover:not(:disabled) { border-color:var(--accent-color); color:var(--accent-color); }
.bt-cal-nav:disabled { opacity:.32; cursor:default; }

.bt-cal { display:grid; grid-template-columns:1fr 1fr; gap:20px; }
.bt-mh {
    display:flex; align-items:center; gap:8px; width:100%;
    margin:0 0 8px; padding:5px 8px;
    border:1px solid transparent; border-radius:8px; background:none;
    font:inherit; font-family:var(--font-sans); font-size:.83rem; font-weight:700;
    color:var(--text-primary); cursor:pointer; text-align:left;
}
.bt-mh span { font-family:var(--font-mono); font-size:.66rem; color:var(--text-muted); font-weight:500; }
.bt-mh:hover { border-color:var(--accent-color); }
/* Lit when the chosen range is exactly this month, which is what one press on
   the heading sets. */
.bt-mh.is-on { background:var(--accent-alpha); border-color:var(--accent-color); color:var(--accent-color); }

.bt-cg { display:grid; grid-template-columns:repeat(7,1fr); gap:2px 0; }
.bt-dow {
    font-family:var(--font-mono); font-size:.58rem; font-weight:600;
    color:var(--text-muted); text-align:center; padding-bottom:5px; letter-spacing:.06em;
}
.bt-cd {
    position:relative; aspect-ratio:1/.94; z-index:1;
    display:flex; flex-direction:column; align-items:center; justify-content:center;
    font-size:.74rem; color:var(--text-secondary); font-variant-numeric:tabular-nums;
    cursor:pointer;
    /* A real button, so it can be tabbed to and pressed. */
    border:0; background:none; padding:0; font-family:var(--font-sans);
}
.bt-cd:focus-visible { outline:2px solid var(--accent-color); outline-offset:-2px; border-radius:6px; }
.bt-cd.is-pad { opacity:.16; cursor:default; }
/* Every other row in the modal shows focus; so does the switch and the pager. */
.bt-mrow:focus-visible, .bt-mopt:focus-visible, .bt-mg.bt-mgb:focus-visible,
.bt-swb:focus-visible, .bt-mh:focus-visible, .bt-cal-nav:focus-visible,
.bt-mback:focus-visible, .bt-mx:focus-visible, .bt-mclr:focus-visible,
.bt-done:focus-visible, .bt-mreset:focus-visible, .bt-di:focus-visible {
    outline:2px solid var(--accent-color); outline-offset:-2px;
}
/* One band on the month, so the calendar reads as dates rather than as a stack
   of bars. */
.bt-cd.in-range::before { content:""; position:absolute; inset:12% -1px; z-index:-1; background:var(--accent-alpha); }
.bt-cd.r-start::before { border-radius:9px 0 0 9px; left:8%; }
.bt-cd.r-end::before { border-radius:0 9px 9px 0; right:8%; }
.bt-cd:not(.is-pad):not(.has-dep):hover { color:var(--accent-color); font-weight:700; }
.bt-cd.has-dep b {
    display:grid; place-items:center; width:26px; height:26px; border-radius:50%;
    font-size:.74rem; font-weight:700; color:var(--white);
    background:var(--accent-gradient); transition:transform .16s ease;
}
.bt-cd.has-dep:hover b { transform:scale(1.14); }
.bt-cd.has-dep .bt-pt {
    font-family:var(--font-mono); font-size:.52rem; font-weight:600;
    color:var(--accent-color); margin-top:2px; letter-spacing:-.02em; white-space:nowrap;
    /* A day cell is about 42px wide at 320px, so a long first word is cut
       rather than allowed to run over the day beside it. */
    max-width:100%; overflow:hidden; text-overflow:ellipsis;
}
.bt-cd.r-start b, .bt-cd.r-end b { box-shadow:0 0 0 3px var(--bg-elevated), 0 0 0 5px var(--accent-color); }
/* A departure outside your dates stays on the calendar, hollow: it is the
   answer to when you could go instead. */
.bt-cd.has-dep.is-off b { background:none; border:1.5px solid var(--border-color); color:var(--text-muted); }
.bt-cd.has-dep.is-off .bt-pt { color:var(--text-muted); }

/* ══════════════════════════════════════════════════════════════════
   THE TWO-HANDLED SLIDER
   Two range inputs on one track: the track and the fill are drawn, the
   inputs are transparent and only their thumbs take the pointer, so
   either handle is grabbable anywhere along the bar.
   ══════════════════════════════════════════════════════════════════ */
.bt-rng { padding:6px 6px 2px; }
.bt-rlab { display:flex; justify-content:space-between; align-items:baseline; gap:10px; margin-bottom:14px; }
.bt-rlab b { font-size:.95rem; font-weight:700; letter-spacing:-.015em; }
.bt-rlab .bt-n { font-family:var(--font-mono); font-size:.66rem; color:var(--text-muted); }
.bt-rtrack { position:relative; height:22px; margin:0 11px; }
.bt-rtrack::before {
    content:""; position:absolute; left:-11px; right:-11px; top:9px;
    height:4px; border-radius:4px; background:var(--bg-tertiary);
}
.bt-rfill { position:absolute; top:9px; height:4px; border-radius:4px; background:var(--accent-color); }
.bt-rtrack input[type=range] {
    position:absolute; left:-11px; right:-11px; top:0;
    width:calc(100% + 22px); height:22px; margin:0;
    background:none; -webkit-appearance:none; appearance:none;
    pointer-events:none; outline:none;
}
.bt-rtrack input[type=range]::-webkit-slider-thumb {
    -webkit-appearance:none; pointer-events:auto;
    width:22px; height:22px; border-radius:50%;
    background:var(--bg-elevated); border:2.5px solid var(--accent-color);
    box-shadow:0 1px 4px rgba(0,0,0,.22); cursor:grab;
}
.bt-rtrack input[type=range]::-moz-range-thumb {
    pointer-events:auto; width:18px; height:18px; border-radius:50%;
    background:var(--bg-elevated); border:2.5px solid var(--accent-color);
    box-shadow:0 1px 4px rgba(0,0,0,.22); cursor:grab;
}
.bt-rtrack input[type=range]::-moz-range-track { background:none; border:0; }
.bt-rends { display:flex; justify-content:space-between; margin-top:9px; font-family:var(--font-mono); font-size:.64rem; color:var(--text-muted); }

/* ══════════════════════════════════════════════════════════════════
   THE PHONE
   The same two levels, arriving as a bottom sheet, and one month on the
   calendar rather than two.
   ══════════════════════════════════════════════════════════════════ */
/* 700 and 700.02, not 700 and 701: browser zoom and Windows display scaling
   both land on fractional widths, and 700.5px used to match neither rule --
   the rows stacked for a phone while the modal stayed a centered dialog. */
@media (max-width:700px) {
    /* One row down to 320px: 16 for the glyph, 8 + 8 of gap, 74 for the button
       and 28 of padding leaves the input a little over 130 of the 296 a phone's
       container gives. Nothing wraps and nothing is cut. */
    .bt-tok.bt-add { padding:4px 9px; }
    .bt-pills { gap:5px; }
    .bt-mbox {
        left:0; right:0; bottom:0; top:auto; transform:none;
        width:auto; max-height:88%;
        border-radius:20px 20px 0 0; border-bottom:0;
    }
    .bt-mfoot .bt-done { flex:1 1 auto; text-align:center; }
    .bt-cal { grid-template-columns:1fr; }
}

/* Nothing here animates for a reader who asked it not to. */
@media (prefers-reduced-motion: reduce) {
    .bt-sw::after, .bt-cd.has-dep b, .bt-cal-nav { transition:none; }
}

/* The page behind an open sheet does not scroll under it. */
body.bt-locked { overflow:hidden; }

/* A choice fetches the same page and swaps the results in. The wait is short
   enough that a spinner would be a flash, so the old results only go quiet:
   still readable, plainly not the answer yet, and exactly where they were. */
[aria-busy="true"] { opacity:.55; transition:opacity .12s ease .06s; }
@media (prefers-reduced-motion: reduce) { [aria-busy="true"] { transition:none; } }
