.mb-page {
  min-height: 75vh;
}
.mb-login {
  min-height: 70vh;
  display: grid;
  place-items: center;
  padding: 3rem 1.25rem;
  background: linear-gradient(135deg, var(--cream), var(--yellow-soft));
}
.mb-login-card {
  width: min(620px, 100%);
  background: #fff;
  border: 2px solid var(--navy);
  padding: clamp(1.5rem, 5vw, 3rem);
  box-shadow: var(--shadow-pop);
}
.mb-login-card label,
.mb-field {
  display: grid;
  gap: 0.35rem;
  font-weight: 600;
  margin: 0.9rem 0;
}
.mb-login-card input,
.mb-field input,
.mb-field select,
.mb-field textarea,
.mb-search-input {
  width: 100%;
  font: inherit;
  padding: 0.72rem 0.8rem;
  border: 1.5px solid #aeb8b5;
  background: #fff;
  color: var(--ink);
}
.mb-login-card input:focus,
.mb-field input:focus,
.mb-field select:focus,
.mb-field textarea:focus,
.mb-search-input:focus {
  outline: 3px solid rgba(184, 154, 90, 0.35);
  border-color: var(--navy);
}
.mb-error {
  color: #9b2c20;
  font-weight: 700;
  margin-top: 1rem;
}
.mb-topbar {
  max-width: 1400px;
  margin: auto;
  padding: 2rem 1.25rem 1rem;
  display: flex;
  justify-content: space-between;
  gap: 2rem;
  align-items: end;
}
.mb-topbar h1 {
  font-size: clamp(2rem, 4vw, 3.2rem);
  margin-bottom: 0.3rem;
}
.mb-sub {
  color: var(--muted);
  max-width: 760px;
  font-size: 1.2rem;
}
.mb-venue-box {
  min-width: 280px;
  background: #fff;
  border: 1px solid var(--rule);
  padding: 1rem;
}
.mb-venue-box label {
  display: grid;
  gap: 0.35rem;
  font-weight: 700;
}
.mb-venue-box select {
  font: inherit;
  padding: 0.65rem;
  width: 100%;
}
.mb-text-btn {
  border: 0;
  background: transparent;
  color: var(--navy);
  text-decoration: underline;
  cursor: pointer;
  font-size: 1.05rem;
  font-weight: 600;
  margin-top: 0.6rem;
}
.mb-ip-note,
.mb-warning {
  max-width: 1400px;
  margin: 0 auto 1rem;
  padding: 0.8rem 1.25rem;
  border-left: 5px solid var(--yellow);
  background: #fff;
}
.mb-warning {
  border-left-color: #b54733;
  background: #fff3ef;
}
.mb-tabs {
  max-width: 1400px;
  margin: 1.2rem auto 0;
  padding: 0 1.25rem;
  display: flex;
  gap: 0.5rem;
  overflow: auto;
}
.mb-tabs button {
  border: 1px solid var(--navy);
  background: #fff;
  color: var(--navy);
  font: 600 1rem var(--font-head);
  padding: 0.85rem 1.2rem;
  white-space: nowrap;
  cursor: pointer;
}
.mb-tabs button.active {
  background: var(--navy);
  color: #fff;
}
.mb-tabs span {
  /* 2026-09-20 Phase 13: Lee circled the whole tab row and called it
     "superfluous" -- reading this against his own standing rule from
     earlier today ("we do not disclose actual figures on buttons and
     general descriptions if not really necessary"): these were exact
     counts (14, 32, 2, 8, 11) sitting on every tab. Hidden rather than
     removed from the HTML/JS -- the JS still writes a number into each
     span every render (recipeCount, ingredientCount, etc.), and removing
     the elements outright would make those unconditional `.textContent =`
     assignments throw. Hiding them here has the same visible effect with
     none of that risk. If this isn't what "superfluous" meant, easy to
     revert -- just say so.
     Was: inline-grid pill badge, min-width 1.6rem, height 1.6rem,
     margin-left 0.35rem, border-radius 50%, background var(--yellow-soft),
     color var(--navy). */
  display: none;
}
.mb-panel {
  display: none;
  max-width: 1400px;
  margin: auto;
  padding: 1.5rem 1.25rem 7rem;
}
.mb-panel.active {
  display: block;
}
.mb-panel-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 1rem;
  padding: 1rem 1.2rem;
  background: var(--yellow-soft);
  border: 1px solid var(--line-navy);
  border-left: 4px solid var(--navy);
}
.mb-panel-head p {
  color: var(--ink);
  font-size: 1.2rem;
}
#panel-recipes .mb-panel-head .btn {
  font-size: 1.05rem;
  padding: 1rem 1.6rem;
}
.mb-card-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
  gap: 1rem;
  align-items: start;
}
.mb-card-list > details[open] {
  grid-column: 1 / -1;
}
.mb-empty {
  padding: 2rem;
  background: #fff;
  border: 1px dashed #9eaaa7;
  text-align: center;
  color: var(--muted);
}
.mb-card {
  background: #fff;
  border: 1.5px solid var(--navy);
  box-shadow: 4px 4px 0 rgba(18, 63, 59, 0.22);
}
.mb-card summary {
  list-style: none;
  cursor: pointer;
  padding: 1rem 1.2rem;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: center;
}
.mb-card summary::-webkit-details-marker {
  display: none;
}
.mb-card summary b {
  font: 600 1.2rem var(--font-head);
  color: var(--navy);
}
.mb-card summary small {
  color: var(--ink);
  font-size: 1.05rem;
  line-height: 1.5;
}
.mb-recipe-edit-note {
  margin-bottom: 1rem;
  padding: 0.8rem 1rem;
  border-left: 4px solid var(--yellow);
  background: var(--yellow-soft);
}
.mb-recipe-scaler {
  display: grid;
  grid-template-columns: minmax(260px, 1fr) 220px auto;
  gap: 0.8rem;
  align-items: end;
  margin-bottom: 1rem;
  padding: 1rem;
  border: 2px solid var(--navy);
  background: #eef5f2;
}
.mb-recipe-scaler small,
.mb-recipe-scaler label {
  display: block;
}
.mb-recipe-scaler small {
  font-size: 1.15rem;
  color: var(--ink);
}
.mb-recipe-scaler input {
  width: 100%;
  margin-top: 0.3rem;
  padding: 0.55rem;
  font: inherit;
}
.mb-card-body {
  border-top: 1px solid var(--rule);
  padding: 1.2rem;
}
.mb-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(150px, 1fr));
  gap: 0.8rem;
}
.mb-span-2 {
  grid-column: span 2;
}
.mb-span-4 {
  grid-column: 1/-1;
}
.mb-field {
  margin: 0;
}
.mb-field small {
  font-weight: 400;
  color: var(--muted);
}
/* 2026-09-24: Lee's cost/price simplification. "Priced per" (was labelled
   "Cost basis") and "Per" (the menu item's selling_unit, always "portion" in
   live data) are still real, editable fields -- nothing here hides them or
   the 7 ingredients whose purchase unit genuinely differs from their buy
   unit would lose the only way to see/fix that. This just demotes them
   visually so "Buy unit" + "Buy cost" / "Menu price" read as the two obvious
   numbers, not three competing ones. */
.mb-field-minor {
  font-weight: 400;
  font-size: 0.85em;
}
.mb-field-minor > span {
  color: var(--muted);
}
/* 2026-09-24: buy-cost reprice "machine" dialog (Lee's spec). Same
   .mb-guide-dialog shell as the other Menu Builder dialogs, sized like the
   supplier directory one since a dish list can run long. */
.mb-reprice-dialog {
  width: min(760px, calc(100vw - 2rem));
  max-width: 760px;
}
.mb-reprice-dialog form {
  max-height: 88vh;
  overflow-y: auto;
  overflow-x: hidden;
}
.mb-reprice-toolbar {
  display: flex;
  justify-content: flex-end;
  margin: 0.5rem 0 1rem;
}
.mb-reprice-rows {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.mb-reprice-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  border: 1px solid var(--rule);
  padding: 0.7rem 0.9rem;
  flex-wrap: wrap;
}
.mb-reprice-row-info small {
  color: var(--muted);
}
.mb-reprice-row-action {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.mb-reprice-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 1rem;
}
.mb-card-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
  margin-top: 1rem;
}
/* 2026-09-19 Phase 7: Lee said this was still "a medium button and
   explanatory text almost hidden in the corner" after Phase 5 -- and that
   the Save button had lost the yellow colour he asked for (it was switched
   to navy in Phase 5 by mistake). Fixed both: button restored to the
   site's plain yellow .btn (class changed in menu-builder.js), made
   substantially larger, and the hint text made large/bold enough to read
   as real explanatory copy rather than a caption. */
.mb-dish-actions {
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 1.2rem;
  margin-top: 1.5rem;
  padding-top: 1.2rem;
  border-top: 2px solid var(--rule);
}
.mb-dish-actions-hint {
  color: var(--ink);
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.5;
  flex: 1 1 320px;
  max-width: 52ch;
}
.mb-dish-actions-buttons {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex-wrap: wrap;
}
.mb-dish-actions-buttons [data-save-this-dish] {
  font-size: 1.4rem;
  font-weight: 700;
  padding: 1.25rem 2.4rem;
}
/* 2026-09-19 Phase 11 (revised): Lee -- "make the save this dish button
   flash dont forget to save." First version was a soft box-shadow glow only
   -- checked live and it was too subtle to read as a "flash" at a glance.
   Replaced with an actual colour pulse (fill colour alternates, not just a
   shadow) plus the glow, on a quicker cycle, so it reads unmistakably as
   flashing. Still restrained to the page's own yellow/gold tones -- no new
   colour introduced, just its own colour pulsing brighter and back. Still
   not conditioned on unsaved changes -- flashes all the time, as asked. */
@keyframes mbSaveFlash {
  0%,
  100% {
    background: var(--yellow);
    box-shadow: 0 0 0 0 rgba(184, 154, 90, 0.65);
  }
  50% {
    background: #e8cb84;
    box-shadow: 0 0 0 10px rgba(184, 154, 90, 0);
  }
}
.mb-dish-actions-buttons [data-save-this-dish] {
  animation: mbSaveFlash 1.1s ease-in-out infinite;
}
/* 2026-09-19 Phase 13 (added, then reverted same session): briefly gave the
   smaller "Save dishes" panel button the same flash, on the theory Lee might
   mean either button. Lee confirmed no -- two buttons flashing at once made
   no sense to him, he only ever wanted the one. Back to flashing only
   "Save this dish -- it's yours". */
@media (prefers-reduced-motion: reduce) {
  .mb-dish-actions-buttons [data-save-this-dish] {
    animation: none;
  }
}
/* 2026-09-19 Phase 11: "make it yours" mode for a dish still being built
   from a dish-library idea (menu-builder.js flags this via the existing
   "Started from a Draft dish idea..." note text -- no new field added).
   Lee: "same size fonts design etc for the dishes that exist as the one
   your building" -- this gives the in-progress dish name its own, much
   louder treatment, adds a short explanatory banner, and gives the fields
   still being filled in a warm tint, using only the page's existing
   yellow/navy tokens. */
.mb-make-it-yours {
  margin-bottom: 1rem;
  padding: 1rem 1.2rem;
  border: 2px solid var(--yellow);
  border-radius: 6px;
  background: var(--yellow-soft);
  color: var(--navy-ink);
  font-size: 1.15rem;
  line-height: 1.5;
}
.mb-make-it-yours b {
  color: var(--navy);
}
.mb-card--from-idea .mb-grid input[data-key="recipe_name"] {
  padding: 0.7rem 0.9rem;
  border: 2px solid var(--yellow);
  background: var(--yellow-soft);
  font-size: 1.6rem;
  font-weight: 800;
  color: var(--navy);
}
.mb-card--from-idea .mb-field > span,
.mb-card--from-idea .mb-line > label {
  font-weight: 700;
  color: var(--navy);
}
.mb-card--from-idea .mb-grid input,
.mb-card--from-idea .mb-grid select,
.mb-card--from-idea .mb-line input,
.mb-card--from-idea .mb-line select {
  border-color: var(--yellow);
  background: var(--yellow-soft);
}
.mb-primary-name {
  display: block;
  margin: 0 0 1rem;
  padding: 0.9rem;
  border: 2px solid var(--yellow);
  background: var(--yellow-soft);
  font-weight: 700;
}
.mb-primary-name input {
  margin-top: 0.35rem;
  background: #fff;
}
.mb-danger {
  border: 1px solid #a73b2d;
  background: #fff;
  color: #8b2c21;
  padding: 0.65rem 1rem;
  cursor: pointer;
  font-size: 1.05rem;
}
.mb-secondary {
  border: 1px solid var(--navy);
  background: #fff;
  color: var(--navy);
  padding: 0.65rem 1rem;
  cursor: pointer;
  font-size: 1.05rem;
  font-weight: 700;
}
.mb-lines {
  margin-top: 1rem;
  border-top: 1px solid var(--rule);
  padding-top: 1rem;
}
.mb-lines-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
/* 2026-09-20 Phase 13: 9 grid items sit in this row (Dish component,
   ingredient search block, Quantity, the "Per portion" info cell JS inserts
   right after it, Unit, Cost basis, Cost per basis, the cost total, and the
   remove button) but only 8 column tracks were ever defined here -- the 9th
   was silently falling into an implicit auto-wrapped row. Added the missing
   track, and narrowed the ingredient column now that it shows just a name
   and a "Change ingredient" link by default instead of an always-open
   search box, so the whole line reads as one row rather than sprawling. */
.mb-line {
  display: grid;
  /* 2026-09-25: first column had no minimum, so "Main component" was cut to "Main comp". */
  grid-template-columns: minmax(10.5rem, 0.9fr) minmax(10rem, 1.5fr) repeat(4, minmax(4.5rem, 0.6fr)) minmax(5.5rem, 0.7fr) minmax(4.5rem, 0.6fr) auto;
  gap: 0.55rem;
  align-items: end;
  padding: 0.8rem 0;
  border-bottom: 1px solid #e6e9e7;
}
.mb-line label {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink);
}
.mb-line input,
.mb-line select {
  width: 100%;
  font: inherit;
  padding: 0.55rem;
  border: 1px solid #b8c0bd;
}
/* 2026-09-19 Phase 8: soft colour accent per dish-component tag, so a row
   of ingredients can be scanned at a glance (Sauce vs Starch vs Garnish
   etc.) without reading every label. "Main component" -- the default and
   most common value -- is left uncoloured on purpose so the accent only
   appears once a line is doing something other than the default. Kept to
   the .mb-line row's own select; nothing outside the Menu Builder is
   touched. row.dataset.component is set and kept in sync in
   menu-builder.js (renderLines). */
.mb-line[data-component] select[data-lkey="component_group"] {
  border-left-width: 6px;
  border-left-style: solid;
}
.mb-line[data-component="Sauce or dressing"] select[data-lkey="component_group"] {
  border-left-color: #b5563a;
  background: #faece7;
}
.mb-line[data-component="Starch/accompaniment"] select[data-lkey="component_group"] {
  border-left-color: #b89a5a;
  background: #f7f1e2;
}
.mb-line[data-component="Vegetable/salad"] select[data-lkey="component_group"] {
  border-left-color: #6f9d74;
  background: #eaf1e9;
}
.mb-line[data-component="Garnish"] select[data-lkey="component_group"] {
  border-left-color: #c97b8a;
  background: #f8ecee;
}
.mb-line[data-component="Side"] select[data-lkey="component_group"] {
  border-left-color: #5b7f95;
  background: #e9eef2;
}
.mb-line[data-component="Bread/service item"] select[data-lkey="component_group"] {
  border-left-color: #8a6a4a;
  background: #f2ece2;
}
.mb-line[data-component="Optional extra"] select[data-lkey="component_group"] {
  border-left-color: #8b6ba1;
  background: #f0eaf5;
}
.mb-line[data-component="Customer substitution"] select[data-lkey="component_group"] {
  border-left-color: #4f8f87;
  background: #e7f2f0;
}
.mb-line[data-component="Reusable sub-recipe"] select[data-lkey="component_group"] {
  border-left-color: #4a6670;
  background: #eaeff0;
}
.mb-line-cost {
  padding: 0.55rem 0.2rem;
  font-weight: 700;
}
.mb-line-portion {
  padding: 0.45rem 0.2rem;
}
.mb-line-portion small,
.mb-line-portion b {
  display: block;
}
.mb-line-portion small {
  font-size: 1rem;
  color: var(--ink);
}
/* 2026-09-19 Phase 7: gave the old "Current ingredient" caption a visible
   border/enlarged text per Lee's request that day. 2026-09-20 Phase 13:
   Lee asked for the "CURRENT INGREDIENT" wording removed from every line
   entirely, as part of making each ingredient one compact line rather than
   a sprawling block -- so that caption is gone, replaced below by
   .mb-line-ingredient-head (just the name, plus a "Change ingredient"
   toggle for the search/tree controls, collapsed by default). */
.mb-line-ingredient-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.mb-line-ingredient-name {
  font-size: 1.15rem;
  color: var(--navy);
}
.mb-line-ingredient-head .mb-text-btn {
  margin: 0;
  font-size: 0.95rem;
  white-space: nowrap;
}
.mb-search-controls {
  margin-top: 0.5rem;
  padding: 0.6rem;
  background: #fbfaf6;
  border: 1px solid #d8ddda;
}
.mb-search {
  position: relative;
}
.mb-ingredient-id {
  display: block;
  margin-top: 0.4rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
}
.mb-search-results {
  position: absolute;
  z-index: 20;
  left: 0;
  right: 0;
  top: 100%;
  max-height: 320px;
  overflow: auto;
  background: #fff;
  border: 1px solid var(--navy);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}
.mb-search-results button {
  width: 100%;
  text-align: left;
  background: #fff;
  border: 0;
  border-bottom: 1px solid var(--rule);
  padding: 0.7rem;
  cursor: pointer;
}
.mb-search-results button:hover {
  background: var(--yellow-soft);
}
.mb-search-results small {
  display: block;
  color: var(--ink);
  font-size: 1rem;
}
/* Each result is now a row: the main select button plus a small ⓘ preview toggle.
   Without this, the ⓘ button would inherit the full-width/left-aligned styling meant
   for the select button above. */
.mb-search-result {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--rule);
}
.mb-search-result .mb-result-select {
  flex: 1;
  border-bottom: 0;
}
.mb-result-info {
  flex: none;
  width: 2.2rem;
  border: 0;
  border-left: 1px solid var(--rule);
  border-bottom: 0;
  background: #fff;
  cursor: pointer;
  font-size: 1.1rem;
  padding: 0;
}
.mb-result-info:hover {
  background: var(--yellow-soft);
}
.mb-result-preview {
  padding: 0.65rem 0.8rem;
  background: var(--yellow-soft);
  border-bottom: 1px solid var(--rule);
  font-size: 1.05rem;
  line-height: 1.5;
  color: var(--ink);
}
.mb-metrics {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.6rem;
  margin-top: 1rem;
}
.mb-metric {
  background: var(--yellow-soft);
  padding: 0.8rem;
}
.mb-metric b {
  display: block;
  color: var(--navy);
  font-size: 1.15rem;
}
.mb-savebar {
  /* 2026-09-25: was position: fixed (covered the footer for good). Sticky
     keeps it at the bottom of the screen while you work in the builder,
     then lets it stop above the footer. */
  position: sticky;
  bottom: 0;
  z-index: 90;
  margin-top: 1.5rem;
  background: rgba(252, 252, 249, 0.97);
  border-top: 1px solid var(--rule);
  padding: 0.6rem 1.25rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  font-size: 1rem;
}
.mb-savebar span {
  font-weight: 600;
}
.mb-savebar .btn {
  padding: 0.65rem 1.1rem;
}
.mb-pill {
  display: inline-block;
  padding: 0.3rem 0.7rem;
  background: var(--yellow-soft);
  border: 1px solid var(--yellow);
  font-size: 1rem;
  font-weight: 700;
}
/* 2026-09-19 Phase 8: functional colour, Menu Builder only, requested by
   Lee as "a little colour... not a sweet shop." These four modifiers key
   off status words already shown in a .mb-pill (Active/Draft/Archived/
   Unsaved on ingredient and menu cards, Yes/No/Pending/Not applicable on
   allergen confirmations) via lifecyclePillClass()/allergenResponsePillClass()
   in menu-builder.js. Pills with no modifier (dish cost, selling price,
   row counts) are untouched and stay the original yellow. */
.mb-pill-good {
  background: #e3efe4;
  border-color: #6f9d74;
  color: #2f5233;
}
.mb-pill-caution {
  background: var(--yellow-soft);
  border-color: var(--yellow);
  color: var(--navy-ink);
}
.mb-pill-alert {
  background: #f7e6df;
  border-color: #c1694a;
  color: #8a3c22;
}
.mb-pill-neutral {
  background: #eceeec;
  border-color: var(--muted);
  color: var(--muted);
}
.mb-blocked {
  color: #9b2c20;
  font-weight: 700;
}
/* BUGFIX 2026-09-24: was `display:grid; grid-template-columns: minmax(0,1fr)
   auto;`. The ingredient column on .mb-line only floors at 190px
   (minmax(190px, 1.5fr)), and the "Browse Dictionary tree" button's own
   width doesn't shrink -- so at that floor the search input's minmax(0, ...)
   let it get squeezed down to almost nothing, making it unusable. Switched
   to flex-wrap: the input keeps a guaranteed floor of 160px, and if there
   truly isn't room for both, the button wraps to its own line underneath
   instead of the input collapsing. Doesn't touch .mb-line's own column
   sizing. */
.mb-search-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.mb-search-row .mb-search-input {
  flex: 1 1 160px;
}
.mb-search-row .mb-tree-toggle {
  flex: 0 0 auto;
}
.mb-tree-toggle {
  border: 1px solid var(--navy);
  background: var(--navy);
  color: #fff;
  padding: 0.55rem 0.8rem;
  cursor: pointer;
  font-size: 1.05rem;
  font-weight: 700;
}
.mb-tree {
  position: absolute;
  z-index: 21;
  left: 0;
  right: 0;
  top: 100%;
  display: grid;
  gap: 0.45rem;
  padding: 0.7rem;
  background: #fff;
  border: 1px solid var(--navy);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}
.mb-tree[hidden] {
  display: none;
}
.mb-tree select {
  width: 100%;
  font: inherit;
  padding: 0.55rem;
  border: 1px solid #b8c0bd;
  background: #fff;
}
.mb-suite-nav {
  max-width: 1400px;
  margin: 1rem auto 0;
  padding: 0 1.25rem;
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.mb-suite-nav a {
  padding: 0.8rem 1rem;
  border: 1px solid var(--navy);
  background: #fff;
  color: var(--navy);
  font-weight: 700;
  text-decoration: none;
}
.mb-suite-nav a.active {
  background: var(--navy);
  color: #fff;
}
.mb-section-row {
  display: grid;
  grid-template-columns: minmax(220px, 1fr) auto auto auto;
  gap: 0.5rem;
  margin: 0.55rem 0;
}
.mb-section-row input {
  font: inherit;
  padding: 0.55rem;
  border: 1px solid #b8c0bd;
}
.mb-help {
  margin: 0.35rem 0 0.75rem;
  color: #52605c;
  font-size: 1.2rem;
}
.mb-guide-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  max-width: 1400px;
  margin: 1rem auto;
  padding: 0.9rem 1.1rem;
  background: #eef5f1;
  border-left: 4px solid var(--gold);
  font-size: 1.2rem;
}
.mb-guide-bar span {
  margin-left: 0.35rem;
}
.mb-guide-actions {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  flex-wrap: wrap;
}
#openMenuGuide {
  font-size: 1.05rem;
  padding: 0.9rem 1.4rem;
}
.mb-guide-dialog {
  width: min(760px, calc(100vw - 2rem));
  max-width: 760px;
  border: 2px solid var(--navy);
  padding: 0;
  box-shadow: 8px 8px 0 rgba(7, 55, 54, 0.25);
}
.mb-guide-dialog::backdrop {
  background: rgba(7, 30, 30, 0.62);
}
.mb-guide-dialog form {
  padding: 2rem;
  position: relative;
  box-sizing: border-box;
  max-width: 100%;
  overflow-x: hidden;
}
.mb-guide-dialog .mb-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.mb-guide-dialog input,
.mb-guide-dialog select {
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
}
.mb-guide-dialog li {
  margin: 0.85rem 0;
  line-height: 1.5;
}
.mb-guide-close {
  position: absolute;
  right: 0.8rem;
  top: 0.6rem;
  border: 0;
  background: transparent;
  font-size: 2rem;
  cursor: pointer;
}
/* 2026-09-20 Phase 13: Lee -- "a large popuped acknowledgement" after
   clicking the flashing "Save this dish" button. Reuses the existing
   .mb-guide-dialog <dialog> pattern (so the global open/close/backdrop
   wiring already in menu-builder.js just works), sized and centred larger
   than the instruction dialogs since this one is meant to be seen, not
   read line by line. */
.mb-dish-saved-dialog {
  width: min(560px, calc(100vw - 2rem));
  max-width: 560px;
}
.mb-dish-saved-dialog form {
  text-align: center;
  padding: 2.5rem 2rem 2rem;
}
.mb-dish-saved-tick {
  width: 4.5rem;
  height: 4.5rem;
  margin: 0 auto 1rem;
  border-radius: 50%;
  background: var(--yellow, #f4c542);
  color: var(--navy);
  font-size: 2.4rem;
  font-weight: 700;
  display: grid;
  place-items: center;
}
.mb-dish-saved-dialog h2 {
  font-size: 1.7rem;
  margin: 0 0 0.6rem;
}
.mb-dish-saved-dialog p {
  font-size: 1.2rem;
  line-height: 1.5;
  margin: 0 0 1.5rem;
}
.mb-dish-saved-actions {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  align-items: stretch;
}
.mb-dish-saved-actions .btn {
  width: 100%;
}
/* 2026-09-23: hard-block alert dialog (pending allergens on an Active dish;
   "confirmed" supplier product with no evidence). Same .mb-guide-dialog
   shell as the dish-saved popup, but red instead of the yellow "well done"
   styling -- reuses the .mb-danger red tokens already used elsewhere for
   destructive/warning actions, so the colour means the same thing app-wide. */
.mb-alert-dialog {
  width: min(560px, calc(100vw - 2rem));
  max-width: 560px;
  border-color: #a73b2d;
}
.mb-alert-dialog::backdrop {
  background: rgba(60, 10, 5, 0.55);
}
.mb-alert-dialog form {
  text-align: center;
  padding: 2.5rem 2rem 2rem;
}
.mb-alert-icon {
  width: 4.5rem;
  height: 4.5rem;
  margin: 0 auto 1rem;
  border-radius: 50%;
  background: #a73b2d;
  color: #fff;
  font-size: 2.4rem;
  font-weight: 700;
  display: grid;
  place-items: center;
}
.mb-alert-dialog h2 {
  font-size: 1.5rem;
  margin: 0 0 0.6rem;
  color: #8b2c21;
}
.mb-alert-body {
  font-size: 1.05rem;
  line-height: 1.5;
  margin: 0 0 1.5rem;
  text-align: left;
}
.mb-alert-body p {
  margin: 0 0 0.7rem;
}
.mb-help-tip {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  margin-left: 0.4rem;
  padding: 0;
  border: 1px solid var(--navy);
  border-radius: 50%;
  background: var(--navy);
  color: #fff;
  font: 700 0.95rem/1 sans-serif;
  cursor: help;
}
.mb-help-tip::after {
  content: attr(data-help);
  position: absolute;
  z-index: 50;
  left: 50%;
  bottom: calc(100% + 0.55rem);
  width: 300px;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--navy-deep);
  background: var(--navy);
  color: #fff;
  font:
    600 1.05rem/1.5 "DM Sans",
    sans-serif;
  box-shadow: 4px 4px 0 rgba(184, 154, 90, 0.95);
  opacity: 0;
  visibility: hidden;
  transform: translateX(-50%);
  pointer-events: none;
}
.mb-help-tip:hover::after,
.mb-help-tip:focus::after {
  opacity: 1;
  visibility: visible;
}
.mb-field > span {
  display: flex;
  align-items: center;
}
.mb-step-next {
  display: flex;
  justify-content: flex-end;
  margin: 1.25rem 0;
}
/* Only these three redundant/internal fields stay permanently hidden now.
   owner, service_context, notes and dish_cost_override used to be hidden
   here too, toggled visible by a "Show advanced fields" button -- but that
   button was removed (it did nothing on the Ingredients panel) and nothing
   can ever add the .show-advanced class again, so those four fields were
   permanently invisible by accident. Narrowed back down to restore them. */
.mb-page:not(.show-advanced) .mb-field:has([data-key="menu_id"]),
.mb-page:not(.show-advanced) .mb-field:has([data-key="recipe_id"]),
.mb-page:not(.show-advanced) .mb-field:has([data-key="version"]) {
  display: none;
}
.mb-page:not(.show-advanced) .mb-field:has(select[data-key="recipe_id"]) {
  display: flex;
}
.mb-food-workspace {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  gap: 1.2rem;
  align-items: start;
}
.mb-food-tree {
  position: sticky;
  top: 1rem;
  background: #fff;
  border: 1px solid var(--rule);
  padding: 1rem;
  max-height: calc(100vh - 8rem);
  overflow: auto;
}
.mb-food-tree h2 {
  font-size: 1.25rem;
}
.mb-food-tree details {
  border-top: 1px solid var(--rule);
  padding: 0.55rem 0;
}
.mb-food-tree summary {
  font-weight: 800;
  color: var(--navy);
  cursor: pointer;
}
.mb-tree-heading {
  margin: 0.65rem 0 0.2rem;
  padding-left: 0.35rem;
  color: var(--muted);
  font-size: 0.95rem;
  font-weight: 800;
  text-transform: uppercase;
}
.mb-food-tree button {
  display: block;
  width: 100%;
  padding: 0.55rem 0.7rem;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
}
.mb-food-tree button:hover,
.mb-food-tree button.active {
  background: var(--yellow-soft);
  color: var(--navy);
  font-weight: 800;
}
.mb-allergen-board {
  margin-bottom: 1.2rem;
  padding: 1rem;
  background: #f7f8f6;
  border: 1px solid var(--rule);
}
.mb-allergen-head {
  display: flex;
  justify-content: space-between;
  align-items: start;
  gap: 1rem;
}
.mb-allergen-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  font-size: 0.95rem;
}
.mb-allergen-legend span,
.mb-allergen-pill {
  border-radius: 999px;
  padding: 0.38rem 0.7rem;
  font-weight: 800;
}
.mb-allergen-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin-top: 0.8rem;
}
.mb-allergen-pill.red,
.mb-allergen-legend .red {
  background: #b7372d;
  color: #fff;
}
.mb-allergen-pill.amber,
.mb-allergen-legend .amber {
  background: #e4a11b;
  color: #20200d;
}
.mb-allergen-pill.green,
.mb-allergen-legend .green {
  background: #267247;
  color: #fff;
}
.mb-allergen-pill.grey,
.mb-allergen-legend .grey {
  background: #dfe3e1;
  color: #46504d;
}
.mb-evidence-panel {
  margin: 1rem 0;
  border: 1px solid var(--rule);
}
.mb-evidence-panel > summary {
  padding: 0.8rem 1rem;
  font-weight: 800;
  color: var(--navy);
}
.mb-evidence-panel > .mb-grid {
  padding: 0 1rem 1rem;
}
.mb-nutrient-group {
  margin: 1rem 0;
}
.mb-nutrient-group h3 {
  margin-bottom: 0.55rem;
}
.mb-nutrient-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(135px, 1fr));
  gap: 0.55rem;
}
.mb-nutrient-box {
  margin: 0;
  padding: 0.7rem;
  background: #f7f4e9;
  border: 1px solid #d8cfb8;
}
.mb-nutrient-box input {
  font-size: 1.05rem;
  font-weight: 800;
}
.mb-publication {
  margin-top: 1.4rem;
  padding-top: 1rem;
  border-top: 2px solid var(--yellow);
}
.mb-subsection {
  margin-top: 3rem;
  padding-top: 1.4rem;
  border-top: 2px solid var(--yellow);
}
.mb-nutrition-matches {
  padding: 1rem;
  margin-bottom: 1.2rem;
  background: var(--yellow-soft);
  border-left: 5px solid var(--yellow);
}
.mb-nutrition-line {
  display: grid;
  grid-template-columns: minmax(150px, 1fr) minmax(300px, 2fr) auto auto auto;
  gap: 0.55rem;
  align-items: center;
  padding: 0.65rem 0;
  border-bottom: 1px solid rgba(18, 63, 59, 0.18);
}
.mb-nutrition-line small {
  display: block;
  color: var(--muted);
}
.mb-nutrition-line input {
  width: 100%;
  font: inherit;
  padding: 0.55rem;
  border: 1px solid #b8c0bd;
}
.mb-match-choice {
  min-width: 0;
}
.mb-match-choice > b,
.mb-match-choice > small {
  display: block;
  margin-bottom: 0.3rem;
}
@media (max-width: 900px) {
  .mb-topbar {
    display: block;
  }
  .mb-venue-box {
    margin-top: 1rem;
  }
  .mb-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .mb-span-4 {
    grid-column: 1/-1;
  }
  .mb-line {
    grid-template-columns: 1fr 1fr;
  }
  .mb-recipe-scaler {
    grid-template-columns: 1fr;
  }
  .mb-search {
    grid-column: 1/-1;
  }
  .mb-metrics {
    grid-template-columns: 1fr 1fr;
  }
  .mb-food-workspace {
    grid-template-columns: 1fr;
  }
  .mb-food-tree {
    position: static;
    max-height: none;
  }
  .mb-allergen-head {
    display: block;
  }
  .mb-allergen-legend {
    margin-top: 0.5rem;
  }
}
@media (max-width: 560px) {
  .mb-grid {
    grid-template-columns: 1fr;
  }
  .mb-guide-dialog .mb-grid {
    grid-template-columns: 1fr;
  }
  .mb-span-2,
  .mb-span-4 {
    grid-column: auto;
  }
  .mb-panel-head,
  .mb-guide-bar {
    align-items: flex-start;
    flex-direction: column;
  }
  .mb-line,
  .mb-nutrition-line {
    grid-template-columns: 1fr;
  }
  .mb-section-row {
    grid-template-columns: 1fr 1fr;
  }
  .mb-section-row input {
    grid-column: 1/-1;
  }
  .mb-metrics {
    grid-template-columns: 1fr 1fr;
  }
  .mb-savebar {
    font-size: 0.85rem;
  }
}
.mb-standalone-header {
  /* 2026-09-25: was space-between, which left "builder v123" floating in
     the middle of the bar. Title + build stamp now sit together on the
     left, links on the right, lined up with the site header above. */
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 0.4rem 1rem;
  align-items: baseline;
  padding: 0.6rem max(1.25rem, calc((100vw - 1400px) / 2 + 1.25rem));
  background: var(--navy);
  color: #fff;
  border-bottom: 4px solid var(--yellow);
}
.mb-standalone-header a {
  color: #fff;
}
.mb-standalone-header b {
  font: 700 1.05rem var(--font-head);
}
.mb-standalone-header span {
  font-size: 1.05rem;
}
.mb-standalone-header > span:last-child {
  margin-left: auto;
}
.mb-standalone-header .mb-build-stamp {
  font-size: 0.85rem;
  opacity: 0.75;
}
.mb-custom-ingredient {
  margin-top: 0.35rem;
  border: 0;
  background: transparent;
  color: var(--navy);
  text-decoration: underline;
  cursor: pointer;
  padding: 0.25rem 0;
  font-size: 1.05rem;
  font-weight: 700;
}
.mb-preview-disabled {
  margin-top: 1rem;
  padding: 1rem;
  background: #fff;
  border: 1px dashed #9eaaa7;
  opacity: 0.7;
}
.mb-preview-disabled input {
  pointer-events: none;
  background: #f2f3f2;
}
.mb-food-empty {
  text-align: left;
}
.mb-topbar {
  padding-top: 1rem;
}
/* This rule is later in the file than the .mb-topbar h1 rule near the top
   (outside any media query), so it wins and was silently capping the page
   title at 2.5rem instead of the larger size intended there. Fixed here,
   at the source of truth, rather than deleting the earlier (now dead) rule. */
.mb-topbar h1 {
  font-size: clamp(2.1rem, 4vw, 3.2rem);
}
.mb-guide-bar {
  margin: 0.35rem auto;
}
.mb-tabs {
  margin-top: 0.65rem;
}
.mb-panel {
  padding-top: 1rem;
}
.mb-process-save {
  /* 2026-09-25: was sticky (floated over the cards, Lee's list #11). The
     bottom bar's "Save all changes" now does the floating; this button just
     sits at the end of its tab. */
  display: flex;
  justify-content: flex-end;
  margin-top: 1rem;
}
.mb-process-save .btn {
  box-shadow: 3px 3px 0 rgba(18, 63, 59, 0.2);
}
.mb-cta-primary {
  font-size: 1.15rem;
  padding: 1.1rem 2rem;
}
.mb-ingredient-editor {
  display: grid;
  gap: 1rem;
}
.mb-source-summary {
  margin-top: 1rem;
  padding: 0.8rem;
  background: #eef5f1;
  border-left: 4px solid var(--yellow);
  line-height: 1.5;
  font-size: 1.15rem;
}
/* 2026-09-20 Phase 13: Lee -- "allergen info contains on each dish...
   Nuitricional Clickable open for button." Per-dish allergen summary +
   the "Show nutrition & allergens" toggle and its results panel. The
   .mb-warning/.mb-source-summary rules above are page-width banners by
   default; scoped down here since these live inside a single dish card. */
.mb-dish-allergen-nutrition {
  margin-top: 1rem;
}
.mb-dish-allergen-nutrition .mb-source-summary {
  margin-top: 0;
}
.mb-dish-allergen-nutrition .mb-source-summary + .mb-source-summary {
  margin-top: 0.6rem;
}
.mb-cofid-summary {
  /* 2026-09-20 Phase 13: Lee -- "id prefer to see the background highlited
     here in red with white text .. shows were serious about allergens." */
  background: #a73b2d;
  border-left-color: #6e2015;
  color: #fff;
}
.mb-nutrition-check {
  background: #fff7e6;
  border-left: 4px solid #c98416;
  color: #3b2a10;
}
.mb-nutrition-check--warn {
  background: #fff1d6;
  border-left-color: #a35b00;
}
.mb-nutrition-cautions { margin: 0.4rem 0 0; padding-left: 1.2rem; }
.mb-nutrition-line { margin: 0.25rem 0 0; }
.mb-dish-allergen-nutrition .mb-nutrition-toggle {
  margin-top: 0.6rem;
}
.mb-dish-nutrition-panel {
  margin-top: 0.6rem;
}
.mb-dish-nutrition-panel .mb-warning {
  /* 2026-09-20 Phase 13: Lee -- "again readability issue - I hate small
     print... double text size." Was 1.05rem; doubled to 2.1rem exactly as
     asked. <small> tags inside (the "not linked"/"candidate values"
     caveats) are sized in em relative to this, so they scale up with it
     automatically rather than staying tiny next to the now-much-larger
     main text. */
  max-width: none;
  margin: 0;
  font-size: 2.1rem;
  line-height: 1.45;
}
.mb-add-saved {
  display: flex;
  gap: 0.45rem;
  align-items: center;
  flex-wrap: wrap;
}
.mb-add-saved select {
  font: inherit;
  padding: 0.55rem;
  border: 1px solid #b8c0bd;
  min-width: 230px;
}
.mb-own-product {
  margin: 0.35rem 0;
  border: 0;
  background: transparent;
  color: var(--navy);
  font-size: 1.05rem;
  font-weight: 700;
  text-decoration: underline;
  cursor: pointer;
}
.mb-browse-suppliers {
  justify-self: start;
  margin: 0.1rem 0 0;
  padding: 0.4rem 0.75rem;
  border: 1px solid var(--navy);
  border-radius: 3px;
  background: var(--yellow-soft);
  color: var(--navy);
  font-weight: 700;
  font-size: 1rem;
  cursor: pointer;
}
.mb-browse-suppliers:hover {
  background: var(--yellow);
  color: #fff;
}
[hidden] {
  display: none !important;
}
/* 2026-09-19 Phase 12: a duplicate ".mb-process-save { display: none
   !important; }" rule sat right here, right after the [hidden] reset --
   almost certainly a stray copy-paste, since nothing in the JS ever toggles
   a class to show it again. It permanently hid three real, otherwise-
   working save buttons everywhere they're used: "Save ingredients" (My
   saved ingredients), "Save menus" (My menus), and "Save menu placements"
   (Put dishes on a menu) -- confirmed live via getComputedStyle before
   touching this: the button existed, was wired up correctly, and had
   offsetParent === null purely because of this rule. This is why Lee could
   create a menu structure but never find a way to save it. Removed the
   duplicate; the original, correctly-designed ".mb-process-save" rule
   above (sticky bar, flex layout) is untouched and now actually applies. */
.mb-workspace-grid {
  display: grid;
  grid-template-columns: 280px minmax(0, 1.5fr) minmax(280px, 1fr);
  gap: 1rem;
  align-items: start;
}
.mb-nav-tree {
  background: #fff;
  border: 1px solid var(--rule);
  padding: 1rem;
  max-height: calc(100vh - 12rem);
  overflow: auto;
  position: sticky;
  top: 1rem;
}
.mb-nav-tree details {
  border-top: 1px solid var(--rule);
  padding: 0.45rem 0;
}
.mb-nav-tree button {
  width: 100%;
  text-align: left;
  border: 0;
  background: transparent;
  padding: 0.5rem;
  cursor: pointer;
}
.mb-nav-tree button.active {
  background: var(--yellow-soft);
  font-weight: 800;
}
.mb-tree-dot {
  display: inline-block;
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  margin-right: 0.4rem;
  background: #c7cdca;
}
.mb-tree-dot.green {
  background: #267247;
}
.mb-tree-dot.amber {
  background: #e4a11b;
}
.mb-tree-dot.red {
  background: #b7372d;
}
.mb-hero-result {
  background: var(--navy);
  color: #fff;
  padding: 1.2rem;
  margin-bottom: 1rem;
}
.mb-hero-result b {
  display: block;
  font-size: 2rem;
}
.mb-cost-compare {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.6rem;
}
.mb-cost-compare > div {
  background: #f7f4e9;
  padding: 0.8rem;
}
.mb-supplier-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.8rem;
}
.mb-supplier-dialog {
  width: min(1120px, 96vw);
  max-width: 1120px;
}
.mb-supplier-dialog form {
  max-height: 88vh;
  overflow-y: auto;
  overflow-x: hidden;
}
.mb-supplier-table-wrap {
  overflow-x: auto;
  margin: 1rem 0;
  border: 1px solid var(--rule);
}
.mb-supplier-table {
  width: 100%;
  min-width: 46rem;
  border-collapse: collapse;
  margin: 0;
  font-size: 1rem;
}
.mb-supplier-table th,
.mb-supplier-table td {
  padding: 0.55rem;
  border-bottom: 1px solid #d8ded9;
  text-align: left;
  vertical-align: top;
}
.mb-supplier-table th:first-child,
.mb-supplier-table td:first-child {
  min-width: 9rem;
  position: sticky;
  left: 0;
  background: #fff;
  z-index: 3;
  box-shadow: 2px 0 4px rgba(18, 63, 59, 0.12);
}
.mb-supplier-table tbody tr:hover {
  background: #f4f7f4;
}
.mb-supplier-table tbody tr:hover td:first-child {
  background: #f4f7f4;
}
/* 2026-09-20: the old "Preferred" column was a bare, unlabeled checkbox
   pinned on the left -- Lee genuinely couldn't tell what it did and asked
   for a labeled "add as a supplier I use" control on the right instead.
   That's this same underlying preferred_supplier_ids toggle, just moved to
   the last column and given a plain-English label so it doesn't need a
   second, duplicate mechanism. */
.mb-supplier-preferred-cell {
  text-align: center;
  white-space: nowrap;
}
.mb-supplier-preferred-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.92rem;
  color: var(--muted);
  cursor: pointer;
}
.mb-supplier-preferred-toggle input {
  width: 1.15rem;
  height: 1.15rem;
  cursor: pointer;
}
.mb-supplier-row-preferred {
  background: var(--yellow-soft);
}
.mb-supplier-row-preferred td:first-child {
  background: var(--yellow-soft);
}
.mb-supplier-row-preferred .mb-supplier-preferred-toggle {
  color: var(--navy);
  font-weight: 700;
}
.mb-supplier-scroll-hint {
  font-size: 0.95rem;
  color: var(--muted);
  margin: 0.3rem 0 0;
}
#supplierDirectory details {
  border-top: 1px solid var(--rule);
  padding: 0.55rem 0;
}
#supplierDirectory summary {
  font-weight: 800;
  color: var(--navy);
  cursor: pointer;
}
#supplierDirectory .mb-supplier-table-wrap {
  margin: 0.5rem 0 0.8rem;
}
#dishLibraryList details {
  border-top: 1px solid var(--rule);
  padding: 0.55rem 0;
}
#dishLibraryList summary {
  font-weight: 800;
  color: var(--navy);
  cursor: pointer;
}
.mb-check-row {
  display: flex;
  gap: 1.2rem;
  margin: 0.4rem 0 0.6rem;
  font-size: 1rem;
}
.mb-check-row label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 700;
}
.mb-dish-idea-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.6rem;
  margin: 0.5rem 0 0.9rem;
}
.mb-dish-idea-card {
  border: 1px solid var(--rule);
  background: #fff;
  padding: 0.65rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.mb-dish-idea-card b {
  color: var(--navy);
}
.mb-dish-idea-card .btn--sm {
  align-self: flex-start;
  margin-top: 0.3rem;
}
.mb-pill-muted {
  background: var(--rule);
  color: var(--muted);
  font-weight: 700;
}
#supplierResultCount {
  margin: 0 0 0.4rem;
}
.mb-dish-showcase {
  max-width: 1400px;
  margin: 0.6rem auto 0.7rem;
  padding: 0 1.25rem;
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 0.7rem;
  align-items: stretch;
}
.mb-dish-showcase-card {
  background: #fff;
  border: 1.5px solid var(--navy);
  padding: 0.55rem 0.9rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.6rem;
}
.mb-dish-showcase-primary {
  background: linear-gradient(135deg, #fff, var(--yellow-soft));
}
.mb-dish-showcase-secondary {
  border-style: dashed;
}
.mb-dish-showcase-text {
  min-width: 0;
}
.mb-dish-showcase-card h2 {
  font-size: 1.45rem;
  color: var(--navy);
  line-height: 1.2;
}
.mb-dish-showcase-card p {
  color: var(--ink);
  font-size: 1.2rem;
  line-height: 1.45;
  margin: 0.25rem 0 0;
  max-width: 62ch;
}
.mb-dish-showcase-card .btn {
  flex: none;
  white-space: nowrap;
  font-size: 1.15rem;
  padding: 1rem 1.6rem;
}
@media (max-width: 900px) {
  .mb-dish-showcase {
    grid-template-columns: 1fr;
  }
}
.mb-dictionary-browser {
  border: 2px solid var(--navy);
  background: #f7faf8;
  padding: 0.7rem;
  margin-bottom: 0.8rem;
}
.mb-dictionary-browser > summary {
  cursor: pointer;
  margin-bottom: 0.55rem;
}
.mb-dictionary-browser label {
  display: block;
  margin: 0.45rem 0;
  font-weight: 700;
}
.mb-dictionary-browser select {
  display: block;
  width: 100%;
  margin-top: 0.2rem;
  padding: 0.45rem;
  font: inherit;
}
.mb-copy-setup {
  margin: 1rem 0;
  padding: 1rem;
  border: 1px solid var(--rule);
}
.mb-copy-setup > label {
  display: block;
  margin: 0.5rem 0;
}
.mb-copy-columns {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.8rem;
}
.mb-copy-columns > div {
  max-height: 230px;
  overflow: auto;
  border: 1px solid var(--rule);
  padding: 0.65rem;
}
.mb-copy-columns label {
  display: block;
  margin: 0.35rem 0;
  font-weight: 400;
}
@media (max-width: 750px) {
  .mb-copy-columns {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 1000px) {
  .mb-workspace-grid {
    grid-template-columns: 1fr;
  }
  .mb-nav-tree {
    position: static;
    max-height: none;
  }
}
.mb-menu-board {
  border: 2px solid var(--navy);
  background: #fff;
  margin-bottom: 1.2rem;
}
.mb-menu-board-head {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 1rem;
  padding: 1rem 1.2rem;
  background: var(--yellow-soft);
  border-bottom: 1px solid var(--line-navy);
}
.mb-menu-board-picker {
  min-width: 220px;
  margin: 0;
}
.mb-menu-board-picker select,
.mb-menu-board-picker input {
  padding: 0.55rem;
}
.mb-menu-board-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-left: auto;
}
.mb-menu-board-stats .mb-metric {
  background: #fff;
  border: 1px solid var(--line-navy);
  padding: 0.5rem 0.75rem;
  min-width: 120px;
}
.mb-menu-board-body {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 0;
}
.mb-menu-board-palette {
  padding: 1rem;
  border-right: 1px solid var(--rule);
  max-height: 560px;
  overflow: auto;
}
.mb-menu-board-palette h3 {
  font-size: 1rem;
  margin-bottom: 0.2rem;
}
.mb-menu-board-palette-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.6rem;
}
.mb-board-chip {
  border: 1px solid var(--navy);
  background: #fff;
  padding: 0.5rem 0.7rem;
  cursor: grab;
  font-size: 1rem;
}
.mb-board-chip:active {
  cursor: grabbing;
}
.mb-menu-board-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0;
}
.mb-board-column {
  padding: 1rem;
  border-right: 1px solid var(--rule);
}
.mb-board-column h4 {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 1rem;
  color: var(--navy);
  margin-bottom: 0.6rem;
}
.mb-board-dropzone {
  min-height: 160px;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.4rem;
  border: 2px dashed var(--rule);
}
.mb-board-dropzone.mb-board-dropping {
  border-color: var(--navy);
  background: var(--yellow-soft);
}
.mb-board-empty {
  color: var(--muted);
  font-size: 1rem;
  text-align: center;
  margin: auto;
}
.mb-board-card {
  background: #fff;
  border: 1px solid var(--navy);
  box-shadow: 3px 3px 0 rgba(18, 63, 59, 0.13);
  padding: 0.6rem 0.7rem;
  cursor: grab;
}
.mb-board-card:active {
  cursor: grabbing;
}
.mb-board-card b {
  display: block;
  color: var(--navy);
  margin-bottom: 0.25rem;
}
.mb-board-card-meta {
  display: flex;
  justify-content: space-between;
  color: var(--muted);
  font-size: 0.95rem;
  margin-bottom: 0.3rem;
}
.mb-board-card .mb-text-btn {
  margin: 0;
  font-size: 0.95rem;
}
.mb-board-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 1rem 1.2rem 0;
}
.mb-board-tab {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  border: 1.5px solid var(--navy);
  background: #fff;
  color: var(--navy);
  padding: 0.5rem 0.9rem;
  font-weight: 700;
  font-size: 1rem;
  cursor: pointer;
}
.mb-board-tab.active {
  background: var(--navy);
  color: #fff;
}
.mb-board-tab.active .mb-pill-muted {
  background: rgba(255, 255, 255, 0.25);
  color: #fff;
}
#menuBoardTypeHint {
  padding: 0 1.2rem;
  margin: 0.5rem 0 0;
}
.mb-board-card-head {
  cursor: pointer;
}
.mb-board-card-open {
  cursor: default;
}
.mb-board-card-detail {
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--rule);
}
.mb-board-card-detail .mb-grid {
  grid-template-columns: repeat(2, minmax(110px, 1fr));
}
.mb-board-card-detail .mb-metrics {
  grid-template-columns: repeat(2, 1fr);
  margin-top: 0.7rem;
}
.mb-board-card-detail .mb-card-actions {
  margin-top: 0.7rem;
  flex-wrap: wrap;
}
.mb-menu-list-fallback {
  border: 1px solid var(--rule);
  background: #fff;
  padding: 0 0 0.2rem;
}
.mb-menu-list-fallback > summary {
  cursor: pointer;
  padding: 0.9rem 1.2rem;
  font-weight: 700;
  color: var(--navy);
}
@media (max-width: 900px) {
  .mb-menu-board-body {
    grid-template-columns: 1fr;
  }
  .mb-menu-board-palette {
    border-right: 0;
    border-bottom: 1px solid var(--rule);
    max-height: none;
  }
}

.mb-pill-warn {
  background: #f3d27a;
  color: #3a2a00;
  border: 1px solid #b89a5a;
}
/* 2026-09-23 (later): proactive venue-task banner -- same amber warning
   tokens as .mb-pill-warn, so this reads as "needs attention" consistently
   with the rest of the app rather than inventing a new colour meaning. */
.mb-venue-task-banner {
  background: #f3d27a;
  color: #3a2a00;
  border: 2px solid #b89a5a;
  border-radius: 6px;
  padding: 0.85rem 1rem;
  margin: 0 0 1rem;
}
.mb-venue-task-banner-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  justify-content: space-between;
}
.mb-venue-task-banner-text small {
  color: #3a2a00;
  opacity: 0.85;
}
.mb-venue-task-banner-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.mb-card summary .mb-pill { margin-left: 0.35rem; }

.mb-accept-block { border: 2px solid var(--navy); padding: 1rem; margin-bottom: 1rem; background: #fff; }
.mb-accept-block h3 { margin: 0 0 .5rem; }
.mb-accept-row { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; padding: .45rem 0; border-top: 1px solid #ddd; }

/* 2026-09-23 (later): field-help / reason dock fix. Both #emmaFieldWhy and
   #mbReasonDock were plain <div>s styled inline with position:sticky and no
   width limit, appended as direct children of <body>. A sticky block with no
   ancestor scroll box other than the page itself pins to the bottom of the
   viewport at full page width once you scroll -- so it silently overlaid
   whatever field happened to be near the bottom of the screen (reported: it
   covered the "Evidence that this supplier supplies this product" label).
   Fix: a small fixed-position corner card with a real max-width, plus a
   close button so it does not have to sit there forever. */
.mb-help-dock {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  left: auto;
  max-width: min(380px, calc(100vw - 2rem));
  max-height: 45vh;
  overflow: auto;
  background: #1f4d3a;
  color: #fff;
  padding: 0.75rem 2.2rem 0.75rem 1rem;
  white-space: pre-wrap;
  z-index: 60;
  font: 14px/1.45 sans-serif;
  border-radius: 10px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.3);
}
.mb-help-dock[hidden] { display: none; }
.mb-help-dock-close {
  position: absolute;
  top: 0.35rem;
  right: 0.5rem;
  background: transparent;
  border: 0;
  color: #fff;
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.25rem 0.4rem;
}
.mb-help-dock-close:hover { opacity: 0.75; }
@media (max-width: 520px) {
  .mb-help-dock { right: 0.5rem; left: 0.5rem; bottom: 0.5rem; max-width: none; }
}

/* 2026-09-25: Lee's audit -- "Create from scratch" had no focused
   new-recipe screen. The card just started from scratch gets this short
   step guide on top, and a strong outline so it stands out in the list. */
.mb-card--new {
  outline: 3px solid var(--yellow);
  outline-offset: 2px;
}
.mb-new-recipe-guide {
  margin-bottom: 1.2rem;
  padding: 1rem 1.2rem;
  border: 2px solid var(--navy);
  border-radius: 6px;
  background: var(--yellow-soft);
  color: var(--navy-ink);
}
.mb-new-recipe-guide h3 {
  margin: 0 0 0.6rem;
  color: var(--navy);
}
.mb-new-recipe-guide ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.8rem;
}
.mb-new-recipe-guide label {
  display: grid;
  gap: 0.3rem;
}
.mb-new-recipe-guide input {
  max-width: 32rem;
  width: 100%;
  padding: 0.6rem 0.8rem;
  border: 2px solid var(--navy);
  border-radius: 4px;
  background: #fff;
  font-size: 1.15rem;
}
.mb-new-recipe-guide input[data-guide-name] {
  font-size: 1.4rem;
  font-weight: 700;
}
.mb-new-recipe-guide input[data-guide-portions] {
  max-width: 8rem;
}
.mb-new-recipe-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.3rem;
}
.mb-new-recipe-count,
.mb-new-recipe-later {
  color: var(--muted);
  font-size: 0.95rem;
}
.mb-new-recipe-later {
  margin: 0.8rem 0 0;
}

/* 2026-09-25: add-ingredient row -- search first, saved list second. */
.mb-add-saved-or {
  color: var(--muted);
  font-size: 0.95rem;
}
/* 2026-09-25: recipe name pulled to the top of every recipe card. */
.mb-recipe-name-top {
  display: grid;
  gap: 0.3rem;
  margin: 0 0 1rem;
}
.mb-recipe-name-top > span {
  font-weight: 800;
  color: var(--navy);
}
.mb-recipe-name-top input {
  max-width: 36rem;
  padding: 0.6rem 0.8rem;
  border: 2px solid var(--navy);
  font-size: 1.35rem;
  font-weight: 700;
}
/* 2026-09-25: specialist recipe fields folded away by default. */
.mb-more-fields {
  margin: 0.8rem 0;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: #fff;
}
.mb-more-fields > summary {
  cursor: pointer;
  padding: 0.6rem 0.9rem;
  font-weight: 700;
  color: var(--navy);
}
.mb-more-fields > .mb-grid {
  padding: 0 0.9rem 0.9rem;
}

.mb-savebar--dirty {
  border-top: 3px solid var(--yellow);
  background: var(--yellow-soft);
}
/* 2026-09-25: plain-language map at the top of Allergen confirmations. */
.mb-allergen-map {
  margin: 0 0 1rem;
  padding: 0.9rem 1.1rem;
  border-left: 4px solid var(--navy);
  background: var(--yellow-soft);
  color: var(--navy-ink);
}
.mb-allergen-map ol {
  margin: 0.5rem 0 0;
  padding-left: 1.2rem;
  display: grid;
  gap: 0.4rem;
}
.mb-accept-row button[disabled] {
  opacity: 0.55;
  cursor: default;
}
.mb-board-elsewhere {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin: 0 0 0.6rem;
}
.mb-print-signpost {
  margin: 0 0 0.6rem;
  font-size: 0.95rem;
  color: var(--muted);
}
.mb-print-signpost a {
  font-weight: 700;
  color: var(--navy);
}
/* The step guide already has the name box on a brand-new recipe. */
.mb-card--new .mb-recipe-name-top {
  display: none;
}
.mb-card--new .mb-recipe-edit-note {
  display: none;
}
/* 2026-09-25: tester sign-in form. */
.mb-login-form .btn {
  width: 100%;
  margin-top: 0.4rem;
}
.mb-login-form .mb-help {
  margin-top: 0.9rem;
}
/* 2026-09-25: Yes/No allergen answers right on the recipe card. */
.mb-inline-confirm {
  margin: 0.7rem 0 0.2rem;
  padding: 0.8rem 0.9rem;
  background: #fff;
  color: var(--ink);
  border-radius: 4px;
}
.mb-cofid-summary .mb-inline-confirm b {
  color: var(--navy);
}
.mb-inline-confirm-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.8rem;
  padding: 0.55rem 0 0;
  margin-top: 0.55rem;
  border-top: 1px solid var(--rule);
}
.mb-inline-confirm-row > span {
  flex: 1 1 14rem;
}
.mb-cofid-summary .mb-text-btn {
  color: #fff;
  text-decoration: underline;
  background: none;
  border: 0;
  cursor: pointer;
  font: inherit;
  padding: 0;
}
/* 2026-09-25: Lee's list #6 -- search results were squeezed into the
   narrow ingredient column (one word per line). While a line's search is
   open, that search panel takes the full width of the row. */
.mb-line:has(.mb-search-controls:not([hidden])) .mb-search {
  grid-column: 1 / -1;
  order: -1;
}
.mb-line:has(.mb-search-controls:not([hidden])) .mb-search-results {
  max-width: 44rem;
}
/* The generic ".mb-search-results button { width: 100% }" rule was also
   stretching the small ⓘ preview button, squashing each result's name into
   a sliver ("one word per line"). */
.mb-search-results .mb-result-info {
  width: 2.4rem;
  flex: 0 0 2.4rem;
}
.mb-search-results .mb-result-select {
  width: auto;
  min-width: 0;
}
.mb-search-results .mb-result-select b {
  font-size: 1.1rem;
}
.mb-search-results .mb-result-select small {
  font-size: 0.92rem;
  color: var(--muted);
}
/* 2026-09-25: one line of help under the field that has focus. */
.mb-field-hint {
  display: block;
  font-weight: 400;
  font-size: 0.9rem;
  color: var(--muted);
  line-height: 1.35;
}
/* 2026-09-25: Lee's list #11 -- the quick-check list, its explanation and
   the step headings sat in one narrow grid column with the right side
   empty. They now span the full width; only the venue record cards tile. */
#allergenList > .mb-accept-block,
#allergenList > .mb-allergen-map,
#allergenList > .mb-empty {
  grid-column: 1 / -1;
}
.mb-accept-row > span:first-child {
  flex: 1 1 16rem;
}

/* 2026-09-25: Lee's list #14 -- "Saved ingredients scrolls sideways a
   little; the page is wider than the screen on a phone". Grid/flex children
   defaulted to min-width:auto, so long selects, date inputs and the two
   showcase cards pushed the page wider than the screen. */
.mb-grid > *,
.mb-line > *,
.mb-card-list > *,
.mb-dish-showcase > * {
  min-width: 0;
}
.mb-field input,
.mb-field select,
.mb-field textarea,
.mb-line select,
.mb-line input {
  max-width: 100%;
  box-sizing: border-box;
}
@media (max-width: 760px) {
  .mb-dish-showcase {
    grid-template-columns: 1fr;
  }
  .mb-card-list {
    grid-template-columns: 1fr;
  }
}
/* A closed card's hidden body can still take up layout space in current
   Chrome (it only hides it), which is what pushed Saved ingredients a
   little wider than the screen. */
.mb-card-list > details:not([open]) {
  overflow: hidden;
}
@media (max-width: 760px) {
  .mb-tabs {
    flex-wrap: wrap;
  }
  .mb-dish-showcase .btn {
    white-space: normal;
    max-width: 100%;
  }
  .mb-add-saved select {
    min-width: 0;
    width: 100%;
  }
  .mb-add-saved,
  .mb-lines-head {
    flex-wrap: wrap;
  }
}
/* The hidden "?" tooltip was only made invisible, not removed from layout,
   so a "?" near the right edge made the page ~30px wider than the screen
   (and ~100px on a phone). Take it out of layout until it's shown, and keep
   it inside the screen. */
.mb-help-tip::after {
  display: none;
  width: min(300px, 80vw);
  white-space: pre-line;
}
.mb-help-tip:hover::after,
.mb-help-tip:focus::after {
  display: block;
}
/* 2026-09-25: Lee -- the yellow "things need attention" banner ran the full
   width of the window (past the recipe cards and tabs on both sides). It now
   lines up with the showcase cards and tabs above/below it. */
.mb-venue-task-banner {
  box-sizing: border-box;
  width: calc(100% - 2.5rem);
  max-width: calc(1400px - 2.5rem);
  margin: 0 auto 1rem;
}
/* Same alignment for the save bar's text and button. */
.mb-savebar {
  padding-left: max(1.25rem, calc((100% - 1400px) / 2 + 1.25rem));
  padding-right: max(1.25rem, calc((100% - 1400px) / 2 + 1.25rem));
}

/* 2026-09-26: Lee -- quick purchase-price update (spreadsheet-style). */
.mb-qp{background:#fff;border:1px solid #ccd7d2;border-radius:8px;box-shadow:0 2px 7px rgba(0,0,0,.04);padding:15px;margin:0 0 1rem;font-family:Arial,"Segoe UI",sans-serif;color:#123f3b}
.mb-qp h3{font-family:Syne,"Trebuchet MS",sans-serif;font-size:22px;margin:0 0 4px;color:#123f3b}
.mb-qp .mb-qp-lede{font-size:18px;margin:0 0 12px;line-height:1.4}
.mb-qp-tools{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin:0 0 10px}
.mb-qp-tools input{font:inherit;font-size:18px;padding:8px 10px;border:1px solid #ccd7d2;border-radius:6px;min-width:280px}
.mb-qp-sheet{overflow:auto;max-height:70vh;border:1px solid #ccd7d2;border-radius:8px}
.mb-qp table{border-collapse:collapse;width:100%;font-size:18px}
.mb-qp th{position:sticky;top:0;z-index:1;background:#e9efec;text-align:left;font-size:12px;font-weight:900;letter-spacing:.08em;text-transform:uppercase;padding:10px;border-bottom:2px solid #ccd7d2;white-space:nowrap}
.mb-qp td{padding:8px 10px;border-bottom:1px solid #e3e9e6;vertical-align:middle}
.mb-qp tr:nth-child(even) td{background:#fafbfa}
.mb-qp tr.mb-qp-done td{background:#f1f9f2}
.mb-qp .mb-qp-id{font-family:Consolas,Menlo,monospace;font-size:14px;color:#51615d;white-space:nowrap}
.mb-qp input.mb-qp-new{width:110px;font:inherit;font-size:18px;padding:6px 8px;border:1px solid #9fb3ac;border-radius:4px}
.mb-qp input.mb-qp-ref{width:190px;font:inherit;font-size:16px;padding:6px 8px;border:1px solid #ccd7d2;border-radius:4px}
.mb-qp .mb-qp-btn{background:#123f3b;color:#fff;border:1px solid #123f3b;box-shadow:3px 3px 0 rgb(28,70,95);padding:6px 12px;border-radius:4px;font-family:Syne,"Trebuchet MS",sans-serif;font-size:14px;font-weight:900;cursor:pointer;white-space:nowrap}
.mb-qp .mb-qp-btn.ghost{background:#fff;color:#123f3b;box-shadow:3px 3px 0 #ccd7d2}
.mb-qp .mb-qp-btn:disabled{opacity:.45;cursor:not-allowed}
.mb-qp .mb-qp-when{font-size:14px;color:#51615d;display:block}
.mb-qp .mb-qp-up{color:#8b2722;font-weight:800}.mb-qp .mb-qp-down{color:#1f6b3a;font-weight:800}
.mb-qp .mb-qp-hist td{background:#f6f8f7!important;font-size:16px}
.mb-qp .mb-qp-hist table{font-size:16px;margin:4px 0}
.mb-qp .mb-qp-hist th{position:static;font-size:11px;background:#eef3f1}
.mb-qp .mb-qp-msg{font-size:16px;min-height:1.3em;margin:8px 0 0}
.mb-qp .mb-qp-msg.err{color:#8b2722;font-weight:800}

/* 2026-09-26: EMMA rating / Owner rating-check line on venue allergen rows. */
.mb-emma-check{display:block;font-size:14px;color:#51615d;margin-top:3px;font-weight:400}
.mb-emma-check .mb-emma-ok{color:#1f6b3a;font-weight:800}

/* 2026-10-02: guest allergen page status on each dish placed on a menu */
.mb-guest-page{margin:.75rem 0 .25rem;padding:.6rem .8rem;border-radius:8px;font-size:.92rem;line-height:1.45}
.mb-guest-page a{margin:0 .5rem}
.mb-guest-off{background:#fff8e1;border:1px solid #e0c96a}
.mb-guest-on{background:#e3f4e6;border:1px solid #9fd0aa}
.mb-guest-qr{margin-top:.5rem}
.mb-guest-qr img{display:block;background:#fff;padding:4px;border:1px solid #ccd}
