/* ==========================================================================
   MOTION — restaurant theme stylesheet
   --------------------------------------------------------------------------
   The whole design lives here; index.tpl carries only the five-line colour
   block that feeds the owner's palette into the tokens below. There is no
   Tailwind on this theme and no utility classes in the markup — the reference
   design was written as one hand-made stylesheet and it is kept that way, so a
   rule can be found by the name of the thing it draws.

   Sections
     1  Tokens, ground and type
     2  Header and hero
     3  Story (flip photos)
     4  Menu: tools, categories, cards, allergens
     5  Gallery
     6  Order / address band
     7  Footer and quick contact
     8  The owner's popup messages  (.mo-promo-*)
     9  Motion: keyframes, reveal, reduced motion
    10  Breakpoints
    11  The platform's dialogs — order, booking, login, allergens, cookies

   Sections 1-10 are the reference design, transposed onto the platform's
   markup. Section 11 is not the design's: it restyles the shared dialogs that
   restaurant.js opens, which arrive with their own Bootstrap-shaped markup and
   are styled nowhere else once the modern-cuisine stylesheet is left out.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   Dark is the design's own look and stays the default; the light values are
   restated in the [data-mo-theme="light"] block and are chosen by the owner's
   "Background home page: Light / Dark" setting, which index.tpl stamps onto
   <html> so the first paint is already right.

   Every colour in this file resolves through one of these. The -rgb pairs
   carry the same colour as bare channels, because most of the design's depth
   is washes — rgba(var(--mo-accent-rgb), .08) and friends — and a var() cannot
   be interpolated into a hex.
   -------------------------------------------------------------------------- */
:root {
    color-scheme: dark;

    /* Ground. --mo-bg is the page, --mo-bg-deep the top of its gradient,
       --mo-band the darker plate the order section sits on. */
    --mo-bg: #080808;
    --mo-bg-rgb: 8, 8, 8;
    --mo-bg-deep: #060606;
    --mo-bg-deep-2: #10100f;
    --mo-band: #090909;
    --mo-footer-bg: #050505;

    /* Raised surfaces, from the flattest to the most lifted: fields and the
       menu band, a dish card, a card under focus and the map plate. */
    --mo-panel: #11100f;
    --mo-panel-2: #171412;
    --mo-surface: #101010;
    --mo-surface-rgb: 16, 16, 16;
    --mo-surface-2: #141414;
    --mo-surface-3: #181818;
    --mo-surface-3-rgb: 18, 18, 18;

    /* The dish card is a flat plate, not a lit one — its own pair, because the
       design's other surfaces keep the gradient wash and this one dropped it.
       A menu is read as a list: twenty cards each catching light at their own
       corner is twenty highlights competing with the twenty prices. */
    --mo-card: #1a1a1a;
    --mo-card-hover: #212121;

    /* Ink. --mo-ink-rgb is the colour every hairline and hover wash is mixed
       from — white on the dark ground, near-black on the light one — which is
       what lets one set of rules serve both modes. */
    --mo-text: #f8f3ec;
    --mo-muted: #b7cad8;
    --mo-muted-cool: #c4c8ca;
    --mo-ink-rgb: 255, 255, 255;
    --mo-shade-rgb: 0, 0, 0;

    --mo-line: rgba(211, 181, 145, 0.18);
    --mo-line-rgb: 211, 181, 145;
    --mo-line-strong: rgba(211, 181, 145, 0.34);
    --mo-shadow: rgba(0, 0, 0, 0.42);

    /* Brand. index.tpl restates --mo-accent-base and --mo-accent-rgb from the
       restaurant's own Theme color; everything else here is derived, so one
       setting moves the accent through the entire page.

       --mo-on-accent is the ink printed on top of an accent plate. It is a
       token rather than a literal because the light mode darkens the accent
       and has to flip this with it. */
    --mo-accent-base: #d1aa7e;
    --mo-accent: var(--mo-accent-base);
    --mo-accent-rgb: 209, 170, 126;
    --mo-accent-2: #d7b07e;

    /* The accent as INK — as type, not as a plate. The dish number, the price
       and the order button are the restaurant's own colour set small on a
       near-black card, and a Theme color is not chosen for that job: it is
       picked in a settings form against white. #895100 is a good button on
       paper and 2.7:1 against this card, which is under the 4.5:1 small type
       needs and well under what a menu read on a phone in a restaurant needs.

       So the hue and the chroma are the restaurant's and only the lightness is
       the theme's: max() raises a colour that is too dark and leaves one that
       is already light exactly where it is. A restaurant that saved #ff5722
       keeps #ff6c3b; this one gets #da9c5d at 7.4:1, still its own orange.

       Three declarations, in rising order of what a browser has to know. The
       first is the design's own gold, which every browser understands and
       which is what the price wore before the accent reached it — legible,
       just not the restaurant's. The second keeps some of the hue. The last is
       the real answer; a browser that cannot parse it drops that line and
       falls back to the one above. */
    --mo-accent-ink: var(--mo-accent-2);
    --mo-accent-ink: color-mix(in srgb, var(--mo-accent-base) 62%, #ffd9b0);
    --mo-accent-ink: oklch(from var(--mo-accent-base) max(l, 0.74) c h);
    --mo-accent-soft: #e7cfaa;
    --mo-accent-label: #d8bf9a;
    --mo-accent-hi: #ddb98f;
    --mo-accent-grad-a: #d8b58c;
    --mo-accent-grad-b: #c69a6b;
    --mo-on-accent: #080808;

    /* The warm second gold the design uses for edges and glows only, never for
       type. It follows the owner's accent so a restaurant that picks red does
       not keep a gold halo. */
    --mo-glow-rgb: var(--mo-accent-rgb);

    --mo-jade: #8ea08d;
    --mo-whatsapp: #25d366;

    /* The one colour on the page that is not the restaurant's own. "New" and
       "reduced" are the two things a reader is meant to spot without looking
       for them, and the accent cannot mark them — on this design the accent is
       already the price, the kickers, the card edge and the active tab, so a
       badge wearing it says "more of the same". Red is the exception, and it
       is the only one. */
    --mo-flag: #e0392b;
    --mo-flag-rgb: 224, 57, 43;

    /* The owner's three heading colours. They were picked against a dark
       theme, which this one is, so they are used as given here and overridden
       only in light mode. */
    --mo-name-color: var(--mo-text);
    --mo-subtitle-color: var(--mo-text);
    --mo-category-color: var(--mo-text);

    --mo-serif: "Alumni Sans", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --mo-sans: "Alumni Sans", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --mo-condensed: "Barlow Condensed", "Alumni Sans", ui-sans-serif, system-ui, sans-serif;
}

/* --------------------------------------------------------------------------
   Light mode
   Warm paper rather than white: the accent and the food photography both sit
   better on it. Only tokens are restated — no component rule below knows which
   mode it is in.

   Two things do not simply inverse:

   The accent. A pale gold is a plate colour, not a text colour; printed on
   paper at label size it disappears. It is darkened here, and --mo-on-accent
   flips to paper with it so a button stays a dark plate with light ink rather
   than becoming gold-on-gold. color-mix is stated after a plain fallback so a
   browser without it still gets a usable colour.

   The footer keeps its dark plate in both modes — it closes the page the way
   the hero opens it, and its social buttons and legal links are drawn for it.

   The selector is html[…] rather than a bare attribute for a reason that costs
   an afternoon to find otherwise: index.tpl writes the owner's colours into a
   :root block in the <head>, after this stylesheet. Two selectors of equal
   weight, and the later one wins — so a bare [data-mo-theme="light"] would be
   overruled by RESTAURANT_NAME_COLOR, which every restaurant has saved as
   white because every theme before this one was dark. The tag name is what
   makes this block heavier, and it is why a heading is readable on paper.
   -------------------------------------------------------------------------- */
html[data-mo-theme="light"] {
    color-scheme: light;

    --mo-bg: #f7f4ee;
    --mo-bg-rgb: 247, 244, 238;
    --mo-bg-deep: #fffdf9;
    --mo-bg-deep-2: #f1ece3;
    --mo-band: #f1ece3;

    --mo-panel: #ffffff;
    --mo-panel-2: #f8f4ed;
    --mo-surface: #ffffff;
    --mo-surface-rgb: 255, 255, 255;
    --mo-surface-2: #ffffff;
    --mo-surface-3: #f4efe7;
    --mo-surface-3-rgb: 244, 239, 231;

    --mo-card: #ffffff;
    --mo-card-hover: #fffdf9;

    --mo-text: #16130f;
    --mo-muted: #5a6670;
    --mo-muted-cool: #55606a;
    --mo-ink-rgb: 22, 19, 15;
    --mo-shade-rgb: 22, 19, 15;

    --mo-line: rgba(22, 19, 15, 0.14);
    --mo-line-rgb: 22, 19, 15;
    --mo-line-strong: rgba(22, 19, 15, 0.26);
    --mo-shadow: rgba(22, 19, 15, 0.16);

    --mo-accent: var(--mo-accent-base);
    --mo-accent: color-mix(in srgb, var(--mo-accent-base) 68%, #120d07);
    --mo-accent-soft: var(--mo-accent);
    --mo-accent-label: var(--mo-accent);
    --mo-accent-hi: var(--mo-accent-base);
    --mo-on-accent: #fffdf9;

    /* On paper the correction runs the other way: the card is white, so a pale
       accent is the one that disappears and lightening it would be the bug.
       --mo-accent is already the darkened mix stated three lines up, which is
       exactly what ink on a white card wants, so the token simply follows it
       rather than raising a floor nothing here needs. */
    --mo-accent-ink: var(--mo-accent);

    /* The design's second gold is a plate colour and a text colour at once —
       the price chip, the allergen letters, the hours column, the brand mark.
       Left at its pale value it is legible on the dark ground and gone on
       paper, so in light mode it follows the darkened accent. */
    --mo-accent-2: var(--mo-accent);

    --mo-name-color: var(--mo-text);
    --mo-subtitle-color: var(--mo-text);
    --mo-category-color: var(--mo-text);
}

/* The footer is a dark plate whatever the page is set to, so inside it the ink
   tokens go back to their dark-mode values.

   The hero does NOT belong here, which is the difference between this design
   and every other theme in the folder: its banner is inside the circle on the
   right, not behind the words on the left. The hero's type sits on the page's
   own ground and takes the page's own ink. */
/* The circle is a photograph with type printed over it, and the design darkens
   that photograph hard: a scrim mixed from --mo-surface-3, the picture itself
   at 58% and brightness .64. On paper those tokens turn the scrim into a white
   veil and the banner disappears under it. So the circle keeps the dark
   treatment in both modes, exactly as a banner does on the other themes — the
   picture stays a picture and its caption stays readable. */
html[data-mo-theme="light"] .mo-hero-feature-stage {
    --mo-surface-3: #181818;
    --mo-surface-3-rgb: 18, 18, 18;
    --mo-text: #f8f3ec;
    --mo-muted: #b7cad8;
    --mo-muted-cool: #c4c8ca;
    --mo-ink-rgb: 255, 255, 255;
    --mo-accent: var(--mo-accent-base);
    --mo-accent-2: #d7b07e;

    /* The dish name takes no colour of its own — it inherits, and inheritance
       carries the computed colour body resolved from --mo-text, not the token.
       Re-stating the token here would leave the name at the page's dark ink;
       re-stating the colour is what makes the override reach it. */
    color: var(--mo-text);
}

html[data-mo-theme="light"] .mo-site-footer {
    --mo-text: #f8f3ec;
    --mo-muted: #b7cad8;
    --mo-muted-cool: #c4c8ca;
    --mo-ink-rgb: 255, 255, 255;
    --mo-line: rgba(211, 181, 145, 0.18);
    --mo-line-rgb: 211, 181, 145;
    --mo-accent: var(--mo-accent-base);
    --mo-accent-soft: #e7cfaa;
    --mo-accent-label: #d8bf9a;
    --mo-on-accent: #080808;
    --mo-name-color: var(--mo-text);
    --mo-subtitle-color: var(--mo-text);
}

/* The owner's own colours, applied where the settings page says they go. They
   are stated after the token blocks so a restaurant that picked a colour wins
   over the design's defaults. The category heading takes the tag name as well,
   because the font dialog compiles its selections with !important and
   specificity is what decides between two of those. */
.mo-hero-copy h1 { color: var(--mo-name-color); }
.mo-hero-subtitle { color: var(--mo-subtitle-color); }
h3.mo-cat-title { color: var(--mo-category-color); }


/* --------------------------------------------------------------------------
   2-10. The reference design
   Transposed from restaurant-motion-redesign/index.html. The class names are
   the design's own, prefixed mo- so nothing in this file can be reached by the
   platform's markup or reach into it, and every colour has been routed through
   the tokens in 1 so the light setting is a change of values, not of rules.
   -------------------------------------------------------------------------- */

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100vh;
  background:
    linear-gradient(120deg, rgba(var(--mo-accent-rgb), 0.08), transparent 26%),
    linear-gradient(180deg, var(--mo-bg-deep) 0%, var(--mo-bg) 42%, var(--mo-bg-deep-2) 100%);
  color: var(--mo-text);
  font-family: var(--mo-sans);
  font-size: 21px;
  letter-spacing: 0;
}

body.has-promo {
  overflow: hidden;
}

body::before {
  position: fixed;
  inset: 0;
  z-index: -1;
  content: "";
  pointer-events: none;
  opacity: 0.32;
  background-image:
    linear-gradient(rgba(var(--mo-ink-rgb), 0.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--mo-ink-rgb), 0.02) 1px, transparent 1px);
  background-size: 80px 80px;
  mask-image: linear-gradient(to bottom, transparent 0%, black 20%, black 82%, transparent 100%);
}

.mo-site-shell a,
.mo-quick-contact a,
.mo-promo-modal a {
  color: inherit;
  text-decoration: none;
}

.mo-site-shell img,
.mo-site-shell video,
.mo-promo-media img,
.mo-promo-media video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mo-site-shell figure {
  margin: 0;
}

.mo-site-shell {
  overflow: hidden;
}

.mo-topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 18px clamp(18px, 4vw, 56px);
  background: linear-gradient(180deg, rgba(var(--mo-bg-rgb), 0.82), rgba(var(--mo-bg-rgb), 0));
  backdrop-filter: blur(12px);
}

.mo-brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--mo-serif);
  font-size: clamp(20px, 2vw, 26px);
  line-height: 1;
  white-space: nowrap;
}

.mo-brand-mark {
  width: 34px;
  height: 34px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.26);
  display: grid;
  place-items: center;
  color: var(--mo-accent-2);
  font-size: 20px;
  transform: rotate(45deg);
}

.mo-brand-mark span {
  transform: rotate(-45deg);
}

.mo-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 10px 30px;
  color: rgba(var(--mo-ink-rgb), 0.92);
  font-size: 20px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  text-shadow: 0 10px 28px rgba(var(--mo-shade-rgb), 0.55);
}

.mo-nav a {
  position: relative;
  padding: 10px 0;
  transition: color 220ms ease;
}

.mo-nav a::after {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2px;
  height: 1px;
  content: "";
  background: var(--mo-accent);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 260ms ease;
}

.mo-nav a:hover,
.mo-nav a:focus-visible {
  color: var(--mo-text);
}

.mo-nav a:hover::after,
.mo-nav a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left;
}

.mo-hero {
  position: relative;
  min-height: clamp(620px, 78svh, 760px);
  display: grid;
  align-items: center;
  padding: 86px clamp(18px, 5vw, 58px) 52px;
  background:
    linear-gradient(90deg, rgba(var(--mo-bg-rgb), 0.92) 0%, rgba(var(--mo-bg-rgb), 0.7) 46%, rgba(var(--mo-surface-3-rgb), 0.82) 100%),
    linear-gradient(180deg, transparent 0%, rgba(var(--mo-accent-rgb), 0.08) 100%);
}

.mo-hero::before {
  position: absolute;
  inset: 0;
  content: "";
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(var(--mo-ink-rgb), 0.045), transparent 18%),
    linear-gradient(100deg, transparent 0%, rgba(var(--mo-glow-rgb), 0.08) 74%, transparent 100%);
  opacity: 0.9;
}

.mo-hero-grid {
  position: relative;
  z-index: 1;
  width: min(1240px, 100%);
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(330px, 0.78fr);
  gap: clamp(26px, 4vw, 60px);
  align-items: center;
}

.mo-hero-copy {
  position: relative;
  z-index: 2;
  animation: copyEnter 900ms cubic-bezier(.2, .8, .2, 1) both;
}

.mo-hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
  padding: 7px 12px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.16);
  color: rgba(var(--mo-ink-rgb), 0.84);
  background: rgba(var(--mo-ink-rgb), 0.035);
  font-size: 15px;
  font-weight: 500;
  text-transform: uppercase;
}

.mo-hero-badge::before {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  content: "";
  background: var(--mo-accent-2);
  box-shadow: 0 0 0 6px rgba(var(--mo-glow-rgb), 0.1);
  animation: dotPulse 2100ms ease-out infinite;
}

.mo-hero-welcome {
  margin: 0 0 10px;
  color: var(--mo-accent);
  font-family: var(--mo-serif);
  font-size: clamp(24px, 2.6vw, 34px);
  font-style: italic;
  line-height: 1.1;
}

.mo-site-shell h1,
.mo-site-shell h2,
.mo-site-shell h3,
.mo-promo-content h2 {
  margin: 0;
  font-family: var(--mo-serif);
  font-weight: 500;
  letter-spacing: 0;
}

.mo-site-shell h1 {
  max-width: 760px;
  font-size: clamp(44px, 8vw, 104px);
  line-height: 0.92;
}

.mo-hero-copy h1 {
  max-width: 720px;
  font-size: clamp(52px, 8vw, 104px);
  line-height: 0.88;
}

.mo-hero-subtitle {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 12px;
  color: var(--mo-text);
  font-size: clamp(18px, 1.8vw, 26px);
  font-weight: 500;
  text-transform: uppercase;
}

.mo-hero-subtitle::after {
  width: 54px;
  height: 1px;
  content: "";
  background: var(--mo-accent-2);
  animation: linePulse 2600ms ease-in-out infinite;
}

.mo-hero-subtitle em {
  color: var(--mo-accent-soft);
  font-family: var(--mo-serif);
  font-size: 0.86em;
  font-style: italic;
  text-transform: none;
}

.mo-hero-text {
  max-width: 610px;
  margin: 18px 0 0;
  color: var(--mo-muted);
  font-size: clamp(20px, 1.8vw, 24px);
  line-height: 1.65;
}

.mo-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 24px;
}

.mo-button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  padding: 0 22px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.18);
  border-radius: 4px;
  overflow: hidden;
  color: var(--mo-text);
  font-size: 16px;
  font-weight: 500;
  text-transform: uppercase;
  background: rgba(var(--mo-ink-rgb), 0.04);
  transition: transform 220ms ease, border-color 220ms ease, background 220ms ease;
}

.mo-hero .mo-button.primary {
  border-color: var(--mo-accent);
  color: var(--mo-on-accent);
  background: linear-gradient(135deg, var(--mo-accent-grad-a), var(--mo-accent-grad-b));
}

.mo-hero .mo-button {
  min-width: min(278px, 100%);
  min-height: 58px;
  padding: 0 30px;
  font-size: 18px;
  letter-spacing: 1px;
}

.mo-button::before {
  position: absolute;
  inset: 0;
  content: "";
  background: linear-gradient(110deg, transparent, rgba(var(--mo-ink-rgb), 0.24), transparent);
  transform: translateX(-130%);
  transition: transform 500ms ease;
}

.mo-button span {
  position: relative;
  z-index: 1;
}

.mo-button:hover,
.mo-button:focus-visible {
  transform: translateY(-2px);
  border-color: rgba(var(--mo-ink-rgb), 0.42);
}

.mo-button:hover::before,
.mo-button:focus-visible::before {
  transform: translateX(130%);
}

.mo-hero-info-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(16px, 3vw, 26px);
  max-width: 650px;
  margin-top: 26px;
  padding-top: 20px;
  border-top: 1px solid rgba(var(--mo-ink-rgb), 0.12);
}

.mo-hero-info {
  display: grid;
  gap: 8px;
  color: var(--mo-accent-label);
  font-size: 15px;
  font-weight: 500;
  text-transform: uppercase;
}

.mo-hero-info span {
  color: var(--mo-accent);
}

.mo-hero-info p {
  margin: 0;
  color: var(--mo-muted-cool);
  font-size: 16px;
  line-height: 1.7;
  text-transform: none;
}

.mo-hero-feature-stage {
  position: relative;
  min-height: clamp(340px, 46vh, 480px);
  display: grid;
  place-items: center;
  perspective: 1200px;
  isolation: isolate;
  animation: mediaEnter 1100ms cubic-bezier(.2, .8, .2, 1) 160ms both;
}

.mo-hero-feature-stage::before {
  position: absolute;
  inset: 10% 3%;
  content: "";
  border-radius: 999px;
  border: 1px solid rgba(var(--mo-glow-rgb), 0.1);
  transform: rotate(-8deg);
  animation: ringFloat 9000ms ease-in-out infinite;
}

.mo-dish-orbit {
  position: relative;
  width: min(360px, 32vw);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: 50%;
  transform-style: preserve-3d;
  animation: orbitBreath 7200ms ease-in-out infinite;
}

.mo-dish-orbit::before,
.mo-dish-orbit::after {
  position: absolute;
  content: "";
  border-radius: 50%;
  pointer-events: none;
}

.mo-dish-orbit::before {
  inset: -22px;
  border: 1px solid rgba(var(--mo-glow-rgb), 0.16);
  box-shadow: inset 0 0 38px rgba(var(--mo-glow-rgb), 0.06);
}

.mo-dish-orbit::after {
  inset: -6px;
  z-index: 1;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.1);
  box-shadow: 0 36px 90px rgba(var(--mo-shade-rgb), 0.48);
}

.mo-feature-panel {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: 50%;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.12);
  background: var(--mo-surface-3);
  opacity: 0;
  transform: rotateY(90deg) scale(0.88);
  backface-visibility: hidden;
  animation: heroDishFlip 18s infinite;
}

.mo-feature-panel:nth-child(2) {
  animation-delay: 6s;
}

.mo-feature-panel:nth-child(3) {
  animation-delay: 12s;
}

.mo-feature-panel img,
.mo-feature-panel video {
  position: absolute;
  inset: 0;
  opacity: 0.58;
  filter: saturate(0.92) contrast(1.08) brightness(0.64);
  transform: scale(1.1);
  animation: featureImageMove 18s ease-in-out infinite;
}

.mo-feature-panel:nth-child(2) img,
.mo-feature-panel:nth-child(2) video {
  animation-delay: 6s;
}

.mo-feature-panel:nth-child(3) img,
.mo-feature-panel:nth-child(3) video {
  animation-delay: 12s;
}

.mo-feature-panel::before {
  position: absolute;
  inset: 0;
  content: "";
  background:
    linear-gradient(180deg, rgba(var(--mo-surface-3-rgb), 0.2), rgba(var(--mo-surface-3-rgb), 0.78)),
    linear-gradient(90deg, rgba(var(--mo-surface-3-rgb), 0.76), rgba(var(--mo-surface-3-rgb), 0.58));
}

.mo-feature-panel::after {
  position: absolute;
  inset: -50% -22%;
  content: "";
  background: linear-gradient(105deg, transparent 28%, rgba(var(--mo-ink-rgb), 0.22) 48%, transparent 66%);
  transform: translateX(-72%) rotate(9deg);
  mix-blend-mode: screen;
  animation: featureShine 6000ms ease-in-out infinite;
}

.mo-feature-panel:nth-child(2)::after {
  animation-delay: 6s;
}

.mo-feature-panel:nth-child(3)::after {
  animation-delay: 12s;
}

.mo-feature-content {
  position: relative;
  z-index: 2;
  width: 74%;
  display: grid;
  justify-items: center;
  text-align: center;
}

.mo-feature-line {
  width: 80px;
  height: 2px;
  margin-bottom: 18px;
  background: var(--mo-accent);
}

.mo-feature-kicker {
  margin: 0 0 18px;
  color: rgba(var(--mo-ink-rgb), 0.72);
  font-size: 15px;
  font-weight: 500;
  text-transform: uppercase;
}

.mo-feature-content h2 {
  margin: 0;
  font-family: var(--mo-serif);
  font-size: clamp(30px, 3vw, 42px);
  font-style: italic;
  font-weight: 500;
  line-height: 1.08;
}

.mo-feature-content p {
  max-width: 250px;
  margin: 18px 0 0;
  color: var(--mo-muted-cool);
  font-size: 18px;
  line-height: 1.7;
}

.mo-feature-price {
  margin-top: 18px;
  color: var(--mo-accent-2);
  font-family: var(--mo-serif);
  font-size: 24px;
  font-weight: 500;
}

.mo-pulse-dot {
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: var(--mo-accent);
  box-shadow: 0 0 0 rgba(var(--mo-accent-rgb), 0.5);
  animation: dotPulse 1800ms ease-out infinite;
}

.mo-scroll-marquee {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 4;
  display: flex;
  gap: 0;
  padding: 11px 0;
  border-top: 1px solid rgba(var(--mo-line-rgb), 0.22);
  border-bottom: 1px solid rgba(var(--mo-line-rgb), 0.16);
  overflow: hidden;
  color: rgba(var(--mo-ink-rgb), 0.68);
  background:
    linear-gradient(90deg, rgba(var(--mo-accent-rgb), 0.12), transparent 16%, transparent 84%, rgba(var(--mo-accent-rgb), 0.1)),
    rgba(var(--mo-bg-rgb), 0.62);
  font-size: 16px;
  font-weight: 500;
  text-transform: uppercase;
  backdrop-filter: blur(10px);
}

.mo-scroll-marquee > span {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 16px;
  padding-right: 30px;
  animation: marqueeMove 24s linear infinite;
}

.mo-marquee-item {
  white-space: nowrap;
}

.mo-marquee-item.is-accent {
  color: var(--mo-accent-2);
  text-shadow: 0 0 18px rgba(var(--mo-accent-rgb), 0.24);
}

.mo-marquee-divider {
  color: rgba(var(--mo-accent-rgb), 0.72);
  font-family: var(--mo-condensed);
  font-size: 21px;
  line-height: 1;
}

.mo-marquee-icon {
  width: 9px;
  height: 9px;
  border: 1px solid rgba(var(--mo-accent-rgb), 0.9);
  background: rgba(var(--mo-accent-rgb), 0.16);
  transform: rotate(45deg);
  box-shadow: 0 0 0 5px rgba(var(--mo-accent-rgb), 0.08);
}

.mo-section {
  padding: clamp(52px, 7vw, 86px) clamp(18px, 6vw, 78px);
}

.mo-section-inner {
  width: min(1180px, 100%);
  margin: 0 auto;
}

.mo-section-heading {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 28px;
}

.mo-section-kicker {
  margin: 0 0 12px;
  color: var(--mo-accent);
  font-size: 15px;
  font-weight: 500;
  text-transform: uppercase;
}

.mo-site-shell h2 {
  font-size: clamp(34px, 5vw, 62px);
  line-height: 1;
}

.mo-section-heading p {
  max-width: 420px;
  margin: 0;
  color: var(--mo-muted);
  font-size: 21px;
  line-height: 1.6;
}


.mo-flip-photo {
  position: relative;
  min-height: 410px;
  border-radius: 6px;
  perspective: 1400px;
}

.mo-flip-photo-inner {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  animation: aboutPageFlip 8.8s cubic-bezier(.7, 0, .2, 1) infinite;
}

.mo-flip-photo:nth-child(2) .mo-flip-photo-inner {
  animation-delay: 2.2s;
}

.mo-flip-face {
  position: absolute;
  inset: 0;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.14);
  border-radius: 6px;
  overflow: hidden;
  background: var(--mo-panel);
  box-shadow: 0 26px 72px rgba(var(--mo-shade-rgb), 0.34);
  backface-visibility: hidden;
}

.mo-flip-face.back {
  transform: rotateY(180deg);
}

.mo-flip-face::before {
  position: absolute;
  inset: 0;
  z-index: 2;
  content: "";
  background:
    linear-gradient(90deg, rgba(var(--mo-shade-rgb), 0.34), transparent 30%, transparent 72%, rgba(var(--mo-shade-rgb), 0.42)),
    linear-gradient(180deg, transparent 45%, rgba(var(--mo-shade-rgb), 0.52));
  pointer-events: none;
}

.mo-flip-face::after {
  position: absolute;
  inset: 0;
  z-index: 3;
  content: "";
  background: linear-gradient(105deg, transparent 20%, rgba(var(--mo-ink-rgb), 0.2), transparent 52%);
  opacity: 0;
  transform: translateX(-70%);
  animation: pageShine 8.8s ease-in-out infinite;
  pointer-events: none;
}

.mo-flip-photo:nth-child(2) .mo-flip-face::after {
  animation-delay: 2.2s;
}

.mo-flip-face img {
  transform: scale(1.06);
  transition: transform 600ms ease;
}

.mo-flip-photo:hover .mo-flip-face img,
.mo-flip-photo:focus-within .mo-flip-face img {
  transform: scale(1.11);
}

.mo-flip-label {
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 18px;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.12);
  border-radius: 4px;
  color: var(--mo-muted);
  background: rgba(var(--mo-bg-rgb), 0.66);
  backdrop-filter: blur(12px);
  font-size: 16px;
  font-weight: 400;
}

.mo-flip-label span:first-child {
  color: var(--mo-text);
  font-family: var(--mo-serif);
  font-size: 22px;
  font-weight: 500;
}

.mo-menu {
  background:
    linear-gradient(180deg, rgba(var(--mo-ink-rgb), 0.025), transparent 24%),
    var(--mo-surface);
}

.mo-menu-tools {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  padding: 14px;
  border: 1px solid var(--mo-line);
  margin-bottom: 22px;
  background: rgba(var(--mo-ink-rgb), 0.02);
  overflow: hidden;
  transition: grid-template-columns 360ms cubic-bezier(.2, .8, .2, 1), gap 260ms ease;
}

.mo-menu-tools.has-search-open {
  grid-template-columns: minmax(280px, min(430px, 38vw)) minmax(0, 1fr);
  gap: 20px;
}

.mo-search {
  position: relative;
  display: flex;
  align-items: center;
  width: 46px;
  min-width: 46px;
  height: 46px;
  min-inline-size: 0;
  transition: width 360ms cubic-bezier(.2, .8, .2, 1);
}

.mo-search.is-open,
.mo-search:focus-within {
  width: 100%;
}

.mo-search-toggle {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 46px;
  height: 46px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.16);
  border-radius: 4px;
  background: var(--mo-surface);
  cursor: pointer;
  appearance: none;
  transition: transform 220ms ease, border-color 220ms ease, background 220ms ease;
}

.mo-search-toggle:hover,
.mo-search-toggle:focus-visible {
  border-color: var(--mo-accent);
  transform: translateY(-2px);
}

.mo-search-toggle::before {
  position: absolute;
  top: 14px;
  left: 14px;
  width: 13px;
  height: 13px;
  border: 2px solid var(--mo-muted);
  border-radius: 999px;
  content: "";
}

.mo-search-toggle::after {
  position: absolute;
  top: 28px;
  left: 27px;
  width: 8px;
  height: 2px;
  content: "";
  background: var(--mo-muted);
  transform: rotate(45deg);
  transform-origin: left center;
}

.mo-search.is-open .mo-search-toggle,
.mo-search:focus-within .mo-search-toggle {
  right: auto;
  border-color: transparent;
  background: transparent;
  pointer-events: none;
  transform: none;
}

.mo-search input {
  width: 100%;
  height: 46px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.16);
  border-radius: 4px;
  padding: 0 16px 0 46px;
  color: var(--mo-text);
  background: var(--mo-surface);
  outline: none;
  opacity: 0;
  pointer-events: none;
  transform: translateX(-8px);
  transform-origin: left center;
  transition: opacity 220ms ease, transform 360ms cubic-bezier(.2, .8, .2, 1), border-color 220ms ease, box-shadow 220ms ease;
  font-size: 18px;
  font-weight: 400;
}

.mo-search.is-open input,
.mo-search:focus-within input {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(0);
}

.mo-search input:focus {
  border-color: var(--mo-accent);
  box-shadow: 0 0 0 3px rgba(var(--mo-accent-rgb), 0.18);
}

.mo-tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 8px;
  min-width: 0;
  transform: translateX(0);
  transition: transform 360ms cubic-bezier(.2, .8, .2, 1);
}

.mo-menu-tools.has-search-open .mo-tabs {
  transform: translateX(4px);
}

.mo-tab {
  min-height: 46px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.2);
  border-radius: 4px;
  padding: 0 18px;
  color: rgba(var(--mo-ink-rgb), 0.86);
  background: rgba(var(--mo-ink-rgb), 0.035);
  cursor: pointer;
  font: 500 16px var(--mo-sans);
  letter-spacing: 0.8px;
  text-transform: uppercase;
  transition: color 200ms ease, background 200ms ease, border-color 200ms ease, transform 200ms ease;
}

.mo-tab:hover,
.mo-tab:focus-visible {
  transform: translateY(-2px);
  color: var(--mo-text);
  border-color: rgba(var(--mo-ink-rgb), 0.28);
}

.mo-tab.is-active {
  color: var(--mo-on-accent);
  border-color: var(--mo-accent);
  background: var(--mo-accent);
  box-shadow: 0 12px 34px rgba(var(--mo-accent-rgb), 0.28);
  animation: activeTab 1800ms ease-in-out infinite;
}

.mo-menu-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

/* The card is two rows: everything the dish says, and the bar the order button
   sits in. The bar is a child of the card rather than of the body it used to
   live in, which is the whole reason its rule below needs no negative margins
   — its top border reaches both edges of the card on its own, and it does so
   whether or not a photo has split the row above it into two columns.

   1fr auto is what keeps that bar on the floor of the card. Without it the two
   rows would each take their content's height and a short dish would leave the
   bar floating in the middle of the card, out of line with the card beside it. */
.mo-dish-card {
  position: relative;
  display: grid;
  grid-template-rows: 1fr auto;
  min-height: 158px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.16);
  border-radius: 6px;
  overflow: hidden;
  background: var(--mo-card);
  transition: transform 260ms ease, border-color 260ms ease, background 260ms ease, box-shadow 260ms ease;
}

.mo-dish-card::before {
  position: absolute;
  inset: 0 auto 0 0;
  width: 2px;
  content: "";
  background: linear-gradient(180deg, var(--mo-accent), rgba(var(--mo-glow-rgb), 0.7));
  opacity: 0;
  transform: scaleY(0.35);
  transform-origin: center;
  transition: opacity 260ms ease, transform 260ms ease;
}

.mo-dish-card[hidden] {
  display: none;
}

.mo-dish-content {
  display: grid;
  align-content: start;
  gap: 14px;
  padding: 18px;
}

.mo-dish-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
}

.mo-dish-code {
  color: var(--mo-accent-ink);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.7px;
}

.mo-dish-name {
  margin-top: 4px;
  color: var(--mo-text);
  font-size: 24px;
  font-weight: 500;
  line-height: 1.08;
}

/* The price is the restaurant's own accent, outlined and unfilled — the same
   mark as the order button under it, at the other end of the card. It used to
   take --mo-accent-2, the design's second gold, which is a fixed colour: a
   restaurant that picked red got a red page with a gold price on it. */
.mo-dish-price {
  flex: 0 0 auto;
  min-width: 78px;
  padding: 7px 12px;
  border: 1px solid rgba(var(--mo-accent-rgb), 0.55);
  border-color: color-mix(in srgb, var(--mo-accent-ink) 58%, transparent);
  border-radius: 5px;
  color: var(--mo-accent-ink);
  font-family: var(--mo-serif);
  font-size: 20px;
  text-align: center;
  background: transparent;
  transition: border-color 240ms ease, background 240ms ease;
}

.mo-dish-desc {
  margin: 0;
  color: var(--mo-muted-cool);
  font-size: 18px;
  line-height: 1.5;
  font-weight: 400;
}

/* The bar across the foot of the card. It is a child of the card, so its rule
   is padding rather than the negative margins a nested bar would have needed,
   and its top border is the full-width hairline the design draws under the
   dish — under the photo column too, on a card that has one.
   PHP prints it only when there is an order button to put in it: a hairline
   over an empty strip is a card that looks unfinished, not a quiet one. */
.mo-dish-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  padding: 14px 18px;
  border-top: 1px solid rgba(var(--mo-ink-rgb), 0.08);
}

.mo-allergen-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}

/* The allergen letter, as a mark in a ring. Used twice: in the legend above
   the menu and on the dish cards, and it is the same mark in both — a reader
   matching a letter on a card against the legend is comparing two things that
   have to look identical.

   The size is set from the cap rather than from the ring. Alumni Sans is a
   narrow face with a short cap — 9px of ink at 14px of type — so a letter set
   at 14px inside a 28px ring covers under a third of it and reads as a speck
   floating in a circle rather than as a badge. 19px in a 30px ring puts the
   cap at about 40% of the ring, which is where a letter starts looking like it
   belongs to the circle it is in.

   Nothing here nudges the glyph, and nothing needs to: place-items does the
   box and the face's own metrics do the rest. Measured on the page, the ink of
   a capital sits 8.5px from the top of the ring and 9.5px from the bottom —
   half a pixel above centre, which is rounding rather than a fault. A
   correction for it would cost more than it bought. */
.mo-allergen {
  position: relative;
  display: inline-grid;
  place-items: center;
  min-width: 30px;
  height: 30px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.15);
  border-radius: 999px;
  padding: 0 7px;
  color: var(--mo-accent-2);
  background: rgba(var(--mo-ink-rgb), 0.035);
  font-size: 19px;
  font-weight: 600;
  line-height: 1;
  cursor: help;
  transition: border-color 200ms ease, background 200ms ease, transform 200ms ease;
}

/* The full allergen name, on hover.

   It hangs from the LEFT edge of its mark and grows rightward, and that is not
   a stylistic choice. Centred on the mark — left:50% and a -50% translate — it
   reached about 33px past the left edge of the card, and the card clips: it
   carries overflow:hidden so a 40-letter dish name cannot spill out of it. The
   first allergen mark sits 19px from that edge, so a centred tooltip on the
   first mark was always cut in half. Anchored left it starts inside the card
   and runs into the width the card has, which is the direction the room is in.

   240px rather than 160px because the names this prints are German compounds —
   "Soja und Sojaerzeugnisse" was wrapping to three lines inside 160px before it
   was clipped. The longest of them still wraps, which is what it is for. */
.mo-allergen::after {
  position: absolute;
  left: 0;
  bottom: calc(100% + 8px);
  z-index: 4;
  width: max-content;
  max-width: 240px;
  padding: 7px 9px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.14);
  border-radius: 4px;
  color: var(--mo-text);
  background: rgba(var(--mo-bg-rgb), 0.92);
  content: attr(data-label);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.35;
  opacity: 0;
  pointer-events: none;
  transform: translate(0, 4px);
  transition: opacity 180ms ease, transform 180ms ease;
}

.mo-allergen:hover,
.mo-allergen:focus-visible {
  border-color: rgba(var(--mo-glow-rgb), 0.48);
  background: rgba(var(--mo-glow-rgb), 0.1);
  transform: translateY(-1px);
}

.mo-allergen:hover::after,
.mo-allergen:focus-visible::after {
  opacity: 1;
  transform: translate(0, 0);
}

.mo-dish-card:hover,
.mo-dish-card:focus-within {
  transform: translateY(-3px);
  border-color: rgba(var(--mo-glow-rgb), 0.28);
  background: var(--mo-card-hover);
  box-shadow: 0 22px 54px rgba(var(--mo-shade-rgb), 0.22);
}

.mo-dish-card:hover::before,
.mo-dish-card:focus-within::before {
  opacity: 1;
  transform: scaleY(1);
}

.mo-dish-card:hover .mo-dish-price,
.mo-dish-card:focus-within .mo-dish-price {
  border-color: var(--mo-accent-ink);
  background: rgba(var(--mo-accent-rgb), 0.1);
}

/* Outlined and unfilled, in the restaurant's own accent — the price chip at
   the other end of the card wears the same mark, so the two things a reader
   is looking for on a menu card read as a pair. It fills on hover, which is
   the only moment it needs to outweigh the price. */
.mo-order-link {
  flex: 0 0 auto;
  border: 1px solid rgba(var(--mo-accent-rgb), 0.55);
  border-color: color-mix(in srgb, var(--mo-accent-ink) 58%, transparent);
  border-radius: 5px;
  padding: 10px 18px;
  color: var(--mo-accent-ink);
  background: transparent;
  cursor: pointer;
  font: 600 15px var(--mo-sans);
  letter-spacing: 0.8px;
  text-transform: uppercase;
  transition: transform 200ms ease, background 200ms ease, border-color 200ms ease, color 200ms ease;
}

/* Filling with the raw accent would put --mo-on-accent — near-black — on
   whatever the restaurant saved, and #080808 on #895100 is a button nobody can
   read the moment the pointer touches it. The plate is the ink colour, which
   is the accent with a floor under its lightness, so the pair is legible for
   every Theme color rather than only for light ones. */
.mo-order-link:hover,
.mo-order-link:focus-visible {
  transform: translateY(-2px);
  border-color: var(--mo-accent-ink);
  color: var(--mo-on-accent);
  background: var(--mo-accent-ink);
}

.mo-allergen-panel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  margin: -10px 0 22px;
  padding: 12px 0 0;
  color: var(--mo-muted);
  border-top: 1px solid rgba(var(--mo-ink-rgb), 0.08);
  font-size: 16px;
  line-height: 1.5;
}

.mo-allergen-title {
  flex: 0 0 auto;
  color: var(--mo-text);
  font-family: var(--mo-serif);
  font-size: 24px;
  font-weight: 500;
}

.mo-allergen-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px 12px;
}

.mo-allergen-legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.mo-allergen-legend .mo-allergen {
  cursor: default;
}

.mo-allergen-legend .mo-allergen::after {
  display: none;
}

.mo-allergen-legend .mo-allergen:hover {
  transform: none;
}

.mo-reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 700ms ease, transform 700ms ease;
}

.mo-reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.mo-reveal.delay-1 {
  transition-delay: 120ms;
}

.mo-reveal.delay-2 {
  transition-delay: 220ms;
}

.mo-reveal.delay-3 {
  transition-delay: 320ms;
}

.mo-gallery {
  background:
    radial-gradient(circle at 50% 18%, rgba(var(--mo-glow-rgb), 0.08), transparent 32%),
    var(--mo-on-accent);
}

.mo-gallery-heading {
  margin-bottom: 28px;
  text-align: center;
}

.mo-gallery-heading .mo-section-kicker {
  letter-spacing: 6px;
}

.mo-gallery-title {
  justify-content: center;
  font-size: clamp(38px, 6vw, 66px);
}

.mo-gallery-title span {
  color: var(--mo-accent-2);
  font-style: italic;
}

.mo-gallery-filters {
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: 22px auto 0;
  padding: 6px;
  border: 1px solid rgba(var(--mo-line-rgb), 0.18);
  background: rgba(var(--mo-ink-rgb), 0.025);
}

.mo-gallery-filter {
  min-height: 42px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.14);
  border-radius: 4px;
  padding: 0 16px;
  color: rgba(var(--mo-ink-rgb), 0.82);
  background: rgba(var(--mo-bg-rgb), 0.42);
  cursor: pointer;
  font: 500 16px var(--mo-sans);
  letter-spacing: 0.8px;
  text-transform: uppercase;
  transition: transform 200ms ease, border-color 200ms ease, background 200ms ease, color 200ms ease;
}

.mo-gallery-filter span {
  margin-left: 8px;
  color: var(--mo-accent-2);
  font-family: var(--mo-condensed);
  font-size: 20px;
  letter-spacing: 0;
}

.mo-gallery-filter:hover,
.mo-gallery-filter:focus-visible {
  transform: translateY(-2px);
  border-color: rgba(var(--mo-glow-rgb), 0.42);
  color: var(--mo-text);
  background: rgba(var(--mo-glow-rgb), 0.1);
}

.mo-gallery-filter.is-active {
  color: var(--mo-on-accent);
  border-color: var(--mo-accent);
  background: var(--mo-accent);
  box-shadow: 0 16px 38px rgba(var(--mo-accent-rgb), 0.22);
}

.mo-gallery-filter.is-active span {
  color: var(--mo-on-accent);
}

.mo-gallery-stage {
  position: relative;
  min-height: 410px;
  margin: 0 auto;
  isolation: isolate;
}

.mo-gallery-card {
  position: absolute;
  top: 0;
  left: 50%;
  width: min(640px, 54vw);
  height: 340px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.14);
  border-radius: 6px;
  overflow: hidden;
  background: var(--mo-surface-2);
  box-shadow: 0 28px 90px rgba(var(--mo-shade-rgb), 0.46);
  opacity: 0;
  pointer-events: none;
  filter: grayscale(1) brightness(0.58);
  transform: translateX(-50%) scale(0.72);
  transition: opacity 360ms ease, transform 520ms cubic-bezier(.2, .8, .2, 1), filter 360ms ease, border-color 360ms ease;
}

.mo-gallery-card img {
  transform: scale(1.04);
  transition: transform 680ms ease, filter 680ms ease;
}

.mo-gallery-card.is-active {
  z-index: 3;
  opacity: 1;
  pointer-events: auto;
  filter: none;
  border-color: rgba(var(--mo-glow-rgb), 0.3);
  transform: translateX(-50%) scale(1);
}

.mo-gallery-card.is-prev {
  z-index: 2;
  opacity: 0.72;
  transform: translateX(-112%) translateY(28px) rotate(-3deg) scale(0.76);
}

.mo-gallery-card.is-next {
  z-index: 2;
  opacity: 0.72;
  transform: translateX(12%) translateY(28px) rotate(3deg) scale(0.76);
}

.mo-gallery-card.is-active img {
  transform: scale(1.1);
}

.mo-gallery-caption {
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 18px;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.12);
  border-radius: 4px;
  background: rgba(var(--mo-bg-rgb), 0.68);
  backdrop-filter: blur(12px);
  color: var(--mo-muted);
  font-size: 16px;
}

.mo-gallery-caption span:first-child {
  color: var(--mo-text);
  font-family: var(--mo-serif);
  font-size: 22px;
  font-weight: 500;
}

.mo-gallery-arrow {
  position: absolute;
  top: 158px;
  z-index: 5;
  width: 46px;
  height: 46px;
  border: 1px solid rgba(var(--mo-glow-rgb), 0.42);
  border-radius: 999px;
  color: var(--mo-accent-2);
  background: rgba(var(--mo-bg-rgb), 0.56);
  cursor: pointer;
  backdrop-filter: blur(10px);
  transition: transform 220ms ease, background 220ms ease, border-color 220ms ease;
}

.mo-gallery-arrow::before {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 11px;
  height: 11px;
  border-top: 2px solid currentColor;
  border-left: 2px solid currentColor;
  content: "";
}

.mo-gallery-arrow.prev {
  left: 5%;
}

.mo-gallery-arrow.prev::before {
  transform: translate(-35%, -50%) rotate(-45deg);
}

.mo-gallery-arrow.next {
  right: 5%;
}

.mo-gallery-arrow.next::before {
  transform: translate(-65%, -50%) rotate(135deg);
}

.mo-gallery-arrow:hover,
.mo-gallery-arrow:focus-visible {
  transform: translateY(-2px);
  border-color: var(--mo-accent-2);
  background: rgba(var(--mo-glow-rgb), 0.12);
}

.mo-gallery-thumbs {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 12px;
  margin-top: 14px;
}

.mo-gallery-thumb {
  height: 72px;
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 0;
  overflow: hidden;
  background: var(--mo-surface);
  cursor: pointer;
  opacity: 0.55;
  filter: grayscale(1);
  transition: opacity 220ms ease, filter 220ms ease, border-color 220ms ease, transform 220ms ease;
}

.mo-gallery-thumb:hover,
.mo-gallery-thumb:focus-visible,
.mo-gallery-thumb.is-active {
  opacity: 1;
  filter: none;
  border-color: rgba(var(--mo-glow-rgb), 0.58);
  transform: translateY(-2px);
}

.mo-order-location {
  background:
    linear-gradient(180deg, rgba(var(--mo-ink-rgb), 0.018), transparent 28%),
    var(--mo-band);
}

.mo-order-location-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(26px, 5vw, 56px);
  align-items: start;
}

.mo-order-card {
  display: grid;
  gap: 18px;
}

.mo-order-photo {
  position: relative;
  min-height: 220px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.12);
  border-radius: 6px;
  overflow: hidden;
  background: var(--mo-surface);
}

.mo-order-photo img,
.mo-order-photo video {
  filter: grayscale(1) brightness(0.62);
  transform: scale(1.04);
  transition: filter 420ms ease, transform 520ms ease;
}

.mo-order-photo::after {
  position: absolute;
  inset: 0;
  content: "";
  background: linear-gradient(110deg, transparent 20%, rgba(var(--mo-glow-rgb), 0.18), transparent 55%);
  opacity: 0;
  transform: translateX(-80%);
  transition: opacity 240ms ease, transform 720ms ease;
  pointer-events: none;
}

.mo-order-photo:hover img,
.mo-order-photo:hover video,
.mo-order-photo:focus-within img,
.mo-order-photo:focus-within video {
  filter: grayscale(0.25) brightness(0.82);
  transform: scale(1.09);
}

.mo-order-photo:hover::after,
.mo-order-photo:focus-within::after {
  opacity: 1;
  transform: translateX(80%);
}

.mo-order-photo .mo-button {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  color: var(--mo-accent-2);
  border-color: var(--mo-accent-2);
  background: rgba(var(--mo-shade-rgb), 0.35);
  transform: translate(-50%, -50%);
}

.mo-order-photo .mo-button:hover,
.mo-order-photo .mo-button:focus-visible {
  color: var(--mo-text);
  background: rgba(var(--mo-glow-rgb), 0.16);
  transform: translate(-50%, calc(-50% - 2px));
}

.mo-address-card {
  display: grid;
  gap: 18px;
}

.mo-address-line {
  margin: 0;
  color: var(--mo-muted);
  font-size: 24px;
  line-height: 1.6;
}

.mo-map-card {
  position: relative;
  min-height: 250px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.12);
  border-radius: 6px;
  overflow: hidden;
  background:
    linear-gradient(22deg, transparent 0 45%, rgba(var(--mo-ink-rgb), 0.08) 46% 48%, transparent 49%),
    linear-gradient(116deg, transparent 0 55%, rgba(var(--mo-ink-rgb), 0.09) 56% 58%, transparent 59%),
    linear-gradient(90deg, rgba(var(--mo-ink-rgb), 0.04) 1px, transparent 1px),
    linear-gradient(rgba(var(--mo-ink-rgb), 0.035) 1px, transparent 1px),
    var(--mo-surface-3);
  background-size: auto, auto, 72px 72px, 72px 72px, auto;
  filter: grayscale(1);
}

.mo-map-card::after {
  position: absolute;
  inset: 0;
  content: "";
  background: radial-gradient(circle at 48% 44%, rgba(var(--mo-glow-rgb), 0.16), transparent 24%);
  pointer-events: none;
}

.mo-map-road {
  position: absolute;
  height: 8px;
  border-radius: 999px;
  background: rgba(var(--mo-ink-rgb), 0.18);
  transform-origin: left center;
}

.mo-map-road.one {
  top: 38%;
  left: 9%;
  width: 86%;
  transform: rotate(-12deg);
}

.mo-map-road.two {
  top: 64%;
  left: -5%;
  width: 70%;
  transform: rotate(18deg);
}

.mo-map-road.three {
  top: 4%;
  left: 58%;
  width: 8px;
  height: 96%;
  transform: rotate(28deg);
}

.mo-map-pin {
  position: absolute;
  top: 43%;
  left: 49%;
  z-index: 2;
  width: 28px;
  height: 28px;
  border: 2px solid var(--mo-accent-2);
  border-radius: 999px 999px 999px 0;
  background: rgba(var(--mo-bg-rgb), 0.78);
  transform: rotate(-45deg);
  animation: mapPinPulse 2400ms ease-in-out infinite;
}

.mo-map-pin::after {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  content: "";
  background: var(--mo-accent-2);
  transform: translate(-50%, -50%);
}

.mo-map-label {
  position: absolute;
  left: 22px;
  bottom: 20px;
  z-index: 2;
  padding: 10px 12px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.12);
  border-radius: 4px;
  color: var(--mo-text);
  background: rgba(var(--mo-bg-rgb), 0.7);
  font-size: 16px;
  backdrop-filter: blur(10px);
}

.mo-site-footer {
  padding: 42px clamp(18px, 6vw, 78px) 24px;
  border-top: 1px solid rgba(var(--mo-ink-rgb), 0.08);
  background: var(--mo-footer-bg);
}

.mo-footer-inner {
  width: min(1180px, 100%);
  margin: 0 auto;
}

.mo-footer-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1.2fr;
  gap: clamp(24px, 5vw, 62px);
  padding-bottom: 30px;
  border-bottom: 1px solid rgba(var(--mo-ink-rgb), 0.08);
}

.mo-footer-logo {
  display: block;
  color: var(--mo-accent-2);
  font-family: var(--mo-serif);
  font-size: clamp(34px, 5vw, 56px);
  line-height: 1;
}

.mo-footer-copy,
.mo-footer-col p,
.mo-hours-row {
  color: var(--mo-muted);
  font-size: 19px;
  line-height: 1.65;
}

.mo-footer-col h3 {
  margin-bottom: 12px;
  color: var(--mo-accent-2);
  font-family: var(--mo-sans);
  font-size: 15px;
  letter-spacing: 5px;
  text-transform: uppercase;
}

.mo-social-row {
  display: flex;
  gap: 12px;
  margin-top: 24px;
}

.mo-social-row a {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.16);
  border-radius: 999px;
  color: var(--mo-muted);
  transition: transform 220ms ease, color 220ms ease, border-color 220ms ease;
}

.mo-social-row a:hover,
.mo-social-row a:focus-visible {
  transform: translateY(-2px);
  color: var(--mo-accent-2);
  border-color: rgba(var(--mo-glow-rgb), 0.48);
}

.mo-hours {
  display: grid;
  gap: 8px;
}

.mo-hours-row {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 20px;
}

.mo-hours-row span:last-child {
  color: var(--mo-muted-cool);
  text-align: right;
}

.mo-footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px 28px;
  padding-top: 28px;
  color: var(--mo-muted);
  font-size: 16px;
  letter-spacing: 2px;
  text-transform: uppercase;
}

.mo-footer-bottom a {
  transition: color 200ms ease;
}

.mo-footer-bottom a:hover,
.mo-footer-bottom a:focus-visible {
  color: var(--mo-accent-2);
}

.mo-quick-contact {
  position: fixed;
  right: clamp(14px, 3vw, 30px);
  bottom: clamp(18px, 4vw, 32px);
  z-index: 55;
  display: grid;
  gap: 10px;
  align-items: end;
}

.mo-quick-contact-link {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 8px 16px 8px 8px;
  border: 1px solid rgba(var(--mo-line-rgb), 0.28);
  border-radius: 6px;
  color: var(--mo-text);
  background: rgba(var(--mo-bg-rgb), 0.8);
  box-shadow: 0 18px 48px rgba(var(--mo-shade-rgb), 0.34);
  backdrop-filter: blur(16px);
  transition: transform 220ms ease, border-color 220ms ease, background 220ms ease;
}

.mo-quick-contact-link:hover,
.mo-quick-contact-link:focus-visible {
  transform: translateY(-3px);
  border-color: var(--mo-accent);
  background: rgba(var(--mo-surface-3-rgb), 0.92);
}

.mo-quick-contact-icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 4px;
  color: var(--mo-on-accent);
  background: var(--mo-accent);
  font-family: var(--mo-condensed);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.4px;
  line-height: 1;
}

.mo-quick-contact-whatsapp .mo-quick-contact-icon {
  background: var(--mo-whatsapp);
}

.mo-quick-contact-shop .mo-quick-contact-icon {
  background: linear-gradient(135deg, var(--mo-accent-grad-a), var(--mo-accent-grad-b));
}

.mo-quick-contact-reserve .mo-quick-contact-icon {
  color: var(--mo-text);
  background: rgba(var(--mo-ink-rgb), 0.12);
  border: 1px solid rgba(var(--mo-line-rgb), 0.42);
}

.mo-quick-contact-text {
  display: grid;
  gap: 2px;
  line-height: 1;
}

.mo-quick-contact-text strong {
  font-size: 19px;
  font-weight: 500;
}

.mo-quick-contact-text span {
  color: var(--mo-muted);
  font-size: 15px;
  font-weight: 400;
}

.mo-promo-modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: clamp(16px, 4vw, 44px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 280ms ease;
}

.mo-promo-modal[hidden] {
  display: none;
}

.mo-promo-modal.is-open {
  opacity: 1;
  pointer-events: auto;
}

.mo-promo-backdrop {
  position: absolute;
  inset: 0;
  border: 0;
  padding: 0;
  background:
    radial-gradient(circle at 50% 24%, rgba(var(--mo-accent-rgb), 0.18), transparent 34%),
    rgba(var(--mo-shade-rgb), 0.78);
  backdrop-filter: blur(9px);
  cursor: pointer;
}

.mo-promo-card {
  position: relative;
  z-index: 2;
  width: min(860px, 100%);
  max-height: min(86svh, 720px);
  display: grid;
  grid-template-columns: minmax(280px, 0.92fr) minmax(0, 1.08fr);
  border: 1px solid rgba(var(--mo-accent-rgb), 0.32);
  background:
    linear-gradient(135deg, rgba(var(--mo-ink-rgb), 0.055), transparent 44%),
    rgba(var(--mo-surface-rgb), 0.96);
  box-shadow: 0 32px 110px rgba(var(--mo-shade-rgb), 0.62);
  overflow: hidden;
  opacity: 0;
  transform: translateY(26px) scale(0.96);
  transition: opacity 320ms ease, transform 420ms cubic-bezier(.2, .8, .2, 1);
}

.mo-promo-modal.is-open .mo-promo-card {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.mo-promo-close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 6;
  width: 42px;
  height: 42px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.18);
  border-radius: 4px;
  background: rgba(var(--mo-shade-rgb), 0.46);
  cursor: pointer;
  transition: transform 200ms ease, border-color 200ms ease, background 200ms ease;
}

.mo-promo-close:hover,
.mo-promo-close:focus-visible {
  transform: rotate(90deg) scale(1.04);
  border-color: rgba(var(--mo-ink-rgb), 0.42);
  background: rgba(var(--mo-accent-rgb), 0.78);
}

.mo-promo-close::before,
.mo-promo-close::after {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 19px;
  height: 2px;
  content: "";
  background: var(--mo-text);
  transform-origin: center;
}

.mo-promo-close::before {
  transform: translate(-50%, -50%) rotate(45deg);
}

.mo-promo-close::after {
  transform: translate(-50%, -50%) rotate(-45deg);
}

.mo-promo-media {
  position: relative;
  min-height: 430px;
  overflow: hidden;
  background: var(--mo-surface-2);
}

.mo-promo-media::after {
  position: absolute;
  inset: 0;
  z-index: 3;
  content: "";
  pointer-events: none;
  background:
    linear-gradient(90deg, transparent 40%, rgba(var(--mo-shade-rgb), 0.24)),
    linear-gradient(180deg, rgba(var(--mo-shade-rgb), 0.14), transparent 42%, rgba(var(--mo-shade-rgb), 0.56));
}

.mo-promo-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  animation: promoSlide 15s infinite;
}

.mo-promo-slide:nth-child(2) {
  animation-delay: 5s;
}

.mo-promo-slide:nth-child(3) {
  animation-delay: 10s;
}

.mo-promo-slide img {
  transform: scale(1.08);
  animation: promoImageMove 15s ease-in-out infinite;
}

.mo-promo-slide:nth-child(2) img {
  animation-delay: 5s;
}

.mo-promo-slide:nth-child(3) img {
  animation-delay: 10s;
}

.mo-promo-badge {
  position: absolute;
  left: 20px;
  bottom: 20px;
  z-index: 4;
  display: grid;
  gap: 5px;
  max-width: 250px;
  padding: 15px 16px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.16);
  background: rgba(var(--mo-bg-rgb), 0.72);
  backdrop-filter: blur(14px);
}

.mo-promo-badge span:first-child {
  color: var(--mo-accent-2);
  font-family: var(--mo-condensed);
  font-size: 28px;
  line-height: 1;
  font-weight: 500;
}

.mo-promo-badge span:last-child {
  color: var(--mo-muted);
  font-size: 16px;
  line-height: 1.45;
  font-weight: 400;
}

.mo-promo-content {
  display: grid;
  align-content: center;
  gap: 18px;
  padding: clamp(28px, 5vw, 52px);
}

.mo-promo-kicker {
  margin: 0;
  color: var(--mo-accent);
  font-size: 15px;
  font-weight: 500;
  text-transform: uppercase;
}

.mo-promo-content h2 {
  max-width: 360px;
  font-size: clamp(34px, 5vw, 56px);
  line-height: 1;
}

.mo-promo-content p {
  margin: 0;
  color: var(--mo-muted);
  font-size: 21px;
  line-height: 1.75;
  font-weight: 400;
}

.mo-promo-offers {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 4px;
}

.mo-promo-offers span {
  padding: 8px 10px;
  border: 1px solid rgba(var(--mo-ink-rgb), 0.13);
  border-radius: 4px;
  color: var(--mo-text);
  background: rgba(var(--mo-ink-rgb), 0.04);
  font-size: 16px;
  font-weight: 500;
}

.mo-promo-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 8px;
}

.mo-promo-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border-radius: 4px;
  padding: 0 18px;
  color: var(--mo-on-accent);
  background: var(--mo-accent);
  font-size: 16px;
  font-weight: 500;
  text-transform: uppercase;
  transition: transform 200ms ease, background 200ms ease;
}

.mo-promo-cta:hover,
.mo-promo-cta:focus-visible {
  transform: translateY(-2px);
  background: var(--mo-accent-hi);
}

.mo-promo-ghost {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  border: 0;
  padding: 0;
  color: var(--mo-muted);
  background: transparent;
  cursor: pointer;
  font: 500 16px var(--mo-sans);
  text-transform: uppercase;
  transition: color 200ms ease;
}

.mo-promo-ghost:hover,
.mo-promo-ghost:focus-visible {
  color: var(--mo-text);
}

.mo-promo-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3px;
  padding: 0 0 3px;
}

.mo-promo-progress span {
  height: 2px;
  overflow: hidden;
  background: rgba(var(--mo-ink-rgb), 0.14);
}

.mo-promo-progress span::before {
  display: block;
  width: 100%;
  height: 100%;
  content: "";
  background: var(--mo-accent);
  transform: scaleX(0);
  transform-origin: left;
  animation: promoProgress 15s linear infinite;
}

.mo-promo-progress span:nth-child(2)::before {
  animation-delay: 5s;
}

.mo-promo-progress span:nth-child(3)::before {
  animation-delay: 10s;
}

@keyframes copyEnter {
  from {
    opacity: 0;
    transform: translateY(28px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes mediaEnter {
  from {
    opacity: 0;
    transform: translateX(32px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

@keyframes slideCycle {
  0% {
    opacity: 0;
  }
  5% {
    opacity: 1;
  }
  30% {
    opacity: 1;
  }
  38% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@keyframes kenBurns {
  0% {
    transform: scale(1.08) translate3d(-1.5%, 1%, 0);
  }
  50% {
    transform: scale(1.16) translate3d(2%, -1.5%, 0);
  }
  100% {
    transform: scale(1.08) translate3d(-1.5%, 1%, 0);
  }
}

@keyframes lightSweep {
  0%,
  34% {
    transform: translateX(-62%) rotate(8deg);
    opacity: 0;
  }
  52% {
    opacity: 1;
  }
  78%,
  100% {
    transform: translateX(62%) rotate(8deg);
    opacity: 0;
  }
}

@keyframes dotPulse {
  0% {
    box-shadow: 0 0 0 0 rgba(var(--mo-accent-rgb), 0.54);
  }
  100% {
    box-shadow: 0 0 0 14px rgba(var(--mo-accent-rgb), 0);
  }
}

@keyframes floatCard {
  0%,
  100% {
    transform: translate3d(0, 0, 0);
  }
  50% {
    transform: translate3d(-8px, 16px, 0);
  }
}

@keyframes ringFloat {
  0%,
  100% {
    transform: rotate(-8deg) scale(1);
  }
  50% {
    transform: rotate(6deg) scale(1.035);
  }
}

@keyframes orbitBreath {
  0%,
  100% {
    transform: translate3d(0, 0, 0) rotateZ(0deg);
  }
  50% {
    transform: translate3d(0, -10px, 0) rotateZ(1.5deg);
  }
}

@keyframes heroDishFlip {
  0%,
  4% {
    opacity: 0;
    transform: rotateY(94deg) scale(0.86);
  }
  9%,
  29% {
    opacity: 1;
    transform: rotateY(0deg) scale(1);
  }
  35%,
  100% {
    opacity: 0;
    transform: rotateY(-94deg) scale(0.88);
  }
}

@keyframes featureImageMove {
  0%,
  100% {
    transform: scale(1.1) translate3d(-1%, 1%, 0);
  }
  50% {
    transform: scale(1.18) translate3d(2%, -1.5%, 0);
  }
}

@keyframes featureShine {
  0%,
  34% {
    opacity: 0;
    transform: translateX(-72%) rotate(9deg);
  }
  52% {
    opacity: 0.75;
  }
  74%,
  100% {
    opacity: 0;
    transform: translateX(74%) rotate(9deg);
  }
}

@keyframes floatSlow {
  0%,
  100% {
    transform: translate3d(0, 0, 0) scale(1);
  }
  50% {
    transform: translate3d(0, -14px, 0) scale(1.012);
  }
}

@keyframes linePulse {
  0%,
  100% {
    transform: scaleX(0.72);
    opacity: 0.6;
  }
  50% {
    transform: scaleX(1);
    opacity: 1;
  }
}

@keyframes activeTab {
  0%,
  100% {
    box-shadow: 0 0 0 rgba(var(--mo-accent-rgb), 0);
  }
  50% {
    box-shadow: 0 0 28px rgba(var(--mo-accent-rgb), 0.28);
  }
}

@keyframes marqueeMove {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-100%);
  }
}

@keyframes promoSlide {
  0% {
    opacity: 0;
  }
  5% {
    opacity: 1;
  }
  30% {
    opacity: 1;
  }
  38% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@keyframes promoImageMove {
  0% {
    transform: scale(1.08) translate3d(-1.4%, 0, 0);
  }
  50% {
    transform: scale(1.16) translate3d(1.6%, -1%, 0);
  }
  100% {
    transform: scale(1.08) translate3d(-1.4%, 0, 0);
  }
}

@keyframes promoProgress {
  0% {
    transform: scaleX(0);
  }
  33.333% {
    transform: scaleX(1);
  }
  33.334%,
  100% {
    transform: scaleX(0);
  }
}

@keyframes mapPinPulse {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(var(--mo-glow-rgb), 0.28);
  }
  50% {
    box-shadow: 0 0 0 14px rgba(var(--mo-glow-rgb), 0);
  }
}

@keyframes aboutPageFlip {
  0%,
  34% {
    transform: rotateY(0deg);
  }
  48%,
  82% {
    transform: rotateY(-180deg);
  }
  100% {
    transform: rotateY(-360deg);
  }
}

@keyframes pageShine {
  0%,
  30% {
    opacity: 0;
    transform: translateX(-72%);
  }
  42% {
    opacity: 0.82;
  }
  56%,
  100% {
    opacity: 0;
    transform: translateX(72%);
  }
}

@media (max-width: 980px) {
  .mo-topbar {
    position: absolute;
  }

  .mo-hero-grid {
    grid-template-columns: 1fr;
  }


  .mo-flip-photo {
    min-height: 240px;
  }

  .mo-hero {
    padding-top: 94px;
  }

  .mo-hero-feature-stage {
    min-height: 420px;
  }

  .mo-dish-orbit {
    width: min(360px, 74vw);
  }

  .mo-section-heading {
    align-items: flex-start;
    flex-direction: column;
  }

  .mo-menu-tools {
    grid-template-columns: 46px minmax(0, 1fr);
  }

  .mo-tabs {
    justify-content: flex-start;
  }

  .mo-menu-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mo-allergen-panel {
    align-items: flex-start;
    flex-direction: column;
  }

  .mo-allergen-legend {
    justify-content: flex-start;
  }

  .mo-promo-card {
    grid-template-columns: 1fr;
    max-height: min(90svh, 760px);
    overflow-y: auto;
  }

  .mo-promo-media {
    min-height: 300px;
  }

  .mo-gallery-stage {
    min-height: 350px;
  }

  .mo-gallery-card {
    height: 300px;
  }

  .mo-gallery-card.is-prev,
  .mo-gallery-card.is-next {
    opacity: 0.38;
  }

  .mo-gallery-thumbs {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .mo-order-location-grid,
  .mo-footer-grid {
    grid-template-columns: 1fr;
  }

  .mo-hours-row span:last-child {
    text-align: left;
  }
}

@media (max-width: 680px) {

  .mo-hero {
    min-height: auto;
    padding-bottom: 72px;
  }

  .mo-hero-copy h1 {
    font-size: clamp(52px, 18vw, 78px);
  }

  .mo-hero-subtitle {
    align-items: flex-start;
    flex-direction: column;
    gap: 8px;
  }

  .mo-hero .mo-button {
    width: 100%;
  }

  .mo-hero-info-grid {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  .mo-hero-feature-stage {
    min-height: 320px;
  }

  .mo-dish-orbit {
    width: min(290px, 80vw);
  }

  .mo-feature-content {
    width: 78%;
  }

  .mo-feature-content h2 {
    font-size: 28px;
  }

  .mo-feature-content p {
    margin-top: 12px;
    font-size: 17px;
    line-height: 1.55;
  }

  .mo-feature-price {
    margin-top: 12px;
    font-size: 24px;
  }

  .mo-menu-grid {
    grid-template-columns: 1fr;
  }

  .mo-search.is-open,
  .mo-search:focus-within {
    width: 100%;
  }

  .mo-menu-tools.has-search-open {
    grid-template-columns: minmax(230px, 48vw) minmax(0, 1fr);
    gap: 12px;
  }

  /* The bar used to hold the allergen letters as well, and had to break into
     two rows at this width to fit them. They sit with the description now, so
     it is one right-aligned button and stays a single row. */
  .mo-dish-footer {
    padding: 12px 14px;
  }

  .mo-dish-content {
    padding: 14px;
  }


  .mo-flip-photo {
    min-height: 280px;
  }

  .mo-promo-modal {
    padding: 14px;
  }

  .mo-promo-content {
    padding: 26px 20px 24px;
  }

  .mo-promo-content h2 {
    font-size: 34px;
  }

  .mo-promo-media {
    min-height: 250px;
  }

  .mo-promo-badge {
    left: 14px;
    right: 14px;
    bottom: 14px;
    max-width: none;
  }

  .mo-quick-contact {
    left: 12px;
    right: 12px;
    bottom: 12px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mo-quick-contact-link {
    justify-content: center;
    min-height: 54px;
    padding: 8px;
  }

  .mo-quick-contact-text span {
    display: none;
  }

  .mo-site-footer {
    padding-bottom: 104px;
  }

  .mo-gallery-stage {
    min-height: 330px;
  }

  .mo-gallery-card {
    width: 100%;
    height: 250px;
  }

  .mo-gallery-card.is-prev,
  .mo-gallery-card.is-next {
    opacity: 0;
    transform: translateX(-50%) scale(0.7);
  }

  .mo-gallery-arrow {
    top: 108px;
    width: 40px;
    height: 40px;
  }

  .mo-gallery-arrow.prev {
    left: 10px;
  }

  .mo-gallery-arrow.next {
    right: 10px;
  }

  .mo-gallery-thumbs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mo-gallery-thumb {
    height: 64px;
  }

  .mo-order-photo,
  .mo-map-card {
    min-height: 210px;
  }

  .mo-hours-row {
    grid-template-columns: 1fr;
    gap: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }

  .mo-feature-panel:first-child {
    opacity: 1;
    transform: rotateY(0deg) scale(1);
  }
}


/* --------------------------------------------------------------------------
   11. Shared framework overlays
   Adapted from the kuro theme, which solved the same problem: the order,
   booking, login and allergen dialogs arrive with the platform's own markup
   (see the popup block in index.tpl), and dialog-with-tabs.css lays them out
   for a stock look. These rules move them onto this theme's ground without
   touching the shared stylesheet, and they read the tokens in 1, so they
   follow the light and the dark setting alike.
   -------------------------------------------------------------------------- */

/* dialog-with-tabs.css gives .dialog-with-tabs its box (max-width, centring,
   the close button). The dish popup uses .menu-dialog-with-tabs instead, whose
   box lives only in the modern-cuisine stylesheet — so this theme draws it here,
   otherwise the popup opens full-bleed with no padding. */
.menu-dialog-with-tabs {
    padding: 0;
    max-width: 600px;
    margin: 40px auto;
    position: relative;
    box-sizing: border-box;
    text-align: left;
    border-radius: 2px;
    box-shadow: 0 0 40px rgba(0, 0, 0, 0.6);
}

.menu-dialog-with-tabs .mfp-close,
.dialog-with-tabs .mfp-close {
    color: var(--mo-text);
    opacity: 0.8;
}

.popup-tab-content,
.popup-tab-content-login,
.popup-notification-header {
    padding: 20px 24px;
    position: relative;
    z-index: 10;
    display: block;
    width: 100%;
    box-sizing: border-box;
}

/* dialog-with-tabs.css paints the tab strip white — a light header bar on a
   dark dialog, with the close × landing on it. Everything about the strip is
   restated here rather than patched, because "white" is set on the row, on the
   active tab and on its hover state separately. */
.popup-dialog .popup-tabs-nav {
    display: flex;
    list-style: none;
    margin: 0;
    padding: 0 24px;
    background: transparent;
    border-bottom: 1px solid var(--mo-line);
}

.popup-dialog .popup-tabs-nav li,
.popup-dialog .popup-tabs-nav li.active,
.popup-dialog .popup-tabs-nav li.active a:hover {
    float: none;
    height: auto;
    line-height: normal;
    background: transparent;
    border: 0;
}

.popup-dialog .popup-tabs-nav li a,
.popup-dialog .popup-tabs-nav li.active a {
    display: inline-block;
    padding: 16px 0;
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--mo-accent);
    background: transparent;
    /* The shared rule ends every tab with a light 1px rule, which on a dark
       panel reads as a stray white stroke beside the label. */
    border: 0;
}

.popup-dialog .popup-tabs-nav li.active::after { display: none; }

/* Inner pieces of the dish popup, filled in by restaurant.js. Same class
   names the other themes use — only the palette changes. */
.popup-tabs-container .category_name {
    color: var(--mo-accent);
    font-size: 12px;
    letter-spacing: 0.3em;
    text-transform: uppercase;
}

.popup-tabs-container .menu_desc {
    font-size: 16px;
    line-height: 1.7;
    font-weight: 300;
    color: var(--mo-muted);
}

.menu_detail { align-self: center; flex-grow: 1; }
.menu_detail h4 { display: flex; align-items: baseline; }

.menu_detail .menu_title {
    font-family: "Cormorant Garamond", serif;
    font-size: 24px;
    font-style: italic;
    color: var(--mo-text);
}

.menu_detail .menu_dots {
    flex-grow: 1;
    margin: 0 8px;
    border-bottom: 1px dotted var(--mo-line-strong);
}

.menu_detail .menu_price,
.popup-tab-content .menu_detail .menu_price {
    color: var(--mo-accent);
    font-size: 18px;
    text-align: right;
    white-space: nowrap;
}

h4.allegie_title {
    font-size: 13px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--mo-accent);
    margin: 16px 0 8px;
}

.popup-tab-content ul { list-style: none; margin: 0; padding: 0; }
.popup-tab-content ul li { font-size: 15px; color: var(--mo-muted); padding: 3px 0; }
.popup-tab-content ul li img,
.popup-tab-content ul li svg { width: 18px; height: 18px; fill: var(--mo-accent); margin-right: 8px; vertical-align: middle; }

.menu-avatar-add-extra {
    width: 100%;
    height: auto;
    max-height: 260px;
    object-fit: cover;
    display: block;
    margin-bottom: 16px;
}

/* ── The dish popup ───────────────────────────────────────────────────────
   restaurant.js builds this content at runtime out of the platform's own
   utility classes (.d-flex, .align-items-center, .margin-left-auto) and its
   own checkbox widget. Those all live in the modern-cuisine stylesheet, which
   this theme does not load — so without the block below the extras stack vertically,
   the prices sit under their labels and the checkboxes fall back to the
   browser's default. Everything here is scoped to the dialog so it cannot
   leak into the page. */

/* The category name is a sibling of the content block, not part of it, so the
   block's padding never reached it and it sat flush against the panel edge.
   It gets its own, matching the 24px gutter below; the wider right inset keeps
   a long category clear of the close button in that corner. */
.menu-dialog-with-tabs .category_name {
    padding: 20px 56px 0 24px;
    margin: 0;
}

.menu-dialog-with-tabs .menu-popup-tab-content { padding: 12px 24px 24px; }

.popup-dialog .d-flex { display: flex; }
.popup-dialog .align-items-center { align-items: center; }
.popup-dialog .margin-left-auto { margin-left: auto; }
.popup-dialog .margin-bottom-5 { margin-bottom: 5px; }

/* One extras group: "Topping 1" + how many may be picked. */
.popup-dialog .category_extra_wraper,
.popup-dialog .menu-price-option-wrapper {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--mo-line);
}

.popup-dialog .section-headline h5 {
    font-size: 13px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--mo-accent);
    margin: 0 0 4px;
}

.popup-dialog .select_max_title {
    font-size: 14px;
    font-weight: 300;
    color: var(--mo-muted);
    margin: 0 0 10px;
}

/* One option row: label left, price and its checkbox right. */
.popup-dialog .menu-extras-item,
.popup-dialog .menu-price-option-item {
    justify-content: space-between;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px dotted var(--mo-line);
}

.popup-dialog .menu-extras-item:last-child,
.popup-dialog .menu-price-option-item:last-child { border-bottom: 0; }

.popup-dialog .extras-item-title,
.popup-dialog .price-item-title {
    font-size: 16px;
    font-weight: 400;
    color: var(--mo-text);
}

/* row-reverse so the price reads before the box it belongs to, which is the
   order the eye wants when the whole group is right-aligned. */
.popup-dialog .checkbox {
    display: flex;
    flex-direction: row-reverse;
    align-items: center;
    gap: 10px;
    margin: 0;
}

/* The platform's own tick sprite is not loaded here, so the box is drawn from
   scratch rather than left as the browser's default white square, which is the
   one bright thing on an otherwise dark panel. */
.popup-dialog .checkbox input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    position: relative;
    width: 18px;
    height: 18px;
    margin: 0;
    border: 1px solid var(--mo-line-strong);
    border-radius: 2px;
    background: transparent;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

.popup-dialog .checkbox input[type="checkbox"]:hover { border-color: var(--mo-accent); }

.popup-dialog .checkbox input[type="checkbox"]:checked {
    background: var(--mo-accent);
    border-color: var(--mo-accent);
}

.popup-dialog .checkbox input[type="checkbox"]:checked::after {
    content: '';
    position: absolute;
    left: 5px;
    top: 1px;
    width: 5px;
    height: 10px;
    border: solid var(--mo-bg);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.popup-dialog .checkbox input[type="checkbox"]:disabled { opacity: 0.35; cursor: not-allowed; }

.popup-dialog .checkbox label {
    display: flex;
    align-items: center;
    margin: 0;
    cursor: pointer;
}

.popup-dialog .extras-item-price,
.popup-dialog .item-price {
    font-size: 15px;
    color: var(--mo-accent);
    white-space: nowrap;
}

/* The platform's own tick graphic needs its sprite; the native box is doing
   the job here, so the decorative span is dropped rather than left blank. */
.popup-dialog .checkbox-icon { display: none; }

/* Allergens, additives, properties. The icons are <img class="svg"> that
   js/svg.js swaps for inline <svg> — their paths carry no fill of their own,
   so a fill on the <svg> is what colours them. */
#Allegie_detail { border-top-color: var(--mo-line) !important; }

#Allegie_detail ul {
    list-style: none;
    margin: 0 0 4px;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
}

#Allegie_detail li {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 15px;
    font-weight: 300;
    color: var(--mo-muted);
}

#Allegie_detail li img,
#Allegie_detail li svg {
    width: 20px;
    height: 20px;
    flex: 0 0 20px;
    fill: var(--mo-accent);
}

/* Close button. dialog-with-tabs.css positions it for .dialog-with-tabs only,
   and the dish popup is .menu-dialog-with-tabs — without this it has no box to
   sit in and disappears against the header. Magnific renders it as an <a> for
   inline content and a <button> elsewhere, so the selector must not name a tag. */
.menu-dialog-with-tabs .mfp-close,
.popup-dialog .mfp-close {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 40px;
    height: 40px;
    line-height: 40px;
    font-size: 28px;
    color: var(--mo-text);
    background: transparent;
    opacity: 0.75;
    z-index: 20;
}

.menu-dialog-with-tabs .mfp-close:hover,
.popup-dialog .mfp-close:hover { opacity: 1; color: var(--mo-accent); }

/* The bundled magnific build ships the close control with no text in it — the
   × is a feather-icons glyph the shared stylesheet draws in ::before, but only
   for .dialog-with-tabs. The dish popup is .menu-dialog-with-tabs, so without
   this it is a 40px hit area with nothing drawn in it. */
.menu-dialog-with-tabs .mfp-close::before,
.popup-dialog .mfp-close::before {
    content: "\ea02";
    font-family: feather-icons;
    font-size: 26px;
    line-height: 40px;
    display: block;
}

.popup-dialog,
#popup-notification {
    background: var(--mo-panel) !important;
    color: var(--mo-text) !important;
    border: 1px solid rgba(var(--mo-accent-rgb), 0.2);
    border-radius: 2px;
}

.popup-dialog .popup-tabs-container,
.popup-dialog .popup-tab-content,
.popup-dialog .popup-tab-content-login {
    background: transparent !important;
    color: var(--mo-text);
}

.popup-dialog h2,
.popup-dialog h3,
.popup-dialog h4,
.popup-dialog label,
.popup-dialog p,
.popup-dialog li,
.popup-dialog span {
    color: var(--mo-text);
}

.popup-dialog input[type="text"],
.popup-dialog input[type="tel"],
.popup-dialog input[type="email"],
.popup-dialog input[type="password"],
.popup-dialog input[type="date"],
.popup-dialog input[type="time"],
.popup-dialog input[type="number"],
.popup-dialog select,
.popup-dialog textarea {
    background: var(--mo-surface) !important;
    border: 1px solid var(--mo-line) !important;
    color: var(--mo-text) !important;
    border-radius: 2px;
}

.popup-dialog input::placeholder,
.popup-dialog textarea::placeholder { color: var(--mo-muted-cool); }

/* ── Forms inside the dialogs ─────────────────────────────────────────────
   The booking, login and register forms are laid out entirely with the
   platform's grid and field classes (.bookmarks-input-group, .with-border,
   .full-width, .button, the margin-* helpers). Those live in the
   modern-cuisine stylesheet, so here every field would otherwise collapse
   to its intrinsic width and the label, the input and the submit button would
   share one line. This gives them a layout of their own. */

.popup-dialog .text-center { text-align: center; }
.popup-dialog .full-width { width: 100%; }
.popup-dialog .margin-bottom-5 { margin-bottom: 5px; }
.popup-dialog .margin-bottom-15 { margin-bottom: 15px; }
.popup-dialog .margin-top-10 { margin-top: 10px; }

.popup-dialog .section-title-booking,
.popup-dialog .popup-tab-content h2 {
    font-family: "Cormorant Garamond", serif;
    font-size: 26px;
    text-align: center;
    color: var(--mo-text);
    margin: 0 0 20px;
}

/* One field per row: label above, control below, full width. */
.popup-dialog .bookmarks-input-group,
.popup-dialog .submit-field,
.popup-dialog .form-group {
    display: block;
    margin-bottom: 14px;
}

/* The login, register and forgot-password forms mark their fields with an icon
   that belongs INSIDE the control (.input-with-icon-left, the Line Awesome
   glyphs from includes/assets/css/icons.css). What makes it sit there is a
   position pair in the modern-cuisine stylesheet — without it the wrapper is a
   plain block, so the icon is printed as a line of its own above the field and
   the form reads as if it had stray characters in it. */
.popup-dialog .input-with-icon-left {
    position: relative;
    display: block;
}

.popup-dialog .input-with-icon-left > i {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 18px;
    line-height: 1;
    color: var(--mo-accent);
    pointer-events: none;
    z-index: 1;
}


.popup-dialog .bookmarks-input-group label,
.popup-dialog .submit-field label,
.popup-dialog .submit-field h5 {
    display: block;
    font-size: 12px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--mo-accent);
    margin: 0 0 6px;
}

.popup-dialog input[type="text"],
.popup-dialog input[type="tel"],
.popup-dialog input[type="email"],
.popup-dialog input[type="password"],
.popup-dialog input[type="date"],
.popup-dialog input[type="time"],
.popup-dialog input[type="number"],
.popup-dialog select,
.popup-dialog textarea {
    display: block;
    width: 100%;
    padding: 11px 13px;
    font-family: "Inter", sans-serif;
    font-size: 16px;
    box-sizing: border-box;
}

/* Room for the icon inside the field. This has to sit AFTER the block above,
   not with the other .input-with-icon-left rules: the two selectors weigh the
   same, so the later one is the one that applies. */
.popup-dialog .input-with-icon-left input { padding-left: 42px; }

.popup-dialog select { cursor: pointer; }
.popup-dialog textarea { min-height: 90px; resize: vertical; }

/* The date and time controls paint their own picker glyph in the UA's colour,
   which is black on black here. */
.popup-dialog input[type="date"]::-webkit-calendar-picker-indicator,
.popup-dialog input[type="time"]::-webkit-calendar-picker-indicator {
    filter: invert(1);
    opacity: 0.6;
    cursor: pointer;
}

.popup-dialog .button {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 13px 24px;
    font-size: 13px;
    cursor: pointer;
}

.popup-dialog .error-message,
.popup-dialog .form-error {
    display: block;
    color: #f87171;
    font-size: 14px;
    margin-top: 5px;
}

.popup-dialog .register_success_box,
.popup-dialog .order-success-message {
    text-align: center;
    color: var(--mo-accent);
    font-size: 16px;
    padding: 12px 0;
}

.popup-dialog .qr-success-icon { font-size: 34px; display: block; margin-bottom: 8px; }

/* The line under the login form that offers registration and the password
   reset. Its markup asks for centring with Bootstrap's utility classes, which
   are not on the page, so the two halves ran together against the left edge —
   and both links inherited plain body colour, which is not how anything else
   on this theme says "this is a link". */
.popup-dialog .modal-footer {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 4px 16px;
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--mo-line);
    font-size: 15px;
    color: var(--mo-muted);
}

.popup-dialog .modal-footer a {
    color: var(--mo-accent);
    transition: opacity 0.25s ease;
}

.popup-dialog .modal-footer a:hover { opacity: 0.75; text-decoration: underline; }

.popup-dialog .button,
.popup-dialog button[type="submit"] {
    background: var(--mo-accent) !important;
    border: 1px solid var(--mo-accent) !important;
    color: var(--mo-bg) !important;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    border-radius: 2px;
}

.mfp-bg { background: #000 !important; opacity: 0.9 !important; }

/* Cookie banner. Its markup is the platform's (.cookieConsentContainer), and
   the styling normally comes from the modern-cuisine stylesheet — which this theme
   does not load, so it is redrawn here. */
.cookieConsentContainer {
    position: fixed;
    left: 24px;
    bottom: 24px;
    z-index: 9998;
    width: min(340px, calc(100vw - 48px));
    padding: 24px;
    background: var(--mo-panel);
    border: 1px solid rgba(var(--mo-accent-rgb), 0.25);
    border-radius: 2px;
    box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.9);
}

.cookieConsentContainer .cookieTitle h3 {
    font-family: "Cormorant Garamond", serif;
    font-size: 24px;
    color: var(--mo-text);
    margin-bottom: 10px;
}

.cookieConsentContainer .cookieDesc p {
    font-size: 14px;
    line-height: 1.7;
    color: var(--mo-muted);
    margin-bottom: 16px;
}

.cookieConsentContainer .cookieDesc a { color: var(--mo-accent); }

.cookieConsentContainer .cookieAcceptButton {
    display: inline-block;
    padding: 10px 22px;
    font-size: 12px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    border: 1px solid var(--mo-accent);
    color: var(--mo-accent);
    transition: all 0.35s ease;
}

.cookieConsentContainer .cookieAcceptButton:hover {
    background: var(--mo-accent);
    color: var(--mo-bg);
}


/* ── The owner's notice, drawn as the design's promo card ─────────────────
   #popup-notification carries the .mo-promo-card markup from the reference
   design rather than a notice layout of its own. Everything it needs is
   already declared in section 8; the four rules here are only the difference
   between the design's own overlay — a fixed .mo-promo-modal that animates
   itself open — and magnific-popup, which supplies the overlay and the
   centring and hands the card over already visible.

   js/motion.js opens it. restaurant.js has no part in this dialog: it never
   looks the element up, which is why the theme owns both the queue and the
   opening. */
#popup-notification.mo-promo-card {
    opacity: 1;
    transform: none;
    margin: 40px auto;
}

/* The picture column is the reason a notice is opened at all — a dish, an
   offer, a new opening — so it keeps half the card. When the file behind
   option Message-popup-img is gone (records outlive files, and a missing path
   is answered with the site's HTML and a 200) motion.js sets .is-imageless and
   the text takes the whole card. */
#popup-notification.is-imageless .mo-promo-media { display: none; }
#popup-notification.is-imageless { grid-template-columns: 1fr; }

/* A notice's own slideshow, driven by js/motion.js rather than by keyframes.

   The design's media column is a carousel of exactly three: promoSlide brings
   each slide up for a third of a fixed 15s cycle, and the delays that stagger
   them are written per nth-child. A notice carries however many pictures the
   restaurant uploaded — one, or nine — so neither the count nor the timing is
   known to the stylesheet. The animation is dropped here and .is-current is
   what shows a slide; the script adds and removes it, and the fade is a plain
   transition, so one picture and nine cost the same rules.

   The slow drift over the picture itself is a loop of its own and stays: it is
   the thing that keeps a single-picture notice from looking like a still. */
#popup-notification .mo-promo-slide {
  opacity: 0;
  animation: none;
  transition: opacity 620ms ease;
}

#popup-notification .mo-promo-slide.is-current {
  opacity: 1;
}

/* A picture whose file is gone: the front controller answers with the site's
   HTML and a 200, so the <img> fires error rather than 404. The script marks
   the slide and it is taken out of the rotation — one missing file costs its
   own slide, not the whole column. */
#popup-notification .mo-promo-slide.is-broken {
  display: none;
}

/* The rail under the pictures. The design draws three fixed bars filled by
   keyframes; here the script writes one bar per picture and moves .is-current
   along them, so the bar marks which picture is up rather than animating a
   countdown. It is printed only when there is more than one. */
#popup-notification .mo-promo-progress[hidden] {
  display: none;
}

#popup-notification .mo-promo-progress span::before {
  animation: none;
  transform: scaleX(0);
  transition: transform 400ms ease;
}

#popup-notification .mo-promo-progress span.is-current::before {
  transform: scaleX(1);
}

/* magnific prints its close button inside the panel, where it lands on the
   picture. Its glyph comes from .dialog-with-tabs .mfp-close::before, a
   feather-icons codepoint — and this panel is not a .dialog-with-tabs, it is
   the design's promo card. So the cross is drawn here the way the design draws
   its own .mo-promo-close, which also means it does not depend on an icon font
   having loaded. */
#popup-notification .mfp-close::before,
#popup-notification .mfp-close::after {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 17px;
  height: 2px;
  content: "";
  background: currentColor;
  transform-origin: center;
}

#popup-notification .mfp-close::before { transform: translate(-50%, -50%) rotate(45deg); }
#popup-notification .mfp-close::after { transform: translate(-50%, -50%) rotate(-45deg); }

#popup-notification .mfp-close {
    top: 18px;
    right: 18px;
    width: 40px;
    height: 40px;
    line-height: 40px;
    background: rgba(var(--mo-ink-rgb), 0.06);
    border: 1px solid var(--mo-line-strong);
    color: var(--mo-text);
    opacity: 1;
    z-index: 5;
    transition: background-color 0.25s ease, border-color 0.25s ease;
}

#popup-notification .mfp-close:hover {
    background: var(--mo-accent);
    border-color: var(--mo-accent);
    color: var(--mo-on-accent);
}

@media (max-width: 767px) {
    #popup-notification.mo-promo-card { margin: 20px auto; }
    #popup-notification .mo-promo-media { min-height: 200px; }
}

/* ── Dish photographs in the shared dish dialog ───────────────────────────
   #add-extras is filled by restaurant.js with the dish photo, its price
   options and the allergen list. The image arrives without a size, and the
   design's `.mo-site-shell img { height: 100% }` does not reach into a dialog,
   so it is given its box here. */
#add-extras .popup-content-img,
#add-extras img.menu-image {
    width: 100%;
    height: auto;
    max-height: 320px;
    object-fit: cover;
    display: block;
}

/* ── Type inside the dialogs ─────────────────────────────────────────────
   body carries the design's 19px base, which is a display size — the shared
   dialog markup was drawn against a 14-16px one and its fields, labels and
   helper lines all inherit. The dialogs are put back on their own scale here
   rather than the base being lowered, because every clamp() in sections 2-7
   is measured from 19px. */
.popup-dialog,
.mfp-content .dialog-with-tabs,
.mfp-content .menu-dialog-with-tabs {
    font-size: 17px;
    line-height: 1.6;
    font-family: var(--mo-sans);
}

/* --------------------------------------------------------------------------
   12. What the platform brings and the design did not have
   The reference design was drawn against a fixed demo menu: one flat grid of
   cards under a row of four hard-coded tabs, no category headings, no dish
   photographs, no discount ribbons, no language switcher. A real restaurant
   has all of those and the owner can switch each of them on or off.

   These rules extend the design rather than restate it — every one of them
   reads the same tokens and reuses the shapes from sections 2-7, so a category
   heading is the section kicker at another size and a ribbon is the price chip
   turned into a corner mark.
   -------------------------------------------------------------------------- */

/* ── Categories ───────────────────────────────────────────────────────────
   The design's tab bar filtered one grid; here each category is a block of its
   own with a heading, and the tab bar (built in js/motion.js from these
   blocks) shows one block at a time. The heading survives the filtering
   because it is what the tab was named after. */
.mo-cat-group {
  display: block;
}

.mo-cat-group[hidden] {
  display: none;
}

.mo-cat-title {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 0 0 6px;
  font-family: var(--mo-serif);
  font-size: clamp(26px, 3.4vw, 40px);
  font-weight: 500;
  line-height: 1.05;
  color: var(--mo-category-color);
}

.mo-cat-title .mo-cat-line {
  flex: 1 1 auto;
  height: 1px;
  background: linear-gradient(90deg, rgba(var(--mo-glow-rgb), 0.4), transparent);
}

.mo-cat-thumb {
  flex: 0 0 auto;
  width: 54px;
  height: 54px;
  border: 1px solid var(--mo-line);
  border-radius: 4px;
  object-fit: cover;
}

.mo-cat-desc {
  max-width: 70ch;
  margin: 0 0 20px;
  color: var(--mo-muted);
  font-size: 19px;
  line-height: 1.55;
}

/* ── Dish card additions ──────────────────────────────────────────────────
   A photograph turns the card into two columns; without one the text keeps the
   whole card rather than reserving an empty frame. min-width: 0 on the text
   column because a flex/grid child will otherwise not shrink below its longest
   word and a long dish name would push the price off the card. */
.mo-dish-card--has-thumb .mo-dish-content {
  grid-template-columns: 96px minmax(0, 1fr);
  align-content: stretch;
  gap: 14px;
}

.mo-dish-thumb {
  width: 96px;
  height: 96px;
  border: 1px solid var(--mo-line);
  border-radius: 4px;
  overflow: hidden;
  background: var(--mo-surface);
}

.mo-dish-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 600ms ease;
}

.mo-dish-card:hover .mo-dish-thumb img {
  transform: scale(1.06);
}

/* Name-and-price row, description, allergen letters — stacked from the top.
   It used to be align-content: space-between, which was pushing the order bar
   to the bottom of the card; the bar is the card's own row now, so the body
   only has to keep its three lines together. */
.mo-dish-body {
  display: grid;
  align-content: start;
  gap: 10px;
  min-width: 0;
}

/* price_format() prints these two itself, so the class names are its own: a
   struck-through old price for an absolute reduction, a percentage line for a
   relative one. Both sit under the current price inside the chip. */
.mo-dish-price .menu-before-price-discount {
  display: block;
  font-family: var(--mo-condensed);
  font-size: 15px;
  text-decoration: line-through;
  opacity: 0.6;
}

.mo-dish-price .menu-percent-Discount {
  display: block;
  font-family: var(--mo-condensed);
  font-size: 14px;
  letter-spacing: 0.08em;
  opacity: 0.75;
}

/* Properties and additives, which arrive as icon files under
   storage/icon-food/. svg.js swaps the <img class="svg"> for the inline <svg>
   asynchronously, so both shapes are given the fill — an unstyled one renders
   black on a black card. */
.mo-dish-props {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 8px;
  vertical-align: middle;
}

.mo-dish-props img,
.mo-dish-props svg {
  width: 16px;
  height: 16px;
  fill: var(--mo-accent);
}

/* ── Menu: search feedback ────────────────────────────────────────────────
   Both are hidden until js/motion.js has something to say. */
.mo-menu-notice,
.mo-menu-empty {
  display: none;
  margin-bottom: 28px;
  color: var(--mo-muted);
  font-size: 19px;
}

.mo-menu-notice.is-on,
.mo-menu-empty.is-on {
  display: block;
}

.mo-menu-empty {
  padding: 48px 24px;
  border: 1px dashed var(--mo-line-strong);
  border-radius: 6px;
  text-align: center;
}

.mo-menu-empty h3 {
  margin: 0 0 8px;
  font-family: var(--mo-serif);
  font-size: 26px;
  color: var(--mo-text);
}

.mo-menu-notice strong {
  color: var(--mo-accent);
  font-weight: 500;
}

/* The PDF card, when the restaurant uploaded one. */
.mo-pdf-row {
  margin-top: 44px;
  text-align: center;
}

/* ── Story blocks ─────────────────────────────────────────────────────────
   RESTAURANT_INTRO is the owner's landing-page rows; position_img ("left" /
   "right") is their choice of which side the photograph sits on, so it drives
   the direction rather than a fixed layout. The design's about section holds
   one such row; further rows repeat under it. */
.mo-story-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(24px, 4vw, 56px);
  margin-top: 56px;
}

.mo-story-row--right .mo-story-figure {
  order: 2;
}

.mo-story-figure {
  overflow: hidden;
  border: 1px solid var(--mo-line);
  border-radius: 6px;
  aspect-ratio: 4 / 3;
  background: var(--mo-surface);
}

.mo-story-figure img {
  transition: transform 900ms ease;
}

.mo-story-row:hover .mo-story-figure img {
  transform: scale(1.05);
}

.mo-story-copy h3 {
  margin: 0 0 14px;
  font-family: var(--mo-serif);
  font-size: clamp(26px, 3.2vw, 40px);
  font-weight: 500;
  line-height: 1.06;
  color: var(--mo-text);
}

.mo-story-copy p {
  margin: 0;
  color: var(--mo-muted);
  font-size: 19px;
  line-height: 1.6;
}

@media (max-width: 780px) {
  .mo-story-row {
    grid-template-columns: 1fr;
  }

  .mo-story-row--right .mo-story-figure {
    order: 0;
  }
}

/* ── Language switcher ────────────────────────────────────────────────────
   Sits in the topbar beside the links. The panel is a plate rather than a
   dropdown arrow-and-list, because the topbar is transparent over the banner
   and a bare list would be unreadable there. */
.mo-langs {
  position: relative;
  flex: 0 0 auto;
}

.mo-langs__toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border: 1px solid var(--mo-line);
  border-radius: 4px;
  background: rgba(var(--mo-bg-rgb), 0.4);
  color: var(--mo-text);
  cursor: pointer;
  font-family: var(--mo-condensed);
  font-size: 16px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.mo-langs__toggle img {
  width: 20px;
  height: 14px;
  object-fit: cover;
}

.mo-langs__panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 30;
  display: none;
  min-width: 190px;
  padding: 6px;
  border: 1px solid var(--mo-line-strong);
  border-radius: 4px;
  background: var(--mo-panel);
  box-shadow: 0 24px 60px rgba(var(--mo-shade-rgb), 0.5);
}

.mo-langs.is-open .mo-langs__panel {
  display: block;
}

.mo-langs__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 3px;
  color: var(--mo-muted);
  cursor: pointer;
  font-size: 18px;
  transition: background 200ms ease, color 200ms ease;
}

.mo-langs__item:hover,
.mo-langs__item.is-active {
  background: rgba(var(--mo-ink-rgb), 0.06);
  color: var(--mo-text);
}

.mo-langs__item img {
  width: 22px;
  height: 15px;
  object-fit: cover;
}

/* ── Empty restaurant ─────────────────────────────────────────────────────
   Every section this theme prints is guarded in index.tpl on having something
   to show, except the hero — which always has the restaurant's name. What is
   left here is the one case markup cannot guard: a banner stage with no
   picture and no video at all, which would otherwise be a tall empty frame. */
.mo-hero-feature-stage:not(:has(.mo-feature-panel)) {
  display: none;
}

/* ── The banner stage, driven rather than timed ───────────────────────────
   The design cycled exactly three panels with one keyframe: heroDishFlip runs
   18s and each panel is offset 6s, so its visible window (9%-29%) is a third
   of the cycle by construction. A restaurant may have uploaded one cover
   picture or nine, and neither the offsets nor those percentages can be
   written for an unknown count in CSS.

   The same flip is therefore expressed as two states and js/motion.js decides
   who wears them. The transition is declared on the states rather than on the
   base rule, so a panel that is already off screen does not animate its way
   there when the class is first applied.

   The ken-burns on the picture and the sweep on ::after are untouched: both
   are loops of their own and do not care how many panels there are. */
.mo-feature-panel {
  animation: none;
  opacity: 0;
  transform: rotateY(94deg) scale(0.86);
}

.mo-feature-panel.is-active,
.mo-feature-panel.is-leaving {
  transition: opacity 820ms ease, transform 820ms ease;
}

.mo-feature-panel.is-active {
  z-index: 3;
  opacity: 1;
  transform: rotateY(0deg) scale(1);
}

.mo-feature-panel.is-leaving {
  z-index: 2;
  opacity: 0;
  transform: rotateY(-94deg) scale(0.88);
}

.mo-feature-panel img,
.mo-feature-panel video {
  animation-delay: 0s;
}

/* A real map rather than the design's drawn one. The frame, its border and the
   label above it are the design's; what sits inside is an embed iframe, which
   is the one map this page is allowed to open — the Google Maps script the
   platform loads spends its key on the delivery-address autocomplete. */
.mo-map-card {
  min-height: 280px;
}

/* The card's own grayscale(1) is for the drawn map it replaces — over a real
   embed it would grey the streets and the pin alike, and it stacks with
   anything set on the frame inside. */
.mo-map-card:has(iframe) {
  filter: none;
}

.mo-map-card iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Google serves one map and it is a light one. On the dark ground it is a
   white rectangle in the middle of the page, so it is inverted and the hue
   turned back — the streets go dark, the labels light, and the colours stay
   the colours. In light mode it is left exactly as Google drew it. */
[data-mo-theme="dark"] .mo-map-card iframe {
  filter: invert(0.9) hue-rotate(180deg) saturate(0.75) contrast(0.95);
}

/* The language flags, named by the English language name — which is what the
   LANGS loop prints. A language with no artwork keeps the empty slot, so the
   names stay aligned. */
.mo-flag {
    display: inline-block;
    flex: 0 0 22px;
    width: 22px;
    height: 15px;
    background: rgba(var(--mo-ink-rgb), 0.08) center/cover no-repeat;
    box-shadow: inset 0 0 0 1px var(--mo-line-strong);
}

.mo-flag--English    { background-image: url(../images/flag/united-kingdom.png); }
.mo-flag--French     { background-image: url(../images/flag/france.png); }
.mo-flag--German     { background-image: url(../images/flag/germany.png); }
.mo-flag--Spanish    { background-image: url(../images/flag/spain.png); }
.mo-flag--Russian    { background-image: url(../images/flag/russia.png); }
.mo-flag--Turkish    { background-image: url(../images/flag/turkey.png); }
.mo-flag--Vietnamese { background-image: url(../images/flag/vietnam.png); }
.mo-flag--Italian    { background-image: url(../images/flag/italy.png); }
.mo-flag--Japanese   { background-image: url(../images/flag/japan.png); }
.mo-flag--Polish     { background-image: url(../images/flag/poland.png); }
.mo-flag--Portuguese { background-image: url(../images/flag/portugal.png); }
.mo-flag--Korean     { background-image: url(../images/flag/south-korea.png); }



/* ── The last few pieces the markup asks for ──────────────────────────────
   Small rules that only exist because the platform's page has parts the
   reference design's demo page did not: an uploaded logo instead of a set
   word, a promotions block above the category tabs, and a heading whose name
   is a span so the tab builder can read it without also reading the rule
   beside it. */
.mo-brand-logo {
  width: auto;
  height: 40px;
  object-fit: contain;
}

.mo-footer-logo-img {
  width: auto;
  height: 46px;
  margin-bottom: 12px;
  object-fit: contain;
}

.mo-cat-name {
  flex: 0 1 auto;
  min-width: 0;
}

/* Unsere Aktionen — a section of its own, above the menu.

   It borrows the menu's card grid and the section heading and adds only a
   ground one step off the page, so the section reads as a plate of its own
   rather than as the top of the menu. Nothing else: the heading is the name
   alone, with no kicker over it and no picture beside it — what the section is
   about is the cards under it. */
.mo-actions {
  background: linear-gradient(180deg, rgba(var(--mo-accent-rgb), 0.05), transparent 60%);
}

/* The link for the section the reader is in. .mo-nav a::after is the design's
   own underline; this only holds it open. */
.mo-nav a.is-active {
  color: var(--mo-text);
}

.mo-nav a.is-active::after {
  transform: scaleX(1);
  transform-origin: left;
}

/* The plate inside the banner circle is hidden until js/motion.js has found a
   dish to put on it. */
.mo-feature-content[hidden] {
  display: none;
}

/* The design's search field is a dark plate; its placeholder inherits nothing,
   and on the light ground the browser default is nearly invisible. */
.mo-search input::placeholder {
  color: var(--mo-muted);
  opacity: 0.75;
}

/* A grid child will not shrink below its longest word: a dish with a 40-letter
   name would otherwise hold its column open and push the price off the card,
   and the card's own overflow: hidden would slice the lines. */
.mo-dish-body,
.mo-dish-top > div:first-child,
.mo-hero-copy,
.mo-story-copy,
.mo-footer-col {
  min-width: 0;
}

.mo-dish-name,
.mo-cat-name,
.mo-hero-copy h1 {
  overflow-wrap: anywhere;
}

/* The font dialog compiles the owner's choices as a flat font-size in pixels —
   a number picked on a desktop and applied at every width — and it overrides
   line-height only where a utility class had set one. Both are answered here,
   and the tag name is what wins the cascade between two !important rules. */
p.mo-hero-welcome {
  line-height: 1.2;
}

@media (max-width: 680px) {
  h1.mo-hero-copy-name,
  .mo-hero-copy h1 {
    font-size: clamp(40px, 14vw, 72px) !important;
    line-height: 0.94;
  }

  h2.mo-cat-title,
  h3.mo-cat-title {
    font-size: clamp(22px, 7vw, 30px) !important;
    line-height: 1.1;
  }
}

/* ── Images that are marks, not fills ─────────────────────────────────────
   The design's blanket rule — .mo-site-shell img { width: 100%; height: 100% }
   — is right for every picture it was written for: each one fills a frame that
   already has a size. The pictures this theme adds are not those. A logo, a
   category thumbnail and a discount ribbon carry their own proportions and
   would otherwise be stretched to the width of whatever contains them.

   They are scoped under .mo-site-shell here for one reason only: the blanket
   rule is a class and an element, and a bare class does not outweigh it. */
.mo-site-shell .mo-brand-logo {
  width: auto;
  max-width: 240px;
  height: 44px;
  object-fit: contain;
}

.mo-site-shell .mo-footer-logo-img {
  width: auto;
  max-width: 220px;
  height: 52px;
  object-fit: contain;
}

.mo-site-shell .mo-cat-thumb {
  width: 54px;
  height: 54px;
  object-fit: cover;
}


@media (max-width: 680px) {
  .mo-site-shell .mo-brand-logo { height: 36px; }
}

/* ── Holding the font dialog to a sane size ───────────────────────────────
   "Use the template default font = No" compiles the owner's choices into the
   head with !important, and the size it writes is a single flat number in
   pixels — 63px is what restaurants routinely save there, chosen on some other
   theme and applied at every width and to every element the class touches.

   The welcome line is a kicker by design: at 63px it is larger than the
   restaurant's own name directly under it, which inverts the whole hero. Its
   size is therefore pinned rather than left to the setting; the dialog's
   family, weight and style still come through. Specificity is what decides
   between two !important declarations, so these carry the tag name.

   The name, the tagline and the category headings keep the owner's size — that
   is a real choice about their own page — and are only given the line-height
   the dialog does not write, so 63px of glyphs cannot land in a 21px line box
   and print over the next element. */
p.mo-hero-welcome {
  font-size: clamp(24px, 2.6vw, 34px) !important;
  line-height: 1.1;
}

div.mo-hero-subtitle {
  line-height: 1.15;
}

h3.mo-cat-title {
  line-height: 1.1;
}

a.mo-button,
a.mo-button span {
  font-size: 16px !important;
  letter-spacing: 0.08em;
  line-height: 1.2;
}

/* ── The three facts under the hero ───────────────────────────────────────
   The design writes one label and two fixed lines per column. Here the lines
   are the restaurant's own, so how many there are depends on what the owner
   switched on — which is why the separator between the services is drawn
   rather than printed: an IF that emits its own comma leaves a trailing one
   the moment the last service is off.

   .mo-hero-info span is the accent label in the design's rules, and it reaches
   the spans inside the paragraph too. They are put back on the paragraph's own
   ink here; the label keeps the accent because a direct-child selector is
   heavier than the bare descendant one. */
.mo-hero-info > span {
  color: var(--mo-accent);
}

.mo-hero-info p span {
  color: inherit;
}

.mo-hero-service span + span::before {
  content: " · ";
  opacity: 0.5;
}

/* The telephone number is the column's second line, the way the design sets a
   second line under each label. */
.mo-hero-info p a {
  display: block;
  color: var(--mo-text);
  transition: color 200ms ease;
}

.mo-hero-info p a:hover {
  color: var(--mo-accent);
}

/* An owner who has switched everything off leaves this column with a label and
   nothing under it. */
.mo-hero-service:empty {
  display: none;
}

/* ── The bar's alignment ──────────────────────────────────────────────────
   In the reference design .topbar holds exactly two things — the brand and the
   links — so justify-content: space-between puts the links hard against the
   right edge. This theme adds a third: the language switcher, which no demo
   page needed. The two are wrapped together in .mo-nav-panel so the bar is
   back to two children, and margin-left: auto on the panel takes all the free
   space to its left — brand at one edge, links and language chip at the other.

   The panel is also what folds away behind the ⋮ button on a narrow screen,
   which is why the wrapper exists at all rather than a margin on .mo-nav. */
.mo-nav-panel {
  display: flex;
  align-items: center;
  gap: 8px 24px;
  margin-left: auto;
}

/* ── The turning photograph in a story row ────────────────────────────────
   js/motion.js gives the figure a second face and the design's 8.8s rotation.
   The figure itself becomes only the stage: the frame, the ground and the clip
   move onto the faces, which .mo-flip-face already declares — leaving them on
   the figure would draw a border around a box that is now empty and clip the
   card as it turns out of plane.

   The two rules that answer the story row rather than the design: the figure
   keeps its 4/3 measure so a turning row is the same height as a still one,
   and the hover zoom on .mo-story-figure img is called off, because it fights
   the flip for the same transform. */
.mo-story-figure.is-flip {
  position: relative;
  overflow: visible;
  border: 0;
  background: none;
  perspective: 1400px;
}

.mo-story-row:hover .mo-story-figure.is-flip img {
  transform: scale(1.06);
}

/* .mo-flip-photo-inner is absolutely placed against its card in the design.
   Here the card is the figure, whose height comes from aspect-ratio — so the
   inner needs no size of its own, only the same corner radius as the faces so
   the shine sweeping over them is not clipped square. */
.mo-story-figure.is-flip .mo-flip-photo-inner {
  border-radius: 6px;
}

/* The design gives .flip-photo a min-height of 410px, which is right for a
   block that owns its own section. In a story row the figure already has a
   measure — 4/3, so that a turning row is exactly as tall as a still one — and
   a fixed 410px would fight it. The card fills the figure instead. */
.mo-story-figure.is-flip .mo-flip-photo {
  min-height: 0;
  height: 100%;
}

/* ── Two cards, the design's own about-flip-gallery ───────────────────────
   A block with two pictures or more gets the arrangement the reference design
   drew for this section: a pair of turning cards side by side, staggered, so
   the section shows the restaurant's pictures rather than one of them.
   js/motion.js adds this class when it built two cards.

   The figure stops being a frame here — .is-flip already took its border and
   its ground away — and becomes the row. Its 4/3 measure goes with it, because
   the height now comes from the cards.

   2/3 per card is not an arbitrary portrait. At a column width W with the
   design's 18px gutter each card is (W-18)/2 wide, so the pair stands
   0.75W-13.5 tall — within a hairline of the 0.75W a single 4/3 frame stood.
   A row that gains a second picture therefore does not move the section under
   it, and a row with one picture still lines up with a row that has four. */
.mo-story-figure.mo-flip-gallery {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  aspect-ratio: auto;
}

.mo-story-figure.mo-flip-gallery .mo-flip-photo {
  height: auto;
  aspect-ratio: 2 / 3;
}

/* Below the width where the story row folds to one column, two portrait cards
   side by side would each be about a thumbnail. The design stacks them at its
   own breakpoints and so does this — turned landscape, because stacked they
   have the whole column and a portrait pair would push the copy off the
   screen. */
@media (max-width: 780px) {
  .mo-story-figure.mo-flip-gallery {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  .mo-story-figure.mo-flip-gallery .mo-flip-photo {
    aspect-ratio: 4 / 3;
  }
}

/* ── The status badge ─────────────────────────────────────────────────────
   What replaced the corner ribbon. It sits in the line of type it belongs to
   rather than across the card's corner, so it costs the card nothing: the
   price chip and the order button keep the card's own right edge whether a
   dish is marked or not, and a marked card lines up with the plain card
   beside it.

   It is drawn as two plates rather than one. The lower plate is the same
   shape in a darker tone, offset down and to the right; the upper one carries
   the glyph and the word and takes a hairline of white along its top and left
   edges. Offset plus edge light is the whole of the depth — there is no blur
   and no box-shadow, which is what keeps it crisp at this size where a soft
   shadow would read as a smudge.

   Both are pseudo-elements, so the markup stays a span with two spans in it.
   They have to be positioned and ordered explicitly: the skew below makes the
   badge a stacking context, and inside one a z-index:-1 child would paint over
   the badge's own background rather than under it. So the badge itself carries
   no background at all — ::before is the lower plate, ::after the upper one,
   and the two spans are lifted above both.

   Four states, and the state is the only thing that changes: each modifier
   restates the two tones and nothing else. The platform flags two of them
   today — neu when the kitchen marks a dish new, angebot when it is
   discounted — and beliebt and chef-tipp are here for the flags that follow. */
.mo-dish-badge {
  --mo-badge-face: #555;
  --mo-badge-deep: #333;
  --mo-badge-lift: 3px;

  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: 10px;
  padding: 3px 8px;
  color: #fff;
  background: transparent;
  font-family: var(--mo-condensed);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: middle;
  transform: translateY(-1px) skewX(-12deg);
}

/* The lower plate. */
.mo-dish-badge::before {
  position: absolute;
  inset: 0;
  z-index: 0;
  content: "";
  border-radius: 2px;
  background: var(--mo-badge-deep);
  transform: translate(var(--mo-badge-lift), var(--mo-badge-lift));
}

/* The upper plate, with the light along the two edges that face the source. */
.mo-dish-badge::after {
  position: absolute;
  inset: 0;
  z-index: 1;
  content: "";
  border-top: 1px solid rgba(255, 255, 255, 0.32);
  border-left: 1px solid rgba(255, 255, 255, 0.32);
  border-radius: 2px;
  background: var(--mo-badge-face);
}

/* A dish may carry several marks at once — dish_status is a list, not a
   choice. They have to read as one run rather than as separate things
   scattered along the line, so they sit closer to each other than the first
   one sits to the name it follows. */
.mo-dish-badge + .mo-dish-badge {
  margin-left: 5px;
}

/* The glyph and the word ride on top of both plates. They are not counter-
   skewed: the design leans the whole mark, lettering included. */
.mo-dish-badge > span {
  position: relative;
  z-index: 2;
}

.mo-dish-badge__icon {
  display: inline-grid;
  width: 12px;
  place-items: center;
  font-size: 12px;
  line-height: 1;
}

/* ── The four states ───────────────────────────────────────────────────── */
.mo-dish-badge--beliebt {
  --mo-badge-face: #1fa363;
  --mo-badge-deep: #10613a;
}

.mo-dish-badge--angebot {
  --mo-badge-face: #f4643a;
  --mo-badge-deep: #b03516;
}

.mo-dish-badge--neu {
  --mo-badge-face: #3b82f6;
  --mo-badge-deep: #1d4ed8;
}

.mo-dish-badge--chef-tipp {
  --mo-badge-face: #e8a221;
  --mo-badge-deep: #96620b;
}

/* Nothing is restated for light mode. These are state colours, not theme
   colours — the same two plates read on paper as they do on the dark card,
   and the depth is an offset rather than a shadow mixed from the ground. */

/* At the width where the menu folds to one column the name and the description
   sit closer, so the mark shrinks with the type around it — the offset with
   it, or three pixels of lift under an eleven-pixel badge reads as a misprint
   rather than as depth. */
@media (max-width: 680px) {
  .mo-dish-badge {
    --mo-badge-lift: 2px;

    gap: 4px;
    margin-left: 7px;
    padding: 2px 7px;
    font-size: 10px;
  }

  .mo-dish-badge__icon {
    width: 11px;
    font-size: 11px;
  }
}

/* The name is a flex row of its own so a long dish title wraps without
   dragging the badge off the card with it. */
.mo-dish-name {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 2px;
}

/* The badge's lower plate is absolutely placed and so takes no height of its
   own: it hangs the lift below the name's line box and would otherwise land on
   the first line of the description. Only a card that carries a mark pays for
   the room, which is what :has() is for — a plain card keeps the name and the
   description exactly where the design put them. */
.mo-dish-name:has(.mo-dish-badge) {
  padding-bottom: 4px;
}

@media (max-width: 680px) {
  .mo-dish-name:has(.mo-dish-badge) {
    padding-bottom: 3px;
  }
}

/* ── The card as the way into the dish dialog ─────────────────────────────
   The ⓘ mark beside the name is gone and the card itself opens the popup, so
   it has to look like something you can press and has to answer the keyboard.
   The focus ring is the design's own card-focus treatment, which was already
   written for :focus-within — it only needs to reach the card's own focus too.

   The two things inside it that keep their own job get their own cursor back,
   so a reader can tell before clicking that Bestellen is not the dish info. */
.mo-dish-card {
  cursor: pointer;
}

.mo-dish-card:focus-visible {
  outline: 2px solid var(--mo-accent);
  outline-offset: 3px;
}

.mo-dish-card .mo-order-link {
  cursor: pointer;
}

.mo-dish-card .mo-allergen {
  cursor: help;
}

/* ── The ⋮ button ─────────────────────────────────────────────────────────
   Not printed on a wide screen: the links are the bar there. It appears only
   at the width where six of them — and "Unsere Aktionen" is not a short word
   in any language — stopped fitting on one row.

   Three dots drawn from one span: the middle is the element, the outer two its
   pseudo-elements. This theme loads no icon font, and a mark this small is
   cheaper to draw than to fetch. */
.mo-nav-toggle {
  display: none;
  position: relative;
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid var(--mo-line);
  border-radius: 4px;
  background: rgba(var(--mo-bg-rgb), 0.4);
  cursor: pointer;
  transition: border-color 200ms ease, background 200ms ease;
}

.mo-nav-toggle:hover,
.mo-nav-toggle:focus-visible {
  border-color: var(--mo-accent);
  background: rgba(var(--mo-accent-rgb), 0.12);
}

.mo-nav-toggle > span,
.mo-nav-toggle > span::before,
.mo-nav-toggle > span::after {
  position: absolute;
  left: 50%;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--mo-text);
  transform: translateX(-50%);
  transition: background 200ms ease;
}

.mo-nav-toggle > span {
  top: 50%;
  margin-top: -2px;
}

.mo-nav-toggle > span::before,
.mo-nav-toggle > span::after {
  content: "";
  left: 0;
  transform: none;
}

.mo-nav-toggle > span::before { top: -7px; }
.mo-nav-toggle > span::after  { top: 7px; }

.mo-nav-toggle[aria-expanded="true"] > span,
.mo-nav-toggle[aria-expanded="true"] > span::before,
.mo-nav-toggle[aria-expanded="true"] > span::after {
  background: var(--mo-accent);
}

/* ── The bar below 980px ──────────────────────────────────────────────────
   The links and the language chip drop out of the row and become a plate
   hanging under the bar, opened by the ⋮ button. Before this they wrapped onto
   three rows and pushed the restaurant's name off the first screen.

   The bar goes back to being one row here: the 680px rule that stacked it into
   a column existed only to give those wrapped links somewhere to go, and there
   is nothing left in the row to stack. */
@media (max-width: 980px) {
  /* relative, not the design's absolute: an absolute bar takes no space in the
     flow and printed straight over the restaurant's name once the hero
     stacked. relative also gives the plate below something to hang from. */
  .mo-topbar {
    position: relative;
    align-items: center;
    flex-direction: row;
    background: linear-gradient(180deg, rgba(var(--mo-bg-rgb), 0.92), rgba(var(--mo-bg-rgb), 0.55));
  }

  .mo-hero {
    padding-top: 28px;
  }

  .mo-nav-toggle {
    display: block;
  }

  .mo-nav-panel {
    position: absolute;
    top: calc(100% - 8px);
    right: clamp(18px, 4vw, 56px);
    z-index: 40;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    min-width: 230px;
    max-width: calc(100vw - 36px);
    padding: 10px;
    border: 1px solid var(--mo-line-strong);
    border-radius: 6px;
    background: var(--mo-panel);
    box-shadow: 0 28px 70px rgba(var(--mo-shade-rgb), 0.55);
  }

  .mo-topbar.is-nav-open .mo-nav-panel {
    display: flex;
  }

  /* One link per row, each a full-width target rather than a word to aim at. */
  .mo-nav {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    text-shadow: none;
  }

  .mo-nav a {
    padding: 12px 12px;
    border-radius: 4px;
  }

  .mo-nav a:hover,
  .mo-nav a.is-active {
    background: rgba(var(--mo-ink-rgb), 0.06);
  }

  /* The design's underline slides in from the right edge of the link. Down
     here a link is the width of the plate, so the rule would run the whole way
     across — the row's own ground marks the active link instead. */
  .mo-nav a::after {
    display: none;
  }

  .mo-langs {
    margin-top: 6px;
    padding-top: 10px;
    border-top: 1px solid var(--mo-line);
  }

  .mo-langs__toggle {
    width: 100%;
    justify-content: center;
  }

  /* The language list opens inside a plate that is already floating, so it
     drops straight into the flow instead of hanging off it a second time. */
  .mo-langs__panel {
    position: static;
    min-width: 0;
    margin-top: 6px;
    box-shadow: none;
  }
}
