/* =========================================================================
   Ro Cafe menu: styles
   One set of tokens (type, sizes, radii, spacing, colour) used everywhere.
   Light theme in :root, dark theme in html[data-theme="dark"].
   ========================================================================= */

:root {
  /* colour */
  --bg: #ffffff;
  --surface: #ffffff;
  --soft: #f5f5f2;
  --line: #e8e8e3;
  --ink: #141416;
  --mute: #66666d;
  /* over photos and the map: the same in both themes */
  --on-photo: #fff;
  --on-photo-dim: rgb(255 255 255/0.6);
  --on-photo-bg: rgb(255 255 255/0.92);
  --on-photo-ink: #141416;
  --map-land: #f2efe9;
  --map-filter: none;
  --credit-bg: rgb(255 255 255/0.85);
  --credit-ink: #333;
  --brand: #f2c230;
  --brand-soft: #fdf3cf;
  --brand-ink: #18181b;
  --mark: #18181b;
  --pm-bg: #e7f2e4;
  --pm: #2f6a2a;
  --cf-bg: #eef0fb;
  --cf: #3a46a0;
  --n-bg: #fbf0de;
  --n: #8a5a10;
  --scrim: rgba(20, 20, 22, 0.45);
  --t-coffee: #f6eee4;
  --t-brew: #eef1ea;
  --t-warm: #f8ece9;
  --t-tea: #eaf3ea;
  --t-shake: #fbecef;
  --t-iced: #e9f0f6;
  --t-cold: #f4f6e4;
  --t-cake: #f7efe2;
  --t-food: #f1ede8;
  --t-extra: #efefef;

  /* type: five sizes */
  --fs-xs: 0.75rem; /* 12  labels, tags, notes */
  --fs-sm: 0.875rem; /* 14  secondary text, buttons */
  --fs-md: 1rem; /* 16  body, item names */
  --fs-lg: 1.25rem; /* 20  section and sheet titles */
  --fs-xl: 1.5rem; /* 24  totals, item card title */

  /* controls: three heights */
  --h-s: 40px; /* pills, chips, filters, stepper */
  --h-m: 44px; /* search, add button */
  --h-l: 52px; /* primary buttons, bill bar */

  /* radii: four steps + pill */
  --r-xs: 6px;
  --r-s: 10px;
  --r-m: 16px;
  --r-l: 24px;
  --r-pill: 999px;
  /* icon sizes: small (inside small buttons and arrows), controls, list rows */
  --ic-xs: 14px;
  --ic-s: 18px;
  --ic-m: 20px;
  --ic-l: 22px;

  /* spacing: one scale for every gap, padding and margin */
  --sp-1: 0.125rem; /* 2 */
  --sp-2: 0.25rem; /* 4 */
  --sp-3: 0.375rem; /* 6 */
  --sp-4: 0.5rem; /* 8 */
  --sp-5: 0.75rem; /* 12 */
  --sp-6: 1rem; /* 16 */
  --sp-7: 1.25rem; /* 20 */
  --sp-8: 1.5rem; /* 24 */
  --sp-9: 2rem; /* 32 */
  --sp-10: 2.5rem; /* 40 */
  --sp-11: 3rem; /* 48 */
  /* motion: three speeds, one curve (--ease) */
  --t-fast: 0.15s; /* taps, hovers */
  --t-mid: 0.2s; /* small things appearing */
  --t-slow: 0.3s; /* panels, sliding */
  /* line height: headings and labels, running text, descriptions */
  --lh-tight: 1.3;
  --lh-body: 1.6;
  --lh-loose: 1.75;

  /* layout */
  /* page edges: the gutter, or more where a phone's notch or rounded corner needs it */
  --pad-l: max(var(--gut), env(safe-area-inset-left));
  --pad-r: max(var(--gut), env(safe-area-inset-right));
  --billbar-h: calc(var(--h-l) + 1.5rem); /* the bill bar, without the home-bar area below it */
  --gut: var(--sp-6);
  --hello-h: 2rem; /* the welcome line under the logo: one line, so the header knows its height */
  --maxw: 1080px;
  --bar-row: 52px;
  /* photo and panel sizes, in px: files.js reads these to ask for photos of the right size */
  --thumb: 92px; /* menu photos */
  --it-gap: var(--sp-6); /* between a row's photo, text and bill control */
  --sib-thumb: 40px; /* the previous / next item's photo on the item card */
  --pw: 560px; /* widest a panel gets */
  --ph-max: 720px; /* largest the item card's photo gets beside its details */
  /* the item card with its photo on top: height to width. The photo is square, so the details
     get the rest (.7 of the width) */
  --card-shape: 1.7;
  --shadow-2: 0 18px 48px -16px rgba(0, 0, 0, 0.35);
  --shadow-control: 0 2px 8px rgb(0 0 0/0.15); /* round buttons over photos */
  --shadow-header: 0 6px 18px -14px rgb(0 0 0/0.35);
  --shadow-pin: drop-shadow(0 2px 2px rgb(0 0 0/0.35));
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  /* keyboard focus: one ring everywhere */
  --focus-w: 2px;
  --focus: var(--focus-w) solid var(--ink);
}
html[data-theme="dark"] {
  --map-filter: brightness(0.8); /* the light map, dimmed so it does not glare in the dark */
  color-scheme: dark;
  --bg: #121214;
  --surface: #1a1a1d;
  --soft: #222226;
  --line: #2d2d33;
  --ink: #f1f1ee;
  --mute: #a1a1a9;
  --brand-soft: #4a3d12;
  --mark: #000;
  --pm-bg: #1d2e1b;
  --pm: #9fd394;
  --cf-bg: #1f2340;
  --cf: #aab3f2;
  --n-bg: #33280f;
  --n: #e9be6a;
  --scrim: rgba(0, 0, 0, 0.6);
  --t-coffee: #26211c;
  --t-brew: #20231e;
  --t-warm: #271f1d;
  --t-tea: #1d241d;
  --t-shake: #281e21;
  --t-iced: #1d2127;
  --t-cold: #23251b;
  --t-cake: #27211a;
  --t-food: #24211d;
  --t-extra: #222224;
}

/* ---------- base ---------- */
/* IBM Plex Sans Arabic (SIL Open Font License), regular and semibold: the only two weights the
   site uses. Each is split into Persian/Arabic and Latin letters (made by the font preparation
   script), so the browser downloads only what a page shows. */
@font-face {
  font-family: "RoPlex";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/plex-arabic-400.woff2) format("woff2");
  unicode-range:
    U+060C, U+061B, U+061F, U+0621-063A, U+0640-0655, U+0660-066C, U+0670, U+067E, U+0686, U+0698,
    U+06A9, U+06AF, U+06BE, U+06C0-06C3, U+06CC, U+06D5, U+06F0-06F9;
}
@font-face {
  font-family: "RoPlex";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/plex-latin-400.woff2) format("woff2");
  unicode-range:
    U+0020-007E, U+00A0-00FF, U+2013-2014, U+2018-201A, U+201C-201D, U+2022, U+2026, U+2212;
}
@font-face {
  font-family: "RoPlex";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/plex-arabic-600.woff2) format("woff2");
  unicode-range:
    U+060C, U+061B, U+061F, U+0621-063A, U+0640-0655, U+0660-066C, U+0670, U+067E, U+0686, U+0698,
    U+06A9, U+06AF, U+06BE, U+06C0-06C3, U+06CC, U+06D5, U+06F0-06F9;
}
@font-face {
  font-family: "RoPlex";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/plex-latin-600.woff2) format("woff2");
  unicode-range:
    U+0020-007E, U+00A0-00FF, U+2013-2014, U+2018-201A, U+201C-201D, U+2022, U+2026, U+2212;
}

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
[hidden] {
  display: none !important;
} /* hidden wins over any display the element is given */
html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--bar-h, 150px);
}
body {
  font-family: "RoPlex", Tahoma, system-ui, sans-serif;
  font-size: var(--fs-md);
  line-height: var(--lh-body);
  background: var(--bg);
  color: var(--ink);
  -webkit-tap-highlight-color: transparent;
}
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}
a {
  color: inherit;
}
ul {
  list-style: none;
}
/* the font has two weights: regular, and semibold for everything emphasised */
b,
strong,
h1,
h2,
h3 {
  font-weight: 600;
}
img {
  max-width: 100%;
  display: block;
}
:focus-visible {
  outline: var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}
.num {
  font-variant-numeric: tabular-nums;
}
.ltr {
  direction: ltr;
  unicode-bidi: isolate;
}
.defs {
  position: absolute;
}
/* icons: drawn in the sprite in index.html, in the colour of the text around them */
.ic {
  width: var(--ic-m);
  height: var(--ic-m);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* a photo's <picture> wrapper takes no box of its own: the <img> is laid out in its place */
picture {
  display: contents;
}
/* first thing the keyboard reaches: jumps past the header to the menu; shown only when focused */
.skip {
  position: absolute;
  inset-block-start: var(--sp-4);
  inset-inline-start: var(--sp-4);
  z-index: 70;
  padding: var(--sp-4) var(--sp-6);
  border-radius: var(--r-s);
  background: var(--ink);
  color: var(--bg);
  font-weight: 600;
  transform: translateY(-200%);
}
.skip:focus {
  transform: none;
}
#menu:focus {
  outline: none;
}
/* each section colours its photo placeholders (set from data-tint, no inline styles) */
.sec[data-tint="coffee"] {
  --tint: var(--t-coffee);
}
.sec[data-tint="brew"] {
  --tint: var(--t-brew);
}
.sec[data-tint="tea"] {
  --tint: var(--t-tea);
}
.sec[data-tint="warm"] {
  --tint: var(--t-warm);
}
.sec[data-tint="cold"] {
  --tint: var(--t-cold);
}
.sec[data-tint="iced"] {
  --tint: var(--t-iced);
}
.sec[data-tint="shake"] {
  --tint: var(--t-shake);
}
.sec[data-tint="cake"] {
  --tint: var(--t-cake);
}
.sec[data-tint="food"] {
  --tint: var(--t-food);
}
.sec[data-tint="extra"] {
  --tint: var(--t-extra);
}
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.wrap {
  max-width: var(--maxw);
  margin-inline: auto;
  padding-left: var(--pad-l);
  padding-right: var(--pad-r);
}

/* ---------- shared controls ---------- */
.pill,
.chip,
.fbtn {
  height: var(--h-s);
  border-radius: var(--r-pill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  white-space: nowrap;
  font-size: var(--fs-sm);
  transition:
    background var(--t-fast),
    color var(--t-fast),
    border-color var(--t-fast);
}
.pill,
.fbtn {
  border: 1px solid var(--line);
  padding-inline: var(--sp-5);
}
.pill,
.chip,
.fbtn,
.btn {
  min-width: var(--h-s);
  font-weight: 600;
}
.chip {
  padding-inline: var(--sp-6);
  background: var(--soft);
  color: var(--mute);
}
.chip.on,
.fbtn[aria-pressed="true"] {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}
#filterBtn.open {
  background: var(--ink);
  color: var(--bg);
}
@media (hover: hover) {
  .chip:not(.on):hover {
    background: var(--line);
  }
  .pill:hover,
  .tool:hover,
  .sheet-close:hover,
  .fbtn:not([aria-pressed="true"]):hover {
    background: var(--soft);
  }
}
.btn {
  flex: 1;
  min-height: var(--h-l);
  max-width: 100%;
  border-radius: var(--r-m);
  font-weight: 600;
  font-size: var(--fs-md);
  text-align: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--sp-7);
}
.btn-brand {
  background: var(--brand);
  color: var(--brand-ink);
}
.btn-out {
  border: 1px solid var(--line);
}
@media (hover: hover) {
  .btn-out:hover {
    background: var(--soft);
  }
}
.stepper {
  display: inline-flex;
  align-items: center;
  height: var(--h-m);
  border: 1px solid var(--line);
  border-radius: var(--r-s);
}
.stepper button {
  width: var(--h-s);
  height: 100%;
  font-size: var(--fs-lg);
}
.stepper span {
  min-width: 1.6rem;
  text-align: center;
  font-weight: 600;
}
.stepper.lg {
  height: var(--h-l);
}
.stepper.lg button {
  width: var(--h-l);
}
.tool .moon {
  display: none;
}
html[data-theme="dark"] .tool .sun {
  display: none;
}
html[data-theme="dark"] .tool .moon {
  display: block;
}

/* ---------- app bar: brand row, search, categories (sticky) ---------- */
.appbar {
  position: sticky;
  top: 0;
  z-index: 30;
  padding-top: env(safe-area-inset-top);
  background: var(--bg);
  border-bottom: 1px solid transparent;
  transition:
    border-color var(--t-mid),
    box-shadow var(--t-mid);
}
.appbar.stuck {
  border-color: var(--line);
  box-shadow: var(--shadow-header);
}
.bar-row {
  margin-top: var(--sp-2);
}
/* The logo and the tools. Where the motto has the line under them, the header slides up by that
   line as the page scrolls and this row stays put over it (two sticky positions, no script), so
   the logo, the language and day/night are always in reach. */
.bar-top {
  position: sticky;
  top: calc(env(safe-area-inset-top) + var(--sp-2));
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  column-gap: var(--sp-4);
  min-height: var(--bar-row);
  background: var(--bg);
}
/* the name never gets squeezed: with very large text the buttons move to a second row instead */
.bar-row .brand {
  flex: 0 0 auto;
  max-width: 100%;
}
.brand {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-width: 0;
  text-decoration: none;
}
.brand b {
  font-size: var(--fs-md);
  font-weight: 600;
  line-height: var(--lh-tight);
  min-width: 0;
  overflow-wrap: anywhere;
}
.mark {
  width: var(--h-s);
  height: var(--h-s);
  border-radius: var(--r-s);
  background: var(--mark);
  display: grid;
  place-items: center;
  flex: none;
}
.mark svg {
  width: 26px;
}
.top-actions {
  display: flex;
  gap: var(--sp-1);
}
/* a plain header button: an icon or a short word, no outline; its shape shows on hover and focus */
.tool,
.sheet-close {
  min-width: var(--h-s);
  height: var(--h-s);
  padding-inline: var(--sp-4);
  border-radius: var(--r-s);
  display: inline-grid;
  place-items: center;
  font-size: var(--fs-sm);
  font-weight: 600;
  text-decoration: none;
  transition: background var(--t-fast);
}
/* the same, filled: a control that stands on its own beside the search field */
.tool-fill {
  position: relative;
  flex: none;
  width: var(--h-m);
  height: var(--h-m);
  border-radius: var(--r-m);
  background: var(--soft);
  display: grid;
  place-items: center;
  transition: background var(--t-fast);
}
.tool-fill.open,
.tool-fill.on {
  background: var(--ink);
  color: var(--bg);
}
@media (hover: hover) {
  .tool-fill:not(.open):hover {
    background: var(--line);
  }
}
/* the cafe's own words: a line of their own under the logo on phones, beside it on wide screens */
.motto {
  height: var(--hello-h);
  line-height: var(--hello-h);
  color: var(--mute);
  font-size: var(--fs-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* filters: a small non-modal <dialog> inside the search field's box, so it sits under the field
   and moves with the header by itself; the page stays usable */
/* a small menu hanging from its button: the filters, an item's choices (assets/js/popup.js) */
.pop {
  position: absolute;
  inset: auto;
  inset-block-start: calc(100% + var(--sp-3));
  inset-inline-end: 0;
  z-index: 1;
  margin: 0;
  padding: 0;
  max-width: 100%;
  color: inherit;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  box-shadow: var(--shadow-2);
  animation: fade var(--t-fast);
}
.filters {
  display: flex;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding: var(--sp-4);
}
.search {
  position: relative; /* the filter menu hangs under this row */
  display: flex;
  gap: var(--sp-4);
  margin-top: var(--sp-4);
}
.field {
  position: relative;
  flex: 1;
  min-width: 0;
}
.search input {
  appearance: none;
  width: 100%;
  height: var(--h-m);
  border-radius: var(--r-m);
  border: 1px solid transparent;
  background: var(--soft);
  padding-inline: var(--sp-10) var(--h-s);
  font: inherit;
  font-size: var(--fs-md);
  color: var(--ink);
}
.search input::-webkit-search-cancel-button,
.search input::-webkit-search-decoration {
  appearance: none; /* the field has its own clear button */
}
.search input:focus {
  outline: none;
  background: var(--surface);
  border-color: var(--ink);
}
.field > .ic {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  inset-inline-start: var(--sp-6);
  width: var(--ic-m);
  height: var(--ic-m);
  color: var(--mute);
  pointer-events: none;
}
.search .clear {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  inset-inline-end: var(--sp-1);
  width: var(--h-s);
  height: var(--h-s);
  border-radius: 50%;
  display: none;
  place-items: center;
  color: var(--mute);
}
.search.has .clear {
  display: grid;
}
/* filters in use: item count and one chip per filter (tap to remove) */
.fstat {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  padding-top: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--mute);
}
.fchip {
  height: var(--h-s);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-4);
  padding-inline: var(--sp-5) var(--sp-5);
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--bg);
  font-size: var(--fs-sm);
  font-weight: 600;
  white-space: nowrap;
}
.fchip .ic {
  width: var(--ic-xs);
  height: var(--ic-xs);
  opacity: 0.75;
}
.search .clear .ic {
  width: var(--ic-s);
  height: var(--ic-s);
}
.fchip:focus-visible {
  outline: var(--focus);
  outline-offset: 2px;
}
/* the category bar: links to the sections, scrolled sideways; its ends fade out */
.chips {
  display: flex;
  gap: var(--sp-3);
  overflow-x: auto;
  scrollbar-width: none;
  max-width: var(--maxw);
  margin-inline: auto;
  padding: var(--sp-4) var(--pad-r) var(--sp-4) var(--pad-l);
  min-height: calc(var(--h-s) + 1rem);
  scroll-padding-inline: var(--gut);
  mask-image: linear-gradient(
    to right,
    transparent,
    #000 var(--gut),
    #000 calc(100% - var(--gut)),
    transparent
  );
}
.chip {
  flex: none;
  text-decoration: none;
}
.chip {
  flex: none;
}

/* ---------- menu ---------- */
main.wrap {
  padding-top: var(--sp-2);
  min-height: 60vh;
}
.sec {
  padding-top: var(--sp-11);
}
.sec:first-of-type {
  padding-top: var(--sp-5);
}
.sec-h {
  margin-bottom: var(--sp-5);
  font-size: var(--fs-xl);
  font-weight: 600;
  line-height: var(--lh-tight);
}
.site-foot h2,
.sheet-title {
  font-size: var(--fs-lg);
  font-weight: 600;
  line-height: var(--lh-tight);
}
/* the bill's close button, in the panel's top corner like the item card's */
.sheet-close {
  position: absolute;
  top: var(--sp-5);
  inset-inline-end: var(--sp-5);
  padding: 0;
  color: var(--mute);
}
/* where a panel or menu opens, focus lands on its start (autofocus, so screen readers begin there); not a control, no ring */
[autofocus][tabindex="-1"]:focus {
  outline: none;
}
.grid {
  --cols: 1;
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr)); /* columns never grow past the page */
  column-gap: var(--sp-9);
}
.it {
  display: flex;
  flex-wrap: wrap; /* with very large text the bill control moves to a line of its own */
  gap: var(--it-gap);
  align-items: center;
  padding: var(--sp-5) var(--sp-4);
  margin-inline: calc(var(--sp-4) * -1);
  position: relative;
  border-radius: var(--r-m);
  cursor: pointer;
  transition: background var(--t-fast);
}
.it::after {
  content: "";
  position: absolute;
  inset-inline: var(--sp-4);
  bottom: 0;
  height: 1px;
  background: var(--line);
  pointer-events: none;
}
.it:active {
  background: var(--soft);
}
@media (hover: hover) {
  .it:hover {
    background: var(--soft);
  }
  .it:hover .pic img {
    transform: scale(1.06);
  }
}
.pic {
  flex: none;
  background: var(--tint, var(--soft));
  position: relative;
  width: var(--thumb);
  height: var(--thumb);
  border-radius: var(--r-m);
  overflow: hidden;
  display: grid;
  place-items: center;
}
.pic img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}
.pic svg {
  width: 50%;
  height: 50%;
  stroke: var(--ink);
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.info {
  flex: 1 1 5rem; /* the least room the name and price need beside the photo */
  align-self: stretch;
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow-wrap: anywhere;
}
.info h3 {
  font-size: var(--fs-md);
  font-weight: 600;
  line-height: var(--lh-body); /* 24px: the name is a tap target */
  overflow-wrap: anywhere;
}
/* the name is the row's button; its invisible layer covers the whole row, so a tap anywhere opens the card */
.it-name {
  display: inline;
  padding: 0;
  font-weight: inherit;
  line-height: inherit;
  text-align: inherit;
  overflow-wrap: anywhere;
}
.it-name::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  border-radius: var(--r-m);
}
.it-name:focus-visible {
  outline: none;
}
.it-name:focus-visible::before {
  box-shadow: inset 0 0 0 var(--focus-w) var(--ink);
}
/* the row's own buttons sit above that layer */
.it .buy {
  position: relative;
}
.info .opts {
  font-size: var(--fs-sm);
  color: var(--mute);
  line-height: var(--lh-body);
}
.info .why {
  font-size: var(--fs-xs);
  color: var(--mute);
  line-height: var(--lh-body);
  margin-top: var(--sp-1);
}
.price {
  margin-top: auto; /* at the foot of the row, in line with the photo's lower edge */
  padding-top: var(--sp-2);
  font-size: var(--fs-md);
  font-weight: 600;
}
.price small,
.unit {
  font-size: var(--fs-xs);
  font-weight: 400;
  color: var(--mute);
}
.add {
  width: var(--h-m);
  height: var(--h-m);
  border-radius: 50%;
  background: var(--soft);
  color: var(--ink);
  display: grid;
  place-items: center;
  font-size: var(--fs-lg);
  font-weight: 400;
  line-height: 1;
  transition:
    background var(--t-fast),
    transform var(--t-fast),
    color var(--t-fast);
}
.add:active {
  transform: scale(0.92);
}
@media (hover: hover) {
  .add:hover {
    background: var(--line);
  }
  .it:hover .add {
    background: var(--bg);
  }
}
@keyframes pop {
  50% {
    transform: scale(1.15);
  }
}
.billbar .c {
  animation: pop var(--t-slow) var(--ease) both;
} /* replayed by bill.js when the count changes ("both" keeps it replayable) */
.it mark {
  background: var(--brand-soft);
  color: inherit;
  border-radius: 3px;
}
/* on a tag's own colour the soft mark would not show */
.tag mark {
  background: var(--brand);
  color: var(--brand-ink);
}
.tags {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin-top: var(--sp-2);
}
.tag {
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: var(--lh-body);
  padding: 0 var(--sp-4);
  border-radius: var(--r-xs);
  max-width: 100%;
}
.tag.pm {
  background: var(--pm-bg);
  color: var(--pm);
}
.tag.cf {
  background: var(--cf-bg);
  color: var(--cf);
}
.tag.n {
  background: var(--n-bg);
  color: var(--n);
}
.empty {
  padding: var(--sp-11) 0;
  text-align: center;
  color: var(--mute);
}
/* While the menu is being built it holds at least a screen, so what follows it (the address)
   never shows for a moment only to be pushed down. */
#menu[aria-busy="true"] {
  min-height: 100vh;
}
/* while the menu is on its way: grey rows in the menu's own shape, so nothing jumps when it arrives */
.sk {
  display: flex;
  align-items: center;
  gap: var(--it-gap);
  padding-block: var(--sp-5);
}
.sk::before,
.sk::after {
  content: "";
  border-radius: var(--r-m);
  background: var(--soft);
  animation: wait 1.2s ease-in-out infinite alternate;
}
.sk::before {
  flex: none;
  width: var(--thumb);
  height: var(--thumb);
}
.sk::after {
  width: 40%;
  height: var(--sp-6);
}
@keyframes wait {
  to {
    opacity: 0.45;
  }
}
@media (scripting: none) {
  .sk {
    display: none;
  }
}
/* shown while the menu's scripts load, or if they cannot run */
.loading {
  padding: var(--sp-11) 0;
  text-align: center;
  color: var(--mute);
}
.loading span {
  display: block;
}
.empty b {
  display: block;
  color: var(--ink);
  font-size: var(--fs-md);
  margin-bottom: var(--sp-2);
}

/* ---------- footer ---------- */
.site-foot {
  margin-top: var(--sp-11);
  background: var(--soft);
  border-top: 1px solid var(--line);
  padding: var(--sp-9) 0 calc(var(--sp-9) + env(safe-area-inset-bottom));
}
html:has(.billbar.up) .site-foot {
  padding-bottom: calc(var(--billbar-h) + var(--sp-8) + env(safe-area-inset-bottom));
}
.site-foot h2 {
  margin-bottom: var(--sp-6);
}
.card {
  background: var(--surface);
  border-radius: var(--r-m);
}
.sheet .card {
  background: var(--soft);
}

/* visit card: one grouped list, every row the same shape */
.visit {
  font-style: normal;
  padding: 0 var(--sp-6);
  container: visit/inline-size;
}
/* The card: two description lists (the address; phone, Instagram, hours) around the map.
   Each row is a term (icon and small label) over its description (the value). */
.vrow {
  position: relative; /* a linked value's tap area is the whole row */
  padding: var(--sp-5) 0;
}
.vrow + .vrow,
.vlist:last-child {
  border-top: 1px solid var(--line);
}
.vrow dt {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  color: var(--mute);
  font-size: var(--fs-xs);
}
.vrow dd {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-top: var(--sp-1);
  padding-inline-start: calc(var(--ic-l) + var(--sp-5)); /* under the label, past the icon */
  font-weight: 600;
  overflow-wrap: anywhere;
}
.vrow dd a {
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
  text-decoration: none;
  transition: opacity var(--t-fast);
}
.vrow dd a::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--r-s);
}
.vrow dd a:active {
  opacity: 0.6;
}
.vrow dd a:focus-visible {
  outline: none;
}
.vrow dd a:focus-visible::before {
  box-shadow: inset 0 0 0 var(--focus-w) var(--ink);
}
.vmapbox {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding-bottom: var(--sp-5);
}
@container visit (width >= 40rem) {
  /* wide card: all the text in one column, the map and its buttons in the other */
  .vbody {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    grid-template-rows: auto 1fr;
    column-gap: var(--sp-10);
    padding-inline: var(--sp-4);
  }
  .vmapbox {
    grid-column: 2;
    grid-row: 1 / -1;
    padding-top: var(--sp-5);
  }
}
.vic {
  flex: none;
  width: var(--ic-l);
  height: var(--ic-l);
}
.vgo {
  flex: none;
  width: var(--ic-s);
  height: var(--ic-s);
  color: var(--mute);
}
/* the apps' own icons, rounded the way phones show them */
.vbrand {
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: 22.5%;
}
.vbrand.vic {
  width: var(--ic-l);
  height: var(--ic-l);
}
/* the map: an OpenStreetMap image at its own scale (labels stay readable), centred on the
   cafe, with the pin drawn on top; wider screens simply show more of the area */
.vmap {
  position: relative;
  height: 14rem;
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  overflow: hidden;
  background: var(--map-land);
}
.vmap img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: none;
  filter: var(--map-filter);
}
a.vmap {
  display: block;
  transition: opacity var(--t-fast);
}
a.vmap:active {
  opacity: 0.85;
}
a.vmap:focus-visible {
  outline: var(--focus);
  outline-offset: 2px;
}
.vpin {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 38px;
  height: 38px;
  transform: translate(-50%, -94%);
  fill: var(--brand);
  stroke: var(--on-photo-ink);
  stroke-width: 1.5;
  filter: var(--shadow-pin);
}
.osm {
  position: absolute;
  right: 0;
  bottom: 0;
  padding: var(--sp-1) var(--sp-3);
  border-top-left-radius: var(--r-s);
  background: var(--credit-bg);
  color: var(--credit-ink);
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  pointer-events: none;
}
/* directions: equal buttons in one row */
.vdir {
  min-width: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4);
}
@container visit (width < 15rem) {
  .vdir {
    grid-auto-flow: row;
  }
  .mapgo {
    overflow-wrap: anywhere;
  }
} /* one row, or all stacked: never 2 + 1 */
.mapgo {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--h-s);
  padding: var(--sp-4) var(--sp-3);
  line-height: var(--lh-tight);
  border: 1px solid var(--line);
  border-radius: var(--r-s);
  background: var(--surface);
  font-weight: 600;
  font-size: var(--fs-sm);
  text-align: center;
  text-decoration: none;
  color: var(--ink);
  transition:
    background-color var(--t-fast),
    transform var(--t-fast) var(--ease);
}
.mapgo:active {
  transform: scale(0.96);
}
@media (hover: hover) {
  .mapgo:hover {
    background: var(--soft);
  }
}
.sheet .mapgo {
  background: var(--surface);
}
/* opening hours that differ by day */
.vdays {
  display: grid;
  gap: var(--sp-2);
  margin-top: var(--sp-1);
  font-weight: 400;
}
.vdays > span {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-6);
}
.vdays .today {
  font-weight: 600;
}
.foot-end {
  margin-top: var(--sp-9);
  text-align: center;
}
.slogan {
  font-size: var(--fs-md);
}
.copy {
  margin-top: var(--sp-2);
  color: var(--mute);
  font-size: var(--fs-xs);
}

/* ---------- bill bar ---------- */
.billbar {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 30;
  padding: var(--sp-5) var(--pad-r) calc(var(--sp-5) + env(safe-area-inset-bottom)) var(--pad-l);
  transform: translateY(120%);
  visibility: hidden;
  transition:
    transform var(--t-slow) var(--ease),
    visibility 0s linear var(--t-slow);
  pointer-events: none;
}
.billbar.up {
  transform: none;
  visibility: visible;
  transition:
    transform var(--t-slow) var(--ease),
    visibility 0s;
}
.billbar button {
  pointer-events: auto;
  width: 100%;
  max-width: 520px;
  margin-inline: auto;
  height: var(--h-l);
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  background: var(--ink);
  color: var(--bg);
  border-radius: var(--r-m);
  padding-inline: var(--sp-6);
  box-shadow: var(--shadow-2);
}
.billbar .c {
  background: var(--brand);
  color: var(--brand-ink);
  min-width: 28px;
  height: 28px;
  border-radius: var(--r-xs);
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: var(--fs-sm);
}
.billbar [data-t="bill"] {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: start;
} /* the label takes the free space, so the total sits at the end */
.billbar .t {
  font-weight: 600;
}

/* ---------- sheets (item card, bill, info) ---------- */
/* panels: <dialog> elements filling the screen; the visible card is .panel inside */
.sheet {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  overflow: hidden;
}
.sheet::backdrop {
  background: var(--scrim);
  animation: fade var(--t-mid);
}
html:has(dialog.sheet[open]) {
  overflow: hidden;
} /* full panels lock the page; the filter menu does not */
.panel {
  --swipe: on;
  position: absolute;
  bottom: 0;
  inset-inline: 0;
  margin-inline: auto;
  width: 100%;
  max-width: var(--pw);
  max-height: 90dvh;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface);
  border-radius: var(--r-l) var(--r-l) 0 0;
  padding: var(--sp-4) var(--sp-7) calc(var(--sp-7) + env(safe-area-inset-bottom));
  animation: up var(--t-slow) var(--ease);
  touch-action: pan-y;
}
.panel.dragging {
  transition: none;
}
.grab {
  display: block;
  width: 44px;
  height: 5px;
  border-radius: var(--r-pill);
  background: var(--line);
  margin: var(--sp-2) auto var(--sp-6);
}
.sheet-title {
  margin-bottom: var(--sp-1);
}
.panel .sub {
  color: var(--mute);
  font-size: var(--fs-sm);
  margin-bottom: var(--sp-6);
}
.acts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-top: var(--sp-7);
}
.acts .btn {
  flex: 1 1 0%;
  min-width: 8rem;
} /* equal halves; with very large text they stack */
.note {
  font-size: var(--fs-xs);
  color: var(--mute);
  margin-top: var(--sp-6);
  text-align: center;
}
@keyframes up {
  from {
    transform: translateY(40px);
    opacity: 0.4;
  }
}
@keyframes fade {
  from {
    opacity: 0;
  }
}

/* bill */
.line {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
  align-items: center;
  padding: var(--sp-5) 0;
  border-bottom: 1px solid var(--line);
}
.line .nm {
  flex: 1 1 5.5rem;
  min-width: 0;
  font-weight: 600;
  overflow-wrap: anywhere;
} /* with large text the name takes its own line */
.line .nm small {
  display: block;
  color: var(--mute);
  font-size: var(--fs-xs);
  font-weight: 400;
}
.line .s {
  min-width: 3.6rem;
  text-align: end;
  font-weight: 600;
}
.split {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-6);
  margin-top: var(--sp-6);
  padding: var(--sp-5) var(--sp-6);
  background: var(--soft);
  border-radius: var(--r-m);
}
.tot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: var(--sp-6) 0 var(--sp-2);
}
.tot b {
  font-size: var(--fs-xl);
}
.per {
  display: flex;
  justify-content: space-between;
  color: var(--mute);
  font-size: var(--fs-sm);
}
.per b {
  color: var(--ink);
}

/* item card */
.panel.dpanel {
  padding: 0 0 calc(var(--sp-7) + env(safe-area-inset-bottom));
}
.dpanel .grab {
  position: absolute;
  top: var(--sp-3);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  margin: 0;
  background: var(--on-photo-dim);
}
/* the photo frame: every photo is square (prepared that way), shown at the card's full width.
   On phones the card is a bottom sheet that scrolls if the screen is short; from 700px up it is
   sized to fit the screen (see "item card on tablets and computers" below). */
.dimg {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  overflow: hidden;
  background: var(--soft);
}
.dimg img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* the small menu photo shows at once, softened, until the large one has loaded over it */
.dimg img.lo {
  filter: blur(10px);
  transform: scale(1.08);
}
/* photo strip: one or more photos, swiped sideways and snapping into place */
.gal {
  position: absolute;
  inset: 0;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.sl {
  position: relative;
  flex: 0 0 100%;
  overflow: hidden;
  scroll-snap-align: center;
  scroll-snap-stop: always;
}
.gdots {
  position: absolute;
  bottom: var(--sp-4);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  padding: 0 4px;
  border-radius: var(--r-pill);
  background: var(--scrim);
}
.gdots button {
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
}
.gdots button::after {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 3px;
  background: var(--on-photo-dim);
  transition:
    width var(--t-mid) var(--ease),
    background-color var(--t-mid);
}
.gdots button[aria-current]::after {
  width: 16px;
  background: var(--on-photo);
}
.dclose {
  position: absolute;
  top: var(--sp-5);
  inset-inline-end: var(--sp-5);
  width: var(--h-m);
  height: var(--h-m);
  border-radius: 50%;
  background: var(--on-photo-bg);
  color: var(--on-photo-ink);
  display: grid;
  place-items: center;
  box-shadow: var(--shadow-control);
}
.dbody {
  padding: var(--sp-6) var(--sp-7) 0;
  overflow: hidden;
}
.dbin {
  padding: 2px;
}
.dbody .dbin {
  margin: -2px;
}
.dbody h2 {
  font-size: var(--fs-xl);
  font-weight: 600;
  line-height: var(--lh-tight);
}
.dbody .alt {
  color: var(--mute);
  font-size: var(--fs-sm);
}
.dbody .desc {
  margin-top: var(--sp-5);
  line-height: var(--lh-loose);
}
.dbody .ingr {
  margin-top: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--mute);
}
.dbody .ask {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-4);
  margin-top: var(--sp-6);
  color: var(--mute);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
}
.dbody .ask .ic {
  width: var(--ic-s);
  height: var(--ic-s);
  margin-top: var(--sp-1);
}
.dbuy {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-5);
  margin-top: var(--sp-7);
}
.dbuy .pr {
  font-size: var(--fs-xl);
  font-weight: 600;
  flex: 1 1 auto;
} /* takes the free space, so the button sits at the end */
.dbuy .btn {
  flex: 0 1 auto;
}
/* an item's choices on its card: one bordered line each */
.picks {
  flex: 1 0 100%;
  display: grid;
  gap: var(--sp-3);
}
.picks .pick {
  border: 1px solid var(--line);
  border-radius: var(--r-m);
}
.picks small {
  color: var(--mute);
  font-size: var(--fs-xs);
  font-weight: 400;
}
/* once the item is in the bill: the bill is the guest's own list, not an order */
.dbuy .order-note {
  flex: 1 0 100%;
  font-size: var(--fs-sm);
  color: var(--mute);
}

/* toast */
.toast {
  position: fixed;
  bottom: calc(var(--billbar-h) + env(safe-area-inset-bottom));
  left: 50%;
  transform: translate(-50%, 10px);
  max-width: calc(100vw - 2rem);
  background: var(--ink);
  color: var(--bg);
  padding: var(--sp-4) var(--sp-6);
  border-radius: var(--r-s);
  font-size: var(--fs-sm);
  z-index: 60;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--t-mid),
    transform var(--t-mid),
    visibility var(--t-mid);
  width: max-content;
  text-align: center;
}
.toast.show {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
}

/* ---------- responsive ---------- */
/* the narrowest phones (320px): slightly smaller controls, so a row still fits */
@media (max-width: 340px) {
  :root {
    --h-xs: 32px;
    --h-s: 36px;
    --h-m: 40px;
  }
}
@media (max-width: 380px) {
  :root {
    --gut: var(--sp-5);
    --thumb: 72px;
    --it-gap: var(--sp-5);
  }
  .top-actions {
    gap: var(--sp-2);
  }
  .panel {
    padding-inline: var(--sp-6);
  }
  .dbody {
    padding-inline: var(--sp-6);
  }
}
@media (min-width: 700px) {
  .grid {
    --cols: 2;
  }
  /* sheets open centred on tablets and desktops */
  .panel {
    --swipe: off;
    bottom: 50%;
    transform: translateY(50%);
    border-radius: var(--r-l);
    animation: fade var(--t-mid);
  }
  .panel .grab {
    display: none;
  }
}
@media (min-width: 860px) {
  /* the header in two rows: logo, slogan and tools; then search, filters and categories */
  .bar-row {
    display: flex;
    align-items: center;
    column-gap: var(--sp-4);
    min-height: var(--bar-row);
  }
  .bar-top {
    display: contents; /* the logo and the tools join the row, with the motto between them */
  }
  .motto {
    flex: 1;
    margin-inline-start: var(--sp-4);
  }
  .top-actions {
    order: 1;
  }
  .find {
    display: flex;
    align-items: center;
    max-width: var(--maxw);
    margin-inline: auto;
    padding-left: var(--pad-l);
    padding-right: var(--pad-r);
  }
  .find-search {
    flex: none;
    margin: 0;
    padding: 0;
  }
  .find .search {
    margin-top: 0;
    gap: var(--sp-3);
  }
  /* the search field is the row's first pill and grows while in use */
  .find .field {
    flex: none;
    width: 10.5rem;
    transition: width var(--t-mid) var(--ease);
  }
  /* at rest the field is a pill that shows its own label; the example text comes with the field */
  .find .search:not(:focus-within, .has) .sr {
    inset-block: 0;
    inset-inline-start: var(--sp-9);
    display: flex;
    align-items: center;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip-path: none;
    color: var(--mute);
    font-size: var(--fs-sm);
    font-weight: 600;
    pointer-events: none;
  }
  .find .search:not(:focus-within, .has) input::placeholder {
    color: transparent;
  }
  .find .search:focus-within .field,
  .find .search.has .field {
    width: 24rem;
  }
  .find .search input {
    height: var(--h-s);
    border-radius: var(--r-pill);
    padding-inline-start: var(--sp-9);
    font-size: var(--fs-sm);
    text-overflow: ellipsis;
  }
  .find .field > .ic {
    inset-inline-start: var(--sp-5);
    width: var(--ic-s);
    height: var(--ic-s);
  }
  .find .tool-fill {
    width: var(--h-s);
    height: var(--h-s);
    border-radius: 50%;
  }
  .find .pop {
    inset-inline: 0 auto;
    width: max-content;
    max-width: 80vw;
  }
  /* the row's fading ends fall on its own padding, never on a category */
  .find .chips {
    flex: 1;
    min-width: 0;
    margin: 0;
    margin-inline-end: calc(-1 * var(--gut));
    padding-inline: var(--gut);
  }
  .sec-h {
    margin-bottom: var(--sp-6);
  }
  .fstat {
    padding-top: 0;
    padding-bottom: var(--sp-3);
  }
  :root {
    --gut: 2rem;
    --thumb: 104px;
  }
  .search {
    max-width: 36rem;
  }
  /* each item is a tile with its own bill control inside, so the two clearly belong together */
  .grid {
    gap: var(--sp-5);
  }
  .it {
    margin-inline: 0;
    padding: var(--sp-5);
    border: 1px solid var(--line);
    background: var(--surface);
  }
  .it::after {
    content: none;
  }
}
/* ---------- item card beyond phones ----------
   One size for every item on a given screen, never taller than the screen, 1rem clear above and
   below. In both layouts the details are a column with the previous/next buttons at its foot,
   and only the details scroll if an item's text is longer than its space. */
@media (orientation: portrait) and (min-width: 700px),
  (orientation: landscape) and (min-width: 560px) {
  .panel.dpanel {
    max-width: none;
    max-height: none;
    overflow: hidden;
    padding-bottom: 0;
  }
  .dpanel .dbody {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    scrollbar-width: thin;
  }
  .dpanel .dbin {
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
  }
  .dpanel .ask {
    margin-bottom: var(--sp-6);
  }
  .dpanel .dsib {
    margin-top: auto;
  }
}
/* upright screens (tablets): the photo on top. The card keeps one shape (--card-shape) and is as
   wide as the screen's width and height allow. */
@media (orientation: portrait) and (min-width: 700px) {
  .panel.dpanel {
    --w: min(var(--pw), 100vw - 2 * var(--gut), (100dvh - 2rem) / var(--card-shape));
    display: grid;
    grid-template-rows: var(--w) minmax(0, 1fr);
    width: var(--w);
    height: calc(var(--w) * var(--card-shape));
  }
  .dpanel .dbody {
    padding-bottom: var(--sp-7);
  }
}
@media (min-width: 1400px) {
  :root {
    --maxw: 1360px;
  }
  .grid {
    --cols: 3;
  }
}
/* where the motto has a line of its own: the header slides up by that line, then stays */
@media (max-width: 859.98px) {
  .appbar {
    top: calc(-1 * var(--hello-h));
  }
}
/* short screens (phones held sideways): there is room for the categories only; where they share
   their row with the search field, that row stays and the logo row scrolls away */
@media (max-height: 520px) {
  .appbar {
    top: calc(-1 * (var(--bar-row) + var(--hello-h) + var(--h-m) + var(--sp-5)));
  }
  .bar-top {
    position: static;
  }
  .panel {
    max-height: 94dvh;
  }
}
@media (max-height: 520px) and (min-width: 860px) {
  .appbar {
    top: calc(-1 * (var(--bar-row) + var(--sp-2)));
  }
}
/* wide screens (computers, tablets and phones held sideways): the square photo beside the
   details. The photo is as tall as the screen allows, up to --ph-max; the details have a fixed
   width, at most half the screen so large text still leaves room for the photo. */
@media (orientation: landscape) and (min-width: 560px) {
  .panel.dpanel {
    --dw: min(24rem, 50vw);
    --ph: min(100dvh - 2rem, 94vw - var(--dw), var(--ph-max));
    display: grid;
    grid-template-columns: var(--ph) var(--dw);
    width: calc(var(--ph) + var(--dw));
    height: var(--ph);
  }
  .dpanel .dbody {
    padding: var(--sp-7);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
  html {
    scroll-behavior: auto;
  }
}
/* an item's choices: a menu at its + button, one line per choice */
.it .pop {
  z-index: 5;
  width: max-content;
  max-width: min(18rem, 80vw);
  padding: var(--sp-2);
  cursor: auto;
}
.pick {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-7);
  width: 100%;
  min-height: var(--h-l);
  padding-inline: var(--sp-5);
  border-radius: var(--r-s);
  font-weight: 600;
  text-align: start;
}
div.pick {
  padding-inline-end: var(--sp-2);
}
@media (hover: hover) {
  button.pick:hover {
    background: var(--soft);
  }
}
/* "/" goes to the search field: said only where there is a keyboard to press it on */
.key {
  display: none;
}
/* a row's bill control: the + button, or the quantity control once the item is in the bill */
.buy {
  display: grid;
  justify-items: end;
  margin-inline-start: auto;
}
.buy .stepper {
  border-color: var(--brand);
  background: var(--brand-soft);
  animation: pop var(--t-mid) var(--ease);
}
/* item card: previous / next */
/* previous / next item: two named buttons at the end of the card */
.dsib {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
  gap: var(--sp-4);
  margin-top: var(--sp-6);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--line);
}
.sib {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-width: 0;
  min-height: 56px;
  padding: var(--sp-4) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  text-align: start;
  transition:
    background-color var(--t-fast),
    transform var(--t-fast) var(--ease);
}
.sib.next {
  flex-direction: row-reverse;
  text-align: end;
}
.sib:active {
  transform: scale(0.97);
}
@media (hover: hover) {
  .sib:hover {
    background: var(--soft);
  }
}
.sib:focus-visible {
  outline: var(--focus);
  outline-offset: 2px;
}
.sib-ic {
  flex: none;
  display: grid;
  color: var(--mute);
}
.sib-ic svg {
  width: var(--ic-s);
  height: var(--ic-s);
}
.sib-pic {
  flex: none;
  width: var(--sib-thumb);
  height: var(--sib-thumb);
  border-radius: var(--r-s);
  overflow: hidden;
  background: var(--soft);
  display: grid;
  place-items: center;
}
.sib-pic img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.sib-pic svg {
  width: 24px;
  height: 24px;
}
.sib-t {
  min-width: 0;
  display: flex;
  flex-direction: column;
  line-height: var(--lh-tight);
}
.sib-t small {
  font-size: var(--fs-xs);
  color: var(--mute);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sib-t b {
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: var(--lh-tight);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* photo arrows for galleries, computers only */
.gnav {
  display: none;
}
@media (hover: hover) and (pointer: fine) {
  .gnav {
    display: grid;
    place-items: center;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: var(--h-s);
    height: var(--h-s);
    border-radius: 50%;
    background: var(--on-photo-bg);
    color: var(--on-photo-ink);
    box-shadow: var(--shadow-control);
    opacity: 0;
    transition: opacity var(--t-mid);
  }
  .gnav svg {
    width: var(--ic-s);
    height: var(--ic-s);
  }
  .gprev {
    inset-inline-start: var(--sp-5);
  }
  .gnext {
    inset-inline-end: var(--sp-5);
  }
  .dimg:hover .gnav:not(:disabled),
  .gnav:focus-visible {
    opacity: 1;
  }
  .gnav:disabled {
    visibility: hidden;
  }
}
.panel.slide-next .dimg img,
.panel.slide-next .dbin {
  animation: slideN var(--t-mid) var(--ease);
}
.panel.slide-prev .dimg img,
.panel.slide-prev .dbin {
  animation: slideP var(--t-mid) var(--ease);
}
@keyframes slideN {
  from {
    opacity: 0;
    transform: translateX(calc(-16px * var(--dirx, 1)));
  }
}
@keyframes slideP {
  from {
    opacity: 0;
    transform: translateX(calc(16px * var(--dirx, 1)));
  }
}
html[dir="ltr"] {
  --dirx: -1;
}

.empty .pill {
  margin: var(--sp-6) auto 0;
}
.empty span {
  display: block;
}

/* ---------- high-contrast mode (forced colours) ----------
   The system replaces the page's colours, so anything shown only by a background or a shadow
   loses its edge: give those parts real borders, and mark chosen buttons the system's way. */
@media (forced-colors: active) {
  .billbar button,
  .toast,
  .panel,
  .btn,
  .add,
  .mapgo,
  .stepper,
  .pop,
  .billbar .c {
    border: 1px solid CanvasText;
  }
  .billbar button,
  .toast {
    background: Canvas;
    color: CanvasText;
  }
  .chip.on,
  .fbtn[aria-pressed="true"],
  .fchip {
    outline: 3px solid Highlight;
    outline-offset: -3px;
  }
}
@media (min-width: 860px) and (hover: hover) {
  .search:not(:focus-within, .has) .key {
    display: grid;
    place-items: center;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    inset-inline-end: var(--sp-4);
    min-width: var(--sp-7);
    height: var(--sp-7);
    border: 1px solid var(--line);
    border-radius: var(--r-xs);
    background: var(--bg);
    color: var(--mute);
    font: inherit;
    font-size: var(--fs-xs);
    pointer-events: none;
  }
}
