/* Night Out styles: "Late Edition" redesign (2026-10-17).
   Layer 1: screens not yet in the design spec (kept from the previous build, on the new tokens).
   Layer 2: the design spec's components (research/claude-raw/design-spec-late-edition.md).
   Layer 3: newer screens whose markup changes in the next pushes (bar page, deals, events, points).
   Rules kept from the pinned guides: never `transition: all`; inputs >= 16px; hover only under
   (hover:hover) and (pointer:fine); transform/opacity motion; reduced motion respected. */

/* ============ Layer 1 ============ */
/* ---------- Venue rows (flat, typographic) ---------- */
.group-title { display: flex; align-items: baseline; gap: 6px; margin: 28px 0 4px; }
.group-title small { font-size: inherit; font-weight: inherit; color: var(--ink-3); }
.group-title small::before { content: "· "; }
.venue-list { margin: 0 calc(-1 * var(--gutter)); }
.venue-row { position: relative; padding: 0 var(--gutter); border-bottom: 1px solid var(--line); transition: background-color var(--d-select) var(--ease-out); }
.venue-row:has(.venue-link:active) { background: var(--surface); }
.venue-link {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "main ring" "meta meta";
  column-gap: 16px; row-gap: 10px; padding: 16px 0 14px; color: inherit; text-decoration: none; min-width: 0;
}
.row-main { grid-area: main; min-width: 0; display: grid; gap: 2px; align-content: start; }
.row-title { font-weight: 700; font-size: 17px; line-height: 22px; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.row-line2 { font-size: 15px; line-height: 20px; color: var(--ink-sub); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-line3 { font-size: 15px; line-height: 20px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.venue-link .ring { grid-area: ring; margin-top: 2px; }
.venue-link .est { grid-area: meta; min-width: 0; padding-right: 44px; }
.venue-row .save { position: absolute; right: calc(var(--gutter) - 10px); bottom: 2px; }

/* Meta line: the ring's text twin. Tone word always carries an icon (not color alone). */
.est { display: block; }
.est-meta { display: flex; flex-wrap: wrap; align-items: center; row-gap: 2px; font-size: 13px; line-height: 18px; color: var(--ink-2); }
.sep { margin: 0 6px; color: var(--ink-3); }
.tone-word { display: inline-flex; align-items: center; gap: 4px; font-weight: 600; color: var(--ink-2); }
.tone-word svg { width: 14px; height: 14px; }
.tw-fresh { color: var(--fresh); }
.tw-aging, .tw-uncertain, .tw-capacity, .tw-paused { color: var(--aging); }

/* ---------- The wait ring ---------- */
.ring { position: relative; flex: none; width: var(--ring); height: var(--ring); display: grid; place-items: center; border-radius: 50%; }
.ring svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.ring-track { fill: none; stroke: var(--fill-2); stroke-width: 2.5; }
.ring-arc { fill: none; stroke: var(--fresh); stroke-width: 3; stroke-linecap: round; transition: stroke-dasharray 400ms var(--ease-out); }
.ring[data-tone="aging"] .ring-arc, .ring[data-tone="uncertain"] .ring-arc, .ring[data-tone="capacity"] .ring-arc, .ring[data-tone="paused"] .ring-arc { stroke: var(--aging); }
.ring[data-tone="aging"] .ring-track, .ring[data-tone="stale"] .ring-track, .ring[data-tone="unknown"] .ring-track { stroke: var(--ink-4); stroke-dasharray: 3 3; }
.ring[data-tone="uncertain"] .ring-arc, .ring[data-tone="paused"] .ring-arc { stroke-dasharray: 5 4; stroke-linecap: butt; }
.ring[data-tone="closed"] .ring-track { stroke: var(--line-strong); }
.ring-text { position: relative; display: grid; justify-items: center; line-height: 1; text-align: center; }
/* Sized by text length so the range always sits inside the ring. */
.ring-num { font-size: calc(var(--ring) * 0.27); font-weight: 800; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--ink); }
.ring-num[data-len="5"] { font-size: calc(var(--ring) * 0.235); }
.ring-num[data-len="6"], .ring-num[data-len="7"] { font-size: calc(var(--ring) * 0.19); }
.ring-text small { margin-top: 2px; font-size: calc(var(--ring) * 0.16); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-2); }
.ring-text .ring-word { margin: 0; font-size: calc(var(--ring) * 0.17); letter-spacing: 0.04em; color: var(--aging); }
.ring[data-tone="closed"] .ring-word { color: var(--ink-3); }
.ring-q { font-size: calc(var(--ring) * 0.36); font-weight: 700; color: var(--ink-2); }
@media (prefers-reduced-motion: reduce) { .ring-arc { transition: none; } }

.tone { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 10px 0 8px; border-radius: var(--r-pill); font-weight: 700; font-size: var(--t-xs); background: var(--muted-soft); color: var(--ink-2); white-space: nowrap; }
.tone svg { width: 14px; height: 14px; }
.tone-fresh { background: var(--fresh-soft); color: var(--fresh); }
.tone-aging, .tone-uncertain, .tone-capacity, .tone-paused { background: var(--aging-soft); color: var(--aging); }

.undo-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: var(--s-3); padding: 4px 4px 4px 14px; border-radius: var(--r-md); background: var(--surface); border: 1px solid var(--fill-2); font-size: var(--t-sm); }

/* ---------- Skeleton ---------- */
.skeleton-row { display: grid; grid-template-columns: minmax(0, 1fr) 56px; gap: 16px; padding: 16px 0 14px; border-bottom: 1px solid var(--line); }
.sk { background: var(--fill-2); border-radius: 6px; }
.sk-lines { display: grid; gap: 8px; align-content: start; }
.sk-l1 { height: 18px; width: 60%; } .sk-l2 { height: 14px; width: 45%; } .sk-l3 { height: 14px; width: 30%; } .sk-l4 { height: 12px; width: 70%; margin-top: 6px; }
.sk-ring { width: 56px; height: 56px; border-radius: 50%; }
@media (prefers-reduced-motion: no-preference) {
  .sk-group { animation: sk-fade 1.2s var(--ease-in-out) infinite alternate; }
  @keyframes sk-fade { from { opacity: 1; } to { opacity: 0.5; } }
}

/* ---------- Map (schematic) ---------- */
.map-wrap { margin: 12px calc(-1 * var(--gutter)) 0; overflow: hidden; background: var(--surface); }
/* Same aspect as the viewBox at every width, so labels and roads never stretch. */
.map-svg { width: 100%; height: auto; aspect-ratio: 400 / 440; }
.map-svg text { text-transform: uppercase; letter-spacing: 0.06em; }
.map-caption { display: flex; justify-content: space-between; gap: 8px; padding: 10px var(--gutter); font-size: var(--t-xs); color: var(--ink-3); border-top: 1px solid var(--line); flex-wrap: wrap; }
.map-preview { position: sticky; bottom: calc(var(--tabbar-h) + var(--safe-b) + 24px); z-index: 4; margin-top: 12px; }
.map-stage { position: relative; }
.map-pin-btn {
  position: absolute; transform: translate(-50%, -50%); min-width: 52px; height: 32px; padding: 0 10px; border-radius: var(--r-pill);
  border: 2px solid var(--bg); background: var(--ink); color: var(--bg); font-weight: 800; font-size: 13px; line-height: 1; font-variant-numeric: tabular-nums;
  box-shadow: var(--shadow-pin); cursor: pointer; white-space: nowrap;
  transition: transform var(--d-select) var(--ease-out), background-color var(--d-select) var(--ease-out);
}
.map-pin-btn::before { content: ""; position: absolute; inset: -6px; }
/* Teardrop tail */
.map-pin-btn::after { content: ""; position: absolute; left: 50%; bottom: -6px; width: 10px; height: 10px; margin-left: -5px; transform: rotate(45deg); background: inherit; border-right: 2px solid var(--bg); border-bottom: 2px solid var(--bg); }
.map-pin-btn span { font-weight: 700; font-size: 10px; }
.map-pin-btn.tone-pin-fresh { background: var(--fresh); color: #000; }
.map-pin-btn.tone-pin-aging, .map-pin-btn.tone-pin-uncertain, .map-pin-btn.tone-pin-capacity, .map-pin-btn.tone-pin-paused { background: var(--aging); color: #000; }
.map-pin-btn.tone-pin-aging, .map-pin-btn.tone-pin-uncertain { outline: 1.5px dashed rgb(0 0 0 / 0.75); outline-offset: -5px; }
.map-pin-btn.tone-pin-stale, .map-pin-btn.tone-pin-unknown, .map-pin-btn.tone-pin-closed { background: var(--surface-2); color: var(--ink); border: 2px dashed var(--ink-3); }
.map-pin-btn.tone-pin-stale::after, .map-pin-btn.tone-pin-unknown::after, .map-pin-btn.tone-pin-closed::after { border-color: var(--ink-3); border-style: dashed; }
/* Selected pin: a white ring, distinct from the focus outline. */
.map-pin-btn[aria-pressed="true"] { transform: translate(-50%, -50%) scale(1.15); box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--ink), var(--shadow-pin); z-index: 3; }
.map-pin-btn:active { transform: translate(-50%, -50%) scale(.96); }
.map-pin-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }
/* Reduced motion: the selected pin keeps its ring but not the 1.15 scale; the 4% press stays. */
@media (prefers-reduced-motion: reduce) {
  .map-pin-btn, .map-pin-btn[aria-pressed="true"] { transform: translate(-50%, -50%); transition: transform var(--d-select) var(--ease-out), background-color var(--d-rm-in) linear; }
}

/* ---------- Venue detail ---------- */
/* The disclosure badge icon stays 14px at every size (higher specificity than any hero art rule). */
.back-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: var(--s-3); }
.back-link { display: inline-flex; align-items: center; gap: 4px; min-height: 44px; padding: 0 14px 0 8px; border-radius: var(--r-pill); color: var(--ink); text-decoration: none; font-weight: 600; font-size: 15px; border: 1px solid var(--line-strong); background: transparent; transition: transform var(--d-press) var(--ease-out); }
.back-link svg { width: 20px; height: 20px; }
.back-link:active { transform: scale(0.97); }
.detail-head { margin-top: 14px; display: grid; gap: 4px; }
.detail-kind { font-size: var(--t-md); line-height: 22px; font-weight: 500; }
.detail-line { font-size: 15px; line-height: 20px; color: var(--ink-2); }
.detail-line strong { color: var(--ink); font-weight: 600; }
.detail-blurb { margin-top: 10px; font-size: var(--t-md); line-height: 24px; color: var(--ink-sub); }

.queue-block { margin-top: 24px; padding: 20px; border-radius: var(--r-xl); background: var(--surface); border: 1px solid var(--line); }
.qb-top { display: flex; align-items: center; gap: 8px; justify-content: space-between; flex-wrap: wrap; }
.qb-wait { font-size: var(--t-display); line-height: 1.05; font-weight: 800; letter-spacing: -0.025em; margin-top: 14px; font-variant-numeric: tabular-nums; }
.qb-wait small { font-size: 17px; font-weight: 600; letter-spacing: 0; color: var(--ink-2); margin-left: 4px; }
.queue-block[data-tone="stale"] .qb-wait, .queue-block[data-tone="unknown"] .qb-wait, .queue-block[data-tone="closed"] .qb-wait { font-size: 22px; line-height: 28px; font-weight: 700; color: var(--ink-2); }
.qb-detail { margin-top: 6px; font-size: 15px; line-height: 20px; color: var(--ink-2); overflow-wrap: anywhere; }
.qb-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 14px 16px; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }
.qb-facts > div { display: flex; flex-direction: column-reverse; gap: 2px; min-width: 0; }
.qb-facts dt { font-size: var(--t-2xs); line-height: 14px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }
.qb-facts dd { margin: 0; font-size: 17px; line-height: 22px; font-weight: 700; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
details.how { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 4px; }
details.how summary { cursor: pointer; font-weight: 600; font-size: 15px; color: var(--ink); min-height: 44px; display: flex; align-items: center; justify-content: space-between; list-style: none; }
details.how summary::-webkit-details-marker { display: none; }
details.how summary::after { content: ""; width: 8px; height: 8px; border-right: 2px solid var(--ink-2); border-bottom: 2px solid var(--ink-2); transform: rotate(45deg) translateY(-2px); transition: transform var(--d-select) var(--ease-out); }
details.how[open] summary::after { transform: rotate(225deg) translateY(-2px); }
details.how summary:active { opacity: 0.7; }
details.how p, details.how li { font-size: var(--t-sm); line-height: 20px; color: var(--ink-2); margin-top: 6px; }
details.how ul { list-style: disc; padding-left: 20px; }

.typical { margin-top: 28px; }
.typical .qb-label { display: block; }
.typical-bars { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; align-items: end; height: 64px; margin-top: 12px; }
/* Bar heights carry data: >=3:1 against the page (WCAG 1.4.11). */
.typical-bars span { display: block; border-radius: 4px; background: var(--ink-4); min-height: 6px; }
.typical-bars span.is-now { background: var(--ink); }
.typical-axis { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; font-size: var(--t-2xs); color: var(--ink-3); text-align: center; margin-top: 6px; }

.facts { margin-top: 4px; }
.facts > div { display: flex; justify-content: space-between; gap: 16px; min-height: 48px; padding: 14px 0; border-bottom: 1px solid var(--line); font-size: 15px; line-height: 20px; }
.facts dt { color: var(--ink-2); flex: none; max-width: 45%; }
.facts dd { margin: 0; font-weight: 600; text-align: right; overflow-wrap: anywhere; min-width: 0; }

.menu-section { margin-top: 14px; }
.menu-section h3 { font-size: var(--t-xs); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 2px; }
.menu-item { display: flex; justify-content: space-between; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line); font-size: 15px; line-height: 20px; }
.menu-item span:last-child { font-variant-numeric: tabular-nums; color: var(--ink-2); }

.pass-cta { margin-top: 28px; display: grid; gap: 12px; }
.pass-cta h2 { font-size: var(--t-xs); line-height: 16px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-2); }
.pass-cta p { font-size: 15px; line-height: 21px; color: var(--ink-2); }
.pass-cta .pass-state { display: flex; gap: 8px; align-items: center; min-height: 48px; padding: 0 14px; border-radius: var(--r-md); background: var(--surface-2); color: var(--ink-2); font-weight: 600; }
.pass-state svg { width: 18px; height: 18px; flex: none; }

/* ---------- Passes ---------- */
.pass-card {
  position: relative; overflow: hidden; border-radius: var(--r-xl); padding: 20px; color: var(--pass-ink);
  background: linear-gradient(165deg, #1C1C1E 0%, var(--pass-bg) 60%); border: 1px solid var(--line-strong);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.06); display: grid; gap: 16px; isolation: isolate;
}
.pass-watermark { position: absolute; inset: -40% -20%; z-index: -1; display: grid; place-items: center; transform: rotate(-18deg); pointer-events: none; }
.pass-watermark span { font-size: 14px; font-weight: 800; letter-spacing: 0.3em; color: rgb(255 255 255 / 0.06); white-space: nowrap; line-height: 2.4; }
.pass-top { display: flex; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: 8px 12px; }
.pass-top > div { flex: 1 1 12rem; min-width: 0; }
.pass-top .qb-label { color: var(--pass-ink-2); }
.pass-venue { font-family: var(--font-display); font-size: 26px; font-weight: 800; line-height: 30px; margin-top: 4px; overflow-wrap: break-word; hyphens: auto; }
.pass-status { flex: none; height: 26px; display: inline-flex; align-items: center; padding: 0 10px; border-radius: var(--r-pill); font-size: var(--t-xs); font-weight: 700; border: 1px solid var(--line-input); }
.pass-card[data-status="active"] .pass-status { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.pass-card[data-status="expired"] .pass-status, .pass-card[data-status="cancelled"] .pass-status { background: var(--surface-2); color: var(--ink-2); border-color: var(--surface-2); }
.pass-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px 16px; padding-top: 16px; border-top: 1px dashed var(--line-strong); }
.pass-grid dt { color: var(--ink-3); font-size: var(--t-2xs); line-height: 14px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.pass-grid dd { margin: 3px 0 0; font-size: var(--t-md); line-height: 22px; font-weight: 600; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.pass-invalid { border-top: 1px dashed var(--line-strong); padding-top: 14px; font-size: var(--t-sm); font-weight: 700; display: flex; gap: 8px; align-items: center; }
.pass-invalid svg { width: 18px; height: 18px; flex: none; color: var(--aging); }
.pass-card p, .result .pass-card p { color: var(--pass-ink); max-width: none; }
.pass-ref { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.12em; }
.pass-list { display: grid; gap: 20px; margin-top: 20px; }
.pass-item-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }

/* ---------- Sheet / dialog ---------- */
dialog.sheet {
  width: min(100%, var(--phone-w)); max-width: 100%; max-height: min(92dvh, 860px); margin: auto auto 0; padding: 0; border: 0; border-top: 1px solid var(--fill-2);
  border-radius: var(--r-xl) var(--r-xl) 0 0; background: var(--raised); color: var(--ink); box-shadow: var(--shadow-sheet);
  overflow: hidden; display: none; flex-direction: column;
}
dialog.sheet[open] { display: flex; }
dialog.sheet::backdrop { background: var(--scrim); }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-out { from { opacity: 1; } to { opacity: 0; } }
.sheet-head { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 44px; align-items: center; gap: 8px; padding: 22px 8px 6px var(--gutter); flex: none; }
.sheet-grabber { position: absolute; top: 0; left: 50%; margin-left: -32px; width: 64px; height: 28px; border: 0; background: transparent; cursor: grab; display: grid; place-items: center; touch-action: none; padding: 0; }
.sheet-grabber::after { content: ""; width: 36px; height: 5px; border-radius: 3px; background: #48484A; }
.sheet-title { grid-column: 1; text-align: left; font-size: 17px; line-height: 22px; font-weight: 700; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.sheet-close { grid-column: 2; position: relative; color: var(--ink-2); }
.sheet-close::before { content: ""; position: absolute; width: 30px; height: 30px; border-radius: 50%; background: var(--fill-2); }
.sheet-close svg { position: relative; width: 14px; height: 14px; stroke-width: 2.4; }
.sheet-body { padding: 8px var(--gutter) 24px; overflow-y: auto; overscroll-behavior: contain; flex: 1; }
.sheet-foot { padding: 12px var(--gutter) calc(12px + var(--safe-b)); border-top: 1px solid var(--fill-2); flex: none; background: var(--raised); }
.sheet-foot .total-line { display: flex; justify-content: space-between; align-items: baseline; font-size: 15px; color: var(--ink-2); margin-bottom: 10px; }
.sheet-foot .total-line strong { font-size: 20px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }

fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
legend, .sheet-body .label { font-weight: 700; font-size: 17px; line-height: 22px; margin-bottom: 12px; padding: 0; color: var(--ink); }
.field-group + .field-group { margin-top: 24px; }
.window-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
@media (max-width: 339.98px) { .window-grid { grid-template-columns: minmax(0, 1fr); } }
.window-option { position: relative; display: grid; gap: 2px; align-content: center; min-height: 64px; padding: 10px 12px; border: 1px solid var(--line-input); border-radius: var(--r-md); cursor: pointer; transition: border-color var(--d-select) var(--ease-out), background-color var(--d-select) var(--ease-out), transform var(--d-press) var(--ease-out); }
.window-option input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.window-option:active:not(:has(input:disabled)) { transform: scale(0.98); }
.window-option:has(input:checked) { border-color: var(--accent); background: var(--accent); }
.window-option:has(input:checked) .w-time { color: var(--accent-ink); }
.window-option:has(input:checked) .w-state { color: #3A3A3C; }
.window-option:has(input:disabled) { cursor: not-allowed; border: 1px dashed var(--line-strong); }
.window-option:has(input:disabled) .w-time, .window-option:has(input:disabled) .w-state { color: var(--ink-3); }
.window-option:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.w-time { position: relative; font-size: var(--t-md); line-height: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
.w-state { position: relative; font-size: var(--t-2xs); line-height: 14px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-2); }
.w-state.is-few { color: var(--ink); font-weight: 800; }
.stepper { display: inline-flex; align-items: center; gap: 4px; border: 1px solid var(--line-strong); border-radius: var(--r-pill); padding: 2px; }
.stepper output { min-width: 3ch; text-align: center; font-size: 20px; font-weight: 800; font-variant-numeric: tabular-nums; }
.stepper .icon-btn { width: 44px; height: 44px; }
.stepper .icon-btn[disabled] { opacity: 0.35; cursor: not-allowed; }
.stepper-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.stepper-row .label { margin-bottom: 0; }
.hint { font-size: 13px; line-height: 18px; color: var(--ink-2); margin-top: 6px; }
.price-table { width: 100%; border-collapse: collapse; font-size: 15px; }
.price-table td { padding: 10px 0; border-bottom: 1px solid var(--line); font-variant-numeric: tabular-nums; color: var(--ink-2); }
.price-table td:last-child { text-align: right; color: var(--ink); }
.price-table tr.total td { font-weight: 700; font-size: var(--t-md); border-bottom: 0; color: var(--ink); }
.terms { font-size: 15px; line-height: 21px; color: var(--ink-sub); display: grid; gap: 10px; }
.terms li { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 10px; }
.terms li svg { width: 18px; height: 18px; margin-top: 2px; color: var(--ink-2); }
.check { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 10px; align-items: start; font-size: 15px; line-height: 21px; cursor: pointer; }
.check input { width: 22px; height: 22px; margin: 0; accent-color: var(--accent); }
.field-error { color: var(--danger); font-size: var(--t-sm); font-weight: 600; margin-top: 8px; display: flex; gap: 6px; align-items: center; }
.field-error svg { width: 16px; height: 16px; }
.result { display: grid; gap: var(--s-4); text-align: center; justify-items: center; padding: var(--s-3) 0; }
.result-icon { width: 72px; height: 72px; border-radius: 50%; display: grid; place-items: center; }
.result-icon svg { width: 32px; height: 32px; }
.result-ok .result-icon { background: var(--accent); color: var(--accent-ink); }
.result-err .result-icon { background: var(--danger-soft); color: var(--danger); }
.result h2 { font-family: var(--font-display); font-weight: 800; font-size: 26px; line-height: 30px; text-wrap: balance; }
.result p { color: var(--ink-2); font-size: 15px; line-height: 21px; max-width: 38ch; }
.result .pass-card { text-align: left; width: 100%; }
.spinner { width: 24px; height: 24px; border-radius: 50%; border: 3px solid var(--line-strong); border-top-color: var(--accent); }
@media (prefers-reduced-motion: no-preference) { .spinner { animation: spin 0.9s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } }

/* ---------- Console (operator) ---------- */
.console-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-5); margin-top: var(--s-4); }
.panel { border: 1px solid var(--line); border-radius: var(--r-xl); padding: 20px; background: var(--surface); }
.panel h2 { font-size: 20px; line-height: 26px; font-weight: 700; margin-bottom: 6px; }
.panel .panel-sub { font-size: var(--t-sm); line-height: 20px; color: var(--ink-2); margin-bottom: var(--s-4); }
.radio-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.radio-card { position: relative; }
.radio-card input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.radio-card span { display: grid; place-items: center; text-align: center; min-height: 56px; padding: 8px; border: 1px solid var(--line-input); border-radius: var(--r-md); font-size: 15px; font-weight: 700; transition: background-color var(--d-select) var(--ease-out), border-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out); }
.radio-card input:checked + span { border-color: var(--accent); background: var(--accent); color: var(--accent-ink); }
.radio-card input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 2px; }
.radio-card input:active + span { background: var(--surface-2); }
.radio-card input:checked:active + span { background: #D1D1D6; }
.range-row { display: grid; gap: 6px; }
.range-row input[type="range"] { width: 100%; accent-color: var(--accent); min-height: 44px; }
.text-input { width: 100%; height: 48px; padding: 0 14px; border-radius: var(--r-md); border: 1px solid var(--ink-4); background: var(--surface-2); font-size: 16px; color: var(--ink); }
.text-input::placeholder { color: var(--ink-3); }
.label { display: block; font-weight: 600; font-size: 15px; margin-bottom: 8px; }
.form-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: var(--s-5); }
.audit { font-size: 15px; }
.audit li { padding: 12px 0; border-bottom: 1px solid var(--line); display: grid; gap: 2px; overflow-wrap: anywhere; }
.audit time { font-size: var(--t-xs); color: var(--ink-3); font-variant-numeric: tabular-nums; }
.cap-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.cap-row small { display: block; color: var(--ink-2); font-size: var(--t-xs); }
.switch-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 0 12px; }
.switch { position: relative; width: 51px; height: 31px; flex: none; }
.switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.switch span { position: absolute; inset: 0; border-radius: 16px; background: #39393D; box-shadow: inset 0 0 0 2px var(--line-input); transition: background-color var(--d-select) var(--ease-out); }
.switch span::after { content: ""; position: absolute; left: 2px; top: 2px; width: 27px; height: 27px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgb(0 0 0 / 0.4); transition: transform var(--d-select) var(--ease-out); }
.switch input:checked + span { background: var(--accent); box-shadow: none; }
.switch input:checked + span::after { background: var(--accent-ink); box-shadow: none; transform: translateX(20px); }
.switch input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 2px; }

/* ---------- About ---------- */
.prose p, .prose li { font-size: 15px; line-height: 22px; color: var(--ink-2); }
.prose strong { color: var(--ink); }
.prose p + p { margin-top: 10px; }
.prose ul { list-style: disc; padding-left: 20px; display: grid; gap: 4px; }
.rules-table { width: 100%; border-collapse: collapse; font-size: var(--t-sm); margin-top: var(--s-2); }
.rules-table th, .rules-table td { text-align: left; padding: 12px 6px 12px 0; border-bottom: 1px solid var(--line); vertical-align: top; color: var(--ink-2); }
.rules-table td:first-child { color: var(--ink); font-weight: 600; }
.rules-table th { color: var(--ink-3); font-weight: 700; font-size: var(--t-2xs); letter-spacing: 0.08em; text-transform: uppercase; }
.segmented { display: inline-flex; padding: 3px; border-radius: var(--r-pill); background: var(--surface-2); }
.segmented button, .segmented label { min-height: 38px; padding: 0 14px; border: 0; border-radius: var(--r-pill); background: transparent; color: var(--ink-2); font-size: 15px; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out); }
.segmented [aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.segmented button:active { transform: scale(0.97); }

/* ---------- View transitions (same-document, progressive enhancement) ---------- */
/* Tabs swap instantly. List -> bar morphs the photo; drill-ins push and pop; Scan presents and dismisses (QA plan 5.1-5.3).
   Under reduced motion every one of them is the short root cross-fade below (no shared photo, no translate). */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--d-vt-root); animation-timing-function: var(--ease-out); }
/* The overlay swallows taps while it runs: no group outlives the root fade (the UA default is 250ms). */
::view-transition-group(root), ::view-transition-group(tabbar), ::view-transition-group(topbar) { animation-duration: var(--d-vt-root); animation-timing-function: var(--ease-out); }
::view-transition-group(venue-art) { animation-duration: var(--d-vt); animation-timing-function: var(--ease-in-out); }
::view-transition-old(venue-art), ::view-transition-new(venue-art) { height: 100%; object-fit: cover; overflow: clip; animation-duration: var(--d-vt); }
/* One image scales (no two-crop double exposure) when both ends of the morph exist (main.js sets data-vt-pair). */
html[data-vt-pair]::view-transition-old(venue-art) { display: none; }
html[data-vt-pair]::view-transition-new(venue-art) { animation: none; }
/* The hero chrome is named after the photo, so it layers above it: in after the photo starts moving (80 + 200 = --d-vt), out fast. */
::view-transition-new(hero-scrim), ::view-transition-new(hero-title), ::view-transition-new(hero-back), ::view-transition-new(hero-save), ::view-transition-new(hero-cap) { animation: vt-chrome-in var(--d-reveal) var(--ease-out) 80ms both; }
::view-transition-old(hero-scrim), ::view-transition-old(hero-title), ::view-transition-old(hero-back), ::view-transition-old(hero-save), ::view-transition-old(hero-cap) { animation: vt-chrome-out 120ms var(--ease-out) both; }
/* Chrome copies a glass element's backdrop-filter onto its group as a square that outlives the fade: the snapshots carry the tint. */
::view-transition-group(hero-back), ::view-transition-group(hero-save), ::view-transition-group(hero-cap), ::view-transition-group(topbar) { -webkit-backdrop-filter: none; backdrop-filter: none; }
/* Back to the list: the card's scrim, logo and name fade in as the photo lands, instead of popping out from under it. */
::view-transition-new(card-scrim), ::view-transition-new(card-top), ::view-transition-new(card-id) { animation: vt-fade-in 120ms var(--ease-out) 160ms both; }
@keyframes vt-chrome-in { from { opacity: 0; translate: 0 6px; } }
@keyframes vt-chrome-out { to { opacity: 0; } }
@keyframes vt-fade-in { from { opacity: 0; } }
@keyframes vt-fade-out { to { opacity: 0; } }
@media (prefers-reduced-motion: no-preference) {
  /* Drill-in pushes from the right and Back pops from the left; the old page only fades. The top and tab bars are named so they hold still. */
  html[data-nav="forward"]::view-transition-new(root) { animation: vt-push-in var(--d-vt-root) var(--ease-out) both; }
  html[data-nav="forward"]::view-transition-old(root) { animation: vt-fade-out 120ms var(--ease-out) both; }
  html[data-nav="back"]::view-transition-new(root) { animation: vt-pop-in var(--d-vt-root) var(--ease-out) both; }
  html[data-nav="back"]::view-transition-old(root) { animation: vt-fade-out 120ms var(--ease-out) both; }
  /* Scan is presented: it rises while the tab bar drops away; closing it sinks it and brings the tab bar back up. */
  html[data-nav="present"]::view-transition-new(root) { animation: vt-rise 240ms var(--ease-out) both; }
  html[data-nav="present"]::view-transition-old(tabbar) { animation: vt-drop var(--d-sheet-out) var(--ease-out) both; }
  html[data-nav="dismiss"]::view-transition-old(root) { animation: vt-sink var(--d-sheet-out) var(--ease-out) both; }
  html[data-nav="dismiss"]::view-transition-new(tabbar) { animation: vt-rise-bar 240ms var(--ease-out) both; }
}
@keyframes vt-push-in { from { opacity: 0; translate: 16px 0; } }
@keyframes vt-pop-in { from { opacity: 0; translate: -16px 0; } }
@keyframes vt-rise { from { opacity: 0; translate: 0 24px; } }
@keyframes vt-sink { to { opacity: 0; translate: 0 24px; } }
@keyframes vt-drop { to { translate: 0 100%; } }
@keyframes vt-rise-bar { from { translate: 0 100%; } }

/* ---------- Age gate ---------- */
.age-body { padding: 28px 20px calc(28px + var(--safe-b)); display: grid; gap: 4px; }
.age-title { font-family: var(--font-display); font-weight: 800; font-size: 28px; line-height: 32px; }
.age-sub { margin-top: 8px; font-size: var(--t-md); line-height: 24px; color: var(--ink-2); }

/* ---------- Venue page logo ---------- */

/* ---------- Shared bits ---------- */
.handle { display: inline-flex; align-items: center; gap: 3px; min-height: 28px; padding: 0; border: 0; background: transparent; color: var(--ink-2); font-size: 14px; font-weight: 600; cursor: pointer; text-decoration: underline; text-decoration-color: var(--ink-4); text-underline-offset: 3px; }
.handle svg { width: 14px; height: 14px; }
.mini-tag { display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: var(--r-pill); background: var(--surface-2); color: var(--ink-2); font-size: var(--t-2xs); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; vertical-align: middle; }
.form-stack { display: grid; gap: 18px; margin-top: 20px; }
.field { display: grid; gap: 0; min-width: 0; }
.field.stepper-row { display: flex; }
.field-pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; }
@media (max-width: 359.98px) { .field-pair { grid-template-columns: minmax(0, 1fr); } }
.field .select select { width: 100%; height: 48px; border-radius: var(--r-md); }
.text-area { height: auto; min-height: 88px; padding: 12px 14px; line-height: 22px; resize: vertical; font-family: inherit; }
.input-prefix { position: relative; }
.input-prefix > span { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--ink-3); font-weight: 600; pointer-events: none; }
.input-prefix .text-input { padding-left: 30px; }
.plain-list li > span:first-child { display: grid; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.plain-list small { color: var(--ink-3); font-size: var(--t-xs); }
.list-switch { border-bottom: 1px solid var(--line); padding: 12px 2px; }

/* ---------- Scan ---------- */
.waiting-card { margin-top: 18px; padding: 18px; border-radius: var(--r-xl); background: linear-gradient(160deg, #1F2A22 0%, var(--surface) 75%); border: 1px solid rgb(99 210 156 / 0.35); }
.waiting-top { display: flex; align-items: center; gap: 10px; }
.waiting-top h2 { font-size: 17px; line-height: 22px; font-weight: 700; overflow-wrap: anywhere; }
.pulse { position: relative; flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--fresh); }
.pulse::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 1.5px solid var(--fresh); opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: no-preference) { .pulse::after { animation: pulse-ring var(--d-loop-pulse) var(--ease-out) var(--n-loop-pulse); } @keyframes pulse-ring { from { scale: 1; opacity: .6; } to { scale: 2.6; opacity: 0; } } }
.waiting-time { margin-top: 10px; font-size: var(--t-display); line-height: 1; font-weight: 800; letter-spacing: -0.02em; }
.waiting-time small { margin-left: 6px; font-size: 17px; font-weight: 600; color: var(--ink-2); letter-spacing: 0; }
.waiting-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.waiting-actions .btn-primary { flex: 1 1 12rem; }
.scan-step { margin-top: 18px; }
.pick-list { display: grid; margin-top: 12px; border-top: 1px solid var(--line); }
.pick-row { width: 100%; display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 10px; min-height: 56px; padding: 8px 2px; border: 0; border-bottom: 1px solid var(--line); background: transparent; color: var(--ink); text-align: left; cursor: pointer; }
.pick-row:active { background: var(--surface); }
.pick-name { font-size: 16px; font-weight: 600; overflow-wrap: anywhere; }
.pick-area { font-size: 13px; color: var(--ink-2); white-space: nowrap; }
.pick-row svg { color: var(--ink-3); }
.scan-venue { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.scan-venue-name { font-family: var(--font-display); font-weight: 800; font-size: 22px; line-height: 26px; overflow-wrap: anywhere; }
.viewfinder { position: relative; margin-top: 14px; aspect-ratio: 3 / 4; max-height: 56dvh; width: 100%; border-radius: var(--r-xl); overflow: hidden; background: radial-gradient(120% 80% at 50% 30%, #1A1C22 0%, #050608 70%); border: 1px solid var(--line-strong); display: grid; place-items: center; isolation: isolate; }
.viewfinder > svg { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -1; }
.vf-corners { position: absolute; inset: 18px; background:
  linear-gradient(#fff, #fff) top left / 28px 3px no-repeat, linear-gradient(#fff, #fff) top left / 3px 28px no-repeat,
  linear-gradient(#fff, #fff) top right / 28px 3px no-repeat, linear-gradient(#fff, #fff) top right / 3px 28px no-repeat,
  linear-gradient(#fff, #fff) bottom left / 28px 3px no-repeat, linear-gradient(#fff, #fff) bottom left / 3px 28px no-repeat,
  linear-gradient(#fff, #fff) bottom right / 28px 3px no-repeat, linear-gradient(#fff, #fff) bottom right / 3px 28px no-repeat; opacity: 0.85; }
.vf-hint { display: grid; justify-items: center; gap: 8px; max-width: 22ch; text-align: center; font-size: 15px; font-weight: 600; color: var(--ink-sub); }
.vf-hint svg { width: 28px; height: 28px; }
.vf-tag { position: absolute; top: 14px; left: 14px; display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: var(--r-pill); background: rgb(0 0 0 / 0.66); color: #fff; font-size: 12px; font-weight: 700; }

/* Capture flash (scan and console): JS adds .is-flash and removes it on animationend. */
.viewfinder.is-flash::after { content: ""; position: absolute; inset: 0; z-index: 3; background: #fff; pointer-events: none; animation: shutter var(--d-flash) var(--ease-out) both; }
@keyframes shutter { from { opacity: .5; } to { opacity: 0; } }
@media (prefers-reduced-motion: no-preference) { .viewfinder.is-flash:not(.lp-view) > :is(img, svg) { animation: vf-settle var(--d-flash) var(--ease-out); } @keyframes vf-settle { from { scale: 1.04; } } }
@media (prefers-reduced-motion: reduce) { .viewfinder.is-flash::after { animation: shutter-rm var(--d-rm-in) linear both; } @keyframes shutter-rm { from { opacity: .3; } to { opacity: 0; } } }
.shutter { width: 76px; height: 76px; border-radius: 50%; border: 4px solid #fff; background: transparent; padding: 5px; cursor: pointer; transition: transform var(--d-press) var(--ease-out); }
.shutter span { display: block; width: 100%; height: 100%; border-radius: 50%; background: #fff; }
.shutter:active { transform: scale(.96); }
.bucket-row { display: flex; flex-wrap: wrap; gap: 8px; }
.bucket { position: relative; }
.bucket input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.bucket span { display: inline-flex; align-items: center; height: 44px; padding: 0 16px; border-radius: var(--r-pill); border: 1px solid var(--line-input); font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out); }
.bucket input:checked + span { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.bucket input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 2px; }
fieldset:disabled .bucket span { opacity: 0.4; }
.scan-step > .btn-block { margin-top: 18px; }
.scan-done .actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.scan-done h2 { font-size: var(--t-display); line-height: 1; }


/* ---------- Profile ---------- */
.profile-head { display: flex; align-items: center; gap: 14px; margin-top: 6px; }
.profile-id { flex: 1; min-width: 0; display: grid; gap: 2px; }
.profile-name { font-family: var(--font-display); font-weight: 800; font-size: 28px; line-height: 32px; overflow-wrap: anywhere; }
.profile-head + .form-stack { margin-top: 16px; }
.stat-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 20px 0 0; border: 1px solid var(--line-strong); border-radius: var(--r-lg); overflow: hidden; }
.stat-row > div { display: flex; flex-direction: column-reverse; gap: 2px; padding: 14px 12px; text-align: center; }
.stat-row > div + div { border-left: 1px solid var(--line-strong); }
.stat-row dt { font-size: var(--t-2xs); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }
.stat-row dd { margin: 0; font-size: 22px; font-weight: 800; }

/* ============ Layer 2: design spec ============ */
/* Canonical file: /private/tmp/claude-501/-Users-tt-Documents-Codex-2026-10-17-task-rutgers-nightlife/dba00c9f-1e26-4a8a-b326-735d6ad29462/scratchpad/design/final/src/components.css (613 lines; the mocks inline exactly this file after tokens.css). Full text follows. */
/* =====================================================================
   Night Out components: "Late Edition" final (2026-10-17).
   Class names follow app/index.html, src/ui/components.js and src/views/*.js.
   Classes that do not exist in the app yet are marked [NEW].
   Rules kept from the current app: never `transition: all`; inputs >= 16px; hover only under
   (hover:hover) and (pointer:fine); transform/opacity motion only; reduced motion respected.
   ===================================================================== */

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { background: var(--bg); -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
body {
  margin: 0; min-height: 100dvh; background: var(--bg); color: var(--ink);
  font-family: var(--font-sans); font-size: var(--t-base); line-height: 1.4;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility;
}
h1, h2, h3, p, dl, dd, figure { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
p { text-wrap: pretty; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; text-underline-offset: 3px; }
img, svg { display: block; max-width: 100%; }
.ic { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.num { font-family: var(--font-num); font-stretch: var(--w-cond); font-variant-numeric: tabular-nums lining-nums; }
.roll { display: inline-block; font-variant-numeric: tabular-nums lining-nums; }
/* Mask and clip only while rolling, so resting glyphs are never faded. overflow: clip needs iOS 16 (falls back to hidden). */
.roll.is-rolling { overflow: hidden; overflow: clip; overflow-clip-margin: .06em;
  -webkit-mask-image: linear-gradient(transparent, #000 .2em, #000 calc(100% - .2em), transparent);
          mask-image: linear-gradient(transparent, #000 .2em, #000 calc(100% - .2em), transparent); }
.roll .rl { position: relative; display: inline-block; }
.roll .rl-old { position: absolute; inset: 0; translate: 0 calc(var(--dir, 1) * -0.75em); }
.roll .rl-ghost { visibility: hidden; } /* holds a departing digit's width while it rolls out */
.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
a, button, label, summary, select, input, [role="button"] { touch-action: manipulation; }

/* Focus: 2px white ring + 5px black halo, legible on black, on photos and around white buttons. */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; box-shadow: 0 0 0 5px var(--focus-halo); }
[tabindex="-1"]:focus { outline: none; box-shadow: none; }

/* ---------- Shell: a phone column at every width ---------- */
.app { position: relative; width: 100%; max-width: var(--phone-w); min-height: 100dvh; margin: 0 auto; background: var(--bg); }
@media (min-width: 470px) { html, body { background: #050505; } .app { box-shadow: 0 0 0 1px #161616; } }
main { min-width: 0; padding-bottom: calc(var(--tabbar-h) + var(--safe-b) + 40px); }
.page { padding: 0 calc(var(--gutter) + var(--safe-r)) var(--s-6) calc(var(--gutter) + var(--safe-l)); }

/* ---------- Type helpers ---------- */
.eyebrow, .qb-label, .section-title, .group-title {
  font-size: var(--t-2xs); line-height: 14px; font-weight: 700; font-stretch: var(--w-semi);
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
}
.page-title { font-size: var(--t-3xl); font-weight: 800; letter-spacing: -.035em; line-height: 1.05; text-wrap: balance; }
.page-sub { margin-top: 6px; max-width: 46ch; font-size: var(--t-base); line-height: 1.4; color: var(--ink-2); }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 32px 0 14px; } /* [NEW] */
.section-head h2 { font-size: var(--t-xl); font-weight: 800; letter-spacing: -.03em; line-height: 1.1; }
.section-head .eyebrow { white-space: nowrap; }

/* ---------- Top bar (sticky; condenses on scroll) ---------- */
.topbar {
  position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 4px;
  height: calc(var(--topbar-h) + var(--safe-t));
  padding: var(--safe-t) calc(var(--gutter) + var(--safe-r)) 0 calc(var(--gutter) + var(--safe-l));
  background: rgb(0 0 0 / .86); -webkit-backdrop-filter: blur(10px) saturate(140%); backdrop-filter: blur(10px) saturate(140%);
  border-bottom: 1px solid transparent; transition: border-color var(--d-select) var(--ease-out);
}
@media (prefers-reduced-transparency: reduce) { .topbar { background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; } }
.wordmark { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink); }
/* Brand mark: the team's hand-lettered "Night out" (wine-glass g), white on black, drawn from the sprite in index.html. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.wm-logo { display: block; height: 30px; width: auto; aspect-ratio: 722 / 207; fill: currentColor; overflow: visible; }
.age-logo { height: 52px; margin: 0 0 20px; color: #fff; }
.topbar-spacer { flex: 1; }
.topbar-area { display: none; align-items: center; gap: 6px; min-width: 0; min-height: 44px; color: var(--ink); font-size: 19px; font-weight: 800; letter-spacing: -.03em; white-space: nowrap; } /* [NEW] */
.topbar-area > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.topbar-area .ic { width: 16px; height: 16px; stroke-width: 2.4; }
/* Condense (QA plan 6.2): the wordmark and the area share one cell and cross-fade both ways (see "Bars surfaces"). */
@media (max-width: 359.98px) { .topbar-area { font-size: 17px; } }

/* Points chip (top right): the demo balance, links to Points. */
#demo-slot { display: flex; align-items: center; }
.pts-chip { position: relative; display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 11px 0 9px; border-radius: var(--r-pill); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-input); color: var(--ink); white-space: nowrap; transition: transform var(--d-press) var(--ease-out); }
.pts-chip::before { content: ""; position: absolute; inset: -8px -4px; } /* 46px hit area */
.pts-chip .ic { width: 15px; height: 15px; fill: currentColor; stroke-width: 1.4; }
.pts-chip .num { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 17px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.pts-chip:active { transform: scale(.97); }
.pts-chip:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.demo-chip {
  position: relative; display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px 0 8px;
  border: 1px solid var(--line-input); border-radius: var(--r-pill); color: var(--ink);
  font-size: 10.5px; font-weight: 700; font-stretch: var(--w-semi); letter-spacing: .09em; text-transform: uppercase; white-space: nowrap;
}
.demo-chip::before { content: ""; position: absolute; inset: -10px -4px; } /* 46px hit area */
.demo-chip .dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: repeating-linear-gradient(135deg, var(--ink) 0 1.5px, transparent 1.5px 3px); box-shadow: inset 0 0 0 1px var(--ink); }
.demo-time { display: none; } /* the demo clock moves into .results-bar */

/* ---------- Home header: area, search, chips, results bar ---------- */
.area-row { margin-top: 2px; }
.area-title { font: inherit; }
.area-pill {
  display: inline-flex; align-items: center; gap: 10px; max-width: 100%; min-height: 44px; padding: 0; border: 0; background: none;
  color: var(--ink); cursor: pointer; text-align: left; font-size: var(--t-3xl); font-weight: 800; letter-spacing: -.035em; line-height: 1.08;
  transition: opacity var(--d-press) var(--ease-out);
}
.area-pill > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-bottom: 2px; }
.area-pill .ic-pin { display: none; }
.area-pill .ic-chev { width: 28px; height: 28px; padding: 5px; border: 1px solid var(--line-input); border-radius: 50%; stroke-width: 2.2; margin-top: 2px; }
.area-pill:active { opacity: .7; }


.search { position: relative; flex: 1; min-width: 0; }
.search > .ic { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 17px; height: 17px; color: var(--ink-2); pointer-events: none; }
.search input {
  width: 100%; height: 40px; padding: 0 40px 0 37px; border-radius: var(--r-pill); border: 1px solid var(--line-input);
  background: var(--surface-2); color: var(--ink); font-size: 16px; line-height: 20px; -webkit-appearance: none; appearance: none;
}
.search input::placeholder { color: var(--ink-3); }
.search input::-webkit-search-cancel-button { display: none; }
.search input:focus-visible { outline: none; box-shadow: none; border-color: var(--ink); }
.search .clear { position: absolute; right: 2px; top: 50%; transform: translateY(-50%); width: 36px; height: 36px; min-width: 0; min-height: 0; color: var(--ink-2); }
.search .clear .ic { width: 16px; height: 16px; }
.map-btn { position: relative; flex: none; width: 40px; height: 40px; display: grid; place-items: center; border-radius: 50%; border: 1px solid var(--line-input); background: var(--surface-2); color: var(--ink); } /* [NEW] replaces List/Map */
.map-btn[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.map-btn .ic { width: 19px; height: 19px; }
.map-btn::before { content: ""; position: absolute; inset: -2px; } /* 44px hit area */

.chips { display: flex; align-items: center; gap: 8px; margin: 10px calc(-1 * var(--gutter)) 0; padding: 4px var(--gutter); overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; }
.chips::-webkit-scrollbar { display: none; }
.chip-group { display: contents; }
.chip-divider { flex: none; width: 1px; height: 20px; background: var(--line-strong); }
.chip {
  position: relative; flex: none; display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 14px;
  border-radius: var(--r-pill); border: 1px solid var(--line-input); background: transparent; color: var(--ink);
  font-size: var(--t-sm); font-weight: 600; white-space: nowrap; cursor: pointer;
  transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out), transform var(--d-press) var(--ease-out);
}
.chip::before { content: ""; position: absolute; inset: -4px 0; } /* 44px hit area */
.chip .ic { width: 16px; height: 16px; stroke-width: 2; }
.chip .n { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 15px; font-weight: 700; color: var(--ink-3); font-variant-numeric: tabular-nums; } /* [NEW] count */
.chip[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.chip[aria-pressed="true"] .n { color: #555; }
.chip:active { transform: scale(.97); }
.chip-sort { padding: 0 12px 0 10px; } /* [NEW] sort button chip that opens the sort sheet (replaces the <select>) */
.chip-sort .ic:last-child { width: 14px; height: 14px; color: var(--ink-2); }
.chip-clear { border-style: dashed; color: var(--ink-2); }

.results-bar { display: flex; align-items: center; gap: 8px; min-height: 32px; margin-top: 0; }
.summary-line { flex: 1; min-width: 0; display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 10px; margin: 0; font-size: var(--t-xs); line-height: 16px; color: var(--ink-3); }
.summary-line span { white-space: nowrap; }
@media (max-width: 359.98px) { .summary-line .sl-upd { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; } }
.summary-line .sl-main { font-size: var(--t-2xs); font-weight: 700; font-stretch: var(--w-semi); letter-spacing: .08em; text-transform: uppercase; color: var(--ink); } /* [NEW] */
.results-bar .refresh-btn { position: relative; width: 32px; height: 32px; margin-right: -6px; display: grid; place-items: center; border-radius: 50%; color: var(--ink-2); }
.refresh-btn::before { content: ""; position: absolute; inset: -6px; }
.results-bar .refresh-btn .ic { width: 18px; height: 18px; }
.view-toggle { display: none; }

/* ---------- Bar card: photo poster on a plate. TL logo, TR distance, BL deal, BR wait ---------- */
.bar-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 10px; margin-top: 2px; }
.bar-card { position: relative; min-width: 0; container: card / inline-size; }
.bar-link {
  position: relative; display: flex; flex-direction: column; height: 100%; overflow: hidden; border-radius: var(--r-card);
  background: var(--surface); color: inherit; transition: transform var(--d-press) var(--ease-out);
}
.bar-link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: var(--photo-edge); pointer-events: none; }
.bar-link:active { transform: scale(.98); }
.bar-link:focus-visible { outline-offset: 3px; }
.bar-photo { position: relative; display: block; flex: none; aspect-ratio: 1 / 1; overflow: hidden; isolation: isolate; background: #111; }
.bar-photo > img, .bar-photo > svg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 72%; z-index: -2; }
/* Top and bottom scrims in one element (not pseudos), so Back to the list can fade it in over the landing photo (QA plan 5.1). */
.card-scrim { position: absolute; inset: 0; z-index: -1; background: var(--scrim-bottom), var(--scrim-top); pointer-events: none; }
.card-top { position: absolute; top: 8px; left: 8px; right: 8px; display: flex; align-items: flex-start; justify-content: space-between; gap: 6px; min-height: 0; }
.bar-logo { flex: none; width: 34px; height: 34px; border-radius: var(--r-logo); overflow: hidden; display: grid; place-items: center; background: #000; box-shadow: inset 0 0 0 1px rgb(255 255 255 / .22); }
.bar-logo img { width: 100%; height: 100%; object-fit: contain; }
.mono { font-size: 11px; font-weight: 800; font-stretch: var(--w-exp); letter-spacing: .02em; line-height: 1; color: #fff; }
.card-dist {
  display: inline-flex; align-items: center; gap: 4px; height: 26px; padding: 0 9px 0 7px; border-radius: var(--r-pill);
  background: var(--glass); color: #fff; /* solid glass: no backdrop blur on per-card elements */
  font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 14px; font-weight: 700; letter-spacing: .01em; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.card-dist .ic { width: 11px; height: 11px; }
.dist-away { display: none; }
.bar-id { position: absolute; left: 10px; right: 10px; bottom: 9px; display: grid; gap: 3px; } /* [NEW] name + freshness on the photo */
.bar-name {
  font-size: var(--t-md); font-weight: 700; letter-spacing: -.02em; line-height: 1.12; color: #fff; text-wrap: balance; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-shadow: 0 1px 10px rgb(0 0 0 / .45);
}
.card-fresh { display: flex; align-items: center; gap: 4px; min-width: 0; font-size: 11.5px; font-weight: 500; line-height: 1.25; color: var(--ink-2); } /* [NEW] "Demo wait · 4m ago" */
.card-fresh .ic { width: 12px; height: 12px; stroke-width: 2.2; }

/* Footer: row 1 = the two eyebrows, row 2 = deal text (flexible) + wait value (fixed). The deal eyebrow spans
   the whole row so "Demo deal" is never clipped by the width of the wait value. The footer is aria-hidden
   (the sr-only summary speaks), so .deal-slot/.card-status only group markup and styling hooks. */
.card-foot { flex: 1; display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto 1fr; column-gap: 8px; row-gap: 6px; padding: 10px 11px 12px; } /* [NEW] */
.deal-slot, .card-status { display: contents; }
.deal-slot > .foot-eb { grid-area: 1 / 1 / 2 / 3; justify-self: start; }
.card-status > .foot-eb { grid-area: 1 / 2; justify-self: end; }
.deal-tag { grid-area: 2 / 1; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-wrap: balance; } /* card uses deal.short (<= 16 chars) */
.card-status > :last-child { grid-area: 2 / 2; justify-self: end; text-align: right; }
.foot-eb { /* [NEW] the two eyebrows share one line */
  display: inline-flex; align-items: center; gap: 5px; max-width: 100%; min-height: 14px;
  font-size: 10.5px; line-height: 14px; font-weight: 700; font-stretch: var(--w-norm); letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.card-status .foot-eb { color: var(--ink); overflow: visible; position: relative; z-index: 1; }
.card-status[data-maybe] .foot-eb, .card-status[data-level="none"] .foot-eb { color: var(--ink-2); }
.deal-tag { align-self: last baseline; font-size: var(--t-sm); font-weight: 600; line-height: 1.22; color: var(--ink); overflow-wrap: anywhere; }
.deal-tag.is-none { color: var(--ink-2); font-weight: 500; } /* [NEW] no deal: "Open till 2 AM" */
.cs-value { /* [NEW] the wait value: range in condensed numerals, or a word */
  align-self: last baseline; font-family: var(--font-num); font-stretch: var(--w-cond); font-size: var(--t-num-card); font-weight: 800;
  line-height: .9; letter-spacing: -.005em; font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; color: var(--ink);
}
.cs-value small { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: 11.5px; font-weight: 600; letter-spacing: 0; color: var(--ink-2); margin-left: 2px; }
.cs-value.is-dim { color: var(--ink-2); }
.cs-value .approx { font-size: .66em; font-weight: 700; margin-right: 1px; vertical-align: .12em; } /* [NEW] ≈ for "may have changed" / mixed */
.cs-value.is-word { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: 15px; font-weight: 700; line-height: 1.15; letter-spacing: -.01em; }
.cs-tag { /* [NEW] FULL / PAUSED */
  align-self: last baseline; display: inline-block; padding: 3px 6px 2px; border-radius: 5px; background: var(--accent); color: var(--accent-ink);
  font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 19px; font-weight: 800; line-height: 1; letter-spacing: .03em; text-transform: uppercase;
}
.cs-tag.is-outline { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1.5px var(--ink); }
.cs-glyph { width: 14px; height: 14px; color: var(--ink-2); stroke-width: 2; } /* [NEW] moon / pause / clock / ? */

/* Crowd meter (1/2/3 bars, like signal bars). Count + word + range carry meaning; hue is the 4th cue. [NEW] */
.meter { --c: var(--none); position: relative; display: inline-flex; align-items: flex-end; gap: 2px; height: 12px; flex: none; }
.meter i { width: 3.5px; border-radius: 1px; background: var(--meter-off); }
.meter i:nth-child(1) { height: 5px; } .meter i:nth-child(2) { height: 8.5px; } .meter i:nth-child(3) { height: 12px; }
.meter[data-level="quiet"] { --c: var(--quiet); }
.meter[data-level="lively"] { --c: var(--lively); }
.meter:is([data-level="packed"], [data-level="capacity"]) { --c: var(--packed); }
.meter[data-level="quiet"] i:nth-child(1), .meter[data-level="lively"] i:nth-child(-n+2), .meter:is([data-level="packed"], [data-level="capacity"]) i { background-color: var(--c); }
.meter[data-level="capacity"]::before { content: ""; position: absolute; left: -1px; right: -1px; top: -3px; height: 1.5px; border-radius: 1px; background: var(--c); } /* lid = full */
.meter[data-maybe] i { background-image: repeating-linear-gradient(0deg, rgb(0 0 0 / .8) 0 1.5px, transparent 1.5px 3px); } /* hatched = may have changed */
.meter[data-level="mixed"] i:nth-child(1) { background: var(--ink-2); }
.meter[data-level="mixed"] i:nth-child(n+2) { background: repeating-linear-gradient(0deg, var(--ink-2) 0 1.5px, transparent 1.5px 3px); }
.meter.is-lg { height: 18px; gap: 3px; }
.meter.is-lg i { width: 5px; border-radius: 1.5px; }
.meter.is-lg i:nth-child(1) { height: 7px; } .meter.is-lg i:nth-child(2) { height: 12px; } .meter.is-lg i:nth-child(3) { height: 18px; }

@container card (max-width: 170px) {
  .card-foot { padding: 9px 9px 11px; column-gap: 6px; }
  .foot-eb { font-size: 10px; letter-spacing: .05em; gap: 4px; }
  .cs-value { font-size: 24px; }
  .deal-tag { font-size: 12.5px; }
  .bar-name { font-size: 15px; }
}
/* 320–359px: one column of compact posters (2.6:1 banner) so 2 full bars fit at 320x700. */
@media (max-width: 359.98px) {
  :root { --topbar-h: 48px; }

  .chips { margin-top: 8px; }

  .bar-grid { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .bar-photo { aspect-ratio: 2.6 / 1; }
  .bar-photo > img, .bar-photo > svg { object-position: 50% 82%; }
  .bar-id { right: 28%; bottom: 10px; }
  .bar-name { font-size: 18px; -webkit-line-clamp: 1; }
  .card-foot { padding: 11px 12px 13px; column-gap: 14px; }
  .cs-value { font-size: 30px; }
  .deal-tag { font-size: 14px; }
}
/* .bar-card scope: .icon-btn (same specificity, later in the file) would reset it to position: relative, below the card. */
.bar-card .card-save { position: absolute; z-index: 1; top: 50px; right: 6px; width: 44px; height: 44px; color: #fff; }
.card-save::before { content: ""; position: absolute; inset: 6px; border-radius: 50%; background: var(--glass); box-shadow: inset 0 0 0 1px rgb(255 255 255 / .16); z-index: -1; }

/* ---------- Tab bar ---------- */
.tabbar {
  position: fixed; z-index: 30; bottom: 0; left: max(0px, calc(50% - var(--phone-w) / 2)); right: max(0px, calc(50% - var(--phone-w) / 2));
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); padding: 6px max(4px, var(--safe-l)) calc(var(--safe-b) + 10px);
  background: var(--bg); border-top: 1px solid var(--line);
}
.tab { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; min-height: 54px; color: var(--ink-3); transition: color var(--d-select) var(--ease-out); }
.tab-inner { position: relative; display: grid; place-items: center; width: 46px; height: 32px; border-radius: 10px; transition: transform var(--d-press) var(--ease-out), background-color var(--d-select) var(--ease-out); }
.tab-inner svg { width: 24px; height: 24px; stroke-width: 1.7; }
.tab-label { font-size: var(--t-2xs); font-weight: 700; line-height: 13px; letter-spacing: .01em; white-space: nowrap; } /* one weight in both states: no label reflow */
.tab[aria-current="page"] { color: var(--ink); }
.tab .fl { fill: currentColor; fill-opacity: 0; transition: fill-opacity var(--d-select) var(--ease-out); }
.tab[aria-current="page"] .fl { fill-opacity: 1; }
.tab:active .tab-inner { transform: scale(.96); }
.tab-scan .tab-inner { box-shadow: inset 0 0 0 1.5px currentColor; } /* [NEW] distinct center shape; same colors as other tabs */
.tab-scan[aria-current="page"] .tab-inner { background: var(--accent); color: var(--accent-ink); box-shadow: none; }
/* One pill slides to the selected tab (QA plan 3.1). It sits exactly behind .tab-inner: top 9px = tabbar padding-top 6px
   + (54px cell - 48px content) / 2. Content still swaps at once; the first placement and keyboard moves jump (main.js). */
.tab-indicator { position: absolute; z-index: 0; top: 9px; left: max(4px, var(--safe-l)); width: calc((100% - 2 * max(4px, var(--safe-l))) / 5); height: 32px;
  display: grid; place-items: center; pointer-events: none; transform: translateX(calc(var(--tab-i, 0) * 100%)); transition: transform var(--d-thumb) var(--ease-in-out); }
.tab-indicator::before { content: ""; width: 46px; height: 32px; border-radius: 10px; background: var(--fill-2); transition: scale var(--d-press) var(--ease-out); }
.tabbar:not(:has([aria-current="page"])) .tab-indicator { opacity: 0; }
/* Pressing the selected tab presses its pill with the icon. */
.tabbar:has(> .tab[aria-current="page"]:active) .tab-indicator::before { scale: .96; --d-press: var(--d-press-down); }
.kbd .tab-indicator { transition: none; }
@media (prefers-reduced-motion: reduce) { .tab-indicator { transition: none; } }
.tab .badge { position: absolute; top: -2px; right: 2px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--ink); color: var(--bg); font-size: 11px; font-weight: 800; line-height: 18px; text-align: center; box-shadow: 0 0 0 2px var(--bg); }

/* ---------- Buttons ---------- */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 48px; padding: 0 18px;
  border-radius: var(--r-btn-lg); border: 1px solid var(--line-input); background: var(--surface-2); color: var(--ink);
  font-size: var(--t-base); font-weight: 700; line-height: 20px; letter-spacing: -.005em; cursor: pointer;
  transition: transform var(--d-press) var(--ease-out), background-color var(--d-select) var(--ease-out), border-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out);
}
.btn .ic { width: 18px; height: 18px; }
.btn:active { transform: scale(.97); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn-primary:active { background: #D6D6D6; }
.btn-lg { min-height: 52px; }
.btn-block { display: flex; width: 100%; }
.btn-ghost { background: transparent; } /* [NEW] */
.btn-quiet { background: transparent; border-color: transparent; padding: 0 8px; }
.btn-sm { min-height: 36px; padding: 0 14px; border-radius: var(--r-sm); font-size: var(--t-sm); }
.btn-sm::before { content: ""; position: absolute; inset: -4px 0; }
.btn .trail { margin-left: auto; font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 19px; font-weight: 800; font-variant-numeric: tabular-nums; } /* [NEW] "+50" */
.btn[aria-disabled="true"], .btn[disabled] { background: transparent; border-color: var(--line-strong); color: var(--ink-3); cursor: not-allowed; transform: none; }
.btn-danger { color: var(--danger); }
.icon-btn { position: relative; width: 44px; height: 44px; flex: none; display: grid; place-items: center; border-radius: 50%; color: var(--ink); transition: transform var(--d-press) var(--ease-out), background-color var(--d-select) var(--ease-out); }
.icon-btn .ic { width: 22px; height: 22px; }
.ic-stack { display: grid; flex: none; }
.ic-stack > .ic { grid-area: 1 / 1; }
.ic-stack .ic-fill { opacity: 0; scale: .6; transition: opacity var(--d-icon) var(--ease-out), scale var(--d-icon) var(--ease-out); }
[aria-pressed="true"] > .ic-stack .ic-fill { opacity: 1; scale: 1; }
@media (prefers-reduced-motion: reduce) { .ic-stack .ic-fill { scale: 1; transition: opacity var(--d-rm-in) linear; } }
.icon-btn:not(:disabled):active { transform: scale(.96); background: var(--fill-2); }
@media (hover: hover) and (pointer: fine) {
  .btn:hover { border-color: var(--ink-3); }
  .btn-primary:hover { background: #EDEDED; border-color: #EDEDED; }
  .chip:hover { border-color: var(--ink-2); }
  .bar-link:hover .bar-name { text-decoration: underline; text-underline-offset: 3px; }
  .icon-btn:hover { background: var(--fill-2); }
}

/* ---------- Venue detail ---------- */
.page.detail { padding-top: 0; }
/* Route chrome: the venue hero carries Back/Save, and Scan is a full-screen flow. main.js sets <body data-route>. [NEW] */
[data-route="venue"] .topbar { display: none; } /* Scan becomes a full-screen flow in the next push. */
.detail-hero {
  position: relative; isolation: isolate; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end;
  min-height: 292px; margin: 0 calc(-1 * var(--gutter)); padding: 76px var(--gutter) 16px; background: #111;
}
.detail-hero > img, .detail-hero > svg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 64%; z-index: -2; }
/* The scrim is an element (not ::before) so a view transition can fade it in above the moving photo (QA plan 5.1). */
.hero-scrim { position: absolute; inset: 0; z-index: -1; background: var(--scrim-hero); pointer-events: none; }
.hero-btn {
  position: absolute; top: calc(10px + var(--safe-t)); width: 44px; height: 44px; display: grid; place-items: center; border-radius: 50%; color: #fff;
  background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); border: 1px solid rgb(255 255 255 / .16);
  transition: transform var(--d-press) var(--ease-out);
}
.hero-btn .ic { width: 22px; height: 22px; }
.hero-btn:active { transform: scale(.96); }
.back-link.hero-btn { left: 12px; }
.save-detail.hero-btn { right: 12px; }
.hero-caption {
  position: absolute; top: calc(20px + var(--safe-t)); left: 66px; max-width: calc(100% - 132px); display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 10px;
  border-radius: var(--r-pill); background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  color: #fff; font-size: var(--t-2xs); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hero-caption .ic { width: 13px; height: 13px; }
.hero-title { display: grid; gap: 10px; min-width: 0; }
.hero-meta { display: flex; align-items: center; gap: 10px; min-width: 0; } /* [NEW] logo + eyebrow */
.hero-meta .eyebrow { min-width: 0; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hero-logo { width: 40px; height: 40px; border-radius: 10px; }
.hero-logo .mono { font-size: 13px; }
.hero-name { font-size: var(--t-hero); font-weight: 800; letter-spacing: -.04em; line-height: .98; color: #fff; text-wrap: balance; overflow-wrap: anywhere; }
/* Depth on scroll (QA plan 5.5): the photo recedes at 0.25x with a scale inside the 4% cap, and the title lifts away.
   Transform/opacity only, scroll-driven where supported (iOS 26+); older browsers keep a still hero. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .detail-hero > img { animation: hero-recede linear both; animation-timeline: scroll(root); animation-range: 0 292px; }
    .hero-title { animation: hero-title-out linear both; animation-timeline: scroll(root); animation-range: 120px 260px; }
  }
}
@keyframes hero-recede { to { transform: translateY(73px) scale(1.04); } }
@keyframes hero-title-out { to { opacity: 0; translate: 0 -12px; } }

.queue-block { margin-top: 22px; }
.qb-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.qb-top .qb-label { color: var(--ink); }

.qb-wait { margin-top: 10px; font-family: var(--font-num); font-stretch: var(--w-cond); font-size: var(--t-display); font-weight: 800; line-height: .88; letter-spacing: -.01em; font-variant-numeric: tabular-nums lining-nums; }
.qb-wait small { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: 22px; font-weight: 600; letter-spacing: -.01em; color: var(--ink-2); margin-left: 6px; }
.queue-block:is([data-tone="aging"], [data-tone="uncertain"]) .qb-wait { color: var(--ink-2); }
.queue-block:is([data-tone="stale"], [data-tone="unknown"], [data-tone="closed"]) .qb-wait { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: 40px; letter-spacing: -.035em; line-height: 1; color: var(--ink-2); }
.qb-scale { position: relative; display: block; margin-top: 16px; } /* [NEW] 0–30+ scale with the range bracketed */
.qb-scale-track { position: relative; display: block; height: 10px; }
.qb-scale-track::before { content: ""; position: absolute; left: 0; right: 0; top: 4px; height: 2px; border-radius: 1px; background: var(--line-input); }
.qb-scale-track b { position: absolute; top: 2px; width: 1.5px; height: 6px; margin-left: -.75px; background: var(--line-input); }
.qb-scale-range { position: absolute; top: 0; bottom: 0; left: calc(var(--lo) / var(--max) * 100%); width: calc((var(--hi) - var(--lo)) / var(--max) * 100%); min-width: 12px; border-radius: 5px; background: var(--ink); box-shadow: 0 0 0 3px var(--bg); }
.qb-scale-axis { position: relative; display: block; height: 14px; margin-top: 6px; font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 13px; font-weight: 700; line-height: 14px; color: var(--ink-3); }
.qb-scale-axis span { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
.qb-scale-axis span:first-child { transform: none; }
.qb-scale-axis span:last-child { transform: translateX(-100%); }
.qb-level { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin-top: 14px; font-size: var(--t-base); line-height: 20px; color: var(--ink-2); } /* [NEW] */
.qb-level b { display: inline-flex; align-items: center; gap: 8px; color: var(--ink); font-weight: 700; }
.qb-fresh { margin-top: 18px; } /* [NEW] freshness ruler: fresh 0–10 | may have changed 10–20 | out of date 20+ */
.qf-track { position: relative; display: grid; grid-template-columns: 10fr 10fr 6fr; gap: 3px; height: 6px; }
.qf-track i { border-radius: 3px; }
.qf-track .qf-1 { background: var(--fresh); }
.qf-track .qf-2 { background: repeating-linear-gradient(90deg, var(--ink-3) 0 3px, transparent 3px 6px); box-shadow: inset 0 0 0 1px var(--ink-4); }
.qf-track .qf-3 { box-shadow: inset 0 0 0 1px var(--ink-4); }
.qf-mark { position: absolute; top: 50%; left: clamp(7px, calc(var(--age) / 26 * 100%), calc(100% - 7px)); width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%; background: var(--ink); box-shadow: 0 0 0 3px var(--bg); }
.qf-legend { display: grid; grid-template-columns: 10fr 10fr 6fr; gap: 3px; margin-top: 8px; font-size: var(--t-2xs); line-height: 14px; color: var(--ink-3); }
.qf-legend .is-on { color: var(--ink); font-weight: 700; }
.qb-detail { margin-top: 10px; font-size: var(--t-sm); line-height: 1.45; color: var(--ink-3); overflow-wrap: anywhere; }
.qb-detail b { color: var(--ink); font-weight: 600; }

.qb-facts, .fact-strip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 16px; border-top: 1px solid var(--line-strong); border-bottom: 1px solid var(--line-strong); }
.fact-strip > div:nth-child(3n + 1) { padding-left: 0; border-left: 0; }
.fact-strip > div:nth-child(n + 4) { border-top: 1px solid var(--line-strong); }
.qb-facts > div, .fact-strip > div { display: flex; flex-direction: column; gap: 5px; min-width: 0; padding: 12px 0 12px 12px; }
.qb-facts > div:first-child, .fact-strip > div:first-child { padding-left: 0; }
.qb-facts > div + div, .fact-strip > div + div { border-left: 1px solid var(--line-strong); }
.qb-facts dt, .fact-strip dt { font-size: var(--t-2xs); line-height: 14px; font-weight: 700; font-stretch: var(--w-semi); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qb-facts dd, .fact-strip dd { margin: 0; font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 22px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qb-facts dd small, .fact-strip dd small { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: 13px; font-weight: 600; color: var(--ink-2); margin-left: 2px; }
.fact-sub { font-size: var(--t-xs); line-height: 1.3; color: var(--ink-3); } /* [NEW] */

.venue-actions { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: 8px; margin-top: 16px; } /* [NEW] */
.act { /* [NEW] */
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; min-height: 64px; padding: 8px 4px;
  border-radius: var(--r-btn-lg); border: 1px solid var(--line-input); background: var(--surface-2); color: var(--ink);
  font-size: var(--t-xs); font-weight: 600; line-height: 1.15; text-align: center; transition: transform var(--d-press) var(--ease-out);
}
.act .ic { width: 22px; height: 22px; }
.act:not([aria-disabled="true"]):active { transform: scale(.97); }
.act-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 800; }
.act-pts { position: absolute; top: 7px; right: 9px; font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 14px; font-weight: 800; color: var(--accent-sub); }
.act[aria-pressed="true"] > .ic { fill: currentColor; }
/* 320–359px venue: smaller hero, caption on its own row, no scale, so the actions stay on the first screen. */
@media (max-width: 359.98px) {
  .detail-hero { min-height: 250px; }
  .hero-caption { top: calc(62px + var(--safe-t)); left: 12px; max-width: calc(100% - 24px); }
  .hero-name { font-size: 32px; }
  .qb-scale { display: none; } /* the range is already the headline; keep the actions on the first screen */
  .venue-actions { grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 6px; }
  .fact-strip dt, .qb-facts dt { font-stretch: var(--w-norm); letter-spacing: .05em; }
  .fact-strip > div, .qb-facts > div { padding-left: 10px; }
}

/* Deals: tickets with a stub. No edge notches (stacked notches read as connector shapes). */
.deal-list { display: grid; gap: 10px; }
.deal-row { display: grid; grid-template-columns: 36px minmax(0, 1fr) 104px; align-items: center; column-gap: 12px; min-height: 88px; padding-left: 14px; border-radius: var(--r-md); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); }
.deal-icon { width: 36px; height: 36px; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--fill-2); color: var(--ink); }
.deal-icon .ic { width: 20px; height: 20px; }
.deal-main { display: grid; gap: 4px; min-width: 0; padding: 14px 0; }
.deal-main .eyebrow { line-height: 13px; }
.deal-title { font-size: var(--t-lg); font-weight: 700; letter-spacing: -.015em; line-height: 1.18; overflow-wrap: anywhere; text-wrap: balance; }
.deal-meta { font-size: var(--t-xs); line-height: 1.35; color: var(--ink-3); }
.deal-stub { /* [NEW] */
  align-self: stretch; display: flex; flex-direction: column; align-items: flex-end; justify-content: center; gap: 5px; padding: 12px 14px 12px 12px; text-align: right;
  background-image: linear-gradient(var(--line-input) 55%, transparent 0); background-size: 1.5px 6px; background-repeat: repeat-y; background-position: 0 4px;
}
.deal-state { display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; line-height: 13px; font-weight: 700; font-stretch: var(--w-semi); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
.deal-state::before { content: ""; width: 7px; height: 7px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px currentColor; }
.deal-row[data-state="live"] .deal-state { color: var(--ink); }
.deal-row[data-state="live"] .deal-state::before { background: currentColor; }
.deal-time { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 24px; font-weight: 800; line-height: .95; white-space: nowrap; font-variant-numeric: tabular-nums; } /* [NEW] */
.deal-time small { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: 12px; font-weight: 600; color: var(--ink-2); margin-left: 2px; }
.deal-left { display: block; width: 100%; height: 3px; border-radius: 2px; background: var(--meter-off); overflow: hidden; } /* [NEW] time left */
.deal-left i { display: block; width: 100%; height: 100%; background: var(--ink); transform: scaleX(var(--left, 0)); transform-origin: left; } /* --left: 0-1 */
.deal-sub { font-size: var(--t-xs); line-height: 1.2; color: var(--ink-3); white-space: nowrap; }
.deal-row[data-state="ended"] .deal-title { color: var(--ink-2); text-decoration: line-through; text-decoration-color: var(--ink-3); }
@media (max-width: 359.98px) { .deal-row { grid-template-columns: 32px minmax(0, 1fr) 92px; column-gap: 10px; padding-left: 12px; } .deal-icon { width: 32px; height: 32px; } .deal-stub { padding-right: 12px; } .deal-sub { white-space: normal; text-wrap: balance; } }

.reports li { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--line); } /* [NEW] line-report rows */
.reports .th { position: relative; width: 44px; height: 44px; border-radius: 8px; overflow: hidden; background: var(--surface-2); display: grid; place-items: center; color: var(--ink-3); }
.reports .th img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 85%; filter: blur(1.2px) saturate(.85); }
.reports .t { display: block; font-size: var(--t-base); font-weight: 600; line-height: 1.25; }
.reports .m { display: block; margin-top: 2px; font-size: var(--t-xs); line-height: 1.3; color: var(--ink-3); }
.reports .r { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 20px; font-weight: 800; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.reports .r small { display: block; font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: 11px; font-weight: 600; color: var(--ink-3); }

details.how { margin-top: 12px; border-radius: var(--r-md); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); }
details.how summary { display: flex; align-items: center; justify-content: space-between; min-height: 52px; padding: 0 16px; font-size: var(--t-base); font-weight: 600; cursor: pointer; list-style: none; }
details.how summary::-webkit-details-marker { display: none; }
details.how summary::after { content: ""; width: 8px; height: 8px; border-right: 2px solid var(--ink-2); border-bottom: 2px solid var(--ink-2); transform: rotate(45deg) translateY(-2px); }
details.how[open] summary::after { transform: rotate(225deg); }
details.how p, details.how li { padding: 0 16px; font-size: var(--t-sm); line-height: 1.45; color: var(--ink-2); }

.facts { border-top: 1px solid var(--line); }
.facts > div { display: flex; justify-content: space-between; gap: 16px; min-height: 48px; padding: 13px 0; border-bottom: 1px solid var(--line); font-size: 14px; line-height: 20px; }
.facts dt { color: var(--ink-3); flex: none; max-width: 45%; }
.facts dd { margin: 0; text-align: right; font-weight: 600; overflow-wrap: anywhere; min-width: 0; }


/* ---------- Scan the line (full-screen flow over the tabs) ---------- */
.scan-flow { min-height: 100dvh; padding: 0 var(--gutter) calc(104px + var(--safe-b)); } /* [NEW] */
.scan-head { display: grid; grid-template-columns: 44px minmax(0, 1fr) 44px; align-items: center; height: 56px; margin: 0 -6px; } /* [NEW] */
.scan-head h1 { text-align: center; font-size: var(--t-lg); font-weight: 800; letter-spacing: -.02em; }
.scan-head .icon-btn { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-input); }
.scan-count { text-align: center; font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 16px; font-weight: 700; color: var(--ink-2); font-variant-numeric: tabular-nums; } /* [NEW] */
.scan-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; margin-top: 2px; } /* [NEW] */
.scan-steps i { height: 3px; border-radius: 2px; background: var(--line-strong); }
.scan-steps i.is-done { background: var(--ink); }
.scan-steps i.is-now { background: linear-gradient(90deg, var(--ink) 55%, var(--line-strong) 55%); }
.scan-venue { display: flex; align-items: center; gap: 12px; margin-top: 16px; }
.scan-venue .bar-logo { width: 40px; height: 40px; border-radius: 10px; }
.scan-venue > div { flex: 1; min-width: 0; display: grid; gap: 1px; }
.scan-venue-name { font-size: var(--t-lg); font-weight: 700; letter-spacing: -.015em; line-height: 1.2; overflow-wrap: anywhere; }
.scan-venue small { font-size: var(--t-xs); color: var(--ink-3); }
.viewfinder { position: relative; margin-top: 14px; aspect-ratio: 16 / 9; width: 100%; border-radius: var(--r-lg); overflow: hidden; isolation: isolate; background: radial-gradient(120% 80% at 50% 30%, #1A1A1A 0%, #050505 70%); box-shadow: inset 0 0 0 1px var(--line-strong); }
.viewfinder > img, .viewfinder > svg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 92%; z-index: -1; }
.vf-corners { position: absolute; inset: 14px; opacity: .9; background:
  linear-gradient(#fff, #fff) top left / 24px 2.5px no-repeat, linear-gradient(#fff, #fff) top left / 2.5px 24px no-repeat,
  linear-gradient(#fff, #fff) top right / 24px 2.5px no-repeat, linear-gradient(#fff, #fff) top right / 2.5px 24px no-repeat,
  linear-gradient(#fff, #fff) bottom left / 24px 2.5px no-repeat, linear-gradient(#fff, #fff) bottom left / 2.5px 24px no-repeat,
  linear-gradient(#fff, #fff) bottom right / 24px 2.5px no-repeat, linear-gradient(#fff, #fff) bottom right / 2.5px 24px no-repeat; }
.vf-tag { position: absolute; display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: var(--r-pill); background: var(--glass); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); color: #fff; font-size: var(--t-xs); font-weight: 600; white-space: nowrap; }
.vf-tag { top: 10px; left: 10px; }

.vf-tag .ic { width: 14px; height: 14px; }
.vf-retake { position: absolute; top: 4px; right: 4px; } /* [NEW] 44px glass icon button */
.vf-retake .ic { width: 18px; height: 18px; }
.vf-retake::before { content: ""; position: absolute; inset: 6px; border-radius: 50%; background: var(--glass); z-index: -1; }
.field-group { margin-top: 18px; border: 0; padding: 0; min-width: 0; }
.field-group legend { padding: 0; margin-bottom: 10px; }
.bucket-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.bucket { position: relative; display: block; }
.bucket input { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.bucket > span { position: relative; display: grid; gap: 1px; min-height: 76px; padding: 11px 12px; border-radius: var(--r-btn-lg); border: 1px solid var(--line-input); background: var(--surface); transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out); }
.bucket b { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 26px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.bucket b small { display: none; } /* unit lives in the legend ("How many people are in line?") */
.bucket em { font-style: normal; font-size: var(--t-sm); font-weight: 700; margin-top: 3px; }
.bucket i { font-style: normal; font-size: var(--t-xs); color: var(--ink-3); }
.bucket > span::after { content: ""; position: absolute; top: 12px; right: 12px; width: 18px; height: 18px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--line-input); }
.bucket input:checked + span { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.bucket input:checked + span :is(i, small) { color: var(--accent-sub); }
.bucket input:checked + span::after { background: var(--accent-ink) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 12.5 4 4L18 8'/%3E%3C/svg%3E") center / 12px no-repeat; box-shadow: none; }
.bucket input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 2px; box-shadow: 0 0 0 5px var(--focus-halo); }
.segmented { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 4px; padding: 3px; border-radius: var(--r-btn-lg); border: 1px solid var(--line-input); background: var(--surface); }
.segmented button, .segmented label { position: relative; display: grid; place-items: center; min-height: 44px; padding: 0 6px; border-radius: 11px; color: var(--ink-2); font-size: var(--t-sm); font-weight: 600; text-align: center; line-height: 1.15; }
.segmented [aria-pressed="true"], .segmented [aria-checked="true"] { background: var(--accent); color: var(--accent-ink); font-weight: 700; }
.scan-estimate { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 6px 12px; margin-top: 18px; padding: 14px 16px; border-radius: var(--r-md); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); } /* [NEW] */
.scan-estimate .v { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 32px; font-weight: 800; line-height: .9; font-variant-numeric: tabular-nums; }
.scan-estimate .v small { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: 13px; font-weight: 600; color: var(--ink-2); margin-left: 4px; }
.scan-estimate .lv { display: grid; justify-items: end; gap: 4px; text-align: right; font-size: var(--t-xs); color: var(--ink-3); }
.scan-estimate .lv b { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-2xs); font-weight: 700; font-stretch: var(--w-semi); letter-spacing: .08em; text-transform: uppercase; color: var(--ink); }
.scan-submit { position: fixed; z-index: 30; bottom: 0; left: max(0px, calc(50% - var(--phone-w) / 2)); right: max(0px, calc(50% - var(--phone-w) / 2)); padding: 24px var(--gutter) calc(var(--safe-b) + 12px); background: linear-gradient(180deg, rgb(0 0 0 / 0) 0%, #000 34%); } /* [NEW] */

.shutter { width: 76px; height: 76px; border-radius: 50%; border: 4px solid #fff; padding: 5px; }
.shutter span { display: block; width: 100%; height: 100%; border-radius: 50%; background: #fff; }
/* translate (not transform) centres it, so the :active scale still composes. */
.viewfinder .shutter { position: absolute; z-index: 2; left: 50%; bottom: 12px; translate: -50% 0; width: 64px; height: 64px; }
.viewfinder.is-captured .shutter { opacity: 0; pointer-events: none; transition: opacity var(--d-toast-out) var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .viewfinder.is-captured .shutter { transition: opacity var(--d-rm-out) linear; } }

/* ---------- Sheets ---------- */
dialog.sheet {
  width: min(100%, var(--phone-w)); max-width: 100%; max-height: min(92dvh, 860px); margin: auto auto 0; padding: 0; border: 0;
  border-radius: var(--r-xl) var(--r-xl) 0 0; background: var(--raised); color: var(--ink); box-shadow: inset 0 1px 0 var(--line-strong), var(--shadow-sheet);
  overflow: hidden; display: none; flex-direction: column;
}
dialog.sheet[open] { display: flex; }
dialog.sheet::backdrop { background: var(--scrim); }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
.sheet-head { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 44px; align-items: center; gap: 8px; padding: 26px 8px 4px var(--gutter); }
.sheet-grabber { position: absolute; top: 0; left: 50%; width: 64px; height: 26px; margin-left: -32px; display: grid; place-items: center; }
.sheet-grabber::after { content: ""; width: 36px; height: 5px; border-radius: 3px; background: var(--ink-4); }
.sheet-title { font-size: 24px; font-weight: 800; letter-spacing: -.03em; line-height: 1.1; }
.sheet-close { position: relative; color: var(--ink-2); }
.sheet-close::before { content: ""; position: absolute; width: 30px; height: 30px; border-radius: 50%; background: var(--fill-2); box-shadow: inset 0 0 0 1px var(--line-input); }
.sheet-close .ic { position: relative; width: 14px; height: 14px; stroke-width: 2.4; }
.sheet-body { padding: 4px var(--gutter) 20px; overflow-y: auto; overscroll-behavior: contain; }
.sheet-foot { padding: 12px var(--gutter) calc(12px + var(--safe-b)); border-top: 1px solid var(--line); }
.option-list { display: grid; }
.option-row { position: relative; display: flex; align-items: center; gap: 14px; min-height: 56px; border-bottom: 1px solid var(--line); font-size: var(--t-md); font-weight: 600; cursor: pointer; }
.option-row input { position: absolute; inset: 0; z-index: 1; opacity: 0; margin: 0; cursor: pointer; }
.option-row .rd { flex: none; width: 22px; height: 22px; display: grid; place-items: center; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--line-input); color: transparent; } /* [NEW] visible radio */
.option-row .rd .ic { width: 14px; height: 14px; stroke-width: 3; }
.option-row:has(input:checked) .rd { background: var(--accent); box-shadow: none; color: var(--accent-ink); }
.option-row > span:not(.rd):not(.n) { flex: 1; min-width: 0; }
.option-row > .n { flex: none; margin-left: auto; font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 15px; font-weight: 700; color: var(--ink-3); }
.option-row:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: -2px; border-radius: 8px; }

/* ---------- Groups ---------- */
.group-card { display: grid; gap: 12px; padding: 14px; border-radius: var(--r-md); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); }
.group-dest { display: flex; align-items: center; gap: 10px; min-width: 0; } /* [NEW] destination: logo + bar + its wait (BR treatment) */
.group-dest .bar-logo { width: 32px; height: 32px; }
.group-dest > span:not(.bar-logo) { flex: 1; min-width: 0; display: grid; }
.group-dest b { font-size: var(--t-sm); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.group-dest small { font-size: var(--t-xs); color: var(--ink-3); }
.group-dest .cs-value { font-size: 20px; }
.group-title-text { font-size: var(--t-lg); font-weight: 700; letter-spacing: -.015em; line-height: 1.25; overflow-wrap: anywhere; }
.group-when { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 22px; font-weight: 800; line-height: 1; } /* [NEW] */
.group-when small { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: var(--t-xs); font-weight: 600; color: var(--ink-3); margin-right: 6px; text-transform: uppercase; letter-spacing: .08em; }
.group-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 12px; border-top: 1px solid var(--line-strong); }
.avatars { display: flex; } /* [NEW] initials only, never photos */
.avatars .avatar { margin-left: -6px; box-shadow: inset 0 0 0 1px var(--line-input), 0 0 0 2px var(--surface-2); }
.avatars .avatar:first-child { margin-left: 0; }
.avatar { flex: none; width: var(--size, 30px); height: var(--size, 30px); border-radius: 50%; display: grid; place-items: center; background: #000; color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-input); font-size: calc(var(--size, 30px) * .36); font-weight: 800; letter-spacing: -.02em; }
.group-spots { display: flex; align-items: center; gap: 10px; font-size: var(--t-xs); color: var(--ink-2); }
.safety-note { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-radius: var(--r-md); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); font-size: var(--t-sm); line-height: 1.4; color: var(--ink-2); }

/* ---------- Points / rewards ---------- */
.points-card { padding: 4px 0 0; background: none; border: 0; box-shadow: none; }
.points-total { display: flex; align-items: baseline; gap: 8px; margin-top: 6px; font-family: var(--font-num); font-stretch: var(--w-cond); font-size: var(--t-num-xl); font-weight: 800; line-height: .8; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.points-total small { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: 22px; font-weight: 700; color: var(--ink-2); letter-spacing: -.01em; }
.points-note { margin-top: 12px; font-size: var(--t-sm); color: var(--ink-3); }
.reward-grid { display: grid; gap: 10px; }
.reward { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 12px 14px; border-radius: var(--r-md); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); }
.reward-icon { width: 36px; height: 36px; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--fill-2); color: var(--ink); }
.reward-title { font-size: var(--t-base); font-weight: 700; line-height: 1.25; }
.reward-detail { font-size: var(--t-xs); line-height: 1.35; color: var(--ink-3); }
.reward-cost { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 20px; font-weight: 800; text-align: right; white-space: nowrap; }
.reward-cost small { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: 11px; color: var(--ink-3); margin-left: 2px; }
.reward-side { display: grid; justify-items: end; gap: 6px; } /* [NEW] cost over action */
.reward.is-short .reward-title { color: var(--ink-2); }
.reward.is-locked { background: repeating-linear-gradient(135deg, rgb(255 255 255 / .03) 0 6px, transparent 6px 12px); }

/* ---------- Lists, toasts, banners, empty ---------- */
.list-group { border-top: 1px solid var(--line); }
.list-link { display: flex; align-items: center; gap: 14px; min-height: 56px; padding: 10px 2px; border-bottom: 1px solid var(--line); font-size: var(--t-md); font-weight: 600; }
.list-link > span { flex: 1; min-width: 0; display: grid; gap: 2px; }
.list-link small { font-size: var(--t-xs); font-weight: 500; color: var(--ink-3); }
.list-link .ic:first-child { color: var(--ink-2); }
.list-link .ic:last-child { width: 18px; height: 18px; color: var(--ink-3); }
.list-link:active { background: var(--surface); }
.plain-list li { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line); font-size: var(--t-base); }
.plain-list .plus { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 20px; font-weight: 800; color: var(--ink); }
.plain-list .muted { color: var(--ink-3); }
.toast-region { position: fixed; z-index: 60; left: max(0px, calc(50% - var(--phone-w) / 2)); right: max(0px, calc(50% - var(--phone-w) / 2)); bottom: calc(var(--tabbar-h) + var(--safe-b) + 24px + var(--toast-lift, 0px)); /* --toast-lift: main.js liftToasts */ display: grid; justify-items: center; padding: 0 var(--gutter); pointer-events: none; }
.toast { pointer-events: auto; display: flex; align-items: center; gap: 10px; width: 100%; min-height: 52px; padding: 4px 4px 4px 14px; border-radius: 16px; background: var(--accent); color: var(--accent-ink); box-shadow: var(--shadow-float); font-size: 14px; font-weight: 600; line-height: 1.3; transition: transform var(--d-toast) var(--ease-out), opacity var(--d-toast) var(--ease-out); }
.toast .ok { flex: none; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; background: var(--accent-ink); color: var(--accent); } /* [NEW] */
.toast .ok .ic { width: 14px; height: 14px; stroke-width: 3; }
.toast p { flex: 1; }
.toast .btn { min-height: 44px; padding: 0 12px; border: 0; background: transparent; color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px; }
.toast :focus-visible { outline-color: var(--accent-ink); box-shadow: none; }
@starting-style { .toast { transform: translateY(12px); opacity: 0; } }
.banner { display: flex; align-items: flex-start; gap: 12px; padding: 14px 10px 14px 14px; border-radius: var(--r-md); background: var(--surface-2); border: 1px solid var(--line-input); font-size: 14px; line-height: 1.4; color: var(--ink-2); }
.banner > .ic { margin-top: 1px; color: var(--ink); }
.banner > div:not(.banner-actions) { flex: 1; min-width: 0; }
.banner strong { display: block; color: var(--ink); font-weight: 700; }
.banner-actions { flex: none; align-self: center; }
.state { display: grid; justify-items: center; gap: 8px; padding: 28px 16px; text-align: center; border-radius: var(--r-md); box-shadow: inset 0 0 0 1px var(--line-strong); }
.state-icon { display: none; }
.state :is(h1, h2) { font-size: 26px; font-weight: 800; letter-spacing: -.03em; line-height: 1.1; text-wrap: balance; max-width: 16ch; }
.state p { max-width: 30ch; font-size: 14px; line-height: 1.4; color: var(--ink-3); }
.state .actions { display: flex; gap: 8px; margin-top: 8px; }
.field-error { display: flex; gap: 6px; align-items: center; margin-top: 8px; color: var(--danger); font-size: var(--t-sm); font-weight: 600; }

/* Classes NOT carried over from the current app.css (delete them):
   - silver card styling: .bar-link silver bg, .card-status pill, .cs-icon, .cs-text
   - wait ring: .ring, .ring-*
   - .crowd-chip, .area-pill silver, .tabbar silver capsule
   - the old .deal-slot over the photo and .deal-tag white badge
   Keep (restyled by tokens alone): .panel, .radio-card, .switch, .stepper, .text-input, .select, .check, .window-option,
   the pass-card watermark, .map-* pins (pin fills use the level hues via data-pin-tone), console tables, .age-*. */
/* Kept from the previous base (the spec base doesn't define these). */
[hidden] { display: none !important; }
@media (pointer: fine) { html { overscroll-behavior: none; } }
html { scroll-padding-top: calc(var(--topbar-h) + var(--safe-t) + 8px); scroll-padding-bottom: calc(var(--tabbar-h) + var(--safe-b) + 16px); }
button, .btn, .chip, .tab, .venue-link, .back-link, .demo-chip, .window-option, .radio-card, .segmented, .map-pin-btn, details.how summary { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.skip { position: absolute; left: 12px; top: -60px; z-index: 100; background: var(--ink); color: var(--bg); padding: 10px 14px; border-radius: var(--r-sm); font-weight: 700; }
.skip:focus { top: calc(8px + var(--safe-t)); }
.title-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.section-title { margin: 32px 0 10px; }
.page > .page-title:first-child, .page > .back-row:first-child, .page > .title-row:first-child { margin-top: 12px; }

/* Kept from v3: the visible summary when a search or filter is active. */
.filter-summary { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; padding: 6px 6px 6px 14px; border-radius: var(--r-md); background: var(--surface); border: 1px solid var(--line-input); font-size: var(--t-sm); color: var(--ink-sub); }
.filter-summary span { min-width: 0; overflow-wrap: anywhere; }
dialog.picker { max-width: var(--phone-w); }
.picker .hint { display: flex; gap: 6px; align-items: center; margin-top: 14px; }

/* ============ Layer 3 ============ */
/* ---------- Points ---------- */
.earn-list { display: grid; margin-bottom: 12px; }
.earn-list li { display: flex; align-items: center; gap: 12px; min-height: 52px; border-bottom: 1px solid var(--line); font-size: 15px; }
.earn-list li span { flex: 1; }
.earn-list li svg { color: var(--ink-2); }
.earn-list b { color: var(--fresh); font-weight: 800; }

/* ---------- Deals: console type picker (the bar page tickets come from the spec) ---------- */
.deal-kinds { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.deals .hint { margin-top: 10px; }

/* ---------- Bar page (team sections on the spec's system) ---------- */
.back-link.hero-btn { padding: 0; border-color: rgb(255 255 255 / .16); }
.hero-sub { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 16px; font-weight: 700; color: var(--ink-sub); }
.hero-sub .ic { width: 12px; height: 12px; }
.qb-wait .approx { font-size: .55em; font-weight: 700; margin-right: 4px; vertical-align: .2em; }
.qb-level .cs-glyph { width: 18px; height: 18px; }
.fact-strip dd .fact-sub, .qb-facts dd .fact-sub { display: block; margin-top: 5px; font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: var(--t-xs); font-weight: 500; line-height: 1.3; color: var(--ink-3); white-space: normal; }
.fact-strip { margin-top: 16px; }
.act[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.event-card { display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 4px 12px; padding: 14px; border-radius: var(--r-md); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); }
.event-icon { width: 44px; height: 44px; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--fill-2); color: var(--ink); }
.event-main { display: grid; gap: 2px; align-content: center; min-width: 0; }
.event-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: var(--t-lg); font-weight: 800; letter-spacing: -.02em; line-height: 1.2; }
.event-time { font-size: 18px; font-weight: 700; color: var(--ink-sub); }
.live-chip { display: inline-flex; align-items: center; gap: 5px; height: 20px; padding: 0 8px; border-radius: var(--r-pill); background: var(--accent); color: var(--accent-ink); font-size: 10.5px; font-weight: 800; font-stretch: var(--w-semi); letter-spacing: .08em; text-transform: uppercase; }
.event-facts { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 14px; margin: 10px 0 0; padding-top: 12px; border-top: 1px solid var(--line-strong); }
.event-facts div { display: flex; flex-direction: column-reverse; gap: 2px; min-width: 0; }
.event-facts dt { font-size: var(--t-2xs); font-weight: 700; font-stretch: var(--w-semi); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.event-facts dd { margin: 0; font-size: var(--t-base); font-weight: 600; overflow-wrap: anywhere; }
.food-row { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 12px 14px; border-radius: var(--r-md); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); }
.food-row .event-icon { width: 40px; height: 40px; }
.food-main { display: grid; gap: 2px; min-width: 0; }
.food-title { font-weight: 700; font-size: var(--t-base); }
.poll-options { display: grid; gap: 8px; }
.poll-opt { position: relative; isolation: isolate; overflow: hidden; display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 52px; padding: 0 16px; border-radius: var(--r-btn-lg); border: 1px solid var(--line-input); background: var(--surface); color: var(--ink); font-size: var(--t-base); font-weight: 600; text-align: left; transition: transform var(--d-press) var(--ease-out); }
.poll-opt::before { content: ""; position: absolute; inset: 0; background: var(--fill-2); z-index: -1; transform: scaleX(var(--pf, 0)); transform-origin: left center; transition: transform var(--d-fill) var(--ease-out); }
.poll-opt[aria-pressed="true"] { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.poll-opt[aria-pressed="true"]::before { background: #2E2E2E; }
.poll-opt:active { transform: scale(.98); }
.poll-label { display: inline-flex; align-items: center; gap: 6px; }
.poll-pct { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 20px; font-weight: 800; }
@media (prefers-reduced-motion: reduce) { .poll-opt::before { transition: none; } }
.dir-address { display: flex; gap: 8px; align-items: flex-start; font-size: var(--t-lg); font-weight: 700; }
.dir-address .ic { width: 18px; height: 18px; margin-top: 3px; }
.dir-links { display: grid; gap: 10px; margin: 18px 0 6px; }
.menu-item .num { font-size: 17px; font-weight: 700; color: var(--ink-2); }

/* ---------- Events tab ---------- */
.ev-views { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); width: 100%; margin-top: 16px; }
.ev-views button { justify-content: center; }
.ev-filters { margin-top: 10px; }
.chip-select.is-set select { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.chip-select.is-set svg { color: var(--accent-ink); }
.groups-link { margin-top: 10px; border-top: 1px solid var(--line); }
.ev-list { display: grid; gap: 16px; margin-top: 12px; }
.ev-card { border-radius: var(--r-xl); overflow: hidden; background: var(--surface); border: 1px solid var(--line-strong); }
.ev-link { display: grid; color: inherit; text-decoration: none; }
.ev-photo { position: relative; display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--surface-2); isolation: isolate; }
.ev-photo > svg, .ev-photo > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: -1; }
.ev-live { position: absolute; left: 12px; top: 12px; }

.ev-body { display: grid; gap: 5px; padding: 14px 16px 6px; min-width: 0; }
.ev-bar { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: var(--ink-sub); }
.ev-logo { width: 28px; height: 28px; border-radius: 8px; }
.ev-logo .mono { font-size: 11px; }
.ev-title { font-family: var(--font-display); font-weight: 800; font-size: 22px; line-height: 26px; overflow-wrap: anywhere; }
.ev-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; font-size: 14px; color: var(--ink-2); }
.ev-meta svg { flex: none; width: 15px; height: 15px; }
.ev-meta .sep { margin: 0; }
.ev-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 10px 16px 16px; }
.ev-actions .btn { min-height: 44px; }
.ev-actions .btn[aria-pressed="true"] { border-color: #fff; }
.ev-empty { padding-top: 32px; }

/* Native selects (Events filters, forms, console). 16px so iOS doesn't zoom on focus. */
.select { position: relative; }
.select select { -webkit-appearance: none; appearance: none; min-height: 40px; padding: 0 34px 0 14px; border-radius: var(--r-pill); border: 1px solid var(--line-input); background: var(--surface-2); color: var(--ink); font-size: 16px; font-weight: 600; }
.select select option { background: var(--raised); color: var(--ink); }
.select > svg { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; pointer-events: none; color: var(--ink-2); }
.chip-select { flex: none; }
.chip-select select { height: 40px; }
.field .select select { width: 100%; height: 48px; border-radius: var(--r-btn-lg); }

.reward-cost:not(.num) { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: var(--t-xs); font-weight: 600; color: var(--ink-3); }
.reward-side .btn { min-width: 92px; }

/* ---------- Groups (spec card + the team's host row) ---------- */
.group-list { display: grid; gap: 12px; margin-top: 16px; }
.group-dest b { display: block; }
.group-wait { flex: none; display: grid; justify-items: end; gap: 3px; text-align: right; }
.group-wait .card-status { display: contents; }
.group-wait .foot-eb { color: var(--ink); }
.group-wait .cs-value { font-size: 20px; }
.group-wait .cs-tag { font-size: 15px; }
.group-host { display: flex; align-items: center; gap: 10px; min-width: 0; }
.group-host-text { display: grid; min-width: 0; }
.group-host-name { font-weight: 700; font-size: var(--t-base); }
.group-when { display: flex; align-items: baseline; gap: 6px; }
.group-when .num { font-size: 26px; font-weight: 800; line-height: 1; }
.group-when small.ap { margin: 0; text-transform: none; letter-spacing: 0; font-size: var(--t-sm); color: var(--ink-2); }
.group-note { font-size: var(--t-sm); line-height: 1.45; color: var(--ink-2); overflow-wrap: anywhere; }
.handle { display: inline-flex; align-items: center; gap: 3px; min-height: 28px; color: var(--ink-2); font-size: var(--t-sm); font-weight: 600; text-decoration: underline; text-decoration-color: var(--ink-4); text-underline-offset: 3px; }
.handle .ic { width: 14px; height: 14px; }
.mini-tag { display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: var(--r-xs); border: 1px solid var(--line-input); color: var(--ink-2); font-size: 10.5px; font-weight: 700; font-stretch: var(--w-semi); letter-spacing: .08em; text-transform: uppercase; vertical-align: middle; }
.safety-note .ic { flex: none; width: 18px; height: 18px; margin-top: 1px; color: var(--ink); }

/* ---------- Motion (research/claude-raw/motion-spec.md) ---------- */
/* Sheets: transitions retarget, so a close during the open (or a grab mid-flight) never restarts. */
dialog.sheet { transform: translateY(100%); transition: transform var(--d-sheet-out) var(--ease-out); }
dialog.sheet[open] { transform: none; transition-duration: var(--d-sheet-in); transition-timing-function: var(--ease-sheet); }
@starting-style { dialog.sheet[open] { transform: translateY(100%); } }
dialog.sheet.is-closing { transform: translateY(100%); transition-duration: var(--d-sheet-out); transition-timing-function: var(--ease-out); }
dialog.sheet.is-dragging { transition: none; }
dialog.sheet::backdrop { opacity: 0; transition: opacity var(--d-sheet-out) var(--ease-out); }
dialog.sheet[open]::backdrop { opacity: 1; transition-duration: var(--d-sheet-in); transition-timing-function: var(--ease-sheet); }
@starting-style { dialog.sheet[open]::backdrop { opacity: 0; } }
dialog.sheet.is-closing::backdrop { opacity: 0; transition-duration: var(--d-sheet-out); transition-timing-function: var(--ease-out); }
.sheet-head { touch-action: none; }
@media (prefers-reduced-motion: reduce) {
  dialog.sheet, dialog.sheet[open], dialog.sheet.is-closing { transform: none; transition: opacity var(--d-rm-in) linear; }
  dialog.sheet[open] { opacity: 1; }
  @starting-style { dialog.sheet[open] { opacity: 0; } }
  dialog.sheet.is-closing { opacity: 0; transition-duration: var(--d-rm-out); }
  dialog.sheet::backdrop, dialog.sheet[open]::backdrop { transition: opacity var(--d-rm-in) linear; }
  dialog.sheet.is-closing::backdrop { transition-duration: var(--d-rm-out); }
}
/* Toasts leave faster and shorter than they arrive (6px in 160ms against 12px in 220ms), and stop catching taps at once. */
.toast.is-leaving { opacity: 0; transform: translateY(6px); visibility: hidden; pointer-events: none;
  transition: opacity var(--d-toast-out) var(--ease-out), transform var(--d-toast-out) var(--ease-out), visibility 0s linear var(--d-toast-out); }
.toast p { transition: opacity var(--d-swap) var(--ease-out), filter var(--d-swap) var(--ease-out); }
.toast.is-swapping p { opacity: .6; filter: blur(2px); transition: none; }
/* Scan has no tab bar: sit low, except on step 2, where the Send report bar holds the bottom. */
[data-route="scan"]:not(:has(.scan-submit)) .toast-region { bottom: calc(var(--safe-b) + 16px); }
@media (prefers-reduced-motion: reduce) {
  .toast { transition: opacity var(--d-rm-in) linear; }
  @starting-style { .toast { transform: none; } }
  .toast.is-leaving { transform: none; transition: opacity var(--d-rm-out) linear, visibility 0s linear var(--d-rm-out); }
  .toast p { transition: opacity var(--d-rm-in) linear; }
  .toast.is-swapping p { filter: none; }
}
/* Press feedback where it was missing (transform in the transition list, or the scale snaps). */
.segmented button { transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out), transform var(--d-press) var(--ease-out); }
.segmented button:active { transform: scale(.97); }
.bucket > span { transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out), transform var(--d-press) var(--ease-out); }
.bucket input:not(:disabled):active + span { transform: scale(.97); }
.option-row { transition: background-color var(--d-select) var(--ease-out); } /* pressed fill: see "Presses" at the end */
/* Loops stop when nobody can see them. */
html[data-hidden] *, html[data-hidden] *::before, html[data-hidden] *::after { animation-play-state: paused !important; }
/* Reduced motion: list/detail becomes a short cross-fade instead of a hard cut. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*) { animation: none; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--d-rm-in); animation-timing-function: linear; }
  .poll-opt::before { transition: none; }
}

/* ---------- Points (team ideas): head, progress to next reward, check-in, stats ---------- */
.points-head { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.points-head .page-title { margin: 0; }
.points-who { display: flex; align-items: center; gap: 8px; margin-top: 4px; font-size: var(--t-sm); color: var(--ink-2); }
.points-card { margin-top: 18px; }
.points-next { margin-top: 16px; }
.pn-track { position: relative; display: block; height: 6px; border-radius: 3px; background: var(--meter-off); overflow: hidden; }
.pn-track i { position: absolute; inset: 0; background: var(--ink); transform: scaleX(var(--pn, 0)); transform-origin: left center; border-radius: 3px; transition: transform var(--d-fill) var(--ease-out); }
/* Points is patched in place now (QA plan 4.4), so the fill can glide; under reduced motion it changes at once. */
@media (prefers-reduced-motion: reduce) { .pn-track i { transition: none; } }
.points-next p { margin-top: 8px; font-size: var(--t-sm); color: var(--ink-2); }
.points-next b { font-size: 18px; color: var(--ink); }
.checkin-btn { margin-top: 20px; }
.checkin-btn .trail { margin-left: auto; }
.hint.center { text-align: center; }
.points-stats { margin-top: 18px; }
.earn-list { display: grid; border-top: 1px solid var(--line); }
.earn-list li { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; align-items: center; gap: 12px; min-height: 60px; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: var(--t-base); font-weight: 600; }
.earn-list li > span { display: grid; gap: 1px; min-width: 0; }
.earn-list small { font-size: var(--t-xs); font-weight: 500; color: var(--ink-3); }
.earn-list li > .ic:first-child { color: var(--ink-2); }
.earn-list b { font-size: 22px; font-weight: 800; color: var(--ink); }
.qr-finder { aspect-ratio: 1 / 1; max-width: 260px; margin: 6px auto 0; display: grid; place-items: center; }
.qr-glyph { color: var(--ink-2); }
.qr-glyph .ic { width: 44px; height: 44px; stroke-width: 1.4; }
.checkin-done { display: grid; gap: 12px; text-align: center; padding-bottom: 28px; }
.checkin-pts { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 72px; font-weight: 800; line-height: .9; }
.checkin-pts small { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: 20px; font-weight: 700; color: var(--ink-2); margin-left: 6px; }
.pick-list { display: grid; margin-top: 6px; border-top: 1px solid var(--line); }
.pick-row { width: 100%; display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 12px; min-height: 60px; padding: 8px 2px; border-bottom: 1px solid var(--line); text-align: left; color: var(--ink); }
.pick-row .bar-logo { width: 32px; height: 32px; }
.pick-row[aria-disabled="true"] { color: var(--ink-3); cursor: not-allowed; }
.pick-name { font-size: var(--t-md); font-weight: 600; overflow-wrap: anywhere; }
.pick-area { font-size: var(--t-xs); color: var(--ink-3); white-space: nowrap; }
.pick-row:not([aria-disabled="true"]):active { background: var(--surface); }
.pick-row:not(:has(.bar-logo)) { grid-template-columns: minmax(0, 1fr) auto auto; }

/* ---------- My account (Ship D): VIP cards, subscription, settings. All simulated. ---------- */
.account-title { margin-bottom: 12px; }
.settings-btn { flex: none; }
.avatar-lg { font-size: 26px; }

.profile-id .btn-sm { justify-self: start; margin-top: 6px; }

#profile-form { margin-top: 14px; }
.list-group { display: grid; }
button.list-link { width: 100%; border: 0; border-bottom: 1px solid var(--line); background: none; color: inherit; font: inherit; font-size: var(--t-md); font-weight: 600; text-align: left; cursor: pointer; }
.list-link.static { cursor: default; }
.list-link.static:active { background: none; }
.list-switch { min-height: 64px; padding: 10px 2px; border-bottom: 1px solid var(--line); }
.list-switch label { flex: 1; min-width: 0; display: grid; gap: 2px; cursor: pointer; }
.list-switch .hint { margin: 0; }
.opt-sub { display: block; font-size: var(--t-xs); font-weight: 500; color: var(--ink-3); }

.vip-card { position: relative; display: grid; gap: 18px; padding: 18px 18px 16px; border-radius: var(--r-lg); background: linear-gradient(150deg, #26262a 0%, #111113 46%, #050505 100%); box-shadow: inset 0 0 0 1px var(--line-strong), 0 12px 32px rgba(0,0,0,.45); overflow: hidden; isolation: isolate; aspect-ratio: 1.586; max-height: 230px; }
.vip-card::before { content: ""; position: absolute; inset: -40% -10% auto auto; width: 70%; height: 140%; background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,.07) 48%, transparent 66%); transform: rotate(8deg); z-index: -1; pointer-events: none; }
.vip-card:not(.is-main) { aspect-ratio: auto; background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); gap: 12px; }
.vip-card:not(.is-main)::before { display: none; }
.vip-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.vip-brand { font-family: var(--font-display); font-weight: 900; font-size: 20px; letter-spacing: -0.02em; }
.vip-card.is-main .vip-brand .wm-logo { height: 30px; }
.vip-card:not(.is-main) .vip-brand { font-size: var(--t-md); text-transform: none; letter-spacing: 0; }

.vip-title { align-self: end; font-family: var(--font-display); font-weight: 800; font-size: 28px; line-height: 1; letter-spacing: -0.01em; }
.vip-card:not(.is-main) .vip-title { font-size: var(--t-lg); line-height: 1.2; }
.vip-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; }
.vip-foot > span:first-child { display: grid; gap: 2px; min-width: 0; }
.vip-foot b { font-size: var(--t-md); overflow-wrap: anywhere; }
.vip-foot small { font-size: var(--t-xs); color: var(--ink-3); }
.vip-code { flex: none; display: flex; align-items: stretch; gap: 1px; height: 34px; padding: 4px 6px; border-radius: 4px; background: var(--ink); opacity: .9; }
.vip-code i { display: block; width: var(--w); background: var(--bg); }
.vip-code i:nth-child(3n) { background: transparent; }
.vip-card:not(.is-main) .vip-code { height: 26px; }
.vip-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 12px; }
.vip-actions .btn { min-width: 0; padding-inline: 10px; }
.vip-list { display: grid; gap: 10px; margin-top: 12px; }
.vip-list li { display: grid; gap: 4px; }
.vip-list .btn-ghost { justify-self: end; }

.sub-card { padding: 16px; border-radius: var(--r-lg); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); }
.sub-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.sub-name { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-display); font-weight: 800; font-size: var(--t-lg); }
.sub-state { padding: 3px 9px; border-radius: var(--r-pill); font-size: var(--t-xs); font-weight: 700; background: var(--fill-2); color: var(--ink-2); }
.sub-state[data-on="true"] { background: color-mix(in srgb, var(--quiet) 16%, transparent); color: var(--quiet); }
.sub-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 14px 0 0; padding: 12px 0; border-block: 1px solid var(--line); }
.sub-facts div { display: grid; gap: 2px; min-width: 0; }
.sub-facts dt { font-size: var(--t-2xs); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.sub-facts dd { margin: 0; font-size: var(--t-sm); font-weight: 700; }
.sub-perks { display: grid; gap: 8px; margin: 14px 0 16px; }
.sub-perks li { display: flex; align-items: center; gap: 8px; font-size: var(--t-sm); color: var(--ink-2); }
.sub-perks .ic { flex: none; color: var(--ink); }

/* ---------- Scan the line (Redesign 3): full-screen 3-step flow, no top bar or tab bar ---------- */
[data-route="scan"] .topbar, [data-route="scan"] .tabbar { display: none; }
[data-route="scan"] main { padding-bottom: 0; }
.scan-flow { padding-top: var(--safe-t); }
.scan-flow[data-step="1"], .scan-flow[data-step="3"] { padding-bottom: calc(40px + var(--safe-b)); }
.scan-flow .scan-step { margin-top: 14px; }
.scan-lede { font-size: var(--t-md); line-height: 1.4; color: var(--ink-2); }
.scan-lede b { color: var(--ink); font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 1.15em; }
.scan-label { margin: 20px 0 8px; }
.scan-flow .search { margin: 0 0 4px; }
.scan-venue > span:not(.bar-logo):not(.btn) { flex: 1; min-width: 0; display: grid; gap: 1px; }
.scan-venue small { display: block; }
.scan-nearest { width: 100%; margin-top: 0; padding: 12px; border: 0; border-radius: var(--r-lg); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); color: inherit; font: inherit; text-align: left; cursor: pointer; transition: transform var(--d-press) var(--ease-out); }
.scan-nearest:active { transform: scale(.98); }
.scan-nearest:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.scan-nearest .btn { pointer-events: none; }
.vf-tip { left: 50%; transform: translateX(-50%); }
.bucket.is-wide { grid-column: 1 / -1; }
.bucket.is-wide > span { min-height: 56px; grid-template-columns: auto auto minmax(0, 1fr); align-items: baseline; column-gap: 10px; padding-right: 40px; }
.bucket.is-wide em { margin-top: 0; }
.bucket.is-wide i { justify-self: end; }
fieldset:disabled .bucket > span, fieldset:disabled .segmented { opacity: .4; }
fieldset:disabled .bucket input, fieldset:disabled .door-seg input { cursor: not-allowed; }
.door-seg label { cursor: pointer; transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out); }
.door-seg input { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.door-seg label:has(input:checked) { background: var(--accent); color: var(--accent-ink); font-weight: 700; }
.door-seg label:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.scan-estimate .v.is-empty { font-family: var(--font-sans); font-stretch: var(--w-norm); font-size: var(--t-lg); color: var(--ink-3); line-height: 1.2; }

.scan-inline { margin-top: 12px; }
.scan-done { padding-top: 24px; text-align: center; }
.scan-pts { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 104px; font-weight: 800; line-height: .9; letter-spacing: -.01em; }
.scan-pts small { margin-left: 6px; font-size: 22px; font-weight: 700; color: var(--ink-2); }
.scan-done h2 { margin-top: 10px; font-size: var(--t-2xl); line-height: 1.1; }
.scan-done p:not(.scan-pts) { max-width: 32ch; margin: 8px auto 0; color: var(--ink-2); }
.scan-done .actions { margin-top: 20px; }
.scan-flow .waiting-card { margin-top: 16px; background: var(--surface); border: 1px solid var(--line-strong); }

.scan-flow .bucket > span { height: auto; }
.scan-done .scan-pts { font-size: 104px; line-height: .9; margin: 0; color: var(--ink); }

/* ---------- Real bar photos (demo use): each photo sets its own focal point ---------- */
img.real-photo { object-position: var(--pos, 50% 50%) !important; }

/* ---------- Sort row: one segmented control (Nearest / Shortest wait / Deals), no counts ---------- */
.sort-seg { position: relative; flex: 1 0 auto; display: flex; gap: 2px; padding: 3px; border-radius: var(--r-pill); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-input); }
.sort-seg button { position: relative; border: 0; border-radius: var(--r-pill); background: transparent; color: var(--ink-2); font: inherit; cursor: pointer; transition: transform var(--d-press) var(--ease-out); }
/* Sizing shared with the ink labels (every rule that sizes a button names .seg-ink > span too), and one weight in both
   states: the segments never shift when the selection changes (QA plan 3.3). */
.sort-seg button, .seg-ink > span { flex: 1 1 auto; min-width: 0; height: 34px; padding: 0 12px; font-size: 14px; font-weight: 700; letter-spacing: -.005em; white-space: nowrap; }
.sort-seg button::before { content: ""; position: absolute; inset: -5px 0; } /* 44px hit area */
.sort-seg button:active { transform: scale(.97); }
/* The selected look is one ink layer (white, black labels) clipped to the selected segment. The clip glides between
   segments of different widths, so the labels under the moving pill are exactly inverted. --x/--y/--w/--h: main.js. */
.seg-ink { position: absolute; inset: 0; display: flex; gap: 2px; padding: inherit; border-radius: inherit; pointer-events: none;
  background: var(--accent); color: var(--accent-ink);
  clip-path: inset(var(--y, 3px) calc(100% - var(--x, 0px) - var(--w, 0px)) calc(100% - var(--y, 3px) - var(--h, 0px)) var(--x, 0px) round 999px);
  transform-origin: calc(var(--x, 0px) + var(--w, 0px) / 2) 50%;
  transition: clip-path var(--d-thumb) var(--ease-in-out), scale var(--d-press) var(--ease-out); }
.seg-ink > span { display: grid; place-items: center; }
.sort-seg:not(:has(> button[aria-pressed="true"])) .seg-ink { opacity: 0; }
/* Pressing the selected segment presses the pill with it. */
.sort-seg:has(> button[aria-pressed="true"]:active) .seg-ink { scale: .97; --d-press: var(--d-press-down); }
.kbd .seg-ink { transition: scale var(--d-press) var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .seg-ink { transition: scale var(--d-press) var(--ease-out); } } /* the ink jumps; the press stays */
.sort-seg button:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.chip-x { gap: 6px; padding-right: 10px; }
.chip-x .ic { width: 14px; height: 14px; color: var(--ink-2); }

/* ---------- Splash: the nib writes the mark (design panel wf_257e7d2b-276: pen concept + paint drips) ---------- */
/* ===== splash: a glowing nib writes the mark; drips fall, the glass fills, the swash flicks out ===== */
.splash{position:fixed;inset:0;z-index:1000;background:#000;display:flex;flex-direction:column;align-items:center;justify-content:center;
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",Roboto,sans-serif;
  -webkit-tap-highlight-color:transparent;cursor:pointer;
  animation:splash-safety .3s ease 4.5s forwards}                       /* safety net: gone at 4.5s even without JS */
.splash.is-out{opacity:0;visibility:hidden;pointer-events:none;transition:opacity .42s ease,visibility 0s linear .42s}
@keyframes splash-safety{to{opacity:0;visibility:hidden;pointer-events:none}}
.splash-mark{display:block;width:min(86vw,420px);height:auto;aspect-ratio:722/207;overflow:visible}
.sp-tag{margin-top:clamp(14px,4.4vw,22px);padding-left:.22em;font-size:12px;font-weight:700;letter-spacing:.22em;
  text-transform:uppercase;color:#8E8E93;opacity:0}

/* before .is-playing the splash is black; the exact mark (.sp-f) shows per part once its motion is done */
.sp-anim,.sp-f{visibility:hidden}
.splash.is-playing .sp-anim{visibility:visible;animation:sp-off 0s linear 2194ms forwards}
.splash.is-playing .sp-k{animation:sp-off 0s linear forwards}                 /* delay inline: that part's settle time */
.splash.is-playing .sp-f{animation:sp-on 0s linear forwards}                  /* same delay: swap in the same frame */
@keyframes sp-off{to{visibility:hidden}}
@keyframes sp-on{to{visibility:visible}}

/* ink: white round-capped strokes revealed with stroke-dashoffset, clipped to the exact letter and to their own region */
.sp-rv path{fill:none;stroke-dasharray:1 2;stroke-dashoffset:1.002}
.splash.is-playing .sp-rv path{animation-name:sp-draw;animation-fill-mode:both}  /* delay/duration/easing inline per chunk */
@keyframes sp-draw{from{stroke-dashoffset:1.002}to{stroke-dashoffset:0}}

/* the i's dot is tapped in: ink blooms from the touch point */
.sp-bloom{transform:scale(0)}
.splash.is-playing .sp-bloom{animation:sp-bloom 170ms cubic-bezier(.2,.75,.3,1) 418ms both}
@keyframes sp-bloom{from{transform:scale(.01)}to{transform:none}}

/* drips: once the pen leaves, each drip gathers, falls along its stroke, overshoots and settles */
.sp-drip{visibility:hidden}                                                  /* hidden until the pen reaches it */
.splash.is-playing .sp-drip{animation:sp-drip 1s linear forwards}             /* delay/duration inline per drip */
@keyframes sp-drip{
  0%{visibility:visible;transform:scale(1,.02);animation-timing-function:cubic-bezier(.2,.7,.4,1)}
  20%{transform:scale(1,.3);animation-timing-function:cubic-bezier(.55,0,.85,.45)}
  56%{transform:scale(1,1.09);animation-timing-function:cubic-bezier(.3,0,.45,1)}
  73%{transform:scale(1,.965);animation-timing-function:cubic-bezier(.4,0,.5,1)}
  87%{transform:scale(1,1.012);animation-timing-function:ease-out}
  100%{visibility:visible;transform:none}}

/* the glass fills while the pen draws its stem and foot: the art's own liquid surface rises and sloshes into place */
.sp-liq{transform:translateY(47.2px)}
.splash.is-playing .sp-liq{animation:sp-liq 720ms cubic-bezier(.33,.1,.4,1) 602ms both}
@keyframes sp-liq{
  0%{transform:translateY(47.2px) rotate(-6deg)}
  42%{transform:translateY(12.9px) rotate(3.5deg)}
  70%{transform:translateY(3.8px) rotate(-1.6deg)}
  88%{transform:translateY(0.8px) rotate(.5deg)}
  100%{transform:none}}

/* the nib: a small white glow moved along the writing path (translate keyframes; dims and shrinks in the air) */
.sp-nib-a{opacity:0}
.splash.is-playing .sp-nib{animation:sp-nib-move 1790ms linear 110ms both}
.splash.is-playing .sp-nib-a{animation:sp-nib-lift 1830ms linear 70ms both}
@keyframes sp-nib-move{0%{transform:translate(12.5px,166px)}0.391%{transform:translate(14.2px,164.8px)}0.782%{transform:translate(18.2px,161.7px)}1.173%{transform:translate(23.1px,154.9px)}1.564%{transform:translate(29.7px,145.5px)}2.011%{transform:translate(39.4px,131.9px)}2.626%{transform:translate(55.2px,109.9px)}3.352%{transform:translate(74.7px,83.3px)}3.631%{transform:translate(81px,73.9px)}4.022%{transform:translate(86.3px,61.1px)}4.413%{transform:translate(90.4px,51.1px)}4.804%{transform:translate(93.2px,44.2px)}4.972%{transform:translate(94.4px,42.4px)}5.14%{transform:translate(95.8px,44.9px)}5.419%{transform:translate(98.4px,51.9px)}5.81%{transform:translate(103.2px,65.3px)}6.369%{transform:translate(111.4px,88.3px)}6.927%{transform:translate(117.7px,111.5px)}7.207%{transform:translate(121.2px,121.1px)}7.542%{transform:translate(125.2px,130.1px)}7.821%{transform:translate(127.5px,135.1px)}7.933%{transform:translate(128.5px,136.1px)}8.101%{transform:translate(129.8px,133.7px)}8.38%{transform:translate(132.2px,126.5px)}8.603%{transform:translate(135.1px,118.9px)}8.771%{transform:translate(138.4px,112.9px)}9.441%{transform:translate(146.9px,85.5px)}9.777%{transform:translate(151.2px,74.5px)}10.112%{transform:translate(155.2px,66.4px)}10.447%{transform:translate(158.4px,61px)}10.838%{transform:translate(160.2px,57.6px)}11.453%{transform:translate(160.5px,57px)}11.899%{transform:translate(160.7px,57px)}11.955%{transform:translate(167.6px,57.2px)}12.011%{transform:translate(176.5px,60.1px)}12.067%{transform:translate(178.5px,61px)}12.737%{transform:translate(178.4px,61.3px)}13.073%{transform:translate(177.9px,64.5px)}13.352%{transform:translate(176.4px,69.5px)}13.687%{transform:translate(173.8px,78px)}14.19%{transform:translate(170.7px,95.1px)}14.693%{transform:translate(168.5px,112.7px)}14.972%{transform:translate(167.7px,120.2px)}15.196%{transform:translate(167.4px,124px)}15.978%{transform:translate(167.4px,124px)}16.034%{transform:translate(167.3px,123.4px)}16.089%{transform:translate(166.9px,121.8px)}16.145%{transform:translate(166.2px,118.8px)}16.201%{transform:translate(165.3px,114.3px)}16.257%{transform:translate(164.3px,107.9px)}16.313%{transform:translate(163.5px,99.5px)}16.369%{transform:translate(163.3px,89.7px)}16.425%{transform:translate(164.1px,79.2px)}16.48%{transform:translate(165.8px,69.2px)}16.536%{transform:translate(167.9px,60.5px)}16.592%{transform:translate(170.3px,53.5px)}16.648%{transform:translate(172.4px,47.9px)}16.704%{transform:translate(174.3px,43.7px)}16.76%{transform:translate(175.9px,40.6px)}16.872%{transform:translate(177.8px,36.8px)}16.983%{transform:translate(178.5px,35.5px)}17.598%{transform:translate(178.7px,35.2px)}18.268%{transform:translate(182.3px,30.9px)}18.939%{transform:translate(183.5px,29.5px)}19.944%{transform:translate(183.6px,29.6px)}20.056%{transform:translate(185.5px,31.5px)}20.112%{transform:translate(187.5px,33.5px)}20.168%{transform:translate(190.3px,36.3px)}20.223%{transform:translate(193.9px,40.2px)}20.279%{transform:translate(198.2px,45.3px)}20.335%{transform:translate(203.1px,51.8px)}20.391%{transform:translate(208.5px,59.5px)}20.503%{transform:translate(218.3px,77.7px)}20.559%{transform:translate(222.1px,87px)}20.615%{transform:translate(225.1px,95.7px)}20.67%{transform:translate(227.2px,103.5px)}20.726%{transform:translate(228.7px,110.3px)}20.782%{transform:translate(229.8px,116px)}20.838%{transform:translate(230.5px,120.8px)}20.95%{transform:translate(231.2px,127.8px)}21.061%{transform:translate(231.5px,132px)}21.173%{transform:translate(231.7px,134px)}21.955%{transform:translate(232.1px,134.2px)}22.402%{transform:translate(235.5px,133.5px)}22.793%{transform:translate(241px,131.7px)}23.184%{transform:translate(248.5px,127.8px)}23.52%{transform:translate(256.5px,122.7px)}23.799%{transform:translate(263.4px,116.3px)}24.078%{transform:translate(268.9px,107.1px)}24.302%{transform:translate(271.3px,98px)}24.525%{transform:translate(271.7px,87.8px)}24.749%{transform:translate(267.8px,77.6px)}24.972%{transform:translate(260.9px,68.4px)}25.084%{transform:translate(256.1px,65.1px)}25.307%{transform:translate(244.4px,61.9px)}25.587%{transform:translate(228.9px,60.9px)}25.866%{transform:translate(213.5px,63.3px)}26.089%{transform:translate(201.9px,67.3px)}26.257%{transform:translate(195.2px,73.6px)}26.48%{transform:translate(188.9px,83.6px)}26.648%{transform:translate(186.2px,91.7px)}26.816%{transform:translate(185.6px,99.9px)}26.983%{transform:translate(187.3px,107.6px)}27.263%{transform:translate(193.6px,118.2px)}27.43%{transform:translate(198.4px,123px)}27.765%{transform:translate(208.9px,129.2px)}28.045%{transform:translate(216.7px,132.9px)}28.38%{transform:translate(225.2px,134.4px)}28.603%{transform:translate(229.8px,134.3px)}28.659%{transform:translate(230.3px,133.7px)}28.939%{transform:translate(227.1px,131px)}29.05%{transform:translate(227.1px,130.1px)}29.385%{transform:translate(226.8px,134.2px)}29.665%{transform:translate(225.5px,140.2px)}30.112%{transform:translate(222.5px,153.9px)}30.726%{transform:translate(215.4px,172.6px)}31.117%{transform:translate(212.5px,181.9px)}31.508%{transform:translate(210.4px,188.1px)}31.844%{transform:translate(208.8px,190.8px)}32.514%{transform:translate(206.8px,191.8px)}32.849%{transform:translate(203px,192.7px)}33.184%{transform:translate(196.1px,193.6px)}33.855%{transform:translate(178.5px,194.6px)}34.246%{transform:translate(171px,194.6px)}34.637%{transform:translate(166.9px,194.6px)}35.028%{transform:translate(165.7px,194.6px)}35.251%{transform:translate(167.7px,194.6px)}35.475%{transform:translate(172.7px,194.6px)}35.698%{transform:translate(181px,194.6px)}35.922%{transform:translate(192.5px,194px)}36.201%{transform:translate(209.3px,191.4px)}36.425%{transform:translate(222.3px,193.6px)}36.648%{transform:translate(233.5px,194.1px)}36.872%{transform:translate(242px,194.1px)}37.151%{transform:translate(249.2px,194px)}37.43%{transform:translate(253.1px,194px)}37.765%{transform:translate(254.5px,194px)}38.603%{transform:translate(254.5px,193.6px)}38.715%{transform:translate(254.6px,191.5px)}38.827%{transform:translate(254.8px,187.2px)}38.939%{transform:translate(255.3px,180.4px)}39.05%{transform:translate(256.1px,170.5px)}39.162%{transform:translate(257.7px,157.4px)}39.274%{transform:translate(260.4px,141px)}39.385%{transform:translate(264.5px,122.2px)}39.553%{transform:translate(273px,93px)}39.665%{transform:translate(279.6px,75.4px)}39.777%{transform:translate(286.1px,60.3px)}39.888%{transform:translate(292.1px,48px)}40%{transform:translate(297.3px,38.2px)}40.112%{transform:translate(301.6px,30.5px)}40.223%{transform:translate(305.1px,24.7px)}40.391%{transform:translate(308.7px,18.8px)}40.559%{transform:translate(310.8px,15.6px)}40.726%{transform:translate(311.5px,14.5px)}41.453%{transform:translate(311.5px,15px)}41.788%{transform:translate(311.8px,18.5px)}42.067%{transform:translate(312px,24px)}42.402%{transform:translate(308.8px,33.1px)}42.737%{transform:translate(304.4px,45.1px)}43.184%{transform:translate(297.6px,64.7px)}43.855%{transform:translate(288.1px,97px)}44.19%{transform:translate(285.4px,111.7px)}44.358%{transform:translate(284.7px,118.1px)}44.525%{transform:translate(286.9px,123.2px)}44.693%{transform:translate(285.6px,127.8px)}45.028%{transform:translate(282.6px,134.3px)}45.14%{transform:translate(281.9px,135.8px)}45.251%{transform:translate(282.4px,134.7px)}45.531%{transform:translate(285.2px,128.7px)}45.698%{transform:translate(287.2px,123.7px)}45.81%{transform:translate(290.7px,121.9px)}46.034%{transform:translate(299.2px,118.1px)}46.313%{transform:translate(307.3px,108.2px)}46.425%{transform:translate(310.8px,104.2px)}46.648%{transform:translate(320.4px,100.3px)}46.704%{transform:translate(322.9px,100.6px)}46.816%{transform:translate(326.9px,103.5px)}47.039%{transform:translate(329.9px,112.3px)}47.43%{transform:translate(333.4px,125.7px)}47.598%{transform:translate(335.9px,129.7px)}47.709%{transform:translate(338.5px,130.8px)}48.045%{transform:translate(345.3px,129.9px)}48.436%{transform:translate(350px,129.7px)}48.827%{transform:translate(351.6px,129.6px)}49.665%{transform:translate(351.6px,129.5px)}49.721%{transform:translate(351.4px,128.5px)}49.777%{transform:translate(351.2px,126.5px)}49.832%{transform:translate(350.7px,123.3px)}49.888%{transform:translate(350.3px,118.7px)}49.944%{transform:translate(349.9px,112.4px)}50%{transform:translate(349.8px,104.3px)}50.056%{transform:translate(350.3px,94.9px)}50.168%{transform:translate(353.9px,74.4px)}50.223%{transform:translate(356.8px,65.2px)}50.279%{transform:translate(359.9px,57.3px)}50.335%{transform:translate(362.8px,50.8px)}50.391%{transform:translate(365.5px,45.6px)}50.447%{transform:translate(367.8px,41.5px)}50.503%{transform:translate(369.6px,38.4px)}50.615%{transform:translate(372.2px,34.4px)}50.726%{transform:translate(373.4px,32.7px)}51.453%{transform:translate(373.6px,32.9px)}51.732%{transform:translate(373.9px,35.7px)}51.955%{transform:translate(372.7px,39.5px)}52.179%{transform:translate(370.9px,44.9px)}52.514%{transform:translate(370px,56.3px)}52.626%{transform:translate(368.6px,60.5px)}52.793%{transform:translate(364.7px,66.7px)}53.24%{transform:translate(362.2px,88.6px)}53.855%{transform:translate(357.5px,120.3px)}54.022%{transform:translate(356.4px,128.1px)}54.302%{transform:translate(357.4px,139.5px)}54.581%{transform:translate(358px,147.9px)}54.693%{transform:translate(358.1px,150px)}55.475%{transform:translate(358.1px,150px)}55.531%{transform:translate(358px,149.2px)}55.587%{transform:translate(357.9px,147.3px)}55.642%{transform:translate(357.7px,143.7px)}55.698%{transform:translate(357.1px,138.4px)}55.754%{transform:translate(356px,131px)}55.81%{transform:translate(353.8px,121.9px)}55.866%{transform:translate(350.3px,112.1px)}55.922%{transform:translate(346.1px,102.7px)}55.978%{transform:translate(341.4px,94.7px)}56.034%{transform:translate(337.1px,88.5px)}56.089%{transform:translate(333.5px,83.8px)}56.145%{transform:translate(330.5px,80.3px)}56.201%{transform:translate(328.3px,77.9px)}56.313%{transform:translate(325.6px,75.2px)}56.48%{transform:translate(325px,74.5px)}57.039%{transform:translate(325.3px,74.5px)}57.263%{transform:translate(327.9px,74.1px)}57.43%{transform:translate(331.8px,73.1px)}57.598%{transform:translate(337.6px,71px)}57.765%{transform:translate(345.9px,69px)}57.933%{transform:translate(356.9px,67.9px)}57.989%{transform:translate(361.1px,67.5px)}58.045%{transform:translate(365.1px,65.9px)}58.101%{transform:translate(367.7px,62px)}58.156%{transform:translate(371.6px,60.4px)}58.268%{transform:translate(381.6px,60.1px)}58.547%{transform:translate(406.3px,55.9px)}58.771%{transform:translate(423.3px,52.6px)}58.939%{transform:translate(433.8px,50.7px)}59.162%{transform:translate(444.6px,48.8px)}59.385%{transform:translate(452.1px,47.7px)}59.609%{transform:translate(456.9px,47.4px)}59.888%{transform:translate(459.7px,47px)}60.838%{transform:translate(460.3px,47.2px)}60.894%{transform:translate(462.7px,48.7px)}60.95%{transform:translate(468.1px,52.3px)}61.006%{transform:translate(475.7px,59.2px)}61.061%{transform:translate(481.9px,67.4px)}61.117%{transform:translate(485.3px,73.8px)}61.173%{transform:translate(486.9px,77.8px)}61.229%{transform:translate(487.7px,79.8px)}61.397%{transform:translate(487.9px,80.4px)}62.011%{transform:translate(487.5px,80.2px)}62.458%{transform:translate(484.2px,78.5px)}62.793%{transform:translate(479.3px,77px)}63.128%{transform:translate(471.9px,78.1px)}63.464%{transform:translate(462.5px,80.8px)}63.743%{transform:translate(454px,86.4px)}64.078%{transform:translate(443.4px,96px)}64.358%{transform:translate(434.8px,106.8px)}64.581%{transform:translate(428.9px,117.2px)}64.86%{transform:translate(425.6px,132.8px)}64.972%{transform:translate(425.8px,139.3px)}65.028%{transform:translate(427.5px,142.2px)}65.084%{transform:translate(430.2px,144.1px)}65.14%{transform:translate(433.5px,144.6px)}65.419%{transform:translate(450.1px,141.2px)}65.587%{transform:translate(459px,136.4px)}65.81%{transform:translate(469.3px,128.2px)}66.089%{transform:translate(479.5px,116.1px)}66.313%{transform:translate(485.4px,105.9px)}66.592%{transform:translate(488.2px,92.5px)}66.816%{transform:translate(489.3px,82.6px)}66.872%{transform:translate(490.4px,80.6px)}67.207%{transform:translate(502.3px,75.9px)}67.598%{transform:translate(514.2px,72.4px)}67.821%{transform:translate(519.4px,70px)}68.156%{transform:translate(523.5px,64.2px)}68.603%{transform:translate(529.6px,61.4px)}69.05%{transform:translate(532.3px,58.6px)}69.553%{transform:translate(533px,57.5px)}69.832%{transform:translate(532px,59.1px)}70.112%{transform:translate(528.5px,62.1px)}70.335%{transform:translate(523.4px,64.3px)}70.559%{transform:translate(519.6px,70.5px)}70.95%{transform:translate(517.4px,86.4px)}71.508%{transform:translate(511px,111px)}71.844%{transform:translate(509.2px,124px)}72.123%{transform:translate(508.1px,132.3px)}72.402%{transform:translate(506.4px,137.6px)}72.514%{transform:translate(506.4px,138.9px)}72.737%{transform:translate(509.9px,136.8px)}73.073%{transform:translate(517.5px,131px)}73.408%{transform:translate(528.1px,125.2px)}73.911%{transform:translate(541.3px,110.5px)}74.19%{transform:translate(550.4px,106.2px)}74.302%{transform:translate(552.3px,103.2px)}74.637%{transform:translate(554.8px,94.5px)}74.916%{transform:translate(556.1px,89.9px)}74.972%{transform:translate(556.3px,89.5px)}75.14%{transform:translate(556.6px,92.5px)}75.363%{transform:translate(556.9px,99.4px)}75.754%{transform:translate(557.9px,115.4px)}75.922%{transform:translate(560px,121.8px)}76.089%{transform:translate(564.4px,125.5px)}76.313%{transform:translate(570.4px,127.5px)}76.592%{transform:translate(575.5px,128.3px)}76.872%{transform:translate(577.4px,129.7px)}77.821%{transform:translate(577.6px,129.7px)}77.877%{transform:translate(577.5px,128.8px)}77.933%{transform:translate(577.2px,127px)}77.989%{transform:translate(576.8px,124.1px)}78.045%{transform:translate(576.4px,120px)}78.101%{transform:translate(576px,114.5px)}78.156%{transform:translate(575.8px,107.5px)}78.212%{transform:translate(576px,99px)}78.268%{transform:translate(576.7px,89.3px)}78.38%{transform:translate(580.5px,68.9px)}78.436%{transform:translate(583.4px,59.6px)}78.492%{transform:translate(586.5px,51.4px)}78.547%{transform:translate(589.5px,44.5px)}78.603%{transform:translate(592.4px,38.8px)}78.659%{transform:translate(595px,34.2px)}78.771%{transform:translate(598.9px,27.6px)}78.883%{transform:translate(601.5px,23.7px)}78.994%{transform:translate(602.8px,21.9px)}79.721%{transform:translate(602.9px,21.8px)}80%{transform:translate(602.5px,24.7px)}80.279%{transform:translate(600px,29.9px)}80.559%{transform:translate(596.4px,37.7px)}80.67%{transform:translate(594.9px,41.5px)}81.006%{transform:translate(593.8px,56.4px)}81.117%{transform:translate(590.2px,60.6px)}81.453%{transform:translate(587.9px,78.6px)}82.067%{transform:translate(581.4px,113.7px)}82.291%{transform:translate(577.8px,125.1px)}82.346%{transform:translate(576.5px,127.5px)}82.458%{transform:translate(578.6px,132.2px)}82.682%{transform:translate(578.9px,141px)}82.905%{transform:translate(578.8px,147.3px)}83.073%{transform:translate(578.8px,148px)}83.743%{transform:translate(578.8px,147.9px)}83.799%{transform:translate(578.8px,146.9px)}83.855%{transform:translate(578.9px,144.7px)}83.911%{transform:translate(579px,140.9px)}83.966%{transform:translate(578.8px,135.3px)}84.022%{transform:translate(578.2px,127.7px)}84.078%{transform:translate(576.8px,118.4px)}84.134%{transform:translate(574.2px,108.2px)}84.19%{transform:translate(570.7px,98.5px)}84.246%{transform:translate(566.9px,90.1px)}84.302%{transform:translate(563.1px,83.4px)}84.358%{transform:translate(559.8px,78.3px)}84.413%{transform:translate(557px,74.5px)}84.469%{transform:translate(554.9px,71.7px)}84.581%{transform:translate(552.3px,68.5px)}84.693%{transform:translate(551.5px,67.5px)}85.587%{transform:translate(552.2px,67.5px)}86.313%{transform:translate(555.8px,67.3px)}86.927%{transform:translate(561.3px,65.6px)}87.542%{transform:translate(569.4px,63.3px)}88.101%{transform:translate(579.8px,62.3px)}88.492%{transform:translate(588.8px,61.3px)}88.771%{transform:translate(595.1px,57.1px)}89.218%{transform:translate(609.2px,55.2px)}89.609%{transform:translate(624.1px,52.3px)}90%{transform:translate(642px,48.6px)}90.279%{transform:translate(657.2px,45.5px)}90.559%{transform:translate(675.4px,41.8px)}90.782%{transform:translate(692.9px,38.2px)}90.95%{transform:translate(708.8px,35.5px)}91.061%{transform:translate(721.5px,34px)}91.788%{transform:translate(732.1px,32.2px)}92.626%{transform:translate(740.7px,30.8px)}93.687%{transform:translate(747.8px,29.6px)}95.14%{transform:translate(753.6px,28.7px)}97.207%{transform:translate(757.6px,28px)}100%{transform:translate(759px,27.8px)}}
@keyframes sp-nib-lift{0%{opacity:0;transform:scale(0.6)}2.623%{opacity:1;transform:scale(1)}13.156%{opacity:1;transform:scale(1)}13.845%{opacity:0.45;transform:scale(0.82)}14.534%{opacity:1;transform:scale(1)}17.152%{opacity:1;transform:scale(1)}18.256%{opacity:0.45;transform:scale(0.82)}19.36%{opacity:1;transform:scale(1)}20.999%{opacity:1;transform:scale(1)}22.201%{opacity:0.32;transform:scale(0.74)}22.311%{opacity:0.32;transform:scale(0.74)}23.513%{opacity:1;transform:scale(1)}39.215%{opacity:1;transform:scale(1)}40.417%{opacity:0.32;transform:scale(0.74)}41.383%{opacity:0.32;transform:scale(0.74)}42.585%{opacity:1;transform:scale(1)}50.077%{opacity:1;transform:scale(1)}51.241%{opacity:0.45;transform:scale(0.82)}52.406%{opacity:1;transform:scale(1)}55.781%{opacity:1;transform:scale(1)}56.845%{opacity:0.45;transform:scale(0.82)}57.91%{opacity:1;transform:scale(1)}61.006%{opacity:1;transform:scale(1)}61.841%{opacity:0.45;transform:scale(0.82)}62.677%{opacity:1;transform:scale(1)}77.612%{opacity:1;transform:scale(1)}78.846%{opacity:0.45;transform:scale(0.82)}80.079%{opacity:1;transform:scale(1)}83.418%{opacity:1;transform:scale(1)}84.497%{opacity:0.45;transform:scale(0.82)}85.577%{opacity:1;transform:scale(1)}90.929%{opacity:1;transform:scale(1)}93.443%{opacity:0.85;transform:scale(1.25)}100%{opacity:0;transform:scale(0.5)}}

/* finale: ink flecks thrown off the swash tip, and a small glint where the nib leaves */
.sp-fleck,.sp-glint{opacity:0}
.splash.is-playing .sp-fleck1{animation:sp-fleck1 440ms cubic-bezier(.12,.7,.3,1) 1732ms both}@keyframes sp-fleck1{0%{opacity:0;transform:scale(.3)}12%{opacity:1;transform:translate(2.69px,-0.98px)}65%{opacity:.85}100%{opacity:0;transform:translate(26.88px,-9.83px) scale(.55)}}.splash.is-playing .sp-fleck2{animation:sp-fleck2 420ms cubic-bezier(.12,.7,.3,1) 1754ms both}@keyframes sp-fleck2{0%{opacity:0;transform:scale(.3)}12%{opacity:1;transform:translate(4.39px,0.09px)}65%{opacity:.85}100%{opacity:0;transform:translate(43.92px,0.91px) scale(.55)}}.splash.is-playing .sp-fleck3{animation:sp-fleck3 380ms cubic-bezier(.12,.7,.3,1) 1772ms both}@keyframes sp-fleck3{0%{opacity:0;transform:scale(.3)}12%{opacity:1;transform:translate(2.03px,0.88px)}65%{opacity:.85}100%{opacity:0;transform:translate(20.32px,8.8px) scale(.55)}}
.splash.is-playing .sp-glint{animation:sp-glint 340ms cubic-bezier(.3,.6,.4,1) 1770ms both}
@keyframes sp-glint{0%{opacity:0;transform:scale(.2) rotate(-25deg)}30%{opacity:1;transform:scale(1) rotate(0)}100%{opacity:0;transform:scale(.35) rotate(18deg)}}

.splash.is-playing .sp-tag{animation:sp-tag 460ms cubic-bezier(.2,.7,.2,1) 1560ms both}
@keyframes sp-tag{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* no JS: the settled mark fades in on its own (distinct keyframe names, so a late .is-playing restarts cleanly) */
.splash:not(.is-playing) .sp-f{visibility:visible}
.splash:not(.is-playing) .sp-fin{animation:sp-nojs .5s ease 1.2s both}
.splash:not(.is-playing) .sp-tag{animation:sp-nojs .5s ease 1.35s both}
@keyframes sp-nojs{from{opacity:0}to{opacity:1}}

@media (prefers-reduced-motion:reduce){
  .splash .sp-anim{display:none}
  .splash.is-playing .sp-f{visibility:visible;animation:none}
  .splash.is-playing .sp-fin{animation:sp-fade .45s ease both}
  .splash.is-playing .sp-tag{animation:sp-fade .45s ease .15s both}
  @keyframes sp-fade{from{opacity:0}to{opacity:1}}
}

/* ---------- Groups: member faces, bar hops, who's going (illustrated demo people) ---------- */
img.avatar-img { display: block; flex: none; width: var(--size); height: var(--size); border-radius: 50%; object-fit: cover; background: var(--surface); }
.avatars img.avatar-img, .avatars .avatar { margin-left: -8px; box-shadow: 0 0 0 2px var(--surface-2); }
.avatars > :first-child { margin-left: 0; }
.avatar-more { display: inline-grid; place-items: center; font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 13px; font-weight: 800; color: var(--ink); background: var(--fill-2); }
button.group-spots { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.group-spots .gs-text { display: grid; gap: 1px; }
.group-spots .gs-text .num { font-size: var(--t-sm); font-weight: 700; color: var(--ink); }
.group-spots .gs-text small { font-size: var(--t-xs); color: var(--ink-3); }
button.group-spots:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 8px; }
button.group-spots:active .avatars { transform: scale(.97); }

.hop { display: grid; gap: 8px; }
.hop-label { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-2xs); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.hop-list { display: grid; gap: 0; }
.hop-stop { position: relative; display: flex; align-items: center; gap: 10px; min-height: 46px; padding-left: 20px; }
.hop-stop::before { content: ""; position: absolute; left: 5px; top: 0; bottom: 0; width: 2px; background: var(--line-strong); }
.hop-stop:first-child::before { top: 50%; }
.hop-stop:last-child::before { bottom: 50%; }
.hop-dot { position: absolute; left: 1px; top: 50%; width: 10px; height: 10px; margin-top: -5px; border-radius: 50%; background: var(--bg); box-shadow: inset 0 0 0 2px var(--ink-3); }
.hop-stop.is-past .hop-dot { background: var(--ink-3); box-shadow: none; }
.hop-stop.is-now .hop-dot { background: var(--ink); box-shadow: 0 0 0 3px rgb(255 255 255 / .18); }
.hop-stop .bar-logo { width: 28px; height: 28px; }
.hop-bar { flex: 1; min-width: 0; display: grid; }
.hop-bar b { font-size: var(--t-sm); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hop-bar small { font-size: var(--t-xs); color: var(--ink-3); font-family: var(--font-num); font-stretch: var(--w-cond); font-weight: 700; letter-spacing: .01em; }
.hop-stop.is-past .hop-bar b { color: var(--ink-3); }
.hop-now { flex: none; border-color: var(--ink); color: var(--ink); }

.members-sub { margin: 2px 0 10px; font-size: var(--t-sm); color: var(--ink-2); }
.member-list { display: grid; }
.member-list li { display: flex; align-items: center; gap: 12px; min-height: 60px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.member-list li > span { flex: 1; min-width: 0; display: grid; gap: 5px; }
.member-list b { font-size: var(--t-md); font-weight: 700; }
.member-tags { display: flex; flex-wrap: wrap; gap: 4px; }

.hop-switch { margin-top: 2px; }
.hop-edit { border: 0; padding: 0; margin: 0; min-width: 0; display: grid; gap: 8px; }
.hop-edit legend { margin-bottom: 6px; }
.hop-edit-list { display: grid; gap: 8px; counter-reset: stop 1; }
.hop-edit-row { display: grid; grid-template-columns: minmax(0, 1fr) 122px 44px; gap: 6px; align-items: center; }
.hop-edit-row .select select { width: 100%; min-height: 46px; }
.hop-edit .btn-sm { justify-self: start; }

/* ---------- Community ideas (Ship F): status by border, icon and words, never colour alone ---------- */
.ev-views { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.ev-views button { padding: 0 4px; }

.ideas-head { display: grid; gap: 12px; margin-top: 14px; }

.idea-card { border-radius: var(--r-xl); background: var(--surface); border: 1px dashed var(--line-input); }
.idea-card[data-status="approved"] { border-style: solid; border-color: var(--line-strong); }
.idea-card[data-status="declined"] { border: 1px solid var(--line); }
.idea-link { display: grid; gap: 6px; padding: 14px 16px 6px; color: inherit; min-width: 0; text-decoration: none; }
.idea-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
.idea-status { display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 8px; border-radius: var(--r-xs); border: 1px dashed var(--ink-2); font-size: var(--t-2xs); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink); }
.idea-status .ic { width: 13px; height: 13px; }
.idea-card[data-status="approved"] .idea-status { border-style: solid; border-color: var(--ink); }
.idea-card[data-status="declined"] .idea-status { border-style: solid; border-color: var(--line-input); color: var(--ink-2); }
.idea-pitch { font-size: var(--t-sm); line-height: 1.45; color: var(--ink-sub); overflow-wrap: anywhere; }
.idea-card .idea-pitch { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.idea-by { display: flex; align-items: center; gap: 8px; font-size: var(--t-xs); color: var(--ink-3); }
.idea-counts { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; font-size: var(--t-xs); color: var(--ink-2); padding-bottom: 6px; }
.idea-counts .num { font-family: var(--font-num); font-stretch: var(--w-cond); font-weight: 800; font-size: 17px; color: var(--ink); }
.idea-card .ev-actions:has(> :only-child) { grid-template-columns: 1fr; }

.night-picks, .theme-picks, .cover-picks { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.night-picks .radio-card span { gap: 0; line-height: 1.2; }
.night-picks small { display: block; font-size: var(--t-2xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: inherit; opacity: .8; }
@media (max-width: 359.98px) { .night-picks, .theme-picks { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.idea-reviews { display: grid; gap: 12px; margin-top: 8px; }
.idea-review { display: grid; gap: 10px; padding: 14px; border-radius: var(--r-md); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); }
.idea-review-title { font-size: var(--t-lg); font-weight: 800; letter-spacing: -.01em; }
.turnout { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 8px; border-block: 1px solid var(--line-strong); padding: 12px 0; }
.turnout-num { font-family: var(--font-num); font-stretch: var(--w-cond); font-weight: 800; font-size: 30px; line-height: 1; }
.turnout-level { display: inline-flex; align-items: center; gap: 8px; font-size: var(--t-2xs); letter-spacing: .08em; text-transform: uppercase; }
.staff-hint { display: flex; gap: 8px; align-items: flex-start; font-size: var(--t-sm); line-height: 1.4; color: var(--ink-2); }
.staff-hint .ic { flex: none; margin-top: 2px; }
.idea-decide { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.idea-decide .btn { min-height: 44px; }

section.ideas { margin-top: 28px; display: grid; gap: 10px; }
.idea-row { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto auto; align-items: center; gap: 12px; padding: 12px 14px; border-radius: var(--r-md); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); color: inherit; text-decoration: none; }
.idea-row .food-ic { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 12px; background: var(--fill-2); }
.idea-row-main { display: grid; gap: 2px; min-width: 0; }
.idea-row-main b { font-size: var(--t-md); overflow-wrap: anywhere; }
.idea-row small { font-size: var(--t-xs); color: var(--ink-3); }
.idea-row > small.num { font-family: var(--font-num); font-stretch: var(--w-cond); font-weight: 800; font-size: 15px; color: var(--ink-2); white-space: nowrap; }
.idea-row .ic:last-child { width: 18px; height: 18px; color: var(--ink-3); }
@media (max-width: 359.98px) { .idea-row { grid-template-columns: 40px minmax(0, 1fr) auto; } .idea-row > small.num { display: none; } }
.ev-views button { white-space: nowrap; gap: 5px; }
.ev-views button .num { font-size: 13px; opacity: .75; }
.page-sub > .ic:first-child { display: inline-block; vertical-align: -2px; margin-right: 2px; }

/* ---------- Bar card v3 (team ask, 2026-10-17): walk time top right, promo bottom left, line glow bottom right ---------- */
.card-dist { gap: 4px; }
.card-dist .ic { width: 13px; height: 13px; }
.card-dist b { font-weight: 800; }
.card-dist .cd-mi { font-weight: 600; color: var(--ink-2); }
.card-dist .cd-mi::before { content: "·"; margin: 0 3px 0 1px; color: var(--ink-3); }
@media (max-width: 359.98px) { .card-dist .cd-mi { display: none; } }

.card-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 58px; }
.deal-slot { display: grid; gap: 4px; min-width: 0; justify-items: start; }
.promo-badge { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; height: 24px; padding: 0 8px; border-radius: var(--r-pill); background: var(--accent); color: var(--accent-ink); font-size: 12.5px; font-weight: 800; letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.promo-badge .ic { flex: none; width: 12px; height: 12px; stroke-width: 2.4; }
.promo-item { max-width: 100%; font-size: 12px; font-weight: 600; line-height: 1.2; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.promo-next { font-size: 12px; font-weight: 600; color: var(--ink-3); }

.line-badge { flex: none; display: flex; align-items: center; gap: 8px; }
.lb-dot { position: relative; width: 14px; height: 14px; border-radius: 50%; background: var(--ink-4); }
.line-badge[data-level="quiet"] { --glow: rgb(95 227 161 / .55); }
.line-badge[data-level="lively"] { --glow: rgb(255 201 77 / .55); }
.line-badge[data-level="packed"] { --glow: rgb(255 107 94 / .6); }
.line-badge[data-level="quiet"] .lb-dot { background: var(--quiet); }
.line-badge[data-level="lively"] .lb-dot { background: var(--lively); }
.line-badge[data-level="packed"] .lb-dot { background: var(--packed); }
.line-badge:is([data-level="quiet"], [data-level="lively"], [data-level="packed"]) .lb-dot::after { content: ""; position: absolute; inset: -8px; border-radius: 50%; background: radial-gradient(closest-side, var(--glow), transparent); opacity: .85; pointer-events: none; }
.line-badge[data-state="paused"] .lb-dot { background: transparent; box-shadow: inset 0 0 0 2.5px var(--lively); }
.line-badge[data-state="closed"] .lb-dot, .line-badge[data-state="none"] .lb-dot { background: #3A3A3A; box-shadow: none; }
.line-badge[data-state="none"] .lb-dot { background: transparent; box-shadow: inset 0 0 0 2px #5A5A5A; }
.lb-text { display: grid; justify-items: end; line-height: 1; }
.lb-num { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 26px; font-weight: 800; letter-spacing: -.01em; }
.lb-word { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-2); margin-top: 2px; }
.line-badge[data-state="closed"] .lb-word, .line-badge[data-state="none"] .lb-word { color: var(--ink-3); }
.line-badge:not(:has(.lb-num)) .lb-word { font-size: 13px; text-transform: none; letter-spacing: 0; margin: 0; color: var(--ink); }
.line-badge[data-state="closed"]:not(:has(.lb-num)) .lb-word { color: var(--ink-3); }
.bar-card:has(.line-badge[data-state="closed"]) .bar-photo > img { filter: grayscale(1) brightness(.55); }
.bar-card:has(.line-badge[data-state="closed"]) .bar-name { color: var(--ink-2); }
/* tick() adds .is-new only when a card's line turns packed; renders (sort, refresh, search) never replay it. */
@media (prefers-reduced-motion: no-preference) {
  .line-badge.is-new[data-level="packed"] .lb-dot::after { animation: lb-glow var(--d-loop-pulse) var(--ease-in-out) var(--n-loop-pulse); }
  @keyframes lb-glow { 50% { opacity: 1; scale: 1.25; } }
}
.group-dest .line-badge .lb-num { font-size: 20px; }

/* ---------- Deals right now (delivery-app style row) and promo details on the bar page ---------- */
.deals-rail { margin: 16px calc(-1 * var(--gutter)) 4px; }
.rail-head { display: flex; align-items: center; gap: 10px; padding: 0 var(--gutter); }
.rail-head h2 { font-size: var(--t-lg); font-weight: 800; letter-spacing: -.015em; }
.rail-all { margin-left: auto; display: inline-flex; align-items: center; gap: 2px; min-height: 44px; padding: 0; border: 0; background: none; color: var(--ink-2); font: inherit; font-size: var(--t-sm); font-weight: 700; cursor: pointer; }
.rail-list { display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; padding: 4px var(--gutter) 8px; scrollbar-width: none; overscroll-behavior-x: contain; }
.rail-list::-webkit-scrollbar { display: none; }
.rail-list > li { flex: none; width: 196px; scroll-snap-align: start; }
.rail-tile { display: grid; gap: 4px; color: inherit; text-decoration: none; }
.rail-photo { position: relative; display: block; height: 116px; border-radius: var(--r-md); overflow: hidden; background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); }
.rail-photo > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.rail-photo .promo-badge { position: absolute; left: 8px; bottom: 8px; box-shadow: 0 2px 10px rgb(0 0 0 / .45); }
.rail-name { font-size: var(--t-sm); font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail-item { font-size: var(--t-xs); color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail-tile:focus-visible .rail-photo { outline: 2px solid var(--focus); outline-offset: 2px; }

.promo-badge.is-lg { height: 30px; padding: 0 12px; font-size: 15px; }
.promo-badge.is-lg .ic { width: 14px; height: 14px; }
/* One column: the bar page ticket must not inherit .deal-row's 36px / 1fr / 104px tracks (it renders as "deal-row promo-row"). */
.promo-row { display: grid; grid-template-columns: minmax(0, 1fr); min-height: 0; gap: 8px; padding: 14px; border-radius: var(--r-md); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); }
.promo-row[data-state="ended"] { opacity: 1; }
.promo-row[data-state="ended"] .promo-badge { background: var(--fill-2); color: var(--ink-2); }
.promo-row.is-target { box-shadow: inset 0 0 0 2px var(--ink); }
.promo-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.deal-state-word { font-size: var(--t-2xs); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
.promo-row[data-state="live"] .deal-state-word { color: var(--quiet); }
.promo-on { display: grid; gap: 2px; }
.promo-on b { font-size: var(--t-lg); font-weight: 800; letter-spacing: -.01em; }
.promo-row .deal-title { font-size: var(--t-sm); color: var(--ink-2); font-weight: 600; }
.promo-row .deal-meta { font-size: var(--t-xs); color: var(--ink-3); }
.promo-row .deal-left { display: block; height: 4px; border-radius: 2px; background: var(--line-strong); overflow: hidden; }
.promo-row .deal-left i { transition: transform var(--d-fill) var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .promo-row .deal-left i { transition: none; } }
.promo-terms { display: flex; gap: 6px; align-items: flex-start; font-size: var(--t-xs); line-height: 1.4; color: var(--ink-3); }
.promo-terms .ic { flex: none; margin-top: 1px; }
.deals-rail ul.rail-list { padding-inline: var(--gutter); scroll-padding-inline: var(--gutter); }
.card-foot .promo-badge { height: 22px; padding: 0 9px; font-size: 12.5px; }
.line-badge { gap: 7px; }
.lb-dot { width: 12px; height: 12px; }
.lb-word { font-size: 10px; }

/* ---------- Member profiles (demo people) and brand-tinted bar cards ---------- */
button.member-row { width: 100%; display: flex; align-items: center; gap: 12px; min-height: 64px; padding: 8px 0; border: 0; border-bottom: 1px solid var(--line); background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.member-list li { display: block; min-height: 0; padding: 0; border: 0; }
.member-main { flex: 1; min-width: 0; display: grid; gap: 4px; }
.member-main b { font-size: var(--t-md); font-weight: 700; }
.member-handle { font-size: var(--t-xs); color: var(--ink-2); }
button.member-row > .ic:last-child { flex: none; color: var(--ink-3); }
button.member-row:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; border-radius: 8px; }
.sheet-back { margin-right: 2px; }
.mp-head { display: flex; align-items: center; gap: 16px; }
.mp-id { display: grid; gap: 4px; min-width: 0; }
.mp-name { font-family: var(--font-display); font-size: 26px; font-weight: 800; letter-spacing: -.02em; line-height: 1.1; overflow-wrap: anywhere; }
.mp-facts { margin-top: 16px; }
.mp-tags { margin-top: 6px; }
.mp-plan { display: flex; align-items: center; gap: 12px; margin-top: 6px; padding: 12px; border-radius: var(--r-md); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); }
.mp-plan > span:last-child { display: grid; gap: 2px; min-width: 0; }
.mp-plan small { font-size: var(--t-xs); color: var(--ink-2); }
.vip-card.is-tinted { background: linear-gradient(150deg, color-mix(in srgb, var(--tint) 62%, #111) 0%, color-mix(in srgb, var(--tint) 22%, #0d0d0d) 48%, #070707 100%); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tint) 55%, #333); }
.vip-card.is-tinted .vip-brand { color: #fff; }
.sheet-head:has(.sheet-back) { grid-template-columns: 44px minmax(0, 1fr) 44px; padding-left: 8px; }
.sheet-head:has(.sheet-back) .sheet-title { grid-column: 2; }
.sheet-head:has(.sheet-back) .sheet-back { grid-column: 1; }
.sheet-head:has(.sheet-back) .sheet-close { grid-column: 3; }

/* ---------- Review fixes (2026-10-17) ---------- */
.promo-item { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow-wrap: anywhere; }
.card-foot .promo-badge { flex: none; max-width: none; }
.search .clear::before { content: ""; position: absolute; inset: -4px; }
.idea-card .idea-pitch { display: block; -webkit-line-clamp: unset; overflow: visible; }
.mp-facts dd:not(.num) { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; line-height: 1.1; }
.handle { position: relative; }
.handle::before { content: ""; position: absolute; inset: -8px -4px; }
.sheet-title:focus { outline: none; }
.sheet-title:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }

/* ---------- Ship E: door console (photo head count, doors, inputs) ---------- */
.console-lede { margin-top: 10px; font-size: var(--t-md); line-height: 1.4; color: var(--ink); max-width: 46ch; }
.role-group { margin-top: var(--s-4); }
.role-seg { width: 100%; }
.role-group .hint { margin-top: 8px; }
.line-photo h2 { margin-bottom: 10px; }
.story { display: flex; gap: 6px; margin: 0 0 4px; padding: 0; list-style: none; }
.story li { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 32px; padding: 0 8px; border-radius: var(--r-pill); background: var(--surface-2); color: var(--ink-3); font-size: var(--t-sm); font-weight: 600; white-space: nowrap; }
.story li .num { display: inline-grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; box-shadow: inset 0 0 0 1px currentColor; font-size: 11px; font-weight: 700; }
.story li.is-now { background: var(--accent); color: var(--accent-ink); }
.story li.is-done { color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-strong); }
.story li .ic { width: 14px; height: 14px; }
.viewfinder.lp-view { aspect-ratio: 4 / 3; max-height: none; display: block; }
.lp-view > svg, .scene-btn svg { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; display: block; }
.scene-btn { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; padding: 0; border: 0; background: none; cursor: copy; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
.scene-btn:focus-visible { outline: 3px solid var(--focus); outline-offset: -3px; border-radius: inherit; }
.lp-view .vf-tag, .lp-view .vf-retake, .lp-view .beyond-tag { z-index: 2; }
.lp-view .vf-tag, .lp-view .beyond-tag { pointer-events: none; }
.lp-view .vf-tip { top: auto; bottom: 46px; left: 50%; transform: translateX(-50%); }
.beyond-tag { position: absolute; right: 10px; top: 54px; display: inline-flex; align-items: center; height: 26px; padding: 0 10px; border-radius: var(--r-pill); background: var(--glass); color: #fff; font-size: var(--t-xs); font-weight: 700; font-variant-numeric: tabular-nums; }

.count-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 12px; margin-top: 14px; }
.count-row .label { margin: 0; }
.pc-vis { display: block; font-family: var(--font-num); font-size: 40px; line-height: 1; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.count-step { gap: 2px; }
.count-step .icon-btn .num { font-size: 14px; font-weight: 700; }
.line-photo .btn-quiet.btn-block { margin-top: 10px; min-height: 44px; border: 1px solid var(--line-input); justify-content: center; }
.line-photo .btn-quiet[aria-disabled="true"] { opacity: .5; }
.math-strip { margin-top: 14px; padding: 12px 14px; border-radius: var(--r-md); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); display: grid; gap: 4px; }
.ms-main { font-size: var(--t-md); line-height: 1.35; color: var(--ink); overflow-wrap: anywhere; }
.ms-main b { font-weight: 800; }
.ms-sub { font-size: var(--t-xs); line-height: 1.4; color: var(--ink-2); overflow-wrap: anywhere; }
.ms-sub b { color: var(--ink); font-weight: 700; }
.photo-cta { position: sticky; bottom: calc(var(--tabbar-h) + var(--safe-b) + 8px); z-index: 3; margin-top: 14px; }
.photo-cta { padding-top: 12px; background: linear-gradient(180deg, rgb(11 11 11 / 0), var(--surface) 40%); } /* --surface = .panel */
.photo-cta .btn[aria-disabled="true"] { opacity: 1; background: var(--surface-2); border-color: var(--line-strong); color: var(--ink-3); }
.photo-cta .btn { transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out), border-color var(--d-select) var(--ease-out), transform var(--d-press) var(--ease-out); }
[data-route="console"] .toast-region { bottom: calc(var(--tabbar-h) + var(--safe-b) + 84px); }
.door-row { margin: 0 0 14px; padding: 0; border: 0; min-width: 0; }
.door-row legend { margin-bottom: 8px; font-weight: 700; }
.door-row .radio-card span { min-height: 48px; font-size: var(--t-sm); }
.pace-row { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.pace-row > .label { margin: 0; min-width: 40px; }
.pace-seg { flex: 1; min-width: 0; }
.pace-seg label { cursor: pointer; }
.pace-seg input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.pace-seg label:has(input:checked) { background: var(--accent); color: var(--accent-ink); font-weight: 700; }
.pace-seg label:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.door-summary { margin-top: 4px; font-size: var(--t-sm); line-height: 1.4; color: var(--ink-2); }
.door-summary b { color: var(--ink); }
.feed { margin: 4px 0 0; padding: 0; list-style: none; }
.feed li { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 56px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.feed li:last-child { border-bottom: 0; }
.feed-main { display: grid; gap: 2px; min-width: 0; font-size: var(--t-sm); font-weight: 600; overflow-wrap: anywhere; }
.feed-main small { font-size: var(--t-xs); font-weight: 500; color: var(--ink-3); }
.feed-chip { flex: none; display: inline-flex; align-items: center; gap: 4px; height: 26px; padding: 0 9px; border-radius: var(--r-pill); font-size: var(--t-xs); font-weight: 700; white-space: nowrap; background: var(--surface-2); color: var(--ink-2); box-shadow: inset 0 0 0 1px var(--line-strong); }
.feed-chip .ic { width: 13px; height: 13px; }
.feed-chip[data-outcome="sets"] { background: var(--fresh-soft); color: var(--fresh); box-shadow: none; }
.feed-chip[data-outcome="backs"] { color: var(--fresh); }
.feed-chip[data-outcome="against"] { background: var(--aging-soft); color: var(--aging); box-shadow: none; }
@media (prefers-reduced-motion: no-preference) {
  .lp-view .head.is-new .mark { animation: mark-pop 200ms var(--ease-out) both; transform-box: fill-box; transform-origin: center; }
  .lp-view.is-filling .head.is-marked .mark { animation: mark-pop 200ms var(--ease-out) both; animation-delay: calc(max(0, var(--i) - var(--from)) * var(--step)); transform-box: fill-box; transform-origin: center; }
  @keyframes mark-pop { 0% { opacity: 0; scale: .9; } 70% { opacity: 1; scale: 1.03; } 100% { opacity: 1; scale: 1; } }
}

.panel > .section-head { margin: 0 0 12px; }
.panel > .section-head h2 { font-size: 20px; line-height: 26px; font-weight: 700; letter-spacing: normal; margin: 0; }
.console-page .line-photo { scroll-margin-top: calc(var(--topbar-h) + var(--safe-t) + 8px); }

/* ---------- Compact Bars header (team ask, 2026-10-18): sort switch + search + map on one row ---------- */
.search-panel { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; column-gap: 6px; margin-top: 8px; }
.search-panel > .chips { grid-area: 1 / 1; min-width: 0; margin: 0; padding: 0; gap: 6px; }
.search-panel .sort-seg { padding: 2px; }
.search-panel .sort-seg button, .search-panel .seg-ink > span { height: 30px; padding: 0 10px; font-size: 13px; }
.search-panel .sort-seg button::before { inset: -7px 0; }
@media (max-width: 359.98px) { .search-panel { column-gap: 4px; } .search-row { gap: 4px; } .search-panel .sort-seg button, .search-panel .seg-ink > span { padding: 0 6px; font-size: 12.5px; } }
.tool-btn { position: relative; flex: none; width: 34px; height: 34px; display: grid; place-items: center; padding: 0; border-radius: 50%; border: 1px solid var(--line-input); background: var(--surface-2); color: var(--ink); cursor: pointer; }
.tool-btn::before { content: ""; position: absolute; inset: -5px; } /* 44px hit area */
.tool-btn .ic { width: 17px; height: 17px; }
.search-panel .map-btn { width: 34px; height: 34px; }
.search-panel .map-btn::before { inset: -5px; }
.search-panel .search input { height: 34px; }
.search-cancel { position: relative; flex: none; height: 34px; padding: 0 2px 0 6px; border: 0; background: none; color: var(--ink); font: inherit; font-size: var(--t-sm); font-weight: 600; cursor: pointer; }
.search-cancel::before { content: ""; position: absolute; inset: -5px -4px; }
.tool-btn:focus-visible, .search-cancel:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* ---------- Compact Events header (team ask, 2026-10-18) ---------- */
.ev-views { margin-top: 10px; }
.ev-views button { display: inline-flex; align-items: center; justify-content: center; gap: 4px; min-height: 34px; font-size: 13px; }
.ev-views button .num { font-size: 12px; }
.ev-filters { margin-top: 8px; gap: 6px; padding-block: 2px; }
.ev-filters .chip-select select { height: 34px; min-height: 34px; padding: 0 28px 0 12px; font-size: 15px; }
.ev-filters .chip-select > svg { right: 10px; width: 12px; height: 12px; }
a.groups-link { display: flex; align-items: center; gap: 10px; min-height: 44px; margin-top: 8px; padding: 0 2px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); color: var(--ink); font-size: var(--t-sm); font-weight: 600; }
a.groups-link > span { flex: 1; min-width: 0; }
a.groups-link > .ic:first-child { color: var(--ink-2); }
a.groups-link > .ic:last-child { color: var(--ink-3); }
a.groups-link b { font-size: 13px; font-weight: 700; color: var(--ink-2); }
a.groups-link:active { background: var(--surface); }
.ev-list { margin-top: 10px; }
.ev-filters .chip-select select { field-sizing: content; max-width: 150px; text-overflow: ellipsis; }
.topbar .wm-logo { height: 34px; }

/* ---------- Presses (QA plan 2.1): fast in, slow out, kept under reduced motion (all <= 4%) ---------- */
/* Every press transition reads --d-press (tokens.css: --d-press-up, 240ms). A pressed control flips it to --d-press-down,
   so even a quick tap bottoms out in 50ms, and the release (whose after-change style is the rest state) eases back over
   240ms. Descendants inherit it (.tab-inner, .rail-photo, .avatars, a bucket's span). */
:is(.bar-link, .btn, .chip, .act, .hero-btn, .icon-btn, .tool-btn, .poll-opt, .sort-seg button, .segmented button, .segmented label,
  .window-option, .shutter, .bucket, .pts-chip, .back-link, .scan-nearest, .rail-tile, .rail-all, button.group-spots, .map-pin-btn, .tab):active,
.ev-card:has(> .ev-link:active), .idea-card:has(> .idea-link:active) { --d-press: var(--d-press-down); }
/* Presses that were missing. */
.tool-btn { transition: transform var(--d-press) var(--ease-out), background-color var(--d-select) var(--ease-out); }
.tool-btn:active { transform: scale(.96); }
.tool-btn:not([aria-pressed="true"]):active { background: var(--fill-2); }
.rail-photo, .rail-all, .avatars, .ev-card, .idea-card { transition: transform var(--d-press) var(--ease-out); }
.rail-tile:active .rail-photo, .ev-card:has(> .ev-link:active), .idea-card:has(> .idea-link:active) { transform: scale(.98); }
.rail-all:active { transform: scale(.97); }
.segmented label { transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out), transform var(--d-press) var(--ease-out); }
.segmented label:not(:has(input:disabled)):active { transform: scale(.97); }
/* Rows: a visible fill (surface on a sheet's raised plate was invisible). */
button.member-row { transition: background-color var(--d-select) var(--ease-out); }
.option-row:active, button.member-row:active { background: var(--fill-2); }

/* ---------- Segmented thumb (QA plan 3.2): one thumb slides under equal-width segments ---------- */
/* --n (option count) comes from the markup; --i (selected index) from the DOM state, so a control whose node survives
   needs no JS. Labels change color in step with the thumb, so a label inverts as the thumb passes under it. */
.segmented { position: relative; isolation: isolate; --i: 0; }
.segmented:has(> :nth-child(2):is([aria-pressed="true"], [aria-checked="true"]), > :nth-child(2) input:checked) { --i: 1; }
.segmented:has(> :nth-child(3):is([aria-pressed="true"], [aria-checked="true"]), > :nth-child(3) input:checked) { --i: 2; }
.segmented:has(> :nth-child(4):is([aria-pressed="true"], [aria-checked="true"]), > :nth-child(4) input:checked) { --i: 3; }
.segmented::before { content: ""; position: absolute; z-index: -1; top: 3px; bottom: 3px; left: 3px; border-radius: 11px; background: var(--accent);
  width: calc((100% - 6px - (var(--n, 2) - 1) * 4px) / var(--n, 2)); transform: translateX(calc(var(--i) * (100% + 4px)));
  transform-origin: calc(var(--i) * (100% + 4px) + 50%) 50%;
  transition: transform var(--d-thumb) var(--ease-in-out), scale var(--d-press) var(--ease-out); }
.segmented:not(:has([aria-pressed="true"], [aria-checked="true"], input:checked))::before { opacity: 0; }
/* Pressing the selected segment presses the thumb with its label. */
.segmented:has(> [aria-pressed="true"]:active, > label:active input:checked)::before { scale: .97; --d-press: var(--d-press-down); }
.segmented [aria-pressed="true"], .segmented [aria-checked="true"], .segmented label:has(input:checked) { background: transparent; }
.segmented button, .segmented label { font-weight: 700; transition: color var(--d-thumb) var(--ease-in-out), transform var(--d-press) var(--ease-out); }
.ev-views button .num { min-width: 1ch; } /* always rendered, so the Saved label never jumps when the count appears */
/* No slide: the first pick in a control that had none (main.js .no-slide), and keyboard moves. */
.segmented.no-slide::before, .kbd .segmented::before { transition: scale var(--d-press) var(--ease-out); }
.kbd .segmented :is(button, label) { transition: color var(--d-select) var(--ease-out), transform var(--d-press) var(--ease-out); }
@media (prefers-reduced-motion: reduce) {
  .segmented::before { transition: scale var(--d-press) var(--ease-out); }
  .segmented button, .segmented label { transition: color var(--d-rm-in) linear, transform var(--d-press) var(--ease-out); }
}

/* ---------- Switch thumb (QA plan 3.4) ---------- */
/* The knob glides (--d-thumb) and crossfades its own color with the track, so there is no white-on-white frame. A press
   stretches it toward the middle (iOS); `translate` moves it, so the stretch stays anchored to the side it sits on. */
.switch span { pointer-events: none; } /* the track painted over the input and swallowed taps on the switch itself */
.switch span::after { transform-origin: left center; transition: translate var(--d-thumb) var(--ease-in-out), background-color var(--d-select) var(--ease-out), scale var(--d-press-up) var(--ease-out); }
.switch input:checked + span::after { transform: none; translate: 20px 0; }
.switch input:not(:disabled):active + span::after { scale: 1.12 1; transition-duration: var(--d-press-down), var(--d-select), var(--d-press-down); }
.switch input:checked:not(:disabled):active + span::after { translate: calc(20px - 27px * .12) 0; } /* right edge stays put */
@media (prefers-reduced-motion: reduce) {
  .switch span::after { transition: background-color var(--d-rm-in) linear; }
  .switch input:not(:disabled):active + span::after { scale: none; }
  .switch input:checked:not(:disabled):active + span::after { translate: 20px 0; }
}

/* ---------- Patch in place, rolling numbers and live data (QA plan batch 4) ---------- */
/* Bar page estimate (4.1, 4.2). The unit is an inline-block so it glides with the number when the ≈ comes or goes. */
.qb-wait { transition: color var(--d-select) var(--ease-out); }
.qb-wait small { display: inline-block; }
/* The range on the 0–30 scale: two round caps and a middle bar, all on transforms, so a new range glides (--d-ring). The
   caps are zero-width boxes moved by container units, so nothing overflows the track (no horizontal scroll). */
.qb-scale-range { left: 5px; right: 5px; width: auto; min-width: 0; border-radius: 0; background: none; box-shadow: none; }
.qb-scale-range > i { position: absolute; top: 0; bottom: 0; left: 0; transform-origin: left center; transition: transform var(--d-ring) var(--ease-out); }
.qb-scale-range > :is(.r-lo, .r-hi) { width: 0; }
.qb-scale-range > .r-lo { left: calc(var(--lo) / var(--max) * 100%); }
.qb-scale-range > .r-hi { left: calc(var(--hi) / var(--max) * 100%); }
.qb-scale-range > :is(.r-lo, .r-hi)::before { content: ""; position: absolute; left: -5px; top: 0; width: 10px; height: 10px; border-radius: 50%; background: var(--ink); box-shadow: 0 0 0 3px var(--bg); }
.qb-scale-range > .r-mid { right: 0; background: var(--ink); transform: translateX(calc(var(--lo) / var(--max) * 100%)) scaleX(calc((var(--hi) - var(--lo)) / var(--max))); }
/* Freshness mark: a zero-width rail carries it along the track, so the age glides. */
.qf-rail { position: absolute; top: 0; bottom: 0; width: 0; pointer-events: none; left: clamp(7px, calc(var(--age, 0) / 26 * 100%), calc(100% - 7px)); }
.qf-rail .qf-mark { left: 0; }
@supports (width: 1cqw) {
  .qb-scale-range, .qf-track { container-type: inline-size; }
  .qb-scale-range > .r-lo { left: 0; transform: translateX(calc(100cqw * var(--lo) / var(--max))); }
  .qb-scale-range > .r-hi { left: 0; transform: translateX(calc(100cqw * var(--hi) / var(--max))); }
  .qf-rail { left: 7px; translate: calc((100cqw - 14px) * var(--age, 0) / 26) 0; transition: translate var(--d-ring) var(--ease-out); }
}
.qf-legend span { transition: color var(--d-select) var(--ease-out); }
/* Deal tickets (4.3) and bar cards (4.11): live → ended and a line's level change color in place. */
.promo-row .promo-badge { transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out); }
.deal-state-word, .promo-row .deal-title { transition: color var(--d-select) var(--ease-out); }
.lb-dot { transition: background-color var(--d-select) var(--ease-out), box-shadow var(--d-select) var(--ease-out); }
.lb-word { transition: color var(--d-select) var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .qf-rail, .qb-scale-range > i { transition: none; } }
/* Toggle buttons keep their node (4.5, 4.6): the two labels share one box and cross-fade, so the icon beside them never
   shifts; the fill crosses over --d-select (.btn). */
.lbl-stack { display: inline-grid; }
.lbl-stack > * { grid-area: 1 / 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px; transition: opacity var(--d-swap) var(--ease-out); }
[aria-pressed="true"] > .lbl-stack > :first-child, [aria-pressed="false"] > .lbl-stack > :last-child { opacity: 0; }
/* 320–359px: "Joined" reserves its width in both states, so its check drops to keep the group footer on the screen. */
@media (max-width: 359.98px) { .group-foot .lbl-stack .ic { display: none; } }
/* Points (4.4): the star nods from its center. */
.pts-chip > .ic { transform-origin: 50% 50%; }
/* Poll (4.10): the check has its own slot, so the label never moves; it fades and grows in. */
.poll-check { display: inline-grid; width: 16px; height: 16px; opacity: 0; scale: .9; transition: opacity var(--d-icon) var(--ease-out), scale var(--d-icon) var(--ease-out); }
.poll-check .ic { width: 16px; height: 16px; }
.poll-opt[aria-pressed="true"] .poll-check { opacity: 1; scale: 1; }
/* Scan line size (4.9): the disc fills with the tile; the check is its own layer that grows in over --d-icon. */
.bucket > span::after { transition: background-color var(--d-select) var(--ease-out), box-shadow var(--d-select) var(--ease-out); }
.bucket input:checked + span::after { background-image: none; }
.bucket > span::before { content: ""; position: absolute; z-index: 1; top: 12px; right: 12px; width: 18px; height: 18px; pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 12.5 4 4L18 8'/%3E%3C/svg%3E") center / 12px no-repeat;
  opacity: 0; scale: .6; transition: opacity var(--d-icon) var(--ease-out), scale var(--d-icon) var(--ease-out); }
.bucket input:checked + span::before { opacity: 1; scale: 1; }
/* Map/list toggle (4.12): both glyphs drawn; the incoming one fades and grows in (--d-icon), the outgoing leaves faster. */
.map-btn .ic-stack > .ic { transition: opacity var(--d-quick) var(--ease-out), scale var(--d-quick) var(--ease-out); }
.map-btn[aria-pressed="false"] .ic-list, .map-btn[aria-pressed="true"] .ic-map { opacity: 0; scale: .9; }
.map-btn[aria-pressed="false"] .ic-map, .map-btn[aria-pressed="true"] .ic-list { transition-duration: var(--d-icon); }
/* A cancelled pass dims in place (4.12); the status chip keeps its outline and place. */
.pass-card :is(.pass-grid, .pass-invalid, .pass-venue) { transition: opacity var(--d-select) var(--ease-out); }
.pass-card[data-status="cancelled"] :is(.pass-grid, .pass-invalid, .pass-venue) { opacity: .45; }
.pass-status { transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out), border-color var(--d-select) var(--ease-out); }
.pass-card[data-status="cancelled"] .pass-status { border-color: var(--line-input); }
/* Events filter pills (4.12): a set filter fills over --d-select; the results stay instant. */
.select select { transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out), border-color var(--d-select) var(--ease-out); }
.select > svg { transition: color var(--d-select) var(--ease-out); }
@media (prefers-reduced-motion: reduce) {
  .lbl-stack > * { transition: opacity var(--d-rm-in) linear; }
  .poll-check, .bucket > span::before, .map-btn .ic-stack > .ic { scale: 1; transition: opacity var(--d-rm-in) linear; }
  .map-btn[aria-pressed] .ic-stack > .ic { scale: 1; }
}

/* ---------- Bars surfaces (QA plan batch 6) ---------- */
/* 6.1 Search. The sort row (switch, search, map) and the search row share one grid cell and both stay in layout; the
   idle one is hidden with visibility once its fade is done. The row on its way out sits on top with no pointer events,
   so its button covers the start of the morph. The field's pill is its own layer (JS grows it out of the button). */
.search-panel > .search-toggle { grid-area: 1 / 2; }
.search-panel > .map-btn { grid-area: 1 / 3; }
.search-panel > :is(.chips, .search-toggle, .map-btn) { position: relative; z-index: 1; }
.search-row { grid-area: 1 / 1 / 2 / -1; display: flex; align-items: center; gap: 6px; min-width: 0; }
.search-panel { --sp-d: var(--d-morph-out); --sp-v: 0s; --sp-ease: var(--ease-out); }
.search-panel.is-open { --sp-d: var(--d-quick); --sp-v: var(--d-quick); }
.search-panel > .chips { transition: opacity var(--sp-d) var(--sp-ease), visibility 0s linear var(--sp-v); }
.search-panel > :is(.search-toggle, .map-btn) { transition: transform var(--d-press) var(--ease-out), background-color var(--d-select) var(--ease-out), opacity var(--sp-d) var(--sp-ease), visibility 0s linear var(--sp-v); }
.search-panel.is-open > :is(.chips, .search-toggle, .map-btn) { opacity: 0; visibility: hidden; pointer-events: none; }
.search-panel:not(.is-open) > .search-row { opacity: 0; visibility: hidden; transition: opacity var(--d-quick) var(--ease-out) 60ms, visibility 0s linear var(--d-morph-out); }
.search-panel .search::before { content: ""; position: absolute; inset: 0; border-radius: var(--r-pill); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-input); transform-origin: 0 50%; pointer-events: none; }
.search-panel .search:has(input:focus-visible)::before { box-shadow: inset 0 0 0 1px var(--ink); }
.search-panel .search input, .search-panel .search input:focus-visible { position: relative; border-color: transparent; background: transparent; }
.search-panel.is-instant, .search-panel.is-instant > * { transition: none !important; }
@media (prefers-reduced-motion: reduce) {
  .search-panel { --sp-d: var(--d-rm-in); --sp-ease: linear; }
  .search-panel.is-open { --sp-d: var(--d-rm-out); --sp-v: var(--d-rm-out); }
  .search-panel.is-open > .search-row { transition: opacity var(--d-rm-in) linear; }
  .search-panel:not(.is-open) > .search-row { transition: opacity var(--d-rm-out) linear, visibility 0s linear var(--d-rm-out); }
}

/* 6.2 Top bar. The wordmark and the area share one cell (both always rendered) and cross-fade in both directions:
   the incoming one over --d-select, the outgoing one over --d-quick, then visibility hides it (JS adds the 4px / 3px
   lift). A hairline fades in over the first 48px of scroll where scroll timelines exist, else when condensed. */
.topbar { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; column-gap: 4px; }
.topbar-spacer { display: none; }
.topbar > :is(.wordmark, .topbar-area) { grid-area: 1 / 1; justify-self: start; max-width: 100%; }
.topbar > .top-search { grid-area: 1 / 2; margin-right: 2px; }
.topbar > #demo-slot { grid-area: 1 / 3; }
.topbar > .topbar-area { display: inline-flex; }
.topbar > :is(.wordmark, .topbar-area, .top-search) { --tb-d: var(--d-select); --tb-v: 0s; --tb-ease: var(--ease-out); }
.topbar:not([data-condensed]) > :is(.topbar-area, .top-search), .topbar[data-condensed] > .wordmark { opacity: 0; visibility: hidden; pointer-events: none; --tb-d: var(--d-quick); --tb-v: var(--d-quick); }
.topbar > :is(.wordmark, .topbar-area) { transition: opacity var(--tb-d) var(--tb-ease), visibility 0s linear var(--tb-v); }
.topbar > .top-search { transition: transform var(--d-press) var(--ease-out), background-color var(--d-select) var(--ease-out), opacity var(--tb-d) var(--tb-ease), visibility 0s linear var(--tb-v); }
.topbar.is-instant > * { transition: none !important; }
.topbar::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: var(--line); opacity: 0; pointer-events: none; transition: opacity var(--d-select) var(--ease-out); }
.topbar[data-condensed]::after { opacity: 1; }
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .topbar::after { transition: none; animation: hairline linear both; animation-timeline: scroll(root); animation-range: 0 48px; } /* no scroll: no line */
  }
}
@keyframes hairline { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .topbar::after { transition: opacity var(--d-rm-in) linear; }
  .topbar > :is(.wordmark, .topbar-area, .top-search) { --tb-d: var(--d-rm-in); --tb-ease: linear; }
  .topbar:not([data-condensed]) > :is(.topbar-area, .top-search), .topbar[data-condensed] > .wordmark { --tb-d: var(--d-rm-out); --tb-v: var(--d-rm-out); }
}

/* 6.3 Map preview: one compact card (the bar card's parts) floating above the tab bar. A pin-to-pin change cross-fades
   two cards in one cell. The selected pin's tail joins its white ring instead of cutting it. */
.map-preview:not([hidden]) { display: grid; }
.map-preview > * { grid-area: 1 / 1; min-width: 0; }
.map-card { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 44px; align-items: center; padding-right: 4px; border: 1px solid var(--line-strong); border-radius: var(--r-lg); background: var(--raised); box-shadow: var(--shadow-float); overflow: hidden; }
.map-card-link { display: grid; grid-template-columns: 56px minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 10px 2px 10px 10px; color: inherit; border-radius: calc(var(--r-lg) - 1px) 0 0 calc(var(--r-lg) - 1px); transition: background-color var(--d-select) var(--ease-out); }
.map-card-link:active { background: var(--surface); }
.map-card-link:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.mc-photo { position: relative; width: 56px; height: 56px; border-radius: 10px; overflow: hidden; background: #111; }
.mc-photo > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.mc-main { display: grid; justify-items: start; gap: 6px; min-width: 0; }
.mc-name { max-width: 100%; font-size: var(--t-md); font-weight: 700; letter-spacing: -.02em; line-height: 1.15; overflow: hidden; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } /* fits the 56px photo's height, so a pin change never resizes the card */
.map-card .card-dist { height: 24px; font-size: 13px; background: var(--fill-2); }
.mc-status { justify-self: end; }
.map-pin-btn[aria-pressed="true"]::after { border-color: var(--ink); }

/* 6.4 Refresh: the icon spins (constant motion: linear) while a refresh runs; JS settles it on its next full turn. */
@media (prefers-reduced-motion: no-preference) { .refresh-btn[aria-disabled="true"] .ic { animation: spin .9s linear infinite; } }
@media (prefers-reduced-motion: reduce) {
  .results-bar .refresh-btn { transition: transform var(--d-press) var(--ease-out), background-color var(--d-select) var(--ease-out), opacity var(--d-rm-in) linear; }
  .results-bar .refresh-btn[aria-disabled="true"] { opacity: .5; }
}

/* 6.5 First load: placeholders the size of what arrives (the deals row, the results bar, the cards). */
.sk-card { display: grid; align-content: start; border-radius: var(--r-card); background: var(--surface); overflow: hidden; }
.sk-card .sk-photo { aspect-ratio: 1 / 1; border-radius: 0; }
.sk-card :is(.sk-l1, .sk-l2) { height: 12px; margin-inline: 12px; }
.sk-card .sk-l1 { width: 55%; margin-top: 16px; }
.sk-card .sk-l2 { width: 35%; margin: 10px 12px 26.8px; }
.sk-rail .rail-head { min-height: 44px; }
.sk-rail .sk-h { width: 150px; height: 20px; }
.sk-rail .rail-list { overflow: hidden; }
.sk-tile { flex: none; display: grid; align-content: start; gap: 4px; width: 196px; }
.sk-tile .rail-photo { box-shadow: none; background: var(--fill-2); }
.sk-tile .sk-l1 { width: 60%; height: 14px; margin: 2.1px 0; }
.sk-tile .sk-l2 { width: 80%; height: 12px; margin: 2.4px 0; }
@media (max-width: 359.98px) {
  .sk-card .sk-photo { aspect-ratio: 2.6 / 1; }
  .sk-card .sk-l2 { margin-bottom: 14.4px; }
}

/* 6.6 List photos fade in once, when decoded (JS marks the ones still loading). */
:is(.bar-photo, .rail-photo) > img { transition: opacity var(--d-reveal) var(--ease-out); }
:is(.bar-photo, .rail-photo) > img.is-pending { opacity: 0; }
@media (prefers-reduced-motion: reduce) { :is(.bar-photo, .rail-photo) > img { transition: opacity var(--d-rm-in) linear; } }

/* 6.8 Banners: spaced only when there is one (JS hands the height over on transforms). */
#explore-banners { display: grid; gap: 8px; }
#explore-banners:not(:empty) { margin-top: var(--s-3); }

/* 6.9 Toasts stack (at most two): the one behind steps up and back so its Undo stays in reach. Reduced motion: the
   offset applies at once, only the opacity fades. */
.toast-region > .toast { grid-area: 1 / 1; align-self: end; z-index: 1; }
.toast-region > .toast.is-behind { z-index: 0; }
.toast.is-behind, .toast.is-behind.is-leaving { transform: translateY(var(--peek, -14px)) scale(.95); }
.toast.is-behind { opacity: .6; }
.toast.is-behind.is-leaving { opacity: 0; }

/* ---------- Sheets (QA plan batch 7) ---------- */
/* 7.3 A picked row holds its fill for a beat before the sheet closes (a color: kept under reduced motion). */
.option-row.is-picked { background: var(--fill-2); transition: none; }
/* 7.5 Help: the answer clears the plate's edge; its wrapper clips while it opens and folds. The chevron turns as soon as
   a fold starts. */
.how-a { overflow: hidden; }
details.how .how-a > p { padding: 0 16px 14px; }
details.how.is-closing summary::after { transform: rotate(45deg) translateY(-2px); }

/* ---------- Lists, forms and the rare success beats (QA plan batch 8) ---------- */
/* 8.1 An item on its way out (JS fades it) takes no taps. */
.is-leaving { pointer-events: none; }
/* 8.2 Bar hop: the stops stay in the page and open in place below the switch (rows 0fr → 1fr, --d-tray) as they fade in
   (--d-fade). They share one form row with the switch, and their 18px space above is inside the clip, so a closed editor
   takes no room. The clip has inline and bottom room for focus rings, given back with negative margins. Keyboard and
   reduced motion: the layout changes at once (reduced motion keeps a short fade). */
.hop-edit { display: grid; grid-template-rows: 0fr; gap: 0; margin: 0; transition: grid-template-rows var(--d-tray) var(--ease-in-out); }
.is-hop .hop-edit { grid-template-rows: 1fr; }
.hop-clip { min-width: 0; min-height: 0; padding: 0 8px 8px; margin: 0 -8px -8px; overflow: hidden; opacity: 0; transition: opacity var(--d-fade) var(--ease-out); }
.is-hop .hop-clip { opacity: 1; }
.hop-fields { min-width: 0; display: grid; gap: 8px; border: 0; padding: 0; margin: 18px 0 0; }
.hop-edit-row .select select { min-height: 48px; border-radius: var(--r-btn-lg); }
.kbd .hop-edit { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .hop-edit { transition: none; }
  .hop-clip { transition: opacity var(--d-rm-in) linear; }
}
/* 8.3 A field that failed says so in its outline too (the error line drops in, JS). */
:is(.text-input, .select select)[aria-invalid="true"] { border-color: var(--danger); }
/* 8.5 Scan. Each progress segment fills to --fill (0, .55, 1) on a transform; its node survives the step change. */
.scan-steps i, .scan-steps i.is-done, .scan-steps i.is-now { position: relative; overflow: hidden; background: var(--line-strong); }
.scan-steps i::after { content: ""; position: absolute; inset: 0; background: var(--ink); transform: scaleX(var(--fill, 0)); transform-origin: left center; transition: transform var(--d-fill) var(--ease-out); }
/* The Send bar rises in once when step 2 arrives. */
.scan-submit { transition: translate var(--d-reveal) var(--ease-out), opacity var(--d-reveal) var(--ease-out); }
@starting-style { .scan-submit { translate: 0 12px; opacity: 0; } }
/* Capture: the line-size and door choices fade up from .4 as their fieldsets turn on. */
.scan-flow .bucket > span { transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out), transform var(--d-press) var(--ease-out), opacity var(--d-fade) var(--ease-out); }
.scan-flow fieldset .segmented { transition: opacity var(--d-fade) var(--ease-out); }
.scan-pts .roll { line-height: inherit; }
/* A blocked Send says why right above the button (it stays in view while the missing piece is scrolled to). */
.scan-submit > .field-error { justify-content: center; margin: 0 0 10px; }
@media (prefers-reduced-motion: reduce) {
  .scan-steps i::after { transition: none; }
  .scan-submit { transition: opacity var(--d-rm-in) linear; }
  @starting-style { .scan-submit { translate: none; } }
  .scan-flow .bucket > span { transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out), transform var(--d-press) var(--ease-out), opacity var(--d-rm-in) linear; }
  .scan-flow fieldset .segmented { transition: opacity var(--d-rm-in) linear; }
}
/* 8.6 The published count's chip (JS flies it), and the preview heading clears the tab bar when it is scrolled to. */
.fly-chip { position: fixed; z-index: 45; pointer-events: none; display: inline-block; padding: 5px 11px 4px; border-radius: var(--r-pill); background: var(--accent); color: var(--accent-ink);
  font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 22px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; transform-origin: 0 50%; box-shadow: var(--shadow-float); }
#qb-console { scroll-margin-bottom: calc(var(--tabbar-h) + var(--safe-b) + 16px); }

/* ---------- Static polish (QA plan batch 9) ---------- */
/* 9.1 Bars rhythm: 12 under the controls, 8 between the deals row, the results bar and the cards. */
.search-panel { margin-bottom: var(--s-3); }
.deals-rail { margin-top: 0; margin-bottom: var(--s-2); }
.results-bar + .bar-grid { margin-top: var(--s-2); }
.group-title { margin: var(--s-4) 0 var(--s-1); }
.state.state-sm :is(h1, h2) { font-size: 20px; }
/* 9.2 The walk pill stays inside a narrow card (miles drop below 190px). */
.card-top { align-items: center; }
.card-dist { min-width: 0; overflow: hidden; }
@container card (max-width: 190px) { .card-dist .cd-mi { display: none; } }
/* 9.3 Freshness is one line, so names in a row line up. */
.card-fresh { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card-fresh .ic { display: inline-block; vertical-align: -2px; margin-right: 4px; }
/* 9.4 Bar page: one section rhythm (32px) and one heading system. */
section.ideas { margin-top: 0; }
.typical, .pass-cta { margin-top: 0; }
.pass-cta > .section-head { margin-bottom: 2px; }
.pass-cta .section-head h2 { text-transform: none; color: var(--ink); }
/* 9.7 Events views and filter pills: 34px to the eye, 44px to the finger. */
.ev-views button { position: relative; }
.ev-views button::before { content: ""; position: absolute; inset: -5px 0; }
.ev-filters { margin-top: 10px; }
.ev-filters .chip-select select { height: 44px; min-height: 44px; border-block: 5px solid transparent; border-inline: 0; background-clip: padding-box; box-shadow: inset 0 0 0 1px var(--line-input);
  transition: background-color var(--d-select) var(--ease-out), color var(--d-select) var(--ease-out), box-shadow var(--d-select) var(--ease-out); }
.ev-filters .chip-select.is-set select { border-color: transparent; box-shadow: inset 0 0 0 1px var(--accent); }
/* 9.8 Cards: one radius and one material; shorter photos; the host on one line. */
.ev-card, .idea-card, .group-card, .idea-card[data-status="approved"] { border-radius: var(--r-card); background: var(--surface); border: 1px solid var(--line-strong); box-shadow: none; }
.idea-card[data-status="declined"] { border-color: var(--line); }
.ev-photo { aspect-ratio: 2 / 1; }
.group-host { gap: 8px; }
.group-host-text { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.group-host-name { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.group-host-text .handle { flex: none; min-height: 24px; } /* one line with the name, still a 24px box */
.group-host-text .handle::before { inset: -10px -4px; } /* 44px to the finger */
/* 9.9 Window times: condensed numerals on one line, so every tile is the same height. */
.w-time { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 19px; font-weight: 800; white-space: nowrap; }
/* 9.10 Narrow phones and long bar names. */
.select select { text-overflow: ellipsis; }
.field-pair { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }
@media (max-width: 359.98px) {
  .field-pair { grid-template-columns: minmax(0, 1fr); }
  .venue-actions { grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr)); }
  .act { font-size: 11px; }
  .act-pts { top: 5px; right: 6px; font-size: 12px; }
  .hop-edit-row { grid-template-columns: minmax(0, 1fr) 44px; }
  .hop-edit-row > .hop-time { grid-column: 1; grid-row: 2; }
  .hop-edit-row > .icon-btn { grid-column: 2; grid-row: 1; }
}
/* 9.11 Forms: one 18px rhythm; night cards share a height. */
.form-stack > .field-group { margin-top: 0; }
.radio-card { display: grid; }
.radio-card span { height: 100%; }
/* 9.12 Room under titles. */
.title-row + .safety-note { margin-top: var(--s-3); }
.page-title + .state, .title-row + .state { margin-top: var(--s-4); }
/* 9.13 Icon-only Back on drill-in pages. */
.back-title { justify-content: flex-start; gap: 8px; margin-left: -4px; }
.back-link.back-icon { flex: none; width: 44px; height: 44px; padding: 0; justify-content: center; border-radius: 50%; }
.back-link.back-icon svg { width: 22px; height: 22px; }
.back-title .page-title { min-width: 0; }
/* 9.14 Scan waiting actions on one row; history amounts in one type; the QR hint centered. */
.waiting-actions { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; }
.history-list li > .num:last-child { font-family: var(--font-num); font-stretch: var(--w-cond); font-size: 20px; font-weight: 800; }
.picker .hint.center { justify-content: center; text-align: center; }
/* 9.15 Console: the guests' preview is not a card inside a card; steppers share a right edge. */
.console-grid .queue-block { margin-top: 0; padding: 0; border: 0; background: none; border-radius: 0; box-shadow: none; }
.cap-row { grid-template-columns: minmax(0, 1fr) 176px; }
.cap-row .stepper { justify-self: end; }
.stepper output { min-width: 5ch; }
/* 9.16 Billing on one line. */
.sub-facts dd { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 9.17 One rounded ring per control (never transitioned): the tab rings its pill, the rail tile its photo. */
.tab:focus-visible { outline: none; box-shadow: none; }
.tab:focus-visible .tab-inner { outline: 2px solid var(--focus); outline-offset: 2px; }
.rail-tile:focus-visible { outline: none; box-shadow: none; }
.area-pill, .rail-all { border-radius: var(--r-sm); }
@media (max-width: 359.98px) { .hop-edit-list { gap: 14px; } .hop-edit-row { row-gap: 6px; } } /* stops read as pairs */
