/* ==========================================================================
   lc-dishes — the menu on a restaurant page (.lc-dm) and the universal menu (.lc-um)

   ONE STYLESHEET FOR BOTH, on purpose: a dish looks the same wherever a reader meets it,
   so the price, the description and the photograph keep their relationship between the
   restaurant page and the cross-restaurant search. Two stylesheets would drift.

   WHY A MENU IS NOT A GRID OF CARDS

   A menu is a typographic document. Its order carries meaning — starters before mains,
   the kitchen's own sequencing — and boxing each dish destroys the scan that makes a menu
   readable: name, then price, down the right edge, in one eye movement. So the list is a
   list, with a hairline between rows and the price on a rail.

   The photographs are the exception and they lead. Roughly a fifth of the corpus carries a
   dish photograph, which is far too thin to filter on and plenty to open on, so the shots
   are lifted out of the list into a rail across the top. People choose food with their eyes
   before they read a word, and a page of pure type would be the wordless-page failure with
   the words left in.

   Tokens are the restaurant single's own, redeclared here rather than inherited: this file
   also loads on /menu/, where that page's inline block does not exist. box-sizing is scoped
   to these two components — a global reset is known to make links on this site render wider
   than they were asked to.
   ========================================================================== */

.lc-dm,
.lc-um {
  --dm-ink: #1d2721;
  --dm-muted: #6b7772;          /* 4.7:1 on white — passes body text */
  --dm-line: #e3e6e3;
  --dm-bg: #fff;
  --dm-soft: #f6f7f5;
  --dm-accent: #2f6f57;
  --dm-accent-ink: #24543f;     /* 6.4:1 — the accent as *text*, which the paler one is not */
  --dm-gold: #b8863b;
  --dm-well: #16201b;
  --dm-serif: "PT Serif", Georgia, serif;
  --dm-sans: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --dm-pad: clamp(18px, 4vw, 24px);
  color: var(--dm-ink);
  font-family: var(--dm-serif);
}
.lc-dm *,
.lc-um * { box-sizing: border-box; }

/* ==========================================================================
   THE MENU SECTION on a restaurant page
   ========================================================================== */

.lc-dm {
  background: var(--dm-soft);
  border-top: 1px solid var(--dm-line);
  padding: clamp(38px, 5vw, 60px) 0 clamp(44px, 6vw, 72px);
}
.lc-dm__inner { max-width: 1100px; margin: 0 auto; padding: 0 var(--dm-pad); }

.lc-dm__head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 8px 20px; padding-bottom: 10px; border-bottom: 1px solid var(--dm-line); margin-bottom: 26px;
}
.lc-dm__h {
  font-family: var(--dm-sans); text-transform: uppercase; letter-spacing: 2px;
  font-size: 11px; font-weight: 600; color: var(--dm-muted); margin: 0;
}
/* The date is the whole basis for republishing somebody's prices without asking, so it is
   set as a readable line rather than as fine print. */
.lc-dm__prov { margin: 0; font-size: .92rem; color: var(--dm-muted); }
.lc-dm__prov time { font-variant-numeric: tabular-nums; }
.lc-dm__order { color: var(--dm-accent-ink); font-weight: 700; text-decoration: none; border-bottom: 1px solid currentColor; }
.lc-dm__order:hover { color: var(--dm-ink); }

/* --- the photographed rail ------------------------------------------------ */

.lc-dm__strip {
  list-style: none; margin: 0 0 34px; padding: 0 0 10px;
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(210px, 240px);
  gap: 12px; overflow-x: auto; scroll-snap-type: x proximity;
  /* A rail that is clearly scrollable rather than one that hides its overflow. */
  scrollbar-width: thin;
  overscroll-behavior-x: contain;
}
.lc-dm__shot {
  position: relative; scroll-snap-align: start; border-radius: 3px; overflow: hidden;
  background: var(--dm-well); box-shadow: 0 2px 10px rgba(20, 30, 24, .10);
}
.lc-dm__shot img { display: block; width: 100%; height: 158px; object-fit: cover; }
.lc-dm__shotcap {
  position: absolute; inset: auto 0 0 0; padding: 22px 12px 10px; color: #fff;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 10px;
  background: linear-gradient(to top, rgba(16, 24, 19, .88), rgba(16, 24, 19, 0));
}
.lc-dm__shotname { font-size: .88rem; line-height: 1.25; font-weight: 700; }
.lc-dm__shotprice { font-family: var(--dm-sans); font-size: .78rem; font-weight: 600; white-space: nowrap; }

/* --- menu tabs (radio-driven, no script) ---------------------------------- */

.lc-dm__radio { position: absolute; opacity: 0; pointer-events: none; }
.lc-dm__tabs { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 24px; }
.lc-dm__tab {
  font-family: var(--dm-sans); text-transform: uppercase; letter-spacing: 1.2px;
  font-size: 10.5px; font-weight: 600; padding: 9px 15px; border: 1px solid var(--dm-line);
  border-radius: 2px; background: var(--dm-bg); color: var(--dm-muted); cursor: pointer;
  transition: color .15s, border-color .15s, background .15s;
}
.lc-dm__tab:hover { color: var(--dm-ink); border-color: var(--dm-muted); }
.lc-dm__radio:checked + .lc-dm__tab {
  background: var(--dm-ink); border-color: var(--dm-ink); color: #fff;
}
.lc-dm__radio:focus-visible + .lc-dm__tab { outline: 2px solid var(--dm-accent); outline-offset: 2px; }

/* Only the checked menu shows. nth-of-type pairs each radio with its panel by position —
   the radios all sit in .lc-dm__tabs, so the panel cannot be a sibling selector away, and
   the script below is what actually toggles [hidden]. With script off every menu renders,
   which is the correct degradation: all the food, none of the switching. */
.lc-dm__menu[hidden] { display: none; }

.lc-dm__menuname,
.lc-dm__sec {
  font-family: var(--dm-sans); text-transform: uppercase; letter-spacing: 1.6px;
  font-weight: 600; color: var(--dm-ink); margin: 34px 0 4px;
}
.lc-dm__menuname { font-size: 13px; }
.lc-dm__sec { font-size: 11px; color: var(--dm-accent-ink); }
.lc-dm__menu > :is(.lc-dm__menuname, .lc-dm__sec):first-child { margin-top: 0; }
.lc-dm__secnote { margin: 0 0 6px; font-size: .9rem; color: var(--dm-muted); max-width: 68ch; font-style: italic; }

.lc-dm__items { list-style: none; margin: 0 0 4px; padding: 0; }
.lc-dm__item {
  display: grid; grid-template-columns: 1fr auto; align-items: start;
  gap: 4px 18px; padding: 14px 0; border-bottom: 1px solid var(--dm-line);
}
.lc-dm__item.is-shot { grid-template-columns: 76px 1fr auto; }
.lc-dm__thumb {
  grid-row: span 1; width: 76px; height: 76px; object-fit: cover; border-radius: 3px;
  background: var(--dm-soft);
}
.lc-dm__text { min-width: 0; }
.lc-dm__name { margin: 0; font-size: 1.02rem; font-weight: 700; line-height: 1.3; }
.lc-dm__desc { margin: 3px 0 0; font-size: .93rem; line-height: 1.55; color: var(--dm-muted); max-width: 66ch; }
/* Verbatim as published — "Cup 8 / Bowl 12", "MP", a range — so tabular figures only, never
   a forced format. */
.lc-dm__price {
  margin: 0; font-family: var(--dm-sans); font-size: .9rem; font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--dm-ink);
}

/* --- the correction route -------------------------------------------------- */

.lc-dm__fix { margin: 34px 0 0; border-top: 1px solid var(--dm-line); padding-top: 18px; }
.lc-dm__fixsum {
  font-family: var(--dm-sans); text-transform: uppercase; letter-spacing: 1.4px;
  font-size: 11px; font-weight: 600; color: var(--dm-accent-ink); cursor: pointer;
  list-style: none; display: inline-flex; align-items: center; gap: 8px;
}
.lc-dm__fixsum::-webkit-details-marker { display: none; }
.lc-dm__fixsum::after { content: "+"; font-size: 15px; line-height: 1; }
.lc-dm__fix[open] .lc-dm__fixsum::after { content: "–"; }
.lc-dm__fixsum:hover { color: var(--dm-ink); }
.lc-dm__fixbody { max-width: 640px; margin-top: 16px; }
.lc-dm__fixlede { margin: 0 0 16px; font-size: .95rem; line-height: 1.6; color: var(--dm-muted); max-width: 68ch; }
.lc-dm__f { display: block; font-family: var(--dm-sans); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 1px; color: var(--dm-muted); margin: 0 0 14px; }
/* Regular weight: this one is a sentence a reader ticks, not a field label above a box, and at 600
   it read as emphasised rather than as the ordinary option it is. */
.lc-dm__f--inline { display: flex; align-items: center; gap: 8px; text-transform: none;
  letter-spacing: 0; font-size: .92rem; font-family: var(--dm-serif); font-weight: 400; }
.lc-dm__frow { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.lc-dm__f :is(input[type="text"], input[type="email"], textarea) {
  display: block; width: 100%; margin-top: 6px; padding: 10px 12px;
  /* NOT `font: inherit`. The label wrapping these fields is uppercase 600, and font: inherit pulled
     that weight down into the control — the example placeholder rendered bold and dark enough to
     read as text somebody had already typed into the box. Every inherited axis is set explicitly. */
  font-family: var(--dm-serif); font-size: .95rem; font-weight: 400; font-style: normal;
  line-height: 1.5; text-transform: none; letter-spacing: 0;
  color: var(--dm-ink); background: var(--dm-bg); border: 1px solid var(--dm-line); border-radius: 2px;
}
.lc-dm__f :is(input, textarea):focus-visible { outline: 2px solid var(--dm-accent); outline-offset: 1px; border-color: var(--dm-accent); }
/* #5f6b66 on white is 5.2:1 — a placeholder is read by everyone who opens the form, so it
   is held to the body-text ratio rather than to the 3:1 that "hint text" usually gets. */
.lc-dm__f ::placeholder { color: #5f6b66; opacity: 1; }
.lc-dm__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.lc-dm__submit {
  font-family: var(--dm-sans); text-transform: uppercase; letter-spacing: 1.5px;
  font-size: 11px; font-weight: 600; padding: 12px 24px; border-radius: 2px;
  border: 1px solid var(--dm-accent); background: var(--dm-accent); color: #fff; cursor: pointer;
  transition: background .15s, border-color .15s;
}
.lc-dm__submit:hover:not(:disabled) { background: #285f4a; border-color: #285f4a; }
.lc-dm__submit:disabled { opacity: .55; cursor: default; }
.lc-dm__msg { margin: 12px 0 0; font-size: .94rem; min-height: 1.2em; }
.lc-dm__msg.is-ok { color: var(--dm-accent-ink); }
.lc-dm__msg.is-err { color: #8c2f22; }

@media (max-width: 640px) {
  .lc-dm__frow { grid-template-columns: 1fr; }
  .lc-dm__item.is-shot { grid-template-columns: 60px 1fr auto; }
  .lc-dm__thumb { width: 60px; height: 60px; }
}

/* ==========================================================================
   THE UNIVERSAL MENU — /menu/

   The band is a background, not a hero. The reader came to search 3,000 dishes, so the
   photograph gets the height the title and the search box need and not one pixel more,
   and the results start above the fold on a laptop.
   ========================================================================== */

.lc-um {
  background: var(--dm-bg);
  --um-max: 1360px;             /* the band and the two columns share it, so everything starts
                                   on one vertical line */
  --um-rail: clamp(236px, 19.5vw, 292px);
  --um-gap: 32px;
  /* The theme's navbar is position:fixed from the first paint, so a sticky rail measured from
     0 parks its first facet underneath it. 80px of navbar plus a little air. */
  --um-railtop: 96px;
  --um-thumb: 24px;             /* the pointer target, which is why it is not smaller */
  --um-half: calc(var(--um-thumb) / 2);
  --um-track-h: 28px;
  /* The histogram is one series with a selection state, so the pair is two steps of one hue,
     not two hues.

     The excluded step is set by LIGHTNESS, and that is a decision made at the rendered size. A
     darker grey scores better on paper — one pass ran it at #848f88, which clears 3:1 against
     this ground and separates from the accent by ΔE 24 — but a 5.75px mark carries almost no
     chroma, so on screen the two states read as one dark mass and the selected band vanishes.
     Lighter is legible: the excluded bars sit near 2:1, which is under the floor for an
     isolated mark and fine for thirty-one of them forming a continuous silhouette, and the
     numeric readout above states the selection outright for anyone the shape fails. */
  --um-bar-in: var(--dm-accent-ink);
  --um-bar-out: #aab4af;
  --um-off: #ccd4cf;            /* the unpainted slider rail — chrome, behind the data */
}

/* Full width STRUCTURALLY — the theme boxes page content in a max-width container with a gutter,
   and a band inside that renders as a picture with white margins and the navigation on white above
   it. Removing the constraint is the fix; 100vw and calc(50% - 50vw) both overflow by the
   scrollbar width and loop against the sticky header. */
body.lc-um-page #tm-main.uk-section { padding: 0 !important; }
body.lc-um-page #tm-main .uk-container { max-width: none !important; padding: 0 !important; }
body.lc-um-page #tm-main :is(.uk-article-title, .tm-page-title, .uk-breadcrumb) { display: none !important; }
/* theme.js injects this div to hold space for the overlaid navigation. Here the photograph owns
   the top of the viewport, so the spacer only pushes it back down out from under the menu. */
body.lc-um-page .tm-header-placeholder { display: none !important; }
/* The scrolled ground goes on .uk-navbar-sticky, never .uk-sticky-fixed: an overlay header is
   position:fixed from the first paint, so a white ground on the fixed class paints white under the
   still-light links and the whole navigation vanishes over the photograph. */
body.lc-um-page .tm-header .uk-navbar-container.uk-navbar-sticky {
  background: #fff; box-shadow: 0 1px 0 rgba(0, 0, 0, .08);
}

.lc-um__head {
  position: relative;
  isolation: isolate;            /* confines the two negative-z layers to this band */
  background: var(--dm-well);    /* also the fallback: a 404 photograph leaves a dark well,
                                    never light type on white with the nav invisible */
  padding: calc(80px + clamp(30px, 4vw, 46px)) var(--dm-pad) clamp(30px, 4vw, 44px);
}
.lc-um__head::before {
  content: ""; position: absolute; inset: 0; z-index: -2;
  background: url("/wp-content/uploads/fresh-oysters-on-ice-hero.jpg") 50% 46% / cover no-repeat;
}
/* Two jobs, one layer: the upper stop keeps the overlaid navigation legible over the bright
   plate, the lower carries the title and the search box. Measured over the rendered frame:
   title 14.8:1, lede 8.9:1. */
.lc-um__head::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(to bottom, rgba(14, 20, 16, .62) 0, rgba(14, 20, 16, .10) 150px),
    linear-gradient(to top, rgba(14, 20, 16, .90) 0, rgba(14, 20, 16, .55) 55%, rgba(14, 20, 16, .34) 100%);
}
.lc-um__headinner { position: relative; max-width: var(--um-max); margin: 0 auto; }
.lc-um__title {
  font-family: var(--dm-serif); font-weight: 700; color: #fff; margin: 0 0 10px;
  font-size: clamp(1.9rem, 4.4vw, 3rem); line-height: 1.05;
}
.lc-um__lede { margin: 0 0 22px; color: rgba(255, 255, 255, .88); font-size: 1.03rem; max-width: 56ch; line-height: 1.5; }

/* --- the search row -------------------------------------------------------- */

.lc-um__form { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 8px; max-width: 720px; }
.lc-um__q, .lc-um__area {
  font-family: var(--dm-serif); font-size: 1rem; padding: 13px 15px; color: var(--dm-ink);
  background: #fff; border: 1px solid transparent; border-radius: 2px; min-width: 0;
}
.lc-um__q::placeholder { color: #5f6b66; opacity: 1; }
.lc-um__area { font-family: var(--dm-sans); font-size: .86rem; }
.lc-um__go {
  font-family: var(--dm-sans); text-transform: uppercase; letter-spacing: 1.5px; font-size: 11px;
  font-weight: 600; padding: 13px 22px; border-radius: 2px; border: 1px solid var(--dm-gold);
  background: var(--dm-gold); color: #21160a; cursor: pointer;
}
.lc-um__go:hover { background: #a5762f; border-color: #a5762f; }
.lc-um :is(input, select, button):focus-visible { outline: 2px solid var(--dm-gold); outline-offset: 2px; }

/* --- the toggles, which must be visible ------------------------------------
   The carry-out default is ON, and a default the reader cannot see is a directory that
   looks broken — "where are all the restaurants?". So the switches sit under the search
   box in the band, in the light, with the active one filled rather than merely underlined.
   -------------------------------------------------------------------------- */

.lc-um__toggles { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 0; }
.lc-um__toggle {
  font-family: var(--dm-sans); font-size: 11px; font-weight: 600; letter-spacing: 1px;
  text-transform: uppercase; text-decoration: none; padding: 8px 14px; border-radius: 2px;
  border: 1px solid rgba(255, 255, 255, .40); color: #fff; background: rgba(255, 255, 255, .07);
  display: inline-flex; align-items: center; gap: 7px; transition: background .15s, border-color .15s;
}
.lc-um__toggle:hover { background: rgba(255, 255, 255, .18); border-color: rgba(255, 255, 255, .70); color: #fff; }
.lc-um__toggle.is-on { background: #fff; border-color: #fff; color: var(--dm-ink); }
.lc-um__toggle.is-on::before { content: "✓"; font-size: 12px; line-height: 1; }

/* --- the two-column shell --------------------------------------------------
   The wrapper owns the centring and the gutter for both columns, and the band above it is held
   to the same max width, so the photograph, the search box and the first dish all begin on one
   vertical line. The results block fills its column instead of centring inside it.
   -------------------------------------------------------------------------- */

.lc-um__layout {
  max-width: var(--um-max); margin: 0 auto;
  padding: clamp(26px, 3.5vw, 40px) var(--dm-pad) 72px;
  /* The band above hangs its gutter OUTSIDE its max width, and matching that is the whole
     point of sharing the token. Measured on the border-box default: the first facet landed one
     full gutter — 24px — to the right of the headline it is supposed to line up with. */
  box-sizing: content-box;
  display: grid;
  /* Named areas, so the rail lands below the results on a phone whichever order the markup
     arrives in. The results are what the reader came for, and a column of controls above them
     pushes the first dish off the screen; the skip link in the results carries a keyboard user
     the other way. */
  grid-template-areas: "body" "rail";
}
.lc-um__rail { grid-area: rail; min-width: 0; }
.lc-um__body { grid-area: body; min-width: 0; }

/* A row that ships with the hidden attribute — the near-me block before a location is set —
   has to survive every display rule below, and each of those would otherwise reveal it. */
.lc-um [hidden] { display: none; }

/* Declared rather than assumed: each removable chip carries its instruction in one of these,
   and if the class is undefined the instruction renders as visible text inside the chip. */
.lc-um .screen-reader-text {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* --- the filter rail -------------------------------------------------------
   A column rather than a band across the top. The band had to stay short to keep the first
   dish above the fold, which capped how much of the corpus it could ever show, and it scrolled
   away the moment a reader started reading — so widening a search meant going back up for the
   controls. A rail holds every facet at once and stays on screen while the results move.

   It is still doing two jobs. It filters, and it tells a reader what the corpus HOLDS: a search
   box alone is a wall, because you have to already know what is in there to ask for it.
   -------------------------------------------------------------------------- */

.lc-um__rail { font-family: var(--dm-sans); }
/* The anchor is the target of the skip link, and the theme's navigation is fixed over the top
   of the page, so an un-offset jump lands the first facet underneath it. */
.lc-um__rail { scroll-margin-top: var(--um-railtop); }

.lc-um__frow { padding: 0 0 16px; }
.lc-um__frow + .lc-um__frow { border-top: 1px solid var(--dm-line); padding-top: 16px; }
.lc-um__frow:last-child { padding-bottom: 0; }

.lc-um__flabel {
  margin: 0 0 9px; font-family: var(--dm-sans); text-transform: uppercase;
  letter-spacing: 1.5px; font-size: 10px; font-weight: 600; color: var(--dm-muted);
}
/* A sentence, so it is set as one — the reading face, sentence case, on its own line rather
   than beside the label.

   Spaced by WHERE IT SITS, not by which facet it belongs to. Some facets introduce the note
   before the control and some report back after it, and a single margin cannot serve both: the
   pull-up that closes the gap under a label drags the note into the chip rows when it follows
   them instead. Two adjacency rules cover every position without the facet having to declare
   one, which is what the next facet added here will need. */
.lc-um__fnote {
  margin: 0 0 10px; font-family: var(--dm-serif); font-size: .86rem;
  line-height: 1.45; color: var(--dm-muted);
}
.lc-um__flabel + .lc-um__fnote { margin-top: -3px; }
:is(.lc-um__chips, .lc-um__nearbtn, .lc-um__nearform) + .lc-um__fnote { margin: 10px 0 0; }
/* The near-me row ships this empty and fills it from script, and an empty paragraph still
   carries its margins into the gap below the button. */
.lc-um__fnote:empty { margin: 0; }

/* What is on now, gathered at the top of the rail. Somebody who has stacked four filters and is
   looking at eleven dishes needs to see WHY before they see the results, and every chip here is
   the control that undoes itself.

   No panel behind it, though it wants one: any inline padding indents these chips against every
   label below them, and a rail whose rows start on two different left edges reads as broken
   before it reads as grouped. The filled chips and the mark on each already say this row is
   different from the ones offering choices. */
.lc-um__frow--active {
  padding: 0 0 16px; margin-bottom: 16px;
  border-bottom: 1px solid var(--dm-line);
}
.lc-um__frow--active + .lc-um__frow { border-top: 0; padding-top: 0; }
.lc-um__frow--active .lc-um__flabel { color: var(--dm-ink); }

.lc-um__chips { list-style: none; display: flex; gap: 6px; margin: 0; padding: 0; min-width: 0; }
/* One horizontal rail per row rather than a wrapped block, until there is a column to wrap
   inside: the cravings row alone is fifteen chips, which stacks to five lines and buries the
   results under a wall of controls. */
.lc-um__chips {
  flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
  padding-bottom: 2px; -webkit-overflow-scrolling: touch;
}
.lc-um__chips::-webkit-scrollbar { display: none; }
.lc-um__chip { white-space: nowrap; }

.lc-um__chip {
  display: inline-flex; align-items: baseline; gap: 6px; text-decoration: none;
  font-family: var(--dm-sans); font-size: 11.5px; font-weight: 600; letter-spacing: .2px;
  padding: 6px 10px; border-radius: 2px; border: 1px solid var(--dm-line);
  background: var(--dm-bg); color: var(--dm-ink); transition: border-color .15s, background .15s, color .15s;
}
.lc-um__chip:hover { border-color: var(--dm-muted); background: #fff; color: var(--dm-ink); }
.lc-um__chip.is-on { background: var(--dm-ink); border-color: var(--dm-ink); color: #fff; }
/* The count is an availability signal, not a statistic: it exists so nobody clicks into an empty
   page. Held one step down in weight so it never competes with the word it belongs to. */
.lc-um__n { font-size: 10.5px; font-weight: 500; color: var(--dm-muted); font-variant-numeric: tabular-nums; }
.lc-um__chip.is-on .lc-um__n { color: rgba(255, 255, 255, .72); }
.lc-um__chip:focus-visible { outline: 2px solid var(--dm-accent); outline-offset: 2px; }

/* The mark that makes an on chip read as removable rather than merely selected. Set in the
   chip's own face, so it takes the chip's colour and weight without a second asset, and it
   brightens on hover because that is the moment the chip is about to be clicked off. */
.lc-um__chip--drop { align-items: center; padding-right: 9px; }
.lc-um__chip--drop:hover { background: #2b3a33; border-color: #2b3a33; color: #fff; }
.lc-um__x { font-size: 14px; line-height: 1; opacity: .62; margin-left: 1px; transition: opacity .15s; }
.lc-um__chip--drop:hover .lc-um__x { opacity: 1; }

/* Lower-case and unlettered against the count's small caps: it is an explanation of the number
   beside it, not a second heading competing with it. */
.lc-um__cap {
  font-family: var(--dm-serif); text-transform: none; letter-spacing: 0;
  font-size: .88rem; font-weight: 400; color: var(--dm-muted); margin-left: 8px;
}

.lc-um__clear {
  display: inline-block; margin: 11px 0 0; font-family: var(--dm-sans); font-size: 10px;
  font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase;
  color: var(--dm-accent-ink); text-decoration: none; border-bottom: 1px solid currentColor;
}
.lc-um__clear:hover { color: var(--dm-ink); }

/* --- price -----------------------------------------------------------------
   A distribution with a selection laid over it, rather than two number boxes. The shape is the
   argument: it shows that most of the corpus sits under fifteen dollars, so a reader dragging
   the cap down can see what they are about to keep before they let go.
   -------------------------------------------------------------------------- */

.lc-um__price { margin: 0; }
/* The number a reader watches while dragging, so it is the most confident type in the rail. */
.lc-um__pricenow {
  display: block; margin: 0 0 10px; font-family: var(--dm-serif); font-size: 1.18rem;
  font-weight: 700; font-variant-numeric: tabular-nums; color: var(--dm-ink);
}

.lc-um__hist {
  background: var(--dm-soft); border-radius: 3px;
  /* Exactly half a handle of inline padding: at either end of the range the handle sits flush
     with the chart's outer edge and nothing spills out of the scrolling rail. */
  padding: 12px var(--um-half) 9px;
}
.lc-um__bars {
  display: flex; align-items: flex-end; gap: 2px; height: 54px;
  position: relative; z-index: 0;
  /* The slider rail below doubles as the chart's baseline. Pulling the track up by half its
     height lands that line exactly on the foot of the bars instead of leaving two horizontals
     a few pixels apart, which reads as a rendering fault. */
  margin-bottom: calc(var(--um-track-h) / -2);
}
.lc-um__bar {
  flex: 1 1 0; min-width: 0; min-height: 2px;
  background: var(--um-bar-out); border-radius: 1px 1px 0 0;
}
/* One series with a selection state, so two steps of one hue — a second hue would read as a
   second measurement. Both steps clear 3:1 on this ground and separate by ΔE 24, measured:
   the excluded bars still have to show the reader what they are excluding. */
.lc-um__bar.is-in { background: var(--um-bar-in); }
/* Everything above the cap, which is a different width of world from a two-dollar bucket. The
   gap says so; without it the column reads as "a great many dishes cost exactly $58". */
.lc-um__bar--tail { margin-left: 8px; }

.lc-um__track { position: relative; height: var(--um-track-h); z-index: 1; }
.lc-um__track::before,
.lc-um__track::after {
  content: ""; position: absolute; top: 50%; height: 4px; border-radius: 2px;
  transform: translateY(-50%);
}
.lc-um__track::before { left: 0; right: 0; background: var(--um-off); }
/* The span the two handles enclose. Script sets the custom properties on drag; the fallbacks
   are the whole range, which is what the control legitimately shows before script runs. */
.lc-um__track::after {
  left: var(--lc-lo, 0%); right: calc(100% - var(--lc-hi, 100%));
  background: var(--um-bar-in);
}

.lc-um__handle {
  position: absolute; top: 0; height: 100%; margin: 0; padding: 0;
  background: none; border: 0; -webkit-appearance: none; appearance: none;
  /* Half a handle wider than the track at each end, so a thumb's CENTRE travels the full
     0–100% that the painted span is measured in. Without it the two disagree by 12px at the
     extremes and the fill visibly lags the handle. */
  left: calc(var(--um-half) * -1); width: calc(100% + var(--um-thumb));
  /* Two controls occupy one box, so the box has to be transparent to the pointer and only the
     thumbs may catch it — otherwise the upper input swallows every drag meant for the lower. */
  pointer-events: none;
}
.lc-um__handle--min { z-index: 2; }
.lc-um__handle--max { z-index: 3; }
/* Equal values bury the lower handle under the upper one, where a pointer can never reach it.
   Script that detects the case flips this flag and brings it back to the front. */
.lc-um__price[data-lc-coincident] .lc-um__handle--min { z-index: 4; }

.lc-um__handle::-webkit-slider-runnable-track { height: 100%; background: none; border: 0; }
.lc-um__handle::-moz-range-track { height: 100%; background: none; border: 0; }
.lc-um__handle::-webkit-slider-thumb {
  -webkit-appearance: none; pointer-events: auto; box-sizing: border-box;
  /* 24px is the pointer target, which is why the knob is not the smaller disc it looks like it
     wants to be. */
  width: var(--um-thumb); height: var(--um-thumb);
  /* The runnable track is the full box height and webkit hangs the thumb from its top edge
     rather than centring it, so the offset is what puts the knob on the rail. */
  margin-top: calc((var(--um-track-h) - var(--um-thumb)) / 2);
  border: 2px solid var(--um-bar-in); border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgba(20, 30, 24, .26); cursor: pointer;
}
.lc-um__handle::-moz-range-thumb {
  pointer-events: auto; box-sizing: border-box;
  width: var(--um-thumb); height: var(--um-thumb);
  border: 2px solid var(--um-bar-in); border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgba(20, 30, 24, .26); cursor: pointer;
}
/* Arrow keys are the only way a keyboard drives a two-handle range, so the ring goes on the
   thumb. On the input it draws a rectangle round the whole track and says nothing about which
   of the two handles is about to move. */
.lc-um__track .lc-um__handle:focus-visible { outline: none; }
.lc-um__handle:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 3px var(--dm-gold), 0 1px 3px rgba(20, 30, 24, .26);
}
.lc-um__handle:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 3px var(--dm-gold), 0 1px 3px rgba(20, 30, 24, .26);
}

.lc-um__scale {
  display: grid; grid-template-columns: 1fr auto 1fr; margin: 7px 0 0;
  font-family: var(--dm-sans); font-size: 10px; font-weight: 600; letter-spacing: .6px;
  color: var(--dm-muted); font-variant-numeric: tabular-nums;
}
.lc-um__scale span:nth-child(2) { justify-self: center; }
.lc-um__scale span:last-child { justify-self: end; }

/* A sentence somebody ticks, not a field label above a box — the reading face at regular
   weight, and the box aligned to the first line rather than to the middle of a wrapped one. */
.lc-um__mp {
  display: flex; align-items: flex-start; gap: 8px; margin: 12px 0 0; cursor: pointer;
  font-family: var(--dm-serif); font-size: .88rem; line-height: 1.45; color: var(--dm-ink);
}
.lc-um__mp input { flex: none; width: 15px; height: 15px; margin: 2px 0 0; accent-color: var(--dm-accent); }
/* The sentence runs to three lines in a rail this narrow and the count in it changes with the
   corpus, so the break is balanced rather than left to drop a single word onto its own line. */
.lc-um__mp span { text-wrap: pretty; }

/* The only control in the rail that needs an explicit commit — every chip is a link that
   navigates on click, so the range would be silently inconsistent if its button were easy to
   miss. Sized to its word, not to the column: at full width it is a slab of saturated colour
   the length of the chart, and it pulls the eye away from the results it is meant to serve. */
.lc-um__apply {
  display: inline-block; margin: 14px 0 0;
  font-family: var(--dm-sans); text-transform: uppercase; letter-spacing: 1.4px;
  font-size: 11px; font-weight: 600; padding: 11px 26px; border-radius: 2px;
  border: 1px solid var(--dm-accent); background: var(--dm-accent); color: #fff; cursor: pointer;
  transition: background .15s, border-color .15s;
}
.lc-um__apply:hover:not(:disabled) { background: #285f4a; border-color: #285f4a; }
.lc-um__apply:disabled { opacity: .55; cursor: default; }

/* --- near me ---------------------------------------------------------------- */

/* The same shape as Apply, one step down in weight: the two buttons in this rail have to read
   as the same kind of object, and only their emphasis should differ. */
.lc-um__nearbtn {
  display: inline-block;
  font-family: var(--dm-sans); text-transform: uppercase; letter-spacing: 1.4px;
  font-size: 11px; font-weight: 600; padding: 10px 22px; border-radius: 2px;
  border: 1px solid var(--dm-line); background: var(--dm-bg); color: var(--dm-ink); cursor: pointer;
  transition: border-color .15s, background .15s;
}
.lc-um__nearbtn:hover:not(:disabled) { border-color: var(--dm-muted); background: var(--dm-soft); }
.lc-um__nearbtn:disabled { opacity: .55; cursor: default; }
/* Here the note reports back on the button above it rather than introducing the row, so it
   loses the pull-up that seats it under a label. */
.lc-um__frow--near .lc-um__fnote { margin: 9px 0 0; }
.lc-um__frow--near .lc-um__fnote:empty { margin: 0; }
.lc-um__nearform { margin: 11px 0 0; }

/* --- the rail lying down ----------------------------------------------------
   Below 980 there is no second column to put it in, so the rail goes back to being a stack of
   horizontal chip rails under the results, which is the shape that already works at 414. It
   needs a rule of its own above it: run straight on from the last dish and it reads as more
   results rather than as the controls that produced them.
   -------------------------------------------------------------------------- */

.lc-um__rail { margin-top: 30px; padding-top: 22px; border-top: 1px solid var(--dm-line); }

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

/* The layout wrapper carries the centring and the gutter now, so this block fills its column.
   The count and the order control share one line — stacked, they push the first dish down by a
   whole row for a control most readers never touch. Everything else spans both tracks, so an
   element added here later lands full width rather than squeezed into the count's column. */
.lc-um__body {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: start; row-gap: 16px;
  /* The block is stretched to the full height of the two-column row so its divider runs the
     whole way down; without this the rows would share out that spare height between them and
     the results would drift apart on any short page. */
  align-content: start;
}
.lc-um__body > * { grid-column: 1 / -1; min-width: 0; margin-block: 0; }
.lc-um__body > .lc-um__count { grid-column: 1; align-self: baseline; }
.lc-um__body > .lc-um__sort { grid-column: 2; justify-self: end; align-self: baseline; }

.lc-um__count {
  font-family: var(--dm-sans); text-transform: uppercase; letter-spacing: 1.6px; font-size: 11px;
  font-weight: 600; color: var(--dm-muted);
}
.lc-um__note { font-size: .95rem; color: var(--dm-muted); max-width: 70ch; line-height: 1.6; }
.lc-um__note a { color: var(--dm-accent-ink); }

/* Quiet, and deliberately not chip-shaped: it re-orders what the rail already chose, so it must
   not read as one more thing to pick. */
.lc-um__sort { display: flex; align-items: baseline; gap: 8px; }
.lc-um__sortlabel {
  font-family: var(--dm-sans); text-transform: uppercase; letter-spacing: 1.5px;
  font-size: 10px; font-weight: 600; color: var(--dm-muted); white-space: nowrap;
}
.lc-um__sortsel {
  font-family: var(--dm-sans); font-size: 12px; font-weight: 600; color: var(--dm-ink);
  padding: 6px 8px; border: 1px solid var(--dm-line); border-radius: 2px;
  background: var(--dm-bg); max-width: 100%;
}
.lc-um__sortsel:hover { border-color: var(--dm-muted); }

/* Only earns its place where the rail sits below the results. On the two-column layout the
   filters are already on screen and a link pointing at them is noise. */
.lc-um__jump { font-size: .9rem; }
.lc-um__jump a { color: var(--dm-accent-ink); font-weight: 700; }

/* Masonry-ish columns rather than a rigid card grid: a dish with a photograph is tall, one
   without is two lines, and forcing both into one cell height is what produces the row of
   identical boxes with air in half of them. */
.lc-um__results { list-style: none; margin: 0; padding: 0; columns: 1; column-gap: 22px; }
/* ⛔ THERE IS NO WIDTH ABOVE 820 WHERE THE FILTERS SIT AT THE BOTTOM. Read the ladder below with
   that as the rule it exists to satisfy.

   An earlier ladder ran the results full width at three columns between 840 and 980 and pushed the
   rail underneath them, on the reasoning that three columns beat two. That was the wrong trade and
   it produced the worst state on the page: a browser windowed to about 900px — an ordinary way to
   use a desktop — showed a full-width grid of dishes with the entire filter rail dumped below the
   fold, where it reads as leftover page furniture rather than as the controls for what is above it.
   A filter you have to scroll past the results to reach is not a filter.

   So the rail takes its column from 820px up and the results give up a column to make room. Two
   readable columns beside working filters beat three columns with the filters banished. */
@media (min-width: 620px) { .lc-um__results { columns: 2; } }
/* Three only where a rail AND three columns both fit without any of them going cramped. */
@media (min-width: 1280px) { .lc-um__results { columns: 3; } }

.lc-um__dish {
  break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid;
  margin: 0 0 22px; border: 1px solid var(--dm-line); border-radius: 3px; overflow: hidden;
  background: var(--dm-bg); transition: box-shadow .18s, border-color .18s;
}
.lc-um__dish:hover { border-color: #cfd6d2; box-shadow: 0 6px 18px rgba(20, 30, 24, .09); }
.lc-um__dishimg { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; background: var(--dm-soft); }
.lc-um__dishbody { padding: 14px 16px 16px; }
.lc-um__dishtop { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.lc-um__dishname { margin: 0; font-size: 1.04rem; font-weight: 700; line-height: 1.3; }
.lc-um__dishprice { font-family: var(--dm-sans); font-size: .88rem; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.lc-um__dishdesc { margin: 6px 0 0; font-size: .92rem; line-height: 1.55; color: var(--dm-muted); }
.lc-um__dishfrom { margin: 11px 0 0; font-size: .88rem; line-height: 1.4; }
.lc-um__dishfrom a { color: var(--dm-accent-ink); font-weight: 700; text-decoration: none; }
.lc-um__dishfrom a:hover { text-decoration: underline; }
.lc-um__dishwhere { display: block; color: var(--dm-muted); font-size: .84rem; margin-top: 2px; }

/* An empty state that says what to do next, not that something went wrong. The top padding is
   small because the note above it already carries its own margin — at 40px the two combined left a
   band of dead white that read as a rendering fault rather than as breathing room. */
.lc-um__empty { padding: 6px 0 20px; max-width: 60ch; }
.lc-um__empty p { margin: 0 0 12px; font-size: 1.05rem; line-height: 1.6; }
.lc-um__empty a { color: var(--dm-accent-ink); }

/* ==========================================================================
   THE RAIL TAKES ITS COLUMN — 820 up

   820 is the narrowest width where the rail and two readable result columns both fit: a 236px
   rail plus a 32px gutter leaves about 550px, which is two cards of roughly 265px — the same
   card width the three-column layout uses at 1280, so nothing is cramped by dropping down here.

   Below 820 is a phone or a tablet held upright. There the rail lays down under the results as
   horizontal scrolling rows, which is a different control that works on a thumb, rather than the
   same control pushed out of the way.
   ========================================================================== */

@media (min-width: 820px) {
  .lc-um__layout {
    grid-template-columns: var(--um-rail) minmax(0, 1fr);
    grid-template-areas: "rail body";
    column-gap: var(--um-gap);
    /* Required, not cosmetic: a grid item stretched to its row's height fills its area, and an
       element that fills its containing block has nowhere to stick to. */
    align-items: start;
  }

  .lc-um__rail {
    margin-top: 0; padding-top: 0; border-top: 0;
    position: sticky; top: var(--um-railtop);
    /* Capped and scrolled, because the full facet list runs past the bottom of most laptops and
       the last two facets would otherwise be permanently out of reach while it is stuck. */
    max-height: calc(100vh - var(--um-railtop) - 24px);
    overflow-x: clip; overflow-y: auto; overflow-clip-margin: 6px;
    /* Reaching the end of the rail must not start scrolling the results behind it. */
    overscroll-behavior: contain;
    /* The rail overflows on nearly every laptop, so this bar is on screen permanently rather
       than occasionally. Left at the platform default it arrives with stepper arrows and a grey
       trough, which beside a column of hairlines reads as a rendering fault. */
    scrollbar-width: thin;
    scrollbar-color: #ccd4cf transparent;
  }

  /* The divider belongs to the results, not to the rail: the rail is only as tall as its
     content, so a border on it stops in mid-air wherever the facets happen to run out.

     Stretched, because the results are not reliably the taller column either. On a search that
     returns nothing the line ran three lines deep beside a rail eight hundred pixels tall,
     which reads as a broken border rather than as a boundary. The rail must stay start-aligned
     — a stretched item fills its area and has nothing left to stick to. */
  .lc-um__body {
    border-left: 1px solid var(--dm-line); padding-left: var(--um-gap);
    align-self: stretch;
  }

  /* Room to wrap, so a facet reads as a block of options rather than as a row that has to be
     dragged sideways to be seen. */
  .lc-um__chips { flex-wrap: wrap; overflow-x: visible; padding-bottom: 0; }

  .lc-um__jump { display: none; }
}

@media (max-width: 620px) {
  /* The mobile header is a tall logo block rather than the desktop bar, and the storm ribbon
     paints over the top of the band as well. Measured at 414: the logo runs to about 118px, and
     at the desktop's 126px of clearance the h1 rendered *underneath* it — present in the DOM,
     invisible on the screen, and invisible to a marker check too. Hence a measured value rather
     than a scaled one. */
  .lc-um__head { padding-top: 140px; padding-bottom: clamp(22px, 5vw, 32px); }
  /* Query on its own row, then area and the button share one. Stacking all three cost about 60px
     of band and pushed the first dish off the screen entirely. */
  .lc-um__form { grid-template-columns: 1fr 1fr; }
  .lc-um__q { grid-column: 1 / -1; }
  .lc-um__lede { font-size: .98rem; margin-bottom: 18px; }

}

/* ==========================================================================
   THE COUNT AND THE SORT STOP SHARING A ROW

   ⚠ The threshold is the width of the RESULTS COLUMN, not of the window, which is why this is
   1040 and not a phone breakpoint. Once the rail takes its 236px plus a 32px gutter, the results
   column is roughly 270px narrower than the viewport — so a 1024px laptop leaves about 610px for
   a count line that wants ~440px and a sort control that wants ~200px. They do not fit, and the
   count wraps into a ragged column beside the select where the two read as one broken paragraph
   rather than as a number and a control.

   Measured first at 414, fixed there, and the same collision then turned up at 820 and 900 —
   because the rail had been given its column at those widths too. One rule for all of them.
   ========================================================================== */

@media (max-width: 1039px) {
  .lc-um__body > .lc-um__count,
  .lc-um__body > .lc-um__sort { grid-column: 1 / -1; justify-self: stretch; }
  .lc-um__body { row-gap: 12px; }
  /* The aside drops to its own line rather than trailing the count, so the number a reader
     came for is not buried mid-sentence. */
  .lc-um__cap { display: block; margin-left: 0; margin-top: 4px; }
}

/* ⛔ THE SORT SELECT NEVER STRETCHES. It sizes to its words at every width.
   It was briefly given `flex: 1 1 auto` below 620 so it would not look cramped on a phone. At 620
   that made it 504px — a long empty box with two words in it, sitting directly above the first
   dish and reading as a form to fill in rather than as a quiet way to reorder what is already
   there. The control re-orders what the rail has already chosen; the moment it is the widest thing
   on the screen it is claiming to be the main event. */

/* Parallax and entrance motion cause real vestibular trouble, and there is none here to
   disable — but the hover lift and the tab transitions are still motion. */
@media (prefers-reduced-motion: reduce) {
  .lc-dm *, .lc-um * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
