/* ==========================================================================
   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);
}

/* align-content: start, or the label does not stay put.

   The three columns are grid items of .mo-hero-info-grid and stretch to the
   tallest of them — the address, which wraps to two lines. Each column is then
   a grid of its own with two auto rows and more height than its rows need, and
   the initial align-content distributes that slack INTO the rows. So the
   shortest column got the most padding: "Đóng" is one line where the address is
   two, so its label row grew 14px and pushed the word down a line below the
   address and the phone number beside it.

   Packed to the start, the rows keep their content height, the three labels
   share one line and the three values share the next, and the leftover height
   is left at the foot of the column where nothing is looking. */
.mo-hero-info {
  display: grid;
  align-content: start;
  gap: 8px;
  color: var(--mo-accent-label);
  font-size: 15px;
  font-weight: 500;
  text-transform: uppercase;
}

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

/* The line that says these are today's hours. White — the page's own ink —
   because it is not a second label: the accent above it names the field, this
   names the day, and two accent lines in a row would read as two fields.

   gap on .mo-hero-info is 8px, which is the space between a label and its
   value. This sits between them, so it takes a little off the top to stay with
   the label it belongs to rather than floating between the two. */
.mo-hero-info__today {
  margin-top: -3px;
  color: var(--mo-text);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.16em;
}

.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;
}

/* A picture with nothing written about it shows no plate. display:flex above
   beats the [hidden] rule in the browser's own sheet, so hiding it has to be
   said here. */
.mo-flip-label[hidden] {
  display: none;
}

/* The owner's caption is one line under the picture, not a paragraph over it.
   The field takes 160 characters and someone will use all of them, so it is
   held to the width of the plate and cut rather than allowed to grow up the
   photograph. */
.mo-flip-label span {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.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);
}

/* One row that scrolls, not a block that wraps.

   A restaurant with fifteen categories filled two and sometimes three rows here
   and pushed the menu itself below the fold before a single dish was on screen.
   Kept to one line, the bar is the height it looks like it should be and the
   categories that do not fit are a swipe away rather than a row down.

   The vertical padding is not decoration: overflow-x on a box forces overflow-y
   to a scrolling value too, so `visible` stops being available — and .mo-tab
   lifts 2px on hover while the active one carries a 12px/34px shadow. Without
   room above and below, both get clipped along the line.

   It is also SYMMETRIC, which it was not: 6px over 12px made the bar 3px taller
   below its chips than above them, and the row centres the bar as a whole — so
   the chips sat 3px above the search field and the arrows beside them, on a row
   whose whole job is to look like one row. The 12px is what the shadow needs;
   the top matches it rather than the other way round. */
.mo-tabs {
  display: flex;
  flex-wrap: nowrap;
  justify-content: flex-start;
  gap: 8px;
  min-width: 0;
  padding: 12px 2px;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  transform: translateX(0);
  transition: transform 360ms cubic-bezier(.2, .8, .2, 1);
}

/* A chip never shrinks to fit — that is what the scroll is for. Two-word names
   stay on one line with it. */
.mo-tabs > .mo-tab {
  flex: 0 0 auto;
  white-space: nowrap;
}

.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: 18px;
  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: 16px;
  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);
}

/* The allergen letter, as a mark in a ring. One place now: the legend under
   the menu. The dish cards print their codes as a plain run instead (see
   .mo-dish-codes), so this is the shape a reader matches that run against.

   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. */
/* place-CONTENT, not only place-items. min-width makes the ring wider than the
   letter inside it, and the leftover space belongs to the grid's single column
   — which justify-content places, and which place-items never touches. Its
   initial value is start, so the letter sat against the left of the ring:
   measured on the page, 8px of gap on the left against 14.2px on the right. */
.mo-allergen {
  position: relative;
  display: inline-grid;
  place-items: center;
  place-content: 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;
}

/* The label is the page's own text colour, which is what the design sets on it
   (.order-link: color: var(--text)) — not the accent. The accent is already
   doing two jobs on this card, the price plate and this button's own frame, and
   spending it on the word inside that frame left the one thing a reader is
   looking for reading quieter than the border around it.
   Declared after the block above rather than inside it so the rule sits next to
   the reason. */
.mo-order-link {
  color: var(--mo-text);
}

/* 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-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-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:has(.mo-gallery-caption-text:empty) {
  display: none !important;
}

.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: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  gap: 8px;
  margin-top: 14px;
  overflow-x: auto;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;          /* Firefox */
  cursor: grab;
  user-select: none;
}
.mo-gallery-thumbs::-webkit-scrollbar { display: none; } /* Chrome/Safari */
.mo-gallery-thumbs.is-dragging { cursor: grabbing; scroll-behavior: auto; }

.mo-gallery-thumb {
  flex: 0 0 auto;
  width: 100px;
  height: 68px;
  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 img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.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);
}

/* The mark inside the ring. 22px in a 44px circle: the Facebook and Instagram
   files are filled tiles rather than glyphs, so at any larger size they stop
   being a mark in a ring and become a coloured square with a ring drawn round
   it. The Google file is a bare G with no tile behind it, and 22px is where
   the three read as the same weight despite that.

   contain, not cover: the three files have three different viewBox ratios
   (28x28, 612x612, 21x21.667) and cover would crop the odd one. */
.mo-social-row a img {
  display: block;
  width: 22px;
  height: 22px;
  object-fit: contain;
}

.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: 50px;
  padding: 7px 14px 7px 7px;
  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);
}

/* The plate is the accent's INK, not the raw accent. Same reason
   .mo-order-link gives on hover: --mo-on-accent is near-black, and near-black
   on whatever the restaurant saved is unreadable the moment they save
   something dark. Measured on this one — #080808 on #01696B is a contrast
   ratio of 3.08, under the 4.5 a mark this size needs, and the phone icon read
   as a smudge. --mo-accent-ink is the same colour with a floor under its
   lightness, so the pair holds for every Theme color rather than only for pale
   ones, and it sits beside the gold Bestellen plate as a family. */
.mo-quick-contact-icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 4px;
  color: var(--mo-on-accent);
  background: var(--mo-accent-ink);
  line-height: 1;
}

/* Both shapes, because the swap is asynchronous: js/svg.js replaces the <img>
   with the inline <svg> on load, and until it does the <img> is what is on the
   plate. The <svg> takes the plate's own colour through fill: an <img> cannot
   be filled at all, so it is tinted with a filter instead — brightness(0)
   flattens the artwork to black, and --mo-icon-invert lifts it to white on the
   two plates whose text is light. */
.mo-quick-contact-icon img,
.mo-quick-contact-icon svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.mo-quick-contact-icon img {
  filter: brightness(0) invert(var(--mo-icon-invert, 0));
}

/* WhatsApp's own lockup is a white glyph on this green, and at the size a
   phone app draws it that reads. At 20px on a badge it does not: white on
   #25D366 is a contrast ratio of 1.98, the weakest thing on the rail by a
   wide margin. The near-black takes it to 10.3 and puts this plate in the same
   family as the other three — dark mark, light plate — while the green and the
   glyph still say WhatsApp on their own. */
.mo-quick-contact-whatsapp .mo-quick-contact-icon {
  color: var(--mo-on-accent);
  background: var(--mo-whatsapp);
  --mo-icon-invert: 0;
}

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

/* The one plate that is not a colour: its icon takes the page's own text
   colour, which is light on the dark setting and dark on the light one — so
   the pre-swap tint has to follow the theme rather than the plate. */
.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-icon-invert: 1;
}

html[data-mo-theme="light"] .mo-quick-contact-reserve .mo-quick-contact-icon {
  --mo-icon-invert: 0;
}

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

/* Down from 19/15. This rail is pinned over the page and is read at a glance —
   it is four labels on a badge, not a paragraph, and at nineteen it was the
   largest type in the bottom corner of every screen. */
.mo-quick-contact-text strong {
  font-size: 16px;
  font-weight: 500;
}

.mo-quick-contact-text span {
  color: var(--mo-muted);
  font-size: 13px;
  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);
}

/* One bar per picture, the current one filling left to right over exactly as
   long as its picture is up.

   It used to be three bars on a 15s loop of their own, staggered five seconds
   apart, drawn without reference to the slideshow beside them: a notice with
   two pictures got three bars, one with six got three, and the light moved on
   its own schedule while the pictures moved on the timer's. The dwell is now
   one number — POPUP_SLIDE_MS in js/motion.js — which the script hands here as
   --mo-slide-ms, so the bar and the picture cannot fall out of step. The value
   below is only what a rail would run at if the script never set it.

   grid-auto-flow rather than a fixed column count for the same reason: the
   number of bars is however many pictures the restaurant uploaded, and the
   rail should not have to be told twice. */
.mo-promo-progress {
  --mo-slide-ms: 3600ms;

  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 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;
}

/* A picture already seen keeps its bar full — the rail reads as progress
   through the set rather than as a single travelling light. */
.mo-promo-progress span.is-done::before {
  transform: scaleX(1);
}

.mo-promo-progress span.is-current::before {
  animation: promoProgress var(--mo-slide-ms) linear forwards;
}

@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 {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

@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-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 {
    /* single-row scroll — no grid columns to override */
  }

  .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;
  }

  /* Four marks on one row, not two rows of two.

     With their labels the four plates were two rows tall and pinned to the
     bottom of the window, so on a phone they covered the last 130px of
     whatever was behind them — which at the foot of this page is the opening
     hours and the legal links. The icons are what a reader actually aims at
     here; the words were repeating what the icon and the page already say. */
  .mo-quick-contact {
    left: 12px;
    right: 12px;
    bottom: 12px;
    gap: 8px;
    /* However many marks there are, they share the width. Four is the most a
       restaurant can have here, but each one is printed only if it has
       somewhere to go — no phone number, no online shop, no WhatsApp, no
       reservations, each drops its own plate. repeat(4, 1fr) held four columns
       whatever was in them, so a restaurant with three left a plate-sized hole
       at the right end. grid-auto-flow makes the column count follow the
       children. */
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }

  .mo-quick-contact-link {
    justify-content: center;
    gap: 0;
    min-height: 52px;
    padding: 7px;
  }

  /* Hidden from the eye, not from the page. display: none would take the
     link's accessible name with it — the icon is an <img alt="">, so the name
     is this text and nothing else, and four unlabelled buttons is what a
     screen reader would be left with. */
  .mo-quick-contact-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* One row rather than two: the rail needs that much less room kept clear
     under the footer's last line. */
  .mo-site-footer {
    padding-bottom: 84px;
  }

  .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-thumb {
    width: 80px;
    height: 58px;
  }

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

  /* The day and its hours stay on ONE line at every width. They used to break
     into two here — day above, time below — which turned a seven-row opening
     board into fourteen lines and made a reader count pairs to find today.

     flex rather than the grid above: the fixed 110px first column is what
     forced the break in the first place, and at 430px there is no width to
     give it. The day takes what it needs, the time takes the rest and stays
     against the right edge, which is how a printed board reads. */
  .mo-hours-row {
    display: flex;
    justify-content: space-between;
    gap: 14px;
  }

  .mo-hours-row span:first-child {
    flex: 0 0 auto;
  }

  /* min-width: 0 so a long value — "08:00 - 12:00 & 14:00 - 21:00" is a real
     one — wraps inside its own half instead of holding the row wider than the
     screen. This block is later in the file than the left-align at 980px, so
     it is what applies down here. */
  .mo-hours-row span:last-child {
    min-width: 0;
    text-align: right;
  }
}

@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: 16px;
    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: 13px;
    letter-spacing: 0.15em;
    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; }

/* Match the closure alert to Motion's announcement card in both themes. */
.sweet-alert.mo-closed-notice {
    width: min(860px, calc(100% - 32px));
    max-height: calc(100vh - 48px);
    left: 50%;
    top: 50%;
    margin: 0 !important;
    padding: clamp(28px, 5vw, 52px);
    transform: translate(-50%, -50%);
    overflow-y: auto;
    border: 1px solid rgba(var(--mo-accent-rgb), 0.32);
    border-radius: 0;
    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);
    color: var(--mo-text);
    font-family: var(--mo-sans);
    text-align: left;
}

.sweet-alert.mo-closed-notice h2 {
    margin: 0 0 18px;
    padding: 0;
    color: var(--mo-text);
    font-family: var(--mo-serif);
    font-size: clamp(34px, 5vw, 56px);
    font-weight: 400;
    line-height: 1;
    text-align: left;
    overflow-wrap: anywhere;
}

.sweet-alert.mo-closed-notice > p {
    margin: 0;
    color: var(--mo-muted);
    font-family: var(--mo-sans);
    font-size: 21px;
    font-weight: 400;
    line-height: 1.75;
    text-align: left;
    overflow-wrap: anywhere;
}

.sweet-alert.mo-closed-notice .sa-button-container {
    margin-top: 26px;
    text-align: left;
}

.sweet-alert.mo-closed-notice button.confirm {
    min-height: 44px;
    margin: 0;
    padding: 0 18px;
    border: 0;
    border-radius: 4px;
    background: var(--mo-accent) !important;
    color: var(--mo-on-accent);
    box-shadow: none !important;
    font: 500 16px var(--mo-sans);
    text-transform: uppercase;
    transition: transform 200ms ease, background 200ms ease;
}

.sweet-alert.mo-closed-notice button.confirm:hover,
.sweet-alert.mo-closed-notice button.confirm:focus-visible {
    transform: translateY(-2px);
    background: var(--mo-accent-hi) !important;
}

.sweet-alert.mo-closed-notice button.confirm:focus-visible {
    outline: 2px solid var(--mo-text);
    outline-offset: 4px;
}

@media (max-width: 600px) {
    .sweet-alert.mo-closed-notice { padding: 26px 20px 24px; }
    .sweet-alert.mo-closed-notice h2 { font-size: 34px; }
}

/* Two things the card inherits by accident, both of which show.

   A slide is a <figure>, and the reset that flattens figures is scoped to
   .mo-site-shell — but magnific-popup lifts #popup-notification out of the
   shell and into .mfp-content before it opens, so the reset stops reaching it
   and the browser's own `figure { margin: 1em 40px }` comes back. The slide is
   inset:0 inside the media column, so that margin shrinks it: the picture
   stopped 40px short on each side and 21px short top and bottom, with the
   column's own background showing through the gap.

   The title is a .popup-notification-header, a name it shares with the shared
   dialog padding above. That rule is written for the tab dialogs, where 20px
   24px is the body inset; here it pushed the heading 24px to the right of the
   kicker and the message, which start flush at the content column's own
   padding. Reset both — the promo card sets its own spacing. */
#popup-notification .mo-promo-slide {
  margin: 0;
}

#popup-notification .popup-notification-header {
  padding: 0;
}

/* 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, printed only when there is more than one.

   This block used to switch the fill off — animation: none and a transition to
   scaleX(1) on .is-current — because the rule it was overriding was the
   design's decoration: three fixed bars on a 15s loop of their own, unrelated
   to the pictures beside them. That rule is now the real behaviour, one bar
   per picture filling over the dwell the script hands it, so there is nothing
   left here to override. Only the hidden state is this block's. */
#popup-notification .mo-promo-progress[hidden] {
  display: none;
}

/* 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;
}

/* A <button> keeps the operating system's own look until every part of it is
   overwritten. This rule set the colour and the padding and stopped, so each
   language sat in a grey buttonface plate with a 2px outset border, shrunk to
   its own text rather than filling the panel, and set in Arial — the six of
   them read as six controls in a box instead of one list.
   The toggle beside it never showed the fault because it declares its own
   background and border. */
.mo-langs__item {
  -webkit-appearance: none;
  appearance: none;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: 3px;
  background: transparent;
  color: var(--mo-muted);
  cursor: pointer;
  font-family: var(--mo-sans);
  font-size: 18px;
  line-height: 1.2;
  text-align: left;
  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;
}

/* Two marks, one showing. The restaurant uploads one drawn for a dark ground
   and one for a light one, and which is right changes the moment the reader
   uses the tone switcher — so the mode picks, not the template.

   display: none rather than opacity: the hidden one must leave the bar's flex
   row entirely, or the brand would keep a 40px hole beside it.

   .mo-brand is in every selector to outweigh the reset in section 1 —
   .mo-site-shell img { display: block } is two selectors to a bare class's one
   and would otherwise put both marks in the bar at once. */
.mo-brand .mo-brand-logo--light { display: none; }

html[data-mo-theme="light"] .mo-brand .mo-brand-logo--dark { display: none; }
html[data-mo-theme="light"] .mo-brand .mo-brand-logo--light { display: block; }

/* ── The tone switcher ────────────────────────────────────────────────────
   Two buttons in one plate rather than a single button that toggles: a toggle
   has to say what it will do or what it is doing, and whichever it says the
   other reading is available to the reader. Two labelled options say both at
   once, and the pressed one is the answer to "what am I looking at".

   Same plate as .mo-langs__toggle and .mo-nav-toggle — the bar has one kind of
   control in it and this is that kind. */
.mo-tone {
  display: inline-flex;
  flex: 0 0 auto;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--mo-line);
  border-radius: 4px;
  background: rgba(var(--mo-bg-rgb), 0.4);
}

.mo-tone__option {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border: 0;
  border-radius: 3px;
  background: transparent;
  color: var(--mo-muted);
  cursor: pointer;
  font-family: var(--mo-condensed);
  font-size: 14px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: color 200ms ease, background 200ms ease;
}

.mo-tone__option svg {
  width: 14px;
  height: 14px;
  fill: currentColor;
}

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

.mo-tone__option[aria-pressed="true"] {
  background: var(--mo-accent);
  color: var(--mo-on-accent);
}

.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 had a rule here: a plate one step off the page, so the
   section read as its own thing above the menu. It is the menu's first category
   now — the same grid on the same ground as every other category — so there is
   nothing left for it to paint. */

/* 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: 56px;           /* Desktop default */
  object-fit: contain;
}

/* Large screens ≥ 1440px */
@media (min-width: 1440px) {
  .mo-site-shell .mo-brand-logo { height: 64px; }
}

.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;
}

/* Tablet ≤ 980px */
@media (max-width: 980px) {
  .mo-site-shell .mo-brand-logo { height: 48px; }
}

/* Mobile ≤ 680px */
@media (max-width: 680px) {
  .mo-site-shell .mo-brand-logo { height: 40px; }
}

/* ── 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;
  }

  /* The words go and the two glyphs stay. At this width the bar carries the
     restaurant's name, this and the burger, and a sun and a moon say which is
     which without them — the buttons keep their labels for a screen reader
     through aria-pressed and the title the script writes. */
  .mo-tone__option {
    padding: 7px 9px;
  }

  .mo-tone__option span {
    display: none;
  }

  .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;
  }
}

/* ── The dish card, at the size a real menu needs ─────────────────────────
   The reference design was drawn against six dishes with short names. A menu
   of a hundred and fifty is read as a list, and a list is read at list size:
   the name comes down from 24px, and the allergen marks come down with it.

   The marks are the same shape as the legend's — the legend was already taken
   to 24px so a reader could match one to the other; on the card they were still
   at the design's 30px, which made three of them a row of buttons under a line
   of type they were supposed to annotate. */
.mo-dish-name {
  font-size: 19px;
  line-height: 1.14;
}

/* The number is a reference now, so it is set like one: quieter than the name
   it labels, and tracked out a little so #V15 reads as one token. */
.mo-dish-code {
  font-size: 18px;
  letter-spacing: 1px;
}

/* The codes on a dish: one quiet run after the name, set the way a printed
   menu sets them. Not a ring each — seven rings after a dish name are seven
   objects competing with the name and with the badges beside it, and at that
   size the ring is decoration rather than a container anyone reads a letter
   out of. The ring keeps its job in the legend under the menu, where each one
   labels its own line.

   super rather than baseline: this is a footnote marker, and sitting it on the
   name's baseline made it read as part of the name. */
.mo-dish-codes {
  margin-left: 7px;
  color: var(--mo-muted);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  vertical-align: super;
  white-space: nowrap;
  cursor: help;
}

@media (max-width: 680px) {
  .mo-dish-name { font-size: 17px; }
  .mo-dish-code { font-size: 12px; }

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

/* ── The category heading, once the tab bar names the category ────────────
   The bar above the menu shows every category and lights the open one, so the
   heading under it repeated the word a reader had just tapped — and at
   clamp(26px, 3.4vw, 40px) it repeated it as the largest thing on the screen.

   The whole heading goes, picture included. The thumbnail was kept for a while
   on the grounds that the bar cannot show it, but on its own — name gone, rule
   gone — it read as a stray 56px photo floating above the grid rather than as
   a label for it. The dish cards below carry their own pictures.

   The element stays in the DOM: js/motion.js builds the tab bar by reading
   .mo-cat-name out of each group, so deleting it from index.tpl would leave the
   bar with nothing to label its tabs with. display:none keeps textContent
   readable — it is layout that is switched off, not the text. */
.mo-cat-title {
  display: none;
}

/* ── The category bar: arrows instead of a scrollbar ──────────────────────
   The row scrolls, and on a mouse something has to say so. A thin scrollbar
   said it, but it said it in the browser's voice — a grey 6px track under a
   row of framed chips, present whether or not the row overflowed, and on
   Windows drawn wide enough to read as a second element. Two round handles at
   the ends say the same thing in the theme's own voice, and they are also
   clickable, which the message was really for. Same pattern as the order
   page's category bar in home-orders-3, so a restaurant running both meets one
   control, not two.

   Trackpads, touch and the arrow keys still scroll the row directly — nothing
   below removes that, it only removes the drawn bar. */
.mo-tabs-wrap {
  display: flex;
  align-items: center;
  min-width: 0;
}

/* flex-basis 0, not auto. On auto the row's basis is its content width, and a
   long category list would push the .mo-menu-tools grid column wider than its
   track instead of scrolling inside it. */
.mo-tabs {
  flex: 1 1 0;
}

/* The bar itself is unchanged; only its scrollbar goes. The bottom padding
   stays — it was never the scrollbar's, it is room for the 12px/34px shadow
   the active chip casts, which overflow-x would otherwise clip. */
.mo-tabs {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.mo-tabs::-webkit-scrollbar {
  width: 0;
  height: 0;
}

/* Collapsed to zero rather than reserved-and-faded: a menu with four
   categories has nothing to scroll to and should keep the full width for its
   chips. Collapsing cannot oscillate — an arrow only appears when the content
   is wider than the row, and taking 48px away from the row cannot make it stop
   being wider. */
.mo-tab-nav {
  position: relative;
  flex: 0 0 auto;
  width: 0;
  height: 40px;
  padding: 0;
  /* Zero, not transparent-1px: a collapsed button would still hold its two
     border pixels, and a menu whose categories all fit would pay 4px for two
     controls it never shows. */
  border: 0 solid transparent;
  border-radius: 999px;
  background: rgba(var(--mo-ink-rgb), 0.04);
  color: var(--mo-muted);
  cursor: pointer;
  opacity: 0;
  overflow: hidden;
  pointer-events: none;
  transition:
    width 240ms cubic-bezier(.2, .8, .2, 1),
    margin 240ms cubic-bezier(.2, .8, .2, 1),
    opacity 180ms ease,
    background 180ms ease,
    border-width 240ms cubic-bezier(.2, .8, .2, 1),
    border-color 180ms ease,
    color 180ms ease;
}

.mo-tab-nav.is-visible {
  width: 40px;
  opacity: 1;
  pointer-events: auto;
  border-width: 1px;
  border-color: rgba(var(--mo-ink-rgb), 0.2);
}

.mo-tab-nav--prev.is-visible { margin-right: 8px; }
.mo-tab-nav--next.is-visible { margin-left: 8px; }

.mo-tab-nav:hover,
.mo-tab-nav:focus-visible {
  background: var(--mo-accent);
  border-color: var(--mo-accent);
  color: var(--mo-on-accent);
}

/* The chevron is drawn, not set: this theme ships no icon font, and the search
   toggle builds its lens the same way. Two borders of a small square, turned
   45°, inheriting currentColor so the hover rule above recolours it.
   The X offset is not -50%: a chevron carries its weight on the closed side,
   so centring its box leaves it looking off-centre the other way. */
.mo-tab-nav::before {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  border: 2px solid currentColor;
  content: "";
}

.mo-tab-nav--prev::before {
  border-width: 2px 0 0 2px;
  transform: translate(-30%, -50%) rotate(-45deg);
}

.mo-tab-nav--next::before {
  border-width: 2px 2px 0 0;
  transform: translate(-70%, -50%) rotate(45deg);
}

/* ── The footer, tightened ────────────────────────────────────────────────
   Three short lists — address, phone/mail, and a seven-row opening board —
   were set at the body's reading line-height, 1.65, on 19px type. That figure
   is for paragraphs a reader's eye has to travel along; these are labels, read
   one glance at a time. At 19px it put 31px between "Thứ Hai" and "Thứ Ba" and
   stretched a week over nearly 280px, which is why the board read as a list of
   seven separate things rather than one opening table.

   Type size is untouched — only the air between the lines. */
.mo-footer-copy,
.mo-footer-col p,
.mo-hours-row {
  line-height: 1.35;
}

/* Paragraph margins are the UA's 1em — 19px here, and doubled where two
   paragraphs meet, since these are grid items in a block flow and margins
   still collapse. A fixed 10px reads as one block of contact details. */
.mo-footer-col p {
  margin: 0 0 10px;
}

.mo-footer-col p:last-child {
  margin-bottom: 0;
}

.mo-hours {
  gap: 4px;
}

/* Below 980px the footer columns stack and the board takes the full width. The
   rows themselves stay one line each — see the 680px block above — so this is
   only the air between seven lines, not between fourteen. 12px was set when
   they did break in two, and it left the week reading as seven separate
   things. */
@media (max-width: 980px) {
  .mo-hours {
    gap: 6px;
  }
}

/* ── The dish popup, at reading size ──────────────────────────────────────
   This dialog is where the order is actually decided: ten prices, a list of
   extras, and the allergens under them. It was set from the reference design's
   scale, which was drawn against three short options — at 13px a group heading
   and 15px a price, a menu with ten sizes of the same dish became a column of
   small grey type that has to be leaned into.

   Everything below is the same design, one notch up. The panel is 600px wide
   and none of it is close to filling that, so the room was already there. The
   checkbox is left at 18px on purpose: the row's height is set by the label,
   the box is a target rather than something to read, and its tick is drawn
   from hand-placed pixels that a resize would put out of square. */
.popup-tabs-container .category_name {
    font-size: 13px;
}

.menu_detail .menu_title {
    font-size: 26px;
}

.menu_detail .menu_price,
.popup-tab-content .menu_detail .menu_price {
    font-size: 20px;
}

.popup-tabs-container .menu_desc {
    font-size: 18px;
}

.popup-dialog .popup-tabs-nav li a,
.popup-dialog .popup-tabs-nav li.active a {
    font-size: 15px;
}

.popup-dialog .section-headline h5 {
    font-size: 15px;
}

.popup-dialog .select_max_title {
    font-size: 16px;
}

.popup-dialog .extras-item-title,
.popup-dialog .price-item-title {
    font-size: 18px;
}

.popup-dialog .extras-item-price,
.popup-dialog .item-price {
    font-size: 17px;
}

/* The allergen block under them. Kept a step below the options: it is what a
   reader checks, not what they choose from. */
h4.allegie_title {
    font-size: 15px;
}

.popup-tab-content ul li,
#Allegie_detail li {
    font-size: 16px;
}

/* ── The legend, under the menu ───────────────────────────────────────────
   Allergens on the left, additives on the right, the property icons across
   the bottom — the arrangement a printed German menu uses for the same three
   lists, and the arrangement a reader coming here from a mark on a dish
   already expects.

   It used to be a single row of letters above the first dish. That put a
   reference in front of a reader who had not yet met a single mark, and it
   cost the menu a row before it started. js/motion.js builds it; the markup
   is printed hidden and the script drops whichever of the three has nothing
   in it. */
.mo-legend {
  margin-top: 44px;
  padding-top: 26px;
  border-top: 1px solid rgba(var(--mo-ink-rgb), 0.12);
}

.mo-legend-title {
  margin: 0;
  color: var(--mo-text);
  font-family: var(--mo-serif);
  font-size: clamp(24px, 2.4vw, 32px);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* ── The fold ─────────────────────────────────────────────────────────────
   The row that opens it is the title itself, with a chevron at the far end of
   the line: on a block this wide a small control beside the heading would be a
   target the eye has to look for, and the whole heading is one it cannot miss.

   list-style on the summary and the -webkit- pseudo-element both: the default
   triangle is drawn by a different mechanism in each engine and neither one
   line removes both. */
.mo-legend-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 4px 0;
  list-style: none;
  cursor: pointer;
}

.mo-legend-summary::-webkit-details-marker {
  display: none;
}

.mo-legend-summary:focus-visible {
  outline: 2px solid var(--mo-accent);
  outline-offset: 6px;
}

/* Two borders of a square, turned. It points down while the block is closed
   and up once it is open, and it turns rather than being swapped so the state
   change is legible as a movement. */
.mo-legend-chevron {
  flex: 0 0 auto;
  width: 11px;
  height: 11px;
  margin-right: 6px;
  border-right: 2px solid var(--mo-accent);
  border-bottom: 2px solid var(--mo-accent);
  transform: translateY(-3px) rotate(45deg);
  transition: transform 260ms ease;
}

.mo-legend-fold[open] .mo-legend-chevron {
  transform: translateY(2px) rotate(-135deg);
}

/* The 30px the title used to carry as a margin, moved onto the part that is
   only there when the block is open — a closed fold is the heading row and
   nothing else. */
.mo-legend-body {
  padding-top: 30px;
}

.mo-legend-fold[open] .mo-legend-body {
  animation: moLegendOpen 300ms ease both;
}

@keyframes moLegendOpen {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Two columns where there is room and one where there is not. auto-fit with a
   340px floor rather than a media query: the two lists are very different
   lengths — thirteen allergens against three additives is normal — and the
   breakpoint that suits one restaurant's pair suits nobody else's. */
.mo-legend-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 28px 48px;
  align-items: start;
}

.mo-legend-col h4 {
  margin: 0 0 14px;
  color: var(--mo-accent);
  font-family: var(--mo-sans);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.mo-legend-col ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* One line per entry, and the name allowed to wrap under itself rather than
   under its own code: "Weichtiere (Schnecken, Muscheln Kalamare, Austern)" is
   a real allergen name and it does not fit on one line at this width. */
.mo-legend-col li {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: 10px;
  align-items: start;
  padding: 5px 0;
  color: var(--mo-muted);
  font-size: 16px;
  line-height: 1.45;
}

/* The ring at the size of the type beside it. On a card the mark has to be
   findable at a glance among the dish names; here it is only the swatch in
   front of its own label. The tooltip and the hover lift .mo-allergen carries
   on a card are switched off — the name is already written next to it. */
.mo-legend-col .mo-allergen {
  cursor: default;
  min-width: 26px;
  height: 26px;
  padding: 0 5px;
  font-size: 15px;
}

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

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

.mo-legend-props {
  margin-top: 30px;
  padding-top: 22px;
  border-top: 1px solid rgba(var(--mo-ink-rgb), 0.08);
}

.mo-legend-props h4 {
  margin: 0 0 14px;
  color: var(--mo-accent);
  font-family: var(--mo-sans);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.mo-legend-props-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 28px;
}

.mo-legend-prop {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--mo-muted);
  font-size: 16px;
  white-space: nowrap;
}

/* The property icons are single-colour artwork with no fill of their own — on
   the cards css/motion.css gives it to the inline <svg> that js/svg.js swaps
   in. Here they stay <img>, which cannot be filled from CSS, so the colour is
   put on with a filter instead. brightness(0) flattens whatever the file
   carries to black and invert(1) lifts it to white; the rest tints that toward
   the muted text colour the label beside it uses. */
.mo-legend-prop img {
  width: 22px;
  height: 22px;
  object-fit: contain;
  filter: brightness(0) invert(1) opacity(0.72);
}

html[data-mo-theme="light"] .mo-legend-prop img {
  filter: brightness(0) opacity(0.66);
}

@media (max-width: 680px) {
  .mo-legend {
    margin-top: 32px;
    padding-top: 20px;
  }

  .mo-legend-cols {
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
  }

  .mo-legend-col li {
    font-size: 15px;
  }
}

/* ── The footer's contact column ──────────────────────────────────────────
   One list, one gap. It used to be <p>{ADDRESS}</p> followed by a <p> holding
   the phone and the mail with a <br> between them, and the two gaps that made
   were never going to match: one was a paragraph margin and the other a line
   box. Measured before the change, 26px against 21px on a column three lines
   tall — small enough to look like a mistake rather than a rhythm.

   The icons are 24x24 Material glyphs authored for this theme, because the
   platform's own set has a phone but no pin and no envelope. */
.mo-contact-list {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A fixed first column rather than an inline mark: the address wraps to two or
   three lines and its second line has to start under the first, not under the
   icon. */
.mo-contact-list li {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  gap: 10px;
  align-items: start;
  color: var(--mo-muted);
  font-size: 19px;
  line-height: 1.35;
}

/* Both shapes, because js/svg.js replaces the <img> with an inline <svg> after
   load and the <img> is what is on screen until it does. The <svg> takes the
   row's own colour through fill; an <img> cannot be filled, so it is tinted —
   brightness(0) flattens it to black and invert lifts it to white for the dark
   setting. The nudge down is optical: a 16px glyph centred in its own box sits
   above the x-height of the 19px line beside it. */
.mo-contact-list .mo-contact-icon,
.mo-contact-list svg.mo-contact-icon {
  width: 16px;
  height: 16px;
  margin-top: 4px;
  fill: currentColor;
  opacity: 0.75;
}

.mo-contact-list img.mo-contact-icon {
  filter: brightness(0) invert(1) opacity(0.62);
}

html[data-mo-theme="light"] .mo-contact-list img.mo-contact-icon {
  filter: brightness(0) opacity(0.55);
}

.mo-contact-list a {
  color: inherit;
  text-decoration: none;
  transition: color 200ms ease;
}

.mo-contact-list a:hover,
.mo-contact-list a:focus-visible {
  color: var(--mo-text);
}
/* ── "Online Bestellen" and "Adresse", at card size ───────────────────────
   These two are headings INSIDE cards, not headings over a section, and they
   were taking .mo-site-shell h2 — clamp(34px, 5vw, 62px), the size that sets
   "Speisekarte" and "Galerie" over the whole page. Measured on this page they
   came out at 50.65px each, side by side in a two-column grid, so a card title
   was shouting as loudly as the section titles it sits under.

   The section titles keep their size; only the two card titles come down. */
.mo-order-card h2,
.mo-address-card h2 {
  font-size: clamp(26px, 2.8vw, 36px);
  line-height: 1.05;
}

/* The address under it comes down with them. 24px was body copy set larger
   than the body — it is one line of reference text beside a map, and the map
   is what the eye is going to. */
.mo-address-line {
  font-size: 19px;
  line-height: 1.5;
}

/* ── The hero's three info columns, at 18px ───────────────────────────────
   Asked for on .mo-hero-info, which is the LABEL — Öffnungszeiten, Adresse,
   Bestellen. The value under it goes with it: at 15/16 the two were nearly the
   same size already, and lifting only the label would have left every column
   with its heading set larger than the thing it heads.

   The label keeps its uppercase and its accent colour, so it still reads as a
   label and not as a second value. */
.mo-hero-info {
  font-size: 18px;
}

.mo-hero-info p {
  font-size: 18px;
}

/* ── The legend as running text, not a table ──────────────────────────────
   Twenty-nine entries in two columns, one to a line, made a block as tall as
   the menu above it — a reader looking up a single letter had to scan a
   fourteen-row column to find it, and everyone else scrolled past a screenful
   of list.

   Set as prose instead: each group is one full-width paragraph, the entries
   separated by commas, the codes picked out in the accent so a letter can
   still be found at a glance. The two groups stack rather than sitting side by
   side — a paragraph that wraps wants the width, and a 340px column would put
   three words on a line.

   Same treatment the saigon theme's legend gets, so a restaurant running both
   reads one thing twice rather than two things. */
.mo-legend-cols {
  grid-template-columns: minmax(0, 1fr);
  gap: 26px;
}

.mo-legend-col ul {
  color: var(--mo-muted);
  font-size: 16px;
  line-height: 1.75;
}

/* display: inline, so the entries flow into one another and wrap as text does.
   The grid each row used to be goes with it — a grid item cannot be part of a
   line. */
.mo-legend-col li {
  display: inline;
  padding: 0;
  font-size: inherit;
  line-height: inherit;
}

/* The separator is drawn rather than typed: a comma in the markup would be a
   comma after the last entry too, and the loop that prints these has no idea
   which one that is. */
.mo-legend-col li:not(:last-child)::after {
  content: ", ";
}

/* The ring is gone. It is the right shape where a code has to be picked out of
   a running line — on a dish card, among the name and the price — but in a
   list of twenty-nine the boxes became the thing the eye counted and the words
   became what sat next to them. A code and a full stop, in the accent.

   The space belongs to the full stop, not to the markup: index.tpl prints
   <span>A</span>Glutenhaltig with nothing between them. */
.mo-legend-col .mo-allergen {
  display: inline;
  min-width: 0;
  height: auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--mo-accent-ink);
  font-size: inherit;
  font-weight: 600;
  white-space: nowrap;
}

/* The base .mo-allergen::after is the hover tooltip: absolute, opacity 0, its
   own plate and border, content: attr(data-label). Setting content alone left
   the full stop absolutely positioned and invisible — every one of those
   declarations has to be undone before this pseudo can be a full stop. */
.mo-legend-col .mo-allergen::after {
  /* display too: an earlier rule in this file switched this pseudo off
     outright when the legend was a table of rings, and display: none survives
     everything else set here. */
  display: inline;
  position: static;
  width: auto;
  max-width: none;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  color: inherit;
  content: ". ";
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  opacity: 1;
  transform: none;
  transition: none;
}

@media (max-width: 680px) {
  .mo-legend-col ul {
    font-size: 15px;
  }
}

/* Customer account menu in the desktop header and mobile navigation. */
.mo-login { color: var(--mo-text); }
.mo-account { position: relative; color: var(--mo-text); }
.mo-account summary { cursor: pointer; padding: 6px 0; }
.mo-account__links {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 70;
    min-width: 210px;
    max-width: calc(100vw - 48px);
    padding: 12px;
    background: var(--mo-surface);
    border: 1px solid var(--mo-line);
    border-radius: 4px;
    text-align: left;
}
.mo-account__links a { display: block; padding: 10px 12px; white-space: normal; }
@media (max-width: 980px) {
    .mo-account__links { position: static; margin-top: 8px; }
}
.popup-dialog .popup-tab-content-login .form-title { padding: 8px 28px 24px; }
.popup-dialog .popup-tab-content-login .form-title h2 { margin: 0; line-height: 1.3; overflow-wrap: anywhere; }
.popup-dialog .mfp-close,
.popup-dialog .mfp-close:hover,
.popup-dialog .mfp-close:focus { color: #fff; opacity: 1; }
