/* Fairfield Flavor — styles */

:root {
  --bg: #faf6f0;
  --bg-elev: #ffffff;
  --bg-sunk: #f1ece3;
  --ink: #1c1813;
  --ink-2: #5f584e;
  --ink-3: #938a7d;
  --line: #e7e0d5;
  --line-2: #d8d0c2;
  --accent: #c2410c;
  --accent-soft: #fdece2;
  --accent-ink: #9a3308;
  --open: #157f4a;
  --open-soft: #e2f4ea;
  --shut: #a4362f;
  --shut-soft: #fbe9e7;
  --warn-ink: #8a5a06;
  --warn-soft: #fdf4e3;
  --warn-line: #ecd9a8;
  --geo: #1d4ed8;
  --geo-soft: #eaf0fe;
  --shadow-sm: 0 1px 2px rgba(26, 24, 21, .05), 0 1px 3px rgba(26, 24, 21, .04);
  --shadow-md: 0 4px 6px -2px rgba(26, 24, 21, .06), 0 12px 24px -8px rgba(26, 24, 21, .14);
  --shadow-lg: 0 20px 48px -12px rgba(26, 24, 21, .28);
  --r: 18px;
  --r-sm: 11px;
  --maxw: 1280px;
  --header-h: 132px;
  --sans: ui-sans-serif, -apple-system, "Segoe UI", Inter, Roboto, Helvetica, Arial, sans-serif;
  /* ui-serif resolves to New York on Apple platforms — an editorial voice with no download. */
  --serif: ui-serif, "New York", "Iowan Old Style", Palatino, Georgia, serif;
}

html[data-theme="dark"] {
  --bg: #14120e;
  --bg-elev: #201d17;
  --bg-sunk: #100e0b;
  --ink: #f4f1ea;
  --ink-2: #b7ae9f;
  --ink-3: #8b8274;
  --line: #322e26;
  --line-2: #423d33;
  --accent: #fb923c;
  --accent-soft: #35211284;
  --accent-ink: #fdba74;
  --open: #4ade80;
  --open-soft: #16301f8c;
  --shut: #fca5a5;
  --shut-soft: #3a1a1a8c;
  --warn-ink: #fcd34d;
  --warn-soft: #33280c8c;
  --warn-line: #5c4a16;
  --geo: #7dabff;
  --geo-soft: #16203a8c;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-md: 0 4px 8px rgba(0, 0, 0, .4), 0 16px 32px -12px rgba(0, 0, 0, .55);
  --shadow-lg: 0 24px 56px -12px rgba(0, 0, 0, .7);
}

* { box-sizing: border-box; }

/* Author `display` rules (.grid, .active-row) otherwise beat the UA [hidden] rule. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--sans);
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

svg { width: 1em; height: 1em; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

a { color: var(--accent-ink); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--bg-elev); padding: .7rem 1rem; border-radius: 0 0 var(--r-sm) 0;
}
.skip:focus { left: 0; }

/* ---------- hero ---------- */

.hero {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(120% 140% at 12% -10%, color-mix(in srgb, var(--accent) 13%, transparent), transparent 62%),
    radial-gradient(90% 120% at 92% 0%, color-mix(in srgb, #d9a03c 16%, transparent), transparent 60%),
    var(--bg);
}
.hero-inner {
  position: relative; z-index: 1;
  max-width: var(--maxw); margin: 0 auto;
  padding: clamp(1.7rem, 3.6vw, 2.6rem) 1.25rem clamp(1.3rem, 2.2vw, 1.7rem);
}
.hero-eyebrow {
  margin: 0 0 .7rem; font: 600 .76rem var(--sans);
  letter-spacing: .16em; text-transform: uppercase; color: var(--accent-ink);
}
.hero-title {
  margin: 0; font-family: var(--serif); font-weight: 600;
  font-size: clamp(2.1rem, 5vw, 3.3rem); line-height: 1.02;
  letter-spacing: -.026em; color: var(--ink);
}
/* One line on roomy screens, stacked on phones. */
@media (min-width: 620px) { .hero-title br { display: none; }
  .hero-title em { margin-left: .28em; } }
.hero-title em {
  font-style: italic;
  background: linear-gradient(96deg, var(--accent), #e0863f 60%, #d9a03c);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  /* Safari paints a text-clipped gradient only inside the box, and the italic "?"
     leans out past its right edge, so iPhones cut the question mark off. A little
     padding gives the slant room; the negative margin keeps the line where it was. */
  padding-right: .14em; margin-right: -.14em;
}
.hero-sub {
  margin: .75rem 0 0; max-width: 46ch;
  font-size: .97rem; line-height: 1.5; color: var(--ink-2);
}
.hero-sub strong { color: var(--ink); font-variant-numeric: tabular-nums; }

.hero-quick { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.1rem; }
.qbtn {
  font: 600 .85rem var(--sans); color: var(--ink);
  background: var(--bg-elev);
  border: 1px solid var(--line-2); border-radius: 999px;
  padding: .55rem 1.05rem; cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform .16s cubic-bezier(.2,.7,.3,1), box-shadow .16s, background .16s, color .16s;
}
.qbtn:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
/* The one hero button that opens a different view rather than filtering the list.
   It is set in caps to read as a door rather than a filter, and caps want a little
   tracking to stay legible at this size. */
.qbtn-wide { letter-spacing: .04em; }

.qbtn.is-on {
  background: var(--ink); border-color: var(--ink); color: var(--bg);
}

/* Soft warm bloom behind the headline. */
.hero-glow {
  position: absolute; inset: auto -10% -70% 40%;
  height: 300px; pointer-events: none;
  background: radial-gradient(50% 50% at 50% 50%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 70%);
  filter: blur(48px); opacity: .55;
}
html[data-theme="dark"] .hero-glow { opacity: .34; }

/* ---------- header ---------- */

.topbar {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(1.6) blur(14px);
  -webkit-backdrop-filter: saturate(1.6) blur(14px);
  border-bottom: 1px solid var(--line);
}

.topbar-inner {
  max-width: var(--maxw); margin: 0 auto;
  padding: .8rem 1.25rem .55rem;
  display: flex; align-items: center; gap: 1rem;
}

.brand { display: flex; align-items: center; gap: .6rem; flex: 0 0 auto; }
.brand-mark {
  width: 38px; height: 38px; border-radius: 11px;
  box-shadow: var(--shadow-sm);
  /* icons/icon.svg is a full-bleed square, so the radius does the rounding —
     same mark, same crop as the home-screen icon. */
}
.brand-text { display: flex; flex-direction: column; line-height: 1.1; }
.brand-text strong { font-size: 1.03rem; letter-spacing: -.017em; }
.brand-text small { color: var(--ink-3); font-size: .735rem; margin-top: 2px; }

.search { position: relative; flex: 1 1 auto; max-width: 560px; }
.search-icon {
  position: absolute; left: .82rem; top: 50%; transform: translateY(-50%);
  font-size: 1.05rem; color: var(--ink-3); pointer-events: none;
}
#q {
  width: 100%; font: inherit; font-size: .92rem; color: var(--ink);
  padding: .68rem 4.3rem .68rem 2.5rem;
  background: var(--bg-elev);
  border: 1px solid var(--line-2); border-radius: 11px;
  box-shadow: var(--shadow-sm);
  transition: border-color .15s, box-shadow .15s;
}
#q::placeholder { color: var(--ink-3); }
#q:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3.5px var(--accent-soft);
}
#q::-webkit-search-cancel-button { display: none; }
.q-clear {
  position: absolute; right: 2.35rem; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px; border: 0; border-radius: 50%;
  background: var(--bg-sunk); color: var(--ink-2);
  font-size: 1.05rem; line-height: 1; cursor: pointer;
}
.q-clear:hover { background: var(--line-2); color: var(--ink); }
.slash-hint {
  position: absolute; right: .6rem; top: 50%; transform: translateY(-50%);
  font: 600 .68rem var(--sans); color: var(--ink-3);
  border: 1px solid var(--line-2); border-bottom-width: 2px;
  border-radius: 5px; padding: 1px 5px; background: var(--bg);
}
.search:focus-within .slash-hint { opacity: 0; }

.topbar-actions { display: flex; gap: .45rem; margin-left: auto; flex: 0 0 auto; }

.icon-btn {
  display: inline-flex; align-items: center; gap: .4rem;
  font: 600 .82rem var(--sans); color: var(--ink-2);
  background: var(--bg-elev); border: 1px solid var(--line-2);
  border-radius: 10px; padding: .55rem .75rem; cursor: pointer;
  box-shadow: var(--shadow-sm); transition: .15s;
}
.icon-btn:hover { color: var(--ink); border-color: var(--ink-3); transform: translateY(-1px); }
.icon-btn svg { font-size: 1.05rem; }
.icon-btn.square { padding: .55rem; }

.ico-moon { display: none; }
html[data-theme="dark"] .ico-sun { display: none; }
html[data-theme="dark"] .ico-moon { display: block; }

/* ---------- filters ---------- */

.filters { max-width: var(--maxw); margin: 0 auto; padding: 0 1.25rem .7rem; }

.filter-row { display: flex; align-items: center; gap: .5rem; }
.filter-row.secondary { margin-top: .55rem; flex-wrap: wrap; }
.spacer { flex: 1 1 auto; }

.chips { display: flex; gap: .4rem; overflow-x: auto; padding-bottom: 2px; scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }

.chip {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: .38rem;
  font: 600 .82rem var(--sans); color: var(--ink-2);
  background: transparent; border: 1px solid var(--line-2);
  border-radius: 999px; padding: .4rem .8rem; cursor: pointer;
  white-space: nowrap; transition: .14s;
}
.chip:hover { color: var(--ink); border-color: var(--ink-3); }
.chip .n { font-weight: 500; color: var(--ink-3); font-size: .76rem; font-variant-numeric: tabular-nums; }
.chip.is-on {
  background: var(--ink); border-color: var(--ink); color: var(--bg);
}
.chip.is-on .n { color: color-mix(in srgb, var(--bg) 70%, transparent); }

.toggle {
  display: inline-flex; align-items: center; gap: .42rem;
  font: 600 .82rem var(--sans); color: var(--ink-2);
  background: var(--bg-elev); border: 1px solid var(--line-2);
  border-radius: 999px; padding: .44rem .8rem; cursor: pointer; transition: .14s;
}
.toggle:hover { color: var(--ink); border-color: var(--ink-3); }
.toggle .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--ink-3); box-shadow: 0 0 0 3px transparent; transition: .2s;
}
.toggle[aria-pressed="true"] {
  background: var(--open-soft); border-color: color-mix(in srgb, var(--open) 45%, transparent); color: var(--open);
}
.toggle[aria-pressed="true"] .dot { background: var(--open); box-shadow: 0 0 0 3px color-mix(in srgb, var(--open) 22%, transparent); }
#saved-only[aria-pressed="true"] {
  background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 45%, transparent); color: var(--accent-ink);
}
#saved-only[aria-pressed="true"] .heart-ico { fill: currentColor; }
.heart-ico { font-size: 1rem; }

/* Near me */
.toggle.near .near-ico { font-size: 1rem; }
.toggle.near[aria-pressed="true"] {
  background: var(--geo-soft); border-color: color-mix(in srgb, var(--geo) 45%, transparent);
  color: var(--geo);
}
.toggle.near[data-state="asking"] { color: var(--ink-3); cursor: progress; }
.toggle.near[data-state="asking"] .near-ico { animation: spin 1.1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.toggle.near:disabled { opacity: .75; }

.linkish {
  border: 0; background: none; padding: 0 0 0 .5rem; cursor: pointer;
  font: 600 .8rem var(--sans); color: var(--geo);
  text-decoration: underline; text-underline-offset: 3px;
}
.linkish:hover { filter: brightness(1.15); }

.geo-problem {
  margin: 0 0 1.1rem; padding: .95rem 1.1rem;
  background: var(--geo-soft); border: 1px solid color-mix(in srgb, var(--geo) 28%, transparent);
  border-radius: var(--r);
}
.geo-problem p { margin: 0 0 .8rem; font-size: .87rem; line-height: 1.55; color: var(--ink); }
.geo-problem code {
  font-size: .85em; background: var(--bg-sunk); border: 1px solid var(--line);
  border-radius: 5px; padding: .08em .35em;
}
.geo-problem-actions { display: flex; flex-wrap: wrap; gap: .5rem; }

.pick-banner {
  display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
  margin: 0 0 1.1rem; padding: .8rem 1.1rem;
  background: var(--geo-soft); border: 1px dashed color-mix(in srgb, var(--geo) 50%, transparent);
  border-radius: var(--r); font-size: .87rem; font-weight: 600; color: var(--ink);
}
.pick-banner .btn { margin-left: auto; padding: .45rem .8rem; font-size: .8rem; }
body.is-picking #map { cursor: crosshair; }
body.is-picking .leaflet-marker-icon { cursor: crosshair; }

.you-dot {
  width: 22px; height: 22px; border-radius: 50%;
  background: color-mix(in srgb, var(--geo) 28%, transparent);
  display: grid; place-items: center;
}
.you-dot span {
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--geo); border: 2.5px solid #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .45);
}

.d-away { color: var(--geo); font-weight: 600; white-space: nowrap; }

/* Small pill links inside a detail row. Only the Reviews row uses these now — the
   maps hand-off moved to the Directions button, which asks which app you want. */
.pill-links { display: flex; gap: .5rem; margin-top: .3rem; flex-wrap: wrap; }
.pill-links a {
  font: 600 .755rem var(--sans); color: var(--accent-ink);
  text-decoration: none; white-space: nowrap;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: 999px; padding: .18rem .55rem;
  transition: border-color .15s, transform .15s;
}
.pill-links a:hover { border-color: var(--accent); transform: translateY(-1px); }
.mini-count { font-variant-numeric: tabular-nums; opacity: .75; font-weight: 500; }

.select {
  display: inline-flex; align-items: center; gap: .4rem;
  background: var(--bg-elev); border: 1px solid var(--line-2);
  border-radius: 999px; padding: .3rem .35rem .3rem .75rem;
}
.select > span { font: 600 .74rem var(--sans); color: var(--ink-3); text-transform: uppercase; letter-spacing: .045em; }
.select select {
  font: 600 .82rem var(--sans); color: var(--ink);
  background: transparent; border: 0; padding: .16rem 1.2rem .16rem .2rem; cursor: pointer;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right .55rem center, right .3rem center;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.select select:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.select:has(select:not([data-default])) { border-color: var(--accent); }

.viewswitch {
  display: inline-flex; background: var(--bg-sunk);
  border: 1px solid var(--line); border-radius: 999px; padding: 3px;
}
.vs-btn {
  display: inline-flex; align-items: center; gap: .35rem;
  font: 600 .8rem var(--sans); color: var(--ink-2);
  background: transparent; border: 0; border-radius: 999px;
  padding: .35rem .8rem; cursor: pointer; transition: .15s;
}
.vs-btn.is-on { background: var(--bg-elev); color: var(--ink); box-shadow: var(--shadow-sm); }

.active-row { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .6rem; align-items: center; }
.active-label { font: 600 .74rem var(--sans); color: var(--ink-3); text-transform: uppercase; letter-spacing: .045em; }
.pill {
  display: inline-flex; align-items: center; gap: .35rem;
  font: 600 .78rem var(--sans);
  background: var(--accent-soft); color: var(--accent-ink);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: 999px; padding: .25rem .3rem .25rem .65rem;
}
.pill button {
  border: 0; background: transparent; color: inherit; cursor: pointer;
  font-size: 1rem; line-height: 1; padding: 0 .25rem; opacity: .7;
}
.pill button:hover { opacity: 1; }
.clear-all {
  font: 600 .78rem var(--sans); color: var(--ink-2);
  background: none; border: 0; cursor: pointer; text-decoration: underline;
  text-decoration-color: var(--line-2); text-underline-offset: 3px;
}
.clear-all:hover { color: var(--ink); }

/* ---------- results ---------- */

main { max-width: var(--maxw); margin: 0 auto; padding: 1.1rem 1.25rem 3rem; }

.statusline { display: flex; align-items: baseline; gap: .75rem; flex-wrap: wrap; margin: 0 0 .9rem; }
.count { margin: 0; font-size: .85rem; color: var(--ink-2); }
.count strong { color: var(--ink); font-variant-numeric: tabular-nums; }
/* Honest small print about how far a menu search can see. Set apart so it reads as a
   caveat on the count rather than part of it. */
.count-note {
  display: block; margin-top: .18rem;
  font-size: .76rem; color: var(--ink-3);
}
.geo-note { margin: 0; font-size: .8rem; color: var(--ink-3); }

.grid {
  display: grid; gap: .85rem;
  grid-template-columns: repeat(auto-fill, minmax(288px, 1fr));
}

.card {
  position: relative; display: flex; flex-direction: column;
  background: var(--bg-elev); border: 1px solid transparent;
  border-radius: var(--r); padding: 1.05rem 1.05rem .35rem;
  box-shadow: var(--shadow-sm); cursor: pointer;
  transition: transform .18s cubic-bezier(.2,.7,.3,1), box-shadow .18s, border-color .18s;
  animation: cardIn .42s cubic-bezier(.2,.7,.3,1) both;
  animation-delay: var(--delay, 0ms);
}
html[data-theme="dark"] .card { border-color: var(--line); }

@keyframes cardIn {
  from { opacity: 0; transform: translateY(10px) scale(.985); }
}

/* A wash of the place's own cuisine colour, revealed on hover. */
.card::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(160deg, hsl(var(--h, 30) calc(var(--sat, 1) * 80%) 60% / .09), transparent 55%);
  opacity: 0; transition: opacity .2s; pointer-events: none;
}
.card:hover::before { opacity: 1; }
.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 2px 4px hsl(var(--h, 30) calc(var(--sat, 1) * 40%) 30% / .07),
              0 18px 34px -12px hsl(var(--h, 30) calc(var(--sat, 1) * 45%) 32% / .26);
  border-color: hsl(var(--h, 30) calc(var(--sat, 1) * 55%) 62% / .38);
}
.card:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.card-body { display: flex; align-items: flex-start; gap: .85rem; }

.tile {
  flex: 0 0 auto; width: 58px; height: 58px; border-radius: 16px;
  display: grid; place-items: center; font-size: 1.6rem; line-height: 1;
  background:
    radial-gradient(120% 120% at 28% 18%,
      hsl(var(--h, 30) calc(var(--sat, 1) * 88%) calc(72% - var(--sat, 1) * 2%)),
      hsl(var(--h, 30) calc(var(--sat, 1) * 72%) calc(54% - var(--sat, 1) * 2%)) 62%,
      hsl(calc(var(--h, 30) - 16) calc(var(--sat, 1) * 68%) 46%));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .4),
              0 5px 12px -5px hsl(var(--h, 30) calc(var(--sat, 1) * 60%) 38% / .5);
  transition: transform .22s cubic-bezier(.2,.7,.3,1);
}
.tile { position: relative; overflow: hidden; }
.tile-glyph { filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .28)); }
.card:hover .tile { transform: scale(1.06) rotate(-3deg); }

/* ---------- photo cards ----------
   Where we have a storefront photo it fills the card, and the words sit over a dark
   scrim at the foot. The card is made taller than a tile card so the building has room
   to be seen above the text — at tile height the photo would be a letterbox. Only the
   grid changes; the detail panel keeps its own banner. */
.card.has-photo {
  /* The top padding is a picture area the words can never climb into: a search that adds
     a menu line, or a happy-hour badge, makes the card taller rather than covering the
     sign. Without it Chip's lost its sign under an "egg" search. */
  min-height: 18rem; padding-top: 8.5rem; overflow: hidden; isolation: isolate;
  background: #1c1916; color: #fff;
}
.card-photo {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  /* Same upward bias as the detail banner, for the same reason: the fascia is what
     identifies the place, and centring the crop loses it. */
  object-position: var(--fx, 50%) var(--oy, 28%);   /* --oy pans a portrait photo */
  /* --cs lifts a low sign above the words by zooming in about the bottom edge, which
     keeps the photo covering the card; set per photo by photoFrame() in app.js. */
  transform-origin: var(--fx, 50%) 100%;
  transform: scale(var(--cs, 1));
  transition: transform .5s cubic-bezier(.2,.7,.3,1);
}
.card.has-photo:hover .card-photo { transform: scale(calc(var(--cs, 1) * 1.045)); }
/* The scrim does the readability work. Dark and deep under the text, clear through the
   middle where the storefront is, and a light veil at the top so the heart stays
   visible on a pale sky. */
.card.has-photo::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(0,0,0,.2), transparent 20%),
    linear-gradient(to top, rgba(12,10,8,.76) 0%, rgba(12,10,8,.6) 32%,
                            rgba(12,10,8,.28) 56%, transparent 76%);
}
.card.has-photo::before { display: none; }
.card.has-photo .tile { display: none; }
/* Push the words down onto the scrim and pin the heart to the corner. */
.card.has-photo .card-body { margin-top: auto; padding-bottom: .7rem; }
.card.has-photo .fav {
  position: absolute; top: .6rem; right: .6rem; margin: 0;
  width: 34px; height: 34px; border-radius: 50%;
  color: #fff; background: rgba(0,0,0,.32);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.card.has-photo .fav:hover { background: rgba(0,0,0,.5); color: #fff; }
.card.has-photo .fav[aria-pressed="true"] { color: #ff8a8a; }
/* The scrim is kept light so the photo reads; the shadow carries the rest of the
   contrast — a tight dark edge for crispness and a soft halo for busy backgrounds. */
.card.has-photo .card-text,
.card.has-photo .card-foot { text-shadow: 0 1px 2px rgba(0,0,0,.75), 0 0 14px rgba(0,0,0,.5); }
/* Type a size up from the tile cards: it is read against a picture, not white. */
.card.has-photo h3 { font-size: 1.5rem; line-height: 1.15; margin-bottom: .28rem; }
.card.has-photo .card-kinds { font-size: .94rem; }
.card.has-photo .card-menu { font-size: .88rem; }
.card.has-photo .card-where { font-size: .88rem; }
.card.has-photo .card-foot { font-size: .86rem; }
.card.has-photo .status { font-size: .84rem; text-shadow: none; }
.card.has-photo .hh-badge { font-size: .74rem; text-shadow: none; }
.card.has-photo h3 { color: #fff; }
.card.has-photo .card-kinds,
.card.has-photo .card-menu { color: rgba(255,255,255,.9); }
.card.has-photo .card-where { color: rgba(255,255,255,.76); }
.card.has-photo .card-kinds i { color: rgba(255,255,255,.45); }
.card.has-photo .card-kinds b {
  color: #fff; box-shadow: inset 0 -.18em 0 var(--accent);
}
.card.has-photo .card-menu span { color: #fff; background: rgba(255,255,255,.2); }
.card.has-photo .card-foot {
  margin-top: 0;   /* the body's auto margin does the pushing; two would split the gap */
  border-top-color: rgba(255,255,255,.2); color: rgba(255,255,255,.78);
}
.card.has-photo .dist { color: #fff; }
/* The status pills are pale tints meant for a white card. On a photo they need to be
   solid to stay legible, so they take their own colour as the fill. */
.card.has-photo .status.open { background: #157f4a; color: #fff; }
.card.has-photo .status.soon { background: #c2410c; color: #fff; }
.card.has-photo .status.shut,
.card.has-photo .status.unknown { color: rgba(255,255,255,.8); }
.card.has-photo .hh-badge { background: #fde68a; color: #5b3a06; border-color: transparent; }
.card.has-photo .hh-badge.hh-brunch { background: #bbf7d0; color: #0f5132; }
html[data-theme="dark"] .card.has-photo { border-color: transparent; }

.card-text { flex: 1 1 auto; min-width: 0; }
.card.is-flash { animation: flash 1.5s ease-out; }
@keyframes flash {
  0%, 40% { box-shadow: 0 0 0 3px var(--accent), var(--shadow-md); }
  100% { box-shadow: 0 0 0 0 transparent, var(--shadow-sm); }
}

.card h3 {
  margin: 0 0 .2rem; font-family: var(--serif); font-weight: 600;
  font-size: 1.2rem; letter-spacing: -.016em; line-height: 1.2;
  overflow-wrap: anywhere;
}
.card-kinds {
  margin: 0; font-size: .82rem; color: var(--ink-2); line-height: 1.4;
}
.card-kinds i { font-style: normal; color: var(--line-2); padding: 0 .3rem; }
.card-kinds b {
  font-weight: 700; color: var(--accent-ink);
  box-shadow: inset 0 -.42em 0 var(--accent-soft);
}
/* The dish that explains a search hit. Quiet, because it is a footnote to the result
   rather than part of the place's identity — it only ever appears mid-search. */
.card-menu {
  margin: .3rem 0 0; font-size: .78rem; color: var(--ink-2); line-height: 1.35;
}
.card-menu span {
  font: 700 .62rem/1 var(--sans); letter-spacing: .06em; text-transform: uppercase;
  color: var(--accent-ink); background: var(--accent-soft);
  border-radius: 4px; padding: .18em .32em; margin-right: .38em;
  vertical-align: .06em;
}
.card-where {
  margin: .3rem 0 0; font-size: .79rem; color: var(--ink-3); line-height: 1.4;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
.fav {
  flex: 0 0 auto; width: 30px; height: 30px; margin: -3px -4px 0 0;
  display: grid; place-items: center;
  border: 0; border-radius: 8px; background: transparent;
  color: var(--ink-3); cursor: pointer; font-size: 1.15rem; transition: .15s;
}
.fav:hover { background: var(--accent-soft); color: var(--accent); }
.fav[aria-pressed="true"] { color: var(--accent); }
.fav[aria-pressed="true"] svg { fill: currentColor; }

.card-sub {
  margin: .4rem 0 0; display: flex; align-items: center; gap: .45rem;
  font-size: .8rem; color: var(--ink-2); flex-wrap: wrap;
}
.cat {
  font-weight: 600; font-size: .68rem; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-2); background: var(--bg-sunk);
  border-radius: 5px; padding: .17rem .4rem;
}
.sep { color: var(--line-2); }

/* Only "open" earns a filled pill — everything else is quiet text, so a screen of
   cards reads as a few green highlights instead of 168 coloured boxes. */
.status {
  display: inline-flex; align-items: center; gap: .38rem;
  font: 600 .755rem var(--sans); border-radius: 999px; padding: .22rem .1rem;
}
.status::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex: 0 0 auto;
}
.status.open {
  color: var(--open); background: var(--open-soft); padding: .22rem .6rem .22rem .5rem;
}
.status.open::before { animation: livePulse 2.4s ease-in-out infinite; }
@keyframes livePulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--open) 55%, transparent); }
  60% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--open) 0%, transparent); }
}
.status.soon {
  color: var(--accent-ink); background: var(--accent-soft); padding: .22rem .6rem .22rem .5rem;
}
.status.shut { color: var(--ink-3); }
.status.unknown { color: var(--ink-3); }
.status.unknown::before { opacity: .5; }

.tags { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .65rem; }
.tag {
  font: 500 .755rem var(--sans); color: var(--ink-2);
  border: 1px solid var(--line); border-radius: 6px; padding: .16rem .42rem;
  background: transparent;
  /* Each tag filters the list, so it needs to read as pressable rather than as a label. */
  -webkit-appearance: none; appearance: none;
  cursor: pointer; line-height: inherit;
}
.tag:hover { border-color: var(--accent); color: var(--accent-ink); }
.tag:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tag.is-match { border-color: var(--accent); color: var(--accent-ink); background: var(--accent-soft); }

.stale {
  display: inline-flex; align-items: center; gap: .3rem;
  font: 600 .72rem var(--sans); color: var(--warn-ink);
  cursor: help; white-space: nowrap;
}
.stale::before {
  content: "!"; display: grid; place-items: center;
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--warn-soft); border: 1px solid var(--warn-line);
  font-size: .62rem; font-weight: 800;
}

.fresh-box { margin-top: 1.3rem; display: grid; gap: .5rem; }
.fresh-box p { margin: 0; font-size: .8rem; line-height: 1.55; }
.fresh-ok { color: var(--ink-3); }
.fresh-note {
  color: var(--ink-2); background: var(--bg-sunk);
  border-left: 3px solid var(--line-2); border-radius: 0 6px 6px 0; padding: .5rem .65rem;
}
.fresh-warn {
  color: var(--warn-ink); background: var(--warn-soft);
  border: 1px solid var(--warn-line); border-radius: var(--r-sm); padding: .65rem .75rem;
}
.fresh-warn a { color: inherit; font-weight: 600; }
.fresh-good {
  color: var(--open); background: var(--open-soft);
  border: 1px solid color-mix(in srgb, var(--open) 32%, transparent);
  border-radius: var(--r-sm); padding: .65rem .75rem;
}

.card-foot {
  margin-top: auto; padding: .7rem 0; display: flex; align-items: center;
  gap: .45rem .55rem; flex-wrap: wrap; font-size: .78rem; color: var(--ink-3);
  border-top: 1px solid var(--line);
}
/* Space above the rule without collapsing the auto margin that pins it down. */
.card-body { padding-bottom: .95rem; }
.dist {
  flex: 0 0 auto; margin-left: auto; font-weight: 600; color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.perks { display: flex; gap: .3rem; flex: 0 0 auto; }
.perk { font-size: .82rem; }

/* ---------- empty / footer ---------- */

.empty { text-align: center; padding: 4rem 1rem; }
.empty-art { font-size: 2.6rem; }
.empty h2 { margin: .7rem 0 .3rem; font-size: 1.25rem; letter-spacing: -.02em; }
.empty p { margin: 0 0 1.2rem; color: var(--ink-2); font-size: .9rem; }

.btn {
  font: 600 .86rem var(--sans); border-radius: 10px; padding: .6rem 1rem;
  border: 1px solid var(--line-2); background: var(--bg-elev); color: var(--ink);
  cursor: pointer; transition: .15s; text-decoration: none; display: inline-flex;
  align-items: center; gap: .4rem; justify-content: center;
}
.btn:hover { border-color: var(--ink-3); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.primary:hover { filter: brightness(1.08); }
html[data-theme="dark"] .btn.primary { color: #201404; }

.foot {
  max-width: var(--maxw); margin: 0 auto; padding: 1.6rem 1.25rem 3rem;
  border-top: 1px solid var(--line); font-size: .8rem; color: var(--ink-3);
}
.foot p { margin: 0 0 .5rem; }
.foot strong { color: var(--ink-2); font-variant-numeric: tabular-nums; }
.foot-me {
  display: flex; align-items: center; gap: 1rem; max-width: 34rem;
  margin: 0 0 1.4rem; padding: 1rem 1.1rem; border: 1px solid var(--line);
  border-radius: var(--r); background: var(--bg-elev); box-shadow: var(--shadow-sm);
}
.foot-me img {
  width: 72px; height: 72px; border-radius: 50%; object-fit: cover; flex: none;
}
.foot .foot-me p { margin: 0; font-size: .95rem; line-height: 1.5; color: var(--ink-2); }
.foot-me a { color: var(--accent-ink); font-weight: 600; }
@media (max-width: 480px) {
  .foot-me { gap: .8rem; padding: .85rem .9rem; }
  .foot-me img { width: 56px; height: 56px; }
}

/* ---------- map ---------- */

.mapwrap {
  border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
  box-shadow: var(--shadow-sm); background: var(--bg-sunk);
}
#map { height: clamp(420px, calc(100vh - var(--header-h) - 140px), 780px); }

.leaflet-container { font: inherit; background: var(--bg-sunk); }
.leaflet-popup-content-wrapper {
  border-radius: var(--r-sm); background: var(--bg-elev); color: var(--ink);
  box-shadow: var(--shadow-md); border: 1px solid var(--line);
}
.leaflet-popup-tip { background: var(--bg-elev); border: 1px solid var(--line); }
.leaflet-popup-content { margin: .7rem .85rem; font-size: .85rem; line-height: 1.45; }
.leaflet-popup-close-button { color: var(--ink-3) !important; }
.leaflet-bar a, .leaflet-control-attribution {
  background: var(--bg-elev) !important; color: var(--ink-2) !important; border-color: var(--line) !important;
}
.leaflet-control-attribution a { color: var(--ink-2) !important; }

.pop-name { font-weight: 700; font-size: .95rem; letter-spacing: -.01em; display: block; }
.pop-sub { color: var(--ink-3); font-size: .78rem; }
.pop-open { margin-top: .3rem; display: inline-block; }
.pop-btn {
  display: inline-block; margin-top: .55rem; font: 600 .78rem var(--sans);
  color: var(--accent-ink); background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: 7px; padding: .3rem .6rem; cursor: pointer;
}

.pin {
  width: 26px; height: 26px; border-radius: 50% 50% 50% 4px;
  transform: rotate(45deg);
  background: linear-gradient(150deg, hsl(var(--h, 30) calc(var(--sat, 1) * 85%) 64%), hsl(var(--h, 30) calc(var(--sat, 1) * 72%) 48%));
  border: 2.5px solid var(--bg-elev);
  box-shadow: 0 2px 6px rgba(0,0,0,.35);
  display: grid; place-items: center;
}
.pin span { transform: rotate(-45deg); font-size: .78rem; line-height: 1; }
.pin.shut { background: var(--ink-3); filter: saturate(.25); }

.cluster {
  width: 38px; height: 38px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--ink); color: var(--bg);
  border: 3px solid var(--bg-elev);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .35);
  font: 700 .82rem var(--sans); font-variant-numeric: tabular-nums;
}
.marker-cluster { background: transparent; }
.marker-cluster div { background: transparent; }
.pin.sel { background: var(--ink); width: 32px; height: 32px; z-index: 500; }

/* ---------- drawer ---------- */

.scrim {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(20, 18, 15, .45); backdrop-filter: blur(2px);
  animation: fade .18s ease-out;
}
@keyframes fade { from { opacity: 0; } }

.drawer {
  position: fixed; z-index: 100; top: 0; right: 0; bottom: 0; width: min(440px, 100vw);
  background: var(--bg-elev); border-left: 1px solid var(--line);
  box-shadow: var(--shadow-lg); overflow-y: auto;
  animation: slide .24s cubic-bezier(.2,.8,.25,1);
}
@keyframes slide { from { transform: translateX(102%); } }

/* Sits on the colour band, so it needs its own contrast rather than theme colours. */
.d-close {
  position: absolute; top: .7rem; right: .8rem; z-index: 3;
  width: 34px; height: 34px; border-radius: 50%;
  border: 0; background: rgba(20, 16, 12, .34); color: #fff;
  font-size: 1.35rem; line-height: 1; cursor: pointer;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  transition: background .15s, transform .15s;
}
.d-close:hover { background: rgba(20, 16, 12, .55); transform: scale(1.06); }
.d-close:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* Colour band carrying the same cuisine hue as the card you came from. */
.d-banner {
  height: 116px; display: grid; place-items: center;
  background:
    radial-gradient(120% 150% at 22% 12%,
      hsl(var(--h, 30) calc(var(--sat, 1) * 86%) 70%),
      hsl(var(--h, 30) calc(var(--sat, 1) * 72%) 52%) 58%,
      hsl(calc(var(--h, 30) - 18) calc(var(--sat, 1) * 66%) 42%));
  position: relative; overflow: hidden;
}
.d-banner::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to bottom, transparent 55%, color-mix(in srgb, var(--bg-elev) 92%, transparent));
}
#d-glyph {
  font-size: 3.1rem; line-height: 1;
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .3));
}
/* With a storefront photo the band grows and shows the picture instead. */
#d-photo { display: none; }
.d-banner.has-photo { height: 210px; }
.d-banner.has-photo #d-glyph { display: none; }
.d-banner.has-photo #d-photo {
  display: block; position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  /* The band is far wider than it is tall, so a photo loses most of its height to
     the crop. Centring it cut the fascia off shots where the sign sits high — Bar
     Bagel lost its name entirely. Signage is nearly always in the upper third of a
     storefront picture, so bias the window upwards. Not hard to the top: that would
     fill portrait shots with sky. */
  object-position: center 28%;
}
.d-banner.has-photo::after {
  background: linear-gradient(to bottom, rgba(0, 0, 0, .16) 0%, transparent 38%,
              color-mix(in srgb, var(--bg-elev) 88%, transparent));
}
/* ---------- storefront photo, full size ---------- */

/* Only the photographed banner behaves like a control. */
.d-banner[role="button"] { cursor: zoom-in; }
.d-zoom { display: none; }
.d-banner[role="button"] .d-zoom {
  display: grid; place-items: center;
  position: absolute; right: .7rem; bottom: .7rem; z-index: 2;
  width: 30px; height: 30px; border-radius: 50%;
  background: rgba(0, 0, 0, .45); color: #fff;
  backdrop-filter: blur(3px);
  opacity: .85; transition: opacity .16s, transform .16s;
}
.d-zoom svg { width: 15px; height: 15px; stroke-width: 2; }
.d-banner[role="button"]:hover .d-zoom { opacity: 1; transform: scale(1.08); }
.d-banner[role="button"]:focus-visible {
  outline: 3px solid var(--accent); outline-offset: -3px;
}

.lightbox {
  position: fixed; inset: 0; z-index: 300;
  display: grid; place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(10, 8, 6, .92);
  backdrop-filter: blur(6px);
  animation: fade .18s ease-out;
  cursor: zoom-out;
  /* The whole overlay is a swipe target, so hand every touch to the script rather
     than letting the browser start a scroll or a pinch first. */
  touch-action: none;
  transition: opacity .26s ease;
}
@keyframes fade { from { opacity: 0; } }
.lb-figure {
  margin: 0; display: flex; flex-direction: column; gap: .8rem; align-items: center;
  /* No percentage max-height here. It used to carry one, which meant a tall photo's
     size depended on resolving a percentage against the grid area and then flex-
     shrinking the image to fit — and Safari resolves that differently from Chrome,
     collapsing portrait photos to a thumbnail. The image constrains itself against
     the viewport instead, and this box just wraps whatever comes out. */
  min-height: 0;
  transition: transform .26s cubic-bezier(.2, .8, .3, 1);
}
/* While a finger is on it the position comes from the script frame by frame; the
   transition is only there to carry it home when the swipe falls short. */
.lb-figure.is-dragging { transition: none; }
#lb-img {
  display: block; cursor: default;
  /* Both limits are measured against the viewport, never against the parent. The
     old max-width of 100% pointed at the figure, whose own width comes from this
     image — a circle the browser has to break, and Safari broke it small. The 8rem
     and 2rem leave room for the caption and the overlay's padding. */
  max-width: min(1400px, calc(100vw - 2rem));
  max-height: calc(100vh - 8rem);
  max-height: calc(100dvh - 8rem);   /* ignored where dvh is unknown; mobile chrome-safe */
  width: auto; height: auto;
  /* Never let the column flex shrink it below the size those limits produced. */
  flex: 0 0 auto;
  border-radius: var(--r-sm);
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, .8);
}
#lb-caption {
  color: #f4f1ea; font: 600 .92rem var(--sans); text-align: center;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .6);
}
.lb-close {
  position: absolute; top: 1rem; right: 1rem; z-index: 1;
  width: 42px; height: 42px; border-radius: 50%;
  border: 0; cursor: pointer;
  background: rgba(255, 255, 255, .14); color: #fff;
  font-size: 1.6rem; line-height: 1;
  backdrop-filter: blur(4px);
}
.lb-close:hover { background: rgba(255, 255, 255, .26); }
.lb-close:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .lightbox { animation: none; }
  .d-banner[role="button"]:hover .d-zoom { transform: none; }
}

/* ---------- pull to refresh ---------- */

/* Added to an iPad home screen, the site opens standalone: no address bar, and so
   none of Safari's own pull-to-refresh, which lives on that bar. This puts the
   gesture back. The travel is driven from JS frame by frame while the finger is
   down, so the transition is only switched on for the snap home. */
.ptr {
  position: fixed; top: 0; left: 50%; z-index: 200;
  display: grid; place-items: center;
  width: 38px; height: 38px; margin-left: -19px;
  border-radius: 50%;
  background: var(--bg-elev); color: var(--ink-2);
  box-shadow: var(--shadow-md);
  opacity: 0; pointer-events: none;
  transform: translateY(-46px);
}
.ptr svg {
  width: 19px; height: 19px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.ptr.is-settling { transition: transform .3s cubic-bezier(.2, .8, .3, 1), opacity .3s ease; }
/* Pulled far enough that letting go will reload. */
.ptr.is-ready { color: var(--accent); }
.ptr.is-busy svg { animation: ptr-spin .7s linear infinite; }
@keyframes ptr-spin { to { transform: rotate(360deg); } }

@media (display-mode: standalone) {
  /* Kill the rubber-band at the top so the indicator is the only thing that moves
     during a pull. Scoped to the home-screen app — in an ordinary browser tab the
     bounce belongs to the browser and shouldn't be taken away. */
  html { overscroll-behavior-y: contain; }
}

.menu-btn { text-decoration: none; }

/* Transcribed menu, set like a printed one rather than shown as a photograph */
.menu-box { margin-top: 1.6rem; }
.menu-box h3 {
  margin: 0 0 .7rem; font: 600 .74rem var(--sans); letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-3);
}
.menu-body {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg-sunk); padding: .1rem 1rem .9rem;
}
.ms + .ms { border-top: 1px dashed var(--line-2); margin-top: .9rem; padding-top: .9rem; }
.ms h4 {
  margin: .9rem 0 .6rem; font-family: var(--serif); font-weight: 600;
  font-size: 1.02rem; letter-spacing: -.01em; color: var(--ink);
  display: flex; align-items: baseline; gap: .5rem;
}
.ms-note {
  font: 500 .72rem var(--sans); color: var(--ink-3);
  letter-spacing: .02em; text-transform: none;
}
.mi-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .62rem; }

.mi-head { display: flex; align-items: baseline; gap: .35rem; }
.mi-name { font: 600 .855rem var(--sans); color: var(--ink); }
.mi-raw {
  font-style: normal; font-size: .72em; font-weight: 700; margin-left: .28em;
  vertical-align: super; cursor: help;
  color: var(--ink-3);
}
/* Leader dots, the way a printed menu runs the eye across to the price. */
.mi-dots {
  flex: 1 1 auto; height: .55em;
  border-bottom: 1.5px dotted var(--line-2);
  transform: translateY(-.15em);
}
.mi-price {
  font: 600 .855rem var(--sans); color: var(--accent-ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.mi-desc { margin: .12rem 0 0; font-size: .795rem; line-height: 1.45; color: var(--ink-2); max-width: 46ch; }
.mi-extra { margin: .15rem 0 0; font-size: .755rem; color: var(--ink-3); font-style: italic; }
.ms-footer {
  margin: .75rem 0 0; font-size: .765rem; line-height: 1.5; color: var(--ink-3);
  border-top: 1px solid var(--line); padding-top: .55rem;
}

.menu-note { margin: .6rem 0 0; font-size: .755rem; color: var(--ink-3); line-height: 1.5; }
.menu-link { margin: .45rem 0 0; font-size: .82rem; }
.menu-link a { font-weight: 600; }

.d-body { padding: 1.1rem 1.5rem 2.5rem; }
.d-kicker {
  margin: 0 0 .35rem; font: 600 .72rem var(--sans); letter-spacing: .07em;
  text-transform: uppercase; color: var(--accent-ink);
}
#d-name {
  margin: 0 0 .6rem; font-family: var(--serif); font-weight: 600;
  font-size: 1.72rem; letter-spacing: -.022em; line-height: 1.12;
}
.d-status { margin-bottom: .75rem; }

.d-meta { margin-top: 1.1rem; display: grid; gap: .5rem; font-size: .875rem; }
.d-row { display: flex; gap: .6rem; align-items: flex-start; color: var(--ink-2); }
.d-row svg { flex: 0 0 auto; font-size: 1.05rem; margin-top: 1px; color: var(--ink-3); }
.d-row a { color: var(--accent-ink); text-decoration: none; overflow-wrap: anywhere; }
.d-row a:hover { text-decoration: underline; }
/* Warm rather than alarming — it is a thing to know before you set off, not an error. */
.d-row.cash-only { color: var(--warn-ink); }
.d-row.cash-only svg { color: var(--warn-ink); }

.d-actions { margin-top: 1.2rem; display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
.d-actions .btn { padding: .65rem .8rem; font-size: .84rem; }
.d-actions .btn.wide { grid-column: 1 / -1; }

.hours-box { margin-top: 1.5rem; }
.hours-box h3, .d-minimap-title {
  margin: 0 0 .5rem; font: 600 .74rem var(--sans); letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-3);
}
.hours { width: 100%; border-collapse: collapse; font-size: .85rem; }
.hours th, .hours td { padding: .38rem .1rem; text-align: left; font-weight: 500; }
.hours th { color: var(--ink-2); width: 6.2rem; }
.hours td { color: var(--ink); font-variant-numeric: tabular-nums; }
.hours tr + tr { border-top: 1px dashed var(--line); }
.hours tr.today th, .hours tr.today td { color: var(--accent-ink); font-weight: 700; }
.hours td.off { color: var(--ink-3); }
.no-hours { font-size: .85rem; color: var(--ink-3); margin: 0; line-height: 1.55; }

.d-minimap { margin-top: 1.5rem; }
.d-minimap-link {
  display: block; text-decoration: none; width: 100%;
  /* It became a <button> when it stopped going straight to Google, so reset the
     chrome a button brings with it: background, border, padding and centring. */
  -webkit-appearance: none; appearance: none;
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.d-minimap-inner {
  display: block;
  height: 190px; border-radius: var(--r-sm); overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-sunk);
  transition: border-color .16s, box-shadow .16s;
}
/* The map is a picture inside a link — let every click reach the anchor.
   Leaflet puts .leaflet-container on the element it initialises into, which here
   IS .d-minimap-inner, so this has to match the same element, not a descendant. */
.d-minimap-inner, .d-minimap-inner * { pointer-events: none; }
.d-minimap-link:hover .d-minimap-inner,
.d-minimap-link:focus-visible .d-minimap-inner {
  border-color: var(--accent); box-shadow: 0 0 0 3.5px var(--accent-soft);
}
/* The cue sits in the heading, above the link, so hover is tracked on the shared
   parent rather than with a sibling selector. */
.d-minimap-cta { float: right; color: var(--accent-ink); font-weight: 600; }
.d-minimap:hover .d-minimap-cta { text-decoration: underline; }
.d-osm { margin: 1.4rem 0 0; font-size: .74rem; color: var(--ink-3); }
.d-osm a { color: var(--ink-3); }

/* ---------- toast ---------- */

.toast {
  position: fixed; z-index: 200; left: 50%; bottom: 1.6rem; transform: translateX(-50%);
  background: var(--ink); color: var(--bg);
  font: 600 .85rem var(--sans); padding: .7rem 1.1rem; border-radius: 10px;
  box-shadow: var(--shadow-lg); animation: pop .22s cubic-bezier(.2,.8,.25,1);
  max-width: calc(100vw - 2rem); text-align: center;
}
@keyframes pop { from { opacity: 0; transform: translate(-50%, 12px); } }

/* ---------- responsive ---------- */

@media (max-width: 900px) {
  .topbar-inner { flex-wrap: wrap; padding-bottom: .5rem; }
  .search { order: 3; flex-basis: 100%; max-width: none; }
  .topbar-actions { margin-left: auto; }
  .slash-hint { display: none; }
  #q { padding-right: 2.6rem; }
  .q-clear { right: .6rem; }
}

@media (max-width: 620px) {
  /* The filter block is too tall to pin on a phone — let the header scroll away. */
  .topbar { position: static; }
  .brand-text small { display: none; }
  .icon-btn span { display: none; }
  .icon-btn { padding: .55rem; }
  .filter-row.secondary { gap: .4rem; }
  .select { padding-left: .6rem; flex: 1 1 calc(50% - .25rem); min-width: 0; justify-content: space-between; }
  .select select { flex: 1 1 auto; min-width: 0; }
  .select > span { display: none; }
  .toggle { flex: 1 1 calc(50% - .25rem); justify-content: center; }
  .viewswitch { flex: 1 1 100%; }
  .vs-btn { flex: 1 1 50%; justify-content: center; }
  .spacer { display: none; }
  .grid { grid-template-columns: 1fr; }
  main { padding-left: 1rem; padding-right: 1rem; }
  .filters, .topbar-inner { padding-left: 1rem; padding-right: 1rem; }
  .drawer { width: 100vw; }

  /* Searching on a phone. With the keyboard up there is room for about four lines of
     page, and the brand row and three rows of filters took all of them — you typed
     and saw nothing change. So while the search box has focus the header pins to the
     top as just the search box, the filters step aside, and the results start straight
     under it (app.js scrolls them there). The filters return when the keyboard goes. */
  body.is-searching .topbar { position: sticky; top: 0; }
  body.is-searching .brand,
  body.is-searching .topbar-actions,
  body.is-searching .filters > :not(.sort-quick) { display: none; }
  /* NEARBY and A-Z stay: they are how you order what the search finds. */
  body.is-searching .filters { padding-bottom: .55rem; }
  body.is-searching .topbar-inner { padding-top: .55rem; padding-bottom: .55rem; }
  /* Tall enough to scroll the header to the top even when only one place matches. */
  body.is-searching main { min-height: 100vh; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  html { scroll-behavior: auto; }
  /* The one exception. A spinner is a progress indicator, not decoration — near-zero
     duration would leave it juddering in place while the page reloads behind it. */
  .ptr.is-busy svg { animation-duration: .7s !important; }
}

/* ---------------------------------------------------------------- *
   Directions chooser

   One button asked which map app to use, so this is what it asks in. Sized and
   centred like the lightbox, but a small sheet rather than a full-bleed overlay —
   it is a three-way question, not a picture.
 * ---------------------------------------------------------------- */
.mapchoice {
  position: fixed; inset: 0; z-index: 320;
  display: grid; place-items: center;
  padding: clamp(1rem, 5vw, 3rem);
  background: rgba(10, 8, 6, .55);
  backdrop-filter: blur(3px);
  animation: fade .16s ease-out;
}
.mc-sheet {
  width: min(21rem, 100%);
  background: var(--bg-card, var(--bg)); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-md, 14px);
  box-shadow: 0 24px 60px -18px rgba(0, 0, 0, .55);
  padding: 1.1rem 1.1rem .9rem;
}
.mc-title {
  margin: 0 0 .85rem; font: 700 .95rem/1.35 var(--sans); color: var(--ink);
}
.mc-title span { color: var(--ink-2); font-weight: 600; }
.mc-apps { display: grid; gap: .45rem; }
.mc-app {
  display: flex; align-items: center; justify-content: space-between;
  font: 600 .9rem var(--sans); color: var(--ink); text-decoration: none;
  border: 1px solid var(--line); border-radius: 10px;
  padding: .62rem .8rem; background: var(--bg-sunk, transparent);
  transition: border-color .15s, background .15s;
}
.mc-app span { color: var(--ink-3); font-weight: 400; }
.mc-app:hover { border-color: var(--accent); background: var(--accent-soft); }
.mc-app:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.mc-cancel {
  display: block; width: 100%; margin-top: .7rem;
  font: 600 .85rem var(--sans); color: var(--ink-2);
  background: none; border: 0; padding: .5rem; cursor: pointer; border-radius: 8px;
}
.mc-cancel:hover { color: var(--ink); background: var(--bg-sunk); }
.mc-cancel:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
@media (prefers-reduced-motion: reduce) { .mapchoice { animation: none; } }

/* ---------------------------------------------------------------- *
   Happy hour
   The badge only appears while one is actually running, so it can afford to be
   loud. The panel line is quieter — it is there whether or not the clock agrees,
   because someone planning Thursday wants to read Thursday.
 * ---------------------------------------------------------------- */
.hh-badge {
  display: inline-block; margin: .3rem 0 0;
  font: 700 .68rem/1 var(--sans); letter-spacing: .04em; text-transform: uppercase;
  color: var(--warn-ink); background: var(--warn-soft);
  border: 1px solid var(--warn-line); border-radius: 999px; padding: .24em .5em;
}
.hh-live { color: var(--warn-ink); font-weight: 700; }
.hh-what { display: block; margin-top: .15rem; color: var(--ink-2); font-size: .82rem; line-height: 1.4; }

/* Brunch wears the same badge as happy hour in a different colour, so the two read as
   the same kind of fact — something that is on right now — rather than two inventions. */
.hh-badge.hh-brunch { color: var(--open); background: var(--open-soft); border-color: color-mix(in srgb, var(--open) 30%, transparent); }
/* Lunch in a third colour, so a card never leaves you guessing which of the three is on. */
.hh-badge.hh-lunch { color: #1f5f8b; background: #e3f0fa; border-color: #b9d6ec; }
html[data-theme="dark"] .hh-badge.hh-lunch { color: #9fd0f2; background: #16283a; border-color: #2c4a63; }
.card.has-photo .hh-badge.hh-lunch { background: #bfe0f7; color: #0e3a57; }

/* ---------------------------------------------------------------- *
   Happy hour schedule
   A timetable, not a card grid: the time is the left-hand column and everything
   lines up against it, so the eye can run down the hour rather than hunt.
 * ---------------------------------------------------------------- */
.schedule { max-width: var(--maxw); margin: 0 auto; padding: 0 1.25rem 3rem; }
.sd-tabs { display: flex; flex-wrap: wrap; gap: .4rem; margin: .2rem 0 1.4rem; }
.sd-tab {
  display: inline-flex; align-items: baseline; gap: .38rem;
  font: 600 .85rem var(--sans); color: var(--ink);
  background: var(--bg-elev); border: 1px solid var(--line-2); border-radius: 999px;
  padding: .5rem .9rem; cursor: pointer; box-shadow: var(--shadow-sm);
  transition: transform .16s cubic-bezier(.2,.7,.3,1), box-shadow .16s, background .16s, color .16s;
}
.sd-tab span { font-size: .74rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.sd-tab:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.sd-tab.is-on { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.sd-tab.is-on span { color: var(--bg); opacity: .7; }

.sd-heading { margin: 0 0 .9rem; font: 600 1.35rem var(--serif); letter-spacing: -.01em; }
.sd-heading.sd-sub { margin-top: 2rem; font-size: 1.05rem; color: var(--ink-2); }
.sd-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.sd-row {
  display: grid; grid-template-columns: 10.5rem 1fr; gap: 1rem; align-items: start;
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: .85rem 1rem; cursor: pointer;
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.sd-row:hover { border-color: var(--accent); box-shadow: var(--shadow-md); transform: translateY(-1px); }
.sd-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sd-when {
  font: 700 .88rem var(--sans); color: var(--accent-ink);
  font-variant-numeric: tabular-nums; line-height: 1.5;
}
.sd-when-none { color: var(--ink-3); }
.sd-body { display: block; line-height: 1.45; }
.sd-body b { font-size: .98rem; }
.sd-live {
  margin-left: .5rem; font: 700 .64rem/1 var(--sans); letter-spacing: .05em; text-transform: uppercase;
  color: var(--warn-ink); background: var(--warn-soft); border: 1px solid var(--warn-line);
  border-radius: 999px; padding: .22em .48em; vertical-align: .1em;
}
.sd-what { display: block; margin-top: .18rem; font-size: .84rem; color: var(--ink-2); }
.sd-where { display: block; margin-top: .12rem; font-size: .78rem; color: var(--ink-3); }
.sd-none { color: var(--ink-2); font-size: .95rem; }
.sd-foot { margin-top: 1.6rem; font-size: .8rem; color: var(--ink-3); }
@media (max-width: 560px) {
  .sd-row { grid-template-columns: 1fr; gap: .3rem; }
  .sd-when { font-size: .82rem; }
}

/* Schedule rows with a storefront. The photo runs the full width of the row behind the
   timetable, and the scrim runs left to right: dark under the time and the words, clear
   on the right so the building shows. Rows are made tall enough that the photo reads as
   a band of storefront rather than a sliver. What's on uses the same rows, with a few
   adjustments of its own further down. */
.sd-row.has-photo {
  position: relative; overflow: hidden; isolation: isolate;
  min-height: 8.5rem; align-content: center;
  /* The words get a capped column and the rest of the row is left to the building. */
  grid-template-columns: 10.5rem minmax(0, 32rem) 1fr;
  background: #1c1916; border-color: transparent; color: #fff;
  padding: 1rem 1.2rem;
}
.sd-photo {
  position: absolute; inset: 0; z-index: -2;
  /* The band of the photo the sign is in (--py), slid right by --tx when the sign would
     otherwise sit under the words. The feathered left edge hides the seam that leaves,
     which falls under the darkest part of the scrim anyway. */
  /* --bw narrows it to sit right of the words when its sign is too tall for the band;
     see liftSigns() in app.js. */
  left: auto; right: 0; width: var(--bw, 100%);
  height: 100%; object-fit: cover; object-position: 50% var(--py, 35%);
  transform: translateX(var(--tx, 0%));
  -webkit-mask-image: linear-gradient(to right, transparent, #000 14%);
          mask-image: linear-gradient(to right, transparent, #000 14%);
  transition: transform .5s cubic-bezier(.2,.7,.3,1);
}
.sd-row.has-photo:hover { border-color: transparent; }
.sd-row.has-photo:hover .sd-photo { transform: translateX(var(--tx, 0%)) scale(1.03); }
.sd-row.has-photo::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  /* Measured in rem, not percent: the dark part has to follow the text column, which is
     a fixed width, not stretch and shrink with the row. */
  background: linear-gradient(to right, rgba(12,10,8,.78) 0, rgba(12,10,8,.62) 30rem,
                                        rgba(12,10,8,.28) 44rem, transparent 54rem);
}
.sd-row.has-photo .sd-when,
.sd-row.has-photo .sd-body { text-shadow: 0 1px 2px rgba(0,0,0,.75), 0 0 14px rgba(0,0,0,.5); }
.sd-row.has-photo .sd-when { color: #ffd9a8; font-size: .98rem; }
.sd-row.has-photo .sd-when-none { color: rgba(255,255,255,.6); }
.sd-row.has-photo .sd-body b { color: #fff; font-family: var(--serif); font-size: 1.28rem; font-weight: 600; }
.sd-row.has-photo .sd-what { color: rgba(255,255,255,.92); font-size: .92rem; max-width: 40rem; }
.sd-row.has-photo .sd-where { color: rgba(255,255,255,.76); font-size: .85rem; }
/* The distance is a <b> inside the body too, so it has to out-rank the name rule. */
.sd-row.has-photo .sd-body b.sd-dist { color: #fff; font-family: var(--sans); font-size: inherit; }
.sd-row.has-photo .sd-live {
  background: #fde68a; color: #5b3a06; border-color: transparent; text-shadow: none;
  font-size: .7rem;
}
/* What's on — the town-wide events listing between the hero and the toolbar.
   It borrows the schedule's row and tab styling wholesale rather than growing a second
   set that drifts; only the header and the venue name need anything of their own. */
.whatson {
  max-width: var(--maxw); margin: 0 auto;
  padding: 2rem 1.25rem .4rem;
}
.wo-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: .1rem .7rem; margin-bottom: .7rem; }
.wo-title { margin: 0; font: 600 1.5rem var(--serif); letter-spacing: .04em; }   /* set in caps, so a little tracking */
.wo-sub { font-size: .82rem; color: var(--ink-3); }
.whatson .sd-tabs { margin: .2rem 0 1.1rem; }
.whatson .sd-heading { font-size: 1.05rem; margin-bottom: .7rem; }
.whatson .sd-heading.sd-sub { margin-top: 1.5rem; }
.whatson .sd-row { grid-template-columns: 9.5rem 1fr; padding: .7rem .9rem; }
/* The venue is the point of an events listing — you know what a quiz is, you need to
   know whose quiz it is — so it is coloured and sits directly under the event name. */
.wo-at { display: block; margin-top: .1rem; font: 600 .82rem var(--sans); color: var(--accent-ink); }
.whatson .sd-what { font-size: .8rem; }
/* A dated event running today. Same shape as the on-now badge but in the accent,
   because it means something different: on now is live, today is still to come. */
.wo-today { color: var(--accent-ink); background: var(--accent-soft); border-color: var(--line-2); }
/* The day's events scroll inside a fixed height instead of being cut off at a count.
   This section sits above the search, so it cannot grow without pushing the directory
   off the screen — but hiding rows behind a Show all was worse than asking for a
   scroll, because the row you wanted was as likely to be the hidden one. */
.wo-scroll {
  max-height: min(56vh, 30rem); overflow-y: auto; overscroll-behavior: contain;
  padding: .15rem .3rem .3rem 0; margin-right: -.3rem;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 1.6rem), transparent);
          mask-image: linear-gradient(to bottom, #000 calc(100% - 1.6rem), transparent);
}
/* The fade says there is more below. Once you reach the bottom there is not, and
   leaving it on dims the last row for good — so it comes off, toggled in drawWhatsOn. */
.wo-scroll.at-end { -webkit-mask-image: none; mask-image: none; }
/* What's on rows with the venue's storefront behind them. Its own tighter columns
   would otherwise win over the photo layout, so they are restated here, and the rows
   are a little shorter than on the schedules because this list scrolls in a box. */
.whatson .sd-row.has-photo {
  grid-template-columns: 9.5rem minmax(0, 32rem) 1fr;
  min-height: 7.5rem; padding: .9rem 1.1rem;
}
/* The venue stays coloured, as it is on a plain row — a warmer amber than the time,
   so the two do not read as one line. */
.sd-row.has-photo .wo-at { color: #ffb77a; font-size: .9rem; }
/* Today is still to come rather than live, so it keeps its own colour on a photo. */
.sd-row.has-photo .sd-live.wo-today { background: #c2410c; color: #fff; }
.wo-split {
  list-style: none; margin: .9rem 0 .1rem; padding: 0;
  font: 600 .82rem var(--sans); color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .06em;
}
@media (max-width: 560px) {
  .whatson { padding-top: 1.4rem; }
  .whatson .sd-row { grid-template-columns: 1fr; gap: .25rem; }
  .wo-title { font-size: 1.3rem; }
}

/* Distance on a schedule row, when Closest to me is driving the order. Same weight as
   the address it follows, just not grey — it is the reason the row sits where it does. */
.sd-dist { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }

/* A day whose hours are standing in for the usual ones — a holiday, a one-off. */
.hr-special {
  display: block;
  font-size: .78em;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--accent, #a4462b);
  font-weight: 600;
}

/* What's on — quizzes, leagues, markets. Sits under the hours, where someone
   already looking up "are they open" will see it. */
.events-box { margin-top: 1.1rem; }
.ev-list { list-style: none; margin: .4rem 0 0; padding: 0; }
.ev { padding: .55rem 0; border-top: 1px solid var(--rule, rgba(0,0,0,.09)); }
.ev:first-child { border-top: 0; }
.ev-name { font-weight: 600; }
.ev-when { color: var(--muted, #6b6b60); margin-left: .5rem; font-size: .92em; }
.ev-live {
  margin-left: .5rem; font-size: .74em; letter-spacing: .05em; text-transform: uppercase;
  color: var(--accent, #a4462b); font-weight: 700;
}
.ev-what { margin: .2rem 0 0; color: var(--muted, #6b6b60); font-size: .93em; }

/* Photo rows stack — sign above, words at the foot — whenever the row is too narrow for
   the timetable to leave the sign a clear stretch to the right of the text. The text
   column alone runs to about 43rem, so below a 1040px window a wide row put the sign
   under the words on every tablet and narrow laptop. app.js's STACKED query must match. */
@media (max-width: 1040px) {
  .sd-row.has-photo,
  .whatson .sd-row.has-photo {
    min-height: 15rem; align-content: end; grid-template-columns: 1fr; gap: .3rem;
    /* A picture area the words cannot climb into — a long deal filled whole rows on a
       phone and left the sign nowhere to go. The row grows instead. */
    padding-top: 8rem;
  }
  /* Shorter in What's on, so its scroll box still shows more than two. */
  .whatson .sd-row.has-photo { min-height: 12rem; padding-top: 7rem; }
  /* Framed like a card: no slide; --oy pans a portrait photo, --rs zooms what is left. */
  .sd-photo {
    width: 100%;
    object-position: var(--fx, 50%) var(--oy, 28%);
    transform-origin: var(--fx, 50%) 100%; transform: scale(var(--rs, 1));
    -webkit-mask-image: none; mask-image: none;
  }
  .sd-row.has-photo:hover .sd-photo { transform: scale(calc(var(--rs, 1) * 1.03)); }
  /* A long deal can fill most of a stacked row, so the scrim has to climb further than
     on the wide layout or the time ends up on bare sky. */
  .sd-row.has-photo::after {
    background:
      linear-gradient(to top, rgba(12,10,8,.8) 0%, rgba(12,10,8,.66) 55%,
                              rgba(12,10,8,.32) 80%, rgba(12,10,8,.08) 100%);
  }
}

/* ---------------------------------------------------------------- *
   Phone fixes, October 2026

   From a consultant's read of the site on a phone, after it proved hard to show off
   at a bar: the list now arrives a page at a time, the cuisine wheel is a chip row,
   What's on folds to one line, the hero keeps only what nothing else on the page
   offers, and everything a thumb has to hit is at least 44px.
 * ---------------------------------------------------------------- */

.more-wrap { display: flex; justify-content: center; padding: 1.4rem 0 .5rem; }
.more-wrap:has(> [hidden]) { display: none; }
.btn.more { min-height: 48px; padding: 0 1.6rem; font-weight: 600; }

/* The address in the place panel opens the same map chooser as Directions. */
.d-addr {
  font: inherit; color: var(--accent-ink); background: none; border: 0; padding: 0;
  text-align: left; cursor: pointer; text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
  text-underline-offset: 3px;
}

/* Desktop keeps the cuisine list; the chip row is for phones. */
.cuisine-row { display: none; }

.wo-toggle {
  margin-left: auto; align-self: center;
  font: 600 .85rem var(--sans); color: var(--accent-ink);
  background: var(--accent-soft); border: 1px solid var(--line-2); border-radius: 999px;
  min-height: 44px; padding: 0 1rem; cursor: pointer;
}
.wo-folded { margin-bottom: 0; cursor: pointer; align-items: center; }

@media (max-width: 620px) {
  .cuisine-row { display: block; }
  .select:has(#cuisine) { display: none; }
  .hero-quick .qbtn.dup { display: none; }
  /* The four that remain sit as an even two-by-two rather than a ragged wrap. */
  .hero-quick { display: grid; grid-template-columns: 1fr 1fr; }
  .whatson { padding-top: 1rem; padding-bottom: .2rem; }
  .whatson:has(.wo-folded) {
    margin: .8rem 1rem 0; padding: .35rem .5rem .35rem 1rem;
    border: 1px solid var(--line); border-radius: 16px; background: var(--bg-elev);
  }

  /* Tap targets: 44px is the floor for anything a thumb has to hit. */
  .qbtn, .chip, .toggle, .sd-tab, .tag, .btn { min-height: 44px; }
  .chip { padding: 0 .95rem; }
  .select { min-height: 44px; }
  .fav { width: 44px; height: 44px; margin: -8px -10px 0 0; }
  .card.has-photo .fav { width: 44px; height: 44px; top: .45rem; right: .45rem; }
  .pill button { min-width: 36px; min-height: 36px; }
  .d-close { width: 44px; height: 44px; }
}
@media (max-width: 620px) {
  /* "Schedule" is what pushed two of the four onto a second line at phone width. */
  .q-long { display: none; }
  /* Open now, Near me and Saved share one row; Area and Sort share the next. */
  .filter-row.secondary .toggle { flex: 1 1 calc(33.333% - .3rem); padding-left: .4rem; padding-right: .4rem; }
}

/* Events and the happy hour, lunch and brunch schedules: the day is a menu, starting on today. */
.ev-day { display: inline-block; margin: .1rem 0 1rem; max-width: 100%; }
.ev-day select {
  font: 600 1rem var(--sans); color: var(--ink);
  background: var(--bg-elev); border: 1px solid var(--line-2); border-radius: 999px;
  min-height: 44px; padding: 0 2.4rem 0 1.1rem; max-width: 100%; cursor: pointer;
  -webkit-appearance: none; appearance: none; box-shadow: var(--shadow-sm);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.15rem) 52%, calc(100% - .8rem) 52%;
  background-size: .38rem .38rem; background-repeat: no-repeat;
}
.q-n { font-variant-numeric: tabular-nums; }
/* With the filter rows gone the bar is just the brand and the search box. */
.filters:not(:has(> :not([hidden]))) { display: none; }
@media (max-width: 620px) {
  /* Room for Events and Hide on one line. */
  .whatson .wo-sub { display: none; }
  .wo-head { flex-wrap: nowrap; align-items: center; }
}

/* NEARBY and A-Z under the search box, sized like the hero's four. */
.sort-quick { display: flex; gap: .5rem; padding-top: .1rem; }
@media (max-width: 620px) {
  /* Inset to the hero's 1.25rem gutter so the two match its buttons exactly. */
  .sort-quick { display: grid; grid-template-columns: 1fr 1fr; padding: 0 .25rem; }
}

/* A recent opening. Small and solid, so it reads on a photo and on a plain card. */
.new-badge {
  display: inline-block; vertical-align: .25em; margin-left: .3em;
  font: 800 .62rem/1 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  color: #fff; background: var(--accent); border-radius: 999px; padding: .32em .55em;
  text-shadow: none;
}
#d-name .new-badge { font-size: .7rem; }
.d-osm .d-fix { font-size: .84rem; color: var(--ink-2); }
