/* Fable token sheet. A tenant injects only --brand; every tint is derived from it. */
:root {
  --brand: #14315A;
  --on-brand: #f5f7f9; /* never pure #fff on a filled control */
  --brand-soft: #e6edf4;
  --brand-soft: color-mix(in srgb, var(--brand) 16%, var(--surface));
  --brand-mid: #2c4566;
  --brand-mid: color-mix(in srgb, var(--brand) 58%, var(--ink));
  --brand-fill: #14315A;
  --brand-fill: color-mix(in srgb, var(--brand) 78%, var(--ink));
  --brand-text: #14315A;
  --brand-text: color-mix(in srgb, var(--brand) 70%, var(--ink));

  --ink: #14181a;
  --ink-soft: #2a3338;
  --muted: #5d6b73;
  --bg: #f0f3f6;
  --surface: #f6f8fa;
  --surface-raised: #fbfcfd;
  --line: #dce3e8;
  --line-strong: #c5ced4;
  --sunk: #e8eef2;
  --sunk: color-mix(in srgb, var(--ink) 5%, var(--bg));

  --ok: #1f7a4d;
  --ok-soft: #e7f4ec;
  --warn: #9a5b14;
  --warn-soft: #fdf3ea;
  --danger: #a3302a;
  --danger-soft: #f8eaea;
  --info: #1d5f86;
  --info-soft: #e8f2f7;

  --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --fs-xs: 0.72rem;
  --fs-sm: 0.85rem;
  --fs-md: 1rem;
  --fs-lg: 1.12rem;
  --fs-xl: 1.35rem;
  --fs-2xl: 1.6rem;
  --lh-tight: 1.25;
  --lh-body: 1.6;
  --lh-loose: 1.75;
  --fw-regular: 400;
  --fw-medium: 600;
  --fw-bold: 700;
  --track-tight: -0.015em;

  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 24px;
  --r-pill: 999px;

  --shadow-1: 0 1px 2px rgba(16, 24, 32, 0.05), 0 1px 1px rgba(16, 24, 32, 0.04);
  --shadow-2: 0 6px 16px rgba(16, 24, 32, 0.08), 0 2px 4px rgba(16, 24, 32, 0.04);
  --shadow-3: 0 16px 40px rgba(16, 24, 32, 0.14), 0 6px 12px rgba(16, 24, 32, 0.06);

  --ease: ease-in-out;
  --dur: 200ms;
  --focus-ring: 0 0 0 3px var(--brand-soft);

  --shell-bg: #f3f5f7;
  --shell-nav: #f8fafb;
  --shell-nav-w: 244px;
}
* { box-sizing: border-box; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--font); font-size: var(--fs-md); line-height: var(--lh-body);
  font-weight: var(--fw-regular);
}
.wrap { max-width: 68ch; margin: 0 auto; padding: 0 1.25rem; }
a { color: var(--brand-text); }

/* --- header ------------------------------------------------------------------------- */
/* Light, not a slab of brand colour: a tenant's logo is drawn for their own background. */
header.site {
  position: sticky; top: 0; z-index: 30;
  background: var(--surface-raised);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-1);
  padding: 1.1rem 0 1rem;
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  header.site {
    background: color-mix(in srgb, var(--surface-raised) 82%, transparent);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
  }
}
.head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.brand { display: flex; align-items: center; gap: 0.75rem; text-decoration: none; color: var(--ink); }
.brand .name { font-size: var(--fs-xl); font-weight: var(--fw-bold); letter-spacing: var(--track-tight); }
.brand .logo { height: 40px; width: auto; display: block; }
header.site nav { display: flex; gap: 1.1rem; font-size: 0.92rem; }
header.site nav a {
  color: var(--muted); text-decoration: none;
  transition: color var(--dur) var(--ease);
}
header.site nav a:hover { color: var(--brand-text); text-decoration: underline; }
header.site nav a:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--r-sm); }
header.site .tagline { margin: 0.7rem 0 0; color: var(--muted); font-size: 0.95rem; }

main.wrap { padding-top: 2.25rem; padding-bottom: 3rem; }
main h1 { font-size: var(--fs-2xl); margin: 0 0 1rem; letter-spacing: var(--track-tight); }
main h2 { font-size: var(--fs-lg); margin: 2rem 0 0.5rem; }
main ul { padding-left: 1.2rem; }
main li { margin: 0.3rem 0; }
.muted { color: var(--muted); }

/* --- catalogue ----------------------------------------------------------------------- */
.cards { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
.card {
  display: flex; flex-direction: column; gap: 0.35rem; padding: 1rem 1.1rem;
  background: var(--surface-raised); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-1); text-decoration: none; color: inherit;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.card:hover { border-color: var(--brand); box-shadow: var(--shadow-2); transform: translateY(-2px); }
.card-name { font-weight: var(--fw-medium); }
.card-price { color: var(--brand-text); font-variant-numeric: tabular-nums; }
.price-lead { font-size: var(--fs-xl); color: var(--brand-text); font-weight: var(--fw-medium); margin: 0 0 1rem; }
.product-image { display: block; max-width: 100%; height: auto; border-radius: var(--r-md); margin: 1rem 0; }

/* --- forms --------------------------------------------------------------------------- */
.stack { display: flex; flex-direction: column; gap: 0.5rem; max-width: 26rem; margin: 1.25rem 0; }
.stack.wide { max-width: 42rem; }
.stack label { font-size: 0.9rem; font-weight: 600; }
.stack input[type=email], .stack input[type=text], .stack input:not([type]),
.stack textarea, .stack select {
  padding: 0.6rem 0.7rem; border: 1px solid var(--line); border-radius: var(--r-sm);
  font: inherit; background: var(--surface-raised); width: 100%;
}
.stack textarea { resize: vertical; }
.stack input:focus, .stack textarea:focus, .stack select:focus {
  outline: none; box-shadow: var(--focus-ring); border-color: var(--brand);
}
.stack label.check { display: flex; gap: 0.5rem; align-items: flex-start; font-weight: 400; font-size: 0.9rem; }
.stack h2 { margin: 1.5rem 0 0.25rem; }
.field-note { font-size: 0.82rem; color: var(--muted); margin: -0.25rem 0 0.4rem; }
.hint {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.1rem; height: 1.1rem; margin-left: 0.2rem;
  border-radius: 50%; background: var(--line); color: var(--muted);
  font-size: 0.7rem; font-weight: 700; cursor: help; vertical-align: middle;
  line-height: 1;
}
.hint:focus { outline: none; box-shadow: var(--focus-ring); }
.card.is-active { border-color: var(--brand); box-shadow: var(--focus-ring); }
.ai-active-banner strong { font-variant-numeric: tabular-nums; }
/* Honeypot: present in the DOM, never shown, never announced. */
.trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
button {
  padding: 0.6rem 1.1rem; border: 0; border-radius: var(--r-sm);
  background: var(--brand-fill); color: var(--on-brand);
  font: inherit; font-weight: var(--fw-medium); cursor: pointer; align-self: flex-start;
  transition: box-shadow var(--dur) var(--ease), opacity var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
button:focus-visible { outline: none; box-shadow: var(--focus-ring); }
button.secondary { background: transparent; color: var(--muted); border: 1px solid var(--line); }
button.secondary:focus-visible { box-shadow: var(--focus-ring); }

/* --- messages and tables -------------------------------------------------------------- */
.notice, .warn { padding: 0.7rem 0.9rem; border-radius: var(--r-sm); font-size: 0.92rem; }
.notice { background: var(--ok-soft); border: 1px solid color-mix(in srgb, var(--ok) 28%, var(--ok-soft)); }
.warn { background: var(--warn-soft); border: 1px solid color-mix(in srgb, var(--warn) 28%, var(--warn-soft)); }
table.identity, table.routes {
  border-collapse: collapse; width: 100%; margin: 1.25rem 0; font-size: 0.92rem;
}
table.identity th, table.routes th {
  text-align: left; vertical-align: top; padding: 0.5rem 0.75rem 0.5rem 0;
  white-space: nowrap; color: var(--muted); font-weight: 600;
}
table.identity td, table.routes td { padding: 0.5rem 0; border-bottom: 1px solid var(--line); vertical-align: top; }
table.routes td:first-child { white-space: nowrap; padding-right: 1rem; }
code { background: var(--sunk); padding: 0.1rem 0.35rem; border-radius: 4px; font-size: 0.9em; }
.tag, .tick {
  display: inline-block; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em;
  padding: 0.05rem 0.4rem; border-radius: 4px; vertical-align: middle;
}
.tag { background: var(--brand-fill); color: var(--on-brand); }
.tick { background: var(--ok-soft); color: var(--ok); border: 1px solid color-mix(in srgb, var(--ok) 28%, var(--ok-soft)); }

/* --- footer ---------------------------------------------------------------------------- */
footer.wrap {
  border-top: 1px solid var(--line); padding-top: 1rem; padding-bottom: 2rem;
  color: var(--muted); font-size: 0.85rem;
}
footer.wrap .legal { margin: 0 0 0.35rem; }
footer.wrap .links { margin: 0; display: flex; gap: 1rem; flex-wrap: wrap; }
footer.wrap a { color: var(--muted); }

/* --- getting started ------------------------------------------------------------------- */
.onboard {
  background: var(--surface-raised); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: 1.1rem 1.25rem; margin: 0 0 1.5rem;
}
.onboard h2 { margin-top: 0; }
.bar { height: 6px; background: var(--line); border-radius: 3px; overflow: hidden; margin: 0.75rem 0 1rem; }
.bar span { display: block; height: 100%; background: var(--brand-fill); }
ol.steps { margin: 0; padding-left: 1.3rem; }
ol.steps li { margin: 0 0 0.85rem; }
ol.steps a { text-decoration: none; }
ol.steps a:hover { text-decoration: underline; }
.bigbutton {
  display: inline-block; padding: 0.7rem 1.3rem; border-radius: var(--r-sm); background: var(--brand-fill);
  color: var(--on-brand); font-weight: var(--fw-medium); text-decoration: none;
  transition: opacity var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.bigbutton:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.bigbutton:hover { opacity: 0.92; }

/* Small forms that sit inside a table cell. */
form.inline { display: inline-flex; gap: 0.4rem; align-items: center; margin: 0; }
form.inline select { padding: 0.35rem 0.5rem; border: 1px solid var(--line); border-radius: 6px; font: inherit; }
form.inline button { padding: 0.35rem 0.7rem; font-size: 0.85rem; }

/* --- basket and menu ------------------------------------------------------------------- */
input.qty { width: 5rem; padding: 0.4rem 0.5rem; border: 1px solid var(--line); border-radius: 6px; font: inherit; }
.card.soldout { opacity: 0.55; }
.card.soldout .card-price { color: var(--muted); }
.stack input[type=file] { font: inherit; padding: 0.4rem 0; }
.stack label.check input[type=radio] { margin-top: 0.3rem; }

/* --- choosing a time -------------------------------------------------------------------
   A radio group that reads as a row of times rather than a list of form controls. Each
   label is a whole tap target, because most of these will be chosen on a phone. */
h2.day, h3.day { margin: 1.4rem 0 0.5rem; font-size: 1rem; }
.slots { display: flex; flex-wrap: wrap; gap: 0.45rem; margin-bottom: 0.4rem; }
.slots label.slot {
  display: inline-flex; align-items: center; gap: 0.35rem; margin: 0;
  padding: 0.45rem 0.7rem; border: 1px solid var(--line); border-radius: var(--r-sm);
  cursor: pointer; font-variant-numeric: tabular-nums;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
.slots label.slot:hover { border-color: var(--brand); }
.slots label.slot:has(input:checked) { border-color: var(--brand); background: var(--brand-fill); color: var(--on-brand); }
.slots label.slot input { margin: 0; }

/* --- is the shop open right now ---------------------------------------------------------
   The first thing a customer wants to know, and for a long time the last thing the page
   said. Green dot, present tense, no ceremony. */
p.trading { display:flex; align-items:center; gap:0.5rem; margin:0.9rem 0; font-weight:600; }
p.trading.open { color: var(--ok); }
p.trading .dot {
  width:0.55rem; height:0.55rem; border-radius:50%; background:currentColor;
  box-shadow:0 0 0 0.2rem rgba(26,127,75,0.18);
}

/* --- product photos on the menu ---------------------------------------------------------
   The image was always stored and only ever shown on the product page. A food menu without
   pictures is a price list. */
.card.has-shot { padding-top:0; overflow:hidden; }
.card-shot {
  display:block; width:calc(100% + 2px); margin:-1px -1px 0.7rem; aspect-ratio:16/10;
  object-fit:cover; background:var(--line);
}

/* --- live order status ------------------------------------------------------------------ */
.status-card {
  display:flex; flex-direction:column; gap:0.3rem; padding:1.1rem 1.25rem; margin:0 0 1.2rem;
  border:1px solid var(--line); border-left:4px solid var(--brand); border-radius: var(--r-md);
  background: var(--surface-raised); box-shadow: var(--shadow-1);
}
.status-card .status-label { font-size:1.35rem; font-weight:700; color:var(--brand-text); }
.status-card .status-step,
.status-card .status-ref { font-size:0.85rem; color:var(--muted); }
.status-card.is-live .status-label::after {
  content:''; display:inline-block; width:0.5rem; height:0.5rem; margin-left:0.5rem;
  border-radius:50%; background:currentColor; animation:pulse 1.6s ease-in-out infinite;
  vertical-align:middle;
}
@keyframes pulse { 0%,100%{opacity:0.25} 50%{opacity:1} }
@media (prefers-reduced-motion:reduce){ .status-card.is-live .status-label::after{animation:none} }

/* --- the customer's own order history --------------------------------------------------- */
.orders { display:flex; flex-direction:column; gap:0.5rem; margin:0.6rem 0 1.2rem; }
a.order-row {
  display:grid; grid-template-columns:auto auto 1fr auto; align-items:center; gap:0.35rem 0.8rem;
  padding:0.75rem 0.9rem; border:1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface-raised); text-decoration:none; color:inherit;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
a.order-row:hover { border-color:var(--brand); }
.order-when { color:var(--muted); font-size:0.85rem; }
.order-amount { font-weight:600; }
.order-state { font-size:0.8rem; color:var(--muted); text-align:right; }
.order-state.is-live { color:var(--brand-text); font-weight:600; }
.order-note { grid-column:1/-1; font-size:0.85rem; color:var(--muted); }

/* --- the checkout wizard -----------------------------------------------------------------
   Without script every .step is simply visible, which is the old single form. `.stepped` is
   added by JS only once it has taken over, so a failure to load leaves a working checkout. */
.summary { border:1px solid var(--line); border-radius: var(--r-md); padding:0.9rem 1.1rem; background: var(--surface-raised); margin-bottom:1.2rem; }
.summary table { margin:0; }
.summary .price-lead { margin:0.6rem 0 0; }
.summary tr.is-extra td:first-child::before { content:'+ '; color:var(--muted); }

.wizard { display:flex; flex-direction:column; gap:1rem; }
.wizard .step { border:1px solid var(--line); border-radius: var(--r-md); background: var(--surface-raised); padding:1rem 1.1rem; }
.wizard .step-head {
  display:flex; align-items:center; gap:0.6rem; margin:0 0 0.8rem; font-size:1.05rem;
}
.wizard .step-n {
  display:inline-grid; place-items:center; width:1.6rem; height:1.6rem; border-radius:50%;
  background:var(--line); color:var(--muted); font-size:0.85rem; font-weight:700; flex:none;
}
.wizard .step.current .step-n { background:var(--brand-fill); color: var(--on-brand); }
.wizard .step.done .step-n { background: var(--ok); color: var(--on-brand); }
.wizard .step.done .step-head { cursor:pointer; }
.wizard .step-body { display:flex; flex-direction:column; gap:0.5rem; }
.wizard .step-foot { display:none; margin-top:0.9rem; }
.wizard.stepped .step { display:none; }
.wizard.stepped .step.current,
.wizard.stepped .step.done { display:block; }
.wizard.stepped .step.done .step-body,
.wizard.stepped .step.done .step-foot { display:none; }
.wizard.stepped .step.current .step-foot { display:block; }
.wizard.stepped .wizard-end { display:none; }
.wizard.stepped .wizard-end.ready { display:block; }
.wizard .step-foot button { width:100%; }

label.choice {
  display:flex; gap:0.7rem; align-items:flex-start; margin:0;
  padding:0.75rem 0.9rem; border:1px solid var(--line); border-radius: var(--r-sm); cursor:pointer;
}
label.choice:hover { border-color:var(--brand); }
label.choice input { margin-top:0.25rem; flex:none; }
label.choice input:checked ~ span strong { color:var(--brand-text); }
label.choice .addon-price { font-weight:600; white-space:nowrap; }
.if-delivery { display:flex; flex-direction:column; gap:0.4rem; margin-top:0.4rem; }
.if-delivery[hidden] { display:none; }

a.secondary-button {
  display:inline-block; padding:0.5rem 0.95rem; border:1px solid var(--line); border-radius: var(--r-sm);
  text-decoration:none; color:inherit; font-weight:600; font-size:0.92rem;
}
a.secondary-button:hover { border-color:var(--brand); color:var(--brand-text); }

/* --- pick a day, then a time -------------------------------------------------------------
   ⚠ Replaces printing nine days at once, which put 121 radio buttons on one page and left
   the name field 3.6 screens below the time the customer had just chosen. */
.days { display:flex; gap:0.5rem; overflow-x:auto; padding:0.2rem 0.2rem 0.6rem; scroll-snap-type:x mandatory; }
a.day-chip {
  display:flex; flex-direction:column; align-items:center; gap:0.1rem; flex:none;
  min-width:4.4rem; padding:0.6rem 0.55rem; border:1px solid var(--line); border-radius: var(--r-md);
  text-decoration:none; color:inherit; scroll-snap-align:start; background: var(--surface-raised);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
a.day-chip:hover { border-color:var(--brand); }
a.day-chip.current { border-color:var(--brand); background:var(--brand-fill); color: var(--on-brand); }
a.day-chip .dow { font-size:0.72rem; text-transform:uppercase; letter-spacing:0.05em; opacity:0.75; }
a.day-chip .dom { font-size:1.35rem; font-weight:700; line-height:1.05; }
a.day-chip .mon { font-size:0.72rem; opacity:0.75; }
a.day-chip .free { font-size:0.66rem; margin-top:0.15rem; opacity:0.7; white-space:nowrap; }

.slots.for-day.hide { display:none; }
/* 44px is the smallest a finger reliably hits; the old chips were 39. */
.slots label.slot { min-height:2.75rem; min-width:4.2rem; justify-content:center; }

/* --- the basket that follows you ---------------------------------------------------------
   ⚠ It used to be a link in the body of the page, so on a phone it scrolled away after the
   first screenful — and the header is not sticky either. Three items meant six navigations. */
.cartbar { position:sticky; bottom:0.75rem; z-index:20; margin:1.4rem 0 0.4rem; }
.cartbar[hidden] { display:none; }
.cartbar a {
  display:flex; align-items:center; gap:0.7rem; padding:0.85rem 1.1rem;
  background:var(--brand-fill); color: var(--on-brand); border-radius: var(--r-md); text-decoration:none;
  font-weight: var(--fw-medium); box-shadow: var(--shadow-2);
}
.cartbar-count {
  display:inline-grid; place-items:center; min-width:1.7rem; height:1.7rem; padding:0 0.4rem;
  border-radius: var(--r-pill); background: color-mix(in srgb, var(--on-brand) 22%, transparent); font-size:0.9rem;
}
.cartbar-label { flex:1; }
.cartbar-total { font-variant-numeric:tabular-nums; }
.cartbar.bumped a { transform:scale(1.02); transition:transform var(--dur) var(--ease); }
@media (prefers-reduced-motion:reduce) { .cartbar.bumped a { transform:none; } }

/* --- the owner's chat window -------------------------------------------------------------
   ⚠ .chat-did is deliberately NOT styled like the conversation. What the shop system actually
   did is a fact; what the model said is a sentence. Making them look the same is how a "done!"
   over a failed update stops being noticed. */
.chat { display:flex; flex-direction:column; gap:0.7rem; margin:1rem 0 1.2rem; }
.chat > div { padding:0.7rem 0.95rem; border-radius: var(--r-md); max-width:44rem; }
.chat p { margin:0.2rem 0 0; }
.chat .who {
  font-size:0.7rem; text-transform:uppercase; letter-spacing:0.08em; font-weight:700; opacity:0.7;
}
.chat-you { background: var(--sunk); align-self:flex-end; }
.chat-them { background: var(--surface-raised); border:1px solid var(--line); }
.chat-did { border:1px solid var(--line); border-left:4px solid var(--muted); background: var(--surface-raised); }
.chat-did.good { border-left-color: var(--ok); }
.chat-did.good .who { color: var(--ok); opacity:1; }
.chat-did.bad { border-left-color: var(--danger); }
.chat-did.bad .who { color: var(--danger); opacity:1; }
.chat-did p { white-space:pre-wrap; font-variant-numeric:tabular-nums; }
.chat-form textarea { font:inherit; }
.visually-hidden {
  position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap;
}

/* --- settings, one subject at a time -----------------------------------------------------
   ⚠ This page was 20 814px tall: 62 controls across six unrelated subjects in one form, with
   the setup checklist dropping a first-time owner twenty-five screens above the fields it was
   talking about. */
.settings-tabs { display:flex; flex-wrap:wrap; gap:0.4rem; margin:0 0 1.4rem; }
.settings-tabs .tab {
  display:inline-flex; align-items:center; gap:0.4rem; padding:0.5rem 0.85rem;
  border:1px solid var(--line); border-radius: var(--r-pill); text-decoration:none; color:inherit;
  font-size:0.92rem; background: var(--surface-raised);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
.settings-tabs .tab:hover { border-color:var(--brand); }
.settings-tabs .tab.current { background:var(--brand-fill); border-color:var(--brand); color: var(--on-brand); }
.settings-tabs .tab .tag { font-size: var(--fs-xs); }
.settings-tabs .tab.current .tag { background: color-mix(in srgb, var(--on-brand) 25%, transparent); color: var(--on-brand); }

/* --- carry on shopping, as a button ------------------------------------------------------
   ⚠ "when I choose a product I need to click an underlined link style nav item to go back and
   choose more items" — a text link is a convention, a button is an instruction. */
.bigbutton.ghost {
  background:transparent; color:var(--brand-text); border:2px solid var(--brand);
}
.bigbutton.ghost:hover { background:var(--brand-fill); color: var(--on-brand); opacity:1; }

/* Per-item notes in the basket. */
tr.line-note td { padding-top:0; border-top:0; }
tr.line-note label { display:block; font-size:0.82rem; color:var(--muted); margin-bottom:0.2rem; }
tr.line-note input { width:100%; padding:0.4rem 0.5rem; border:1px solid var(--line); border-radius:6px; font:inherit; }

/* A primary action that fills the width, so it cannot be missed on a phone. */
button.bigbutton.wide {
  display:block; width:100%; padding:0.85rem 1.3rem; border-radius: var(--r-sm); border:0;
  background:var(--brand-fill); color: var(--on-brand); font-weight: var(--fw-medium); font-size: var(--fs-md); cursor:pointer;
}
button.bigbutton.wide:hover { opacity:0.92; }

/* --- the promo band ----------------------------------------------------------------------
   The promo of the week, at the top of the shop, retiring itself on its own date. */
.promos { display:grid; grid-template-columns:repeat(auto-fit,minmax(15rem,1fr)); gap:0.8rem; margin:1.2rem 0 1.6rem; }
a.promo {
  display:flex; gap:0.9rem; align-items:center; padding:0.75rem; border-radius: var(--r-md);
  border:2px solid var(--brand); background: var(--surface-raised); text-decoration:none; color:inherit;
  transition: box-shadow var(--dur) var(--ease);
}
a.promo:hover { box-shadow: var(--shadow-2); }
.promo-shot { width:5.5rem; height:5.5rem; object-fit:cover; border-radius: var(--r-sm); flex:none; background:var(--line); }
.promo-body { display:flex; flex-direction:column; gap:0.15rem; min-width:0; }
.promo-flag {
  align-self:flex-start; background:var(--brand-fill); color: var(--on-brand); font-size:0.7rem; font-weight: var(--fw-bold);
  text-transform:uppercase; letter-spacing:0.06em; padding:0.15rem 0.45rem; border-radius:4px;
}
.promo-name { font-weight:700; }
.promo-price { font-size:1.15rem; font-weight:700; color:var(--brand-text); }
.promo-until { font-size:0.78rem; color:var(--muted); }

/* --- what your assistant may do ---------------------------------------------------------- */
.perm { border:1px solid var(--line); border-radius: var(--r-md); padding:0.9rem 1.1rem; background: var(--surface-raised); }
.perm-what { font-weight:700; margin:0 0 0.2rem; }
.perm .muted { margin:0 0 0.5rem; font-size:0.92rem; }
.perm label.check { margin:0.15rem 0; }

/* --- booking by the night ----------------------------------------------------------------
   ⚠ A guest house could not list a room at all: the ledger modelled appointments. A night is
   the same grid at a coarser granule, and this is the picker for it. */
.nights-strip { display:flex; gap:0.45rem; overflow-x:auto; padding:0.2rem 0.2rem 0.6rem; scroll-snap-type:x mandatory; }
label.night-chip {
  display:flex; flex-direction:column; align-items:center; gap:0.05rem; flex:none;
  min-width:3.9rem; padding:0.55rem 0.5rem; border:1px solid var(--line); border-radius: var(--r-md);
  cursor:pointer; scroll-snap-align:start; background: var(--surface-raised); margin:0;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
label.night-chip input { position:absolute; opacity:0; width:0; height:0; }
label.night-chip:hover { border-color:var(--brand); }
label.night-chip.current { border-color:var(--brand); background:var(--brand-fill); color: var(--on-brand); }
label.night-chip.taken { opacity:0.4; cursor:not-allowed; background: var(--sunk); }
label.night-chip .dow { font-size:0.7rem; text-transform:uppercase; letter-spacing:0.05em; opacity:0.75; }
label.night-chip .dom { font-size:1.25rem; font-weight:700; line-height:1.05; }
label.night-chip .mon { font-size:0.7rem; opacity:0.75; }
label.night-chip .free { font-size:0.62rem; opacity:0.8; }
.stay-total { margin-top:0.8rem; font-weight:700; font-size:1.05rem; color:var(--brand-text); }

/* A month at a time. Six months of nights in one strip is 180 chips to scroll past. */
.months { display:flex; gap:0.4rem; overflow-x:auto; padding:0.1rem 0.1rem 0.7rem; }
a.month-chip {
  display:flex; flex-direction:column; align-items:center; gap:0.1rem; flex:none;
  padding:0.45rem 0.8rem; border:1px solid var(--line); border-radius: var(--r-pill);
  text-decoration:none; color:inherit; font-size:0.92rem; background: var(--surface-raised); white-space:nowrap;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
a.month-chip:hover { border-color:var(--brand); }
a.month-chip.current { background:var(--brand-fill); border-color:var(--brand); color: var(--on-brand); }
a.month-chip .free { font-size:0.66rem; opacity:0.75; }
.nights-strip.for-month.hide { display:none; }

/* --- what happened while you were away ---------------------------------------------------
   ⚠ The assistant LEADS with this. An owner who never opens the admin panel — the whole
   pitch — finds out about a sale only if something reaches out to them. */
.news {
  border:1px solid var(--line); border-left:4px solid var(--ok); border-radius: var(--r-md);
  padding:0.9rem 1.1rem; margin:0 0 1.2rem; background: var(--surface-raised);
}
.news.urgent { border-left-color: var(--danger); }
.news .who {
  font-size:0.7rem; text-transform:uppercase; letter-spacing:0.08em; font-weight: var(--fw-bold);
  color: var(--ok);
}
.news.urgent .who { color: var(--danger); }
.news p { margin:0.25rem 0 0.6rem; font-weight:600; }
.news ul { margin:0 0 0.7rem; padding-left:1.1rem; }
.news li { margin:0.2rem 0; font-size:0.94rem; }
.news li.warn { color: var(--danger); font-weight: var(--fw-medium); }

/* A reminder exactly as the client will read it. Wrapped, not scrolled sideways: an owner
   checking this on a phone must be able to read every line before switching sending on. */
pre.preview {
  white-space: pre-wrap; word-break: break-word; font-family: inherit; font-size: 0.9rem;
  background: var(--sunk); border: 1px solid var(--line); border-left: 3px solid var(--brand);
  border-radius: var(--r-sm); padding: 0.8rem 0.9rem; margin: 0 0 1rem; line-height: var(--lh-body);
}

/* The one package, and the add-ons that are not ready. Plain list, generous line height:
   a visitor deciding whether to spend R299 is reading, not scanning a comparison table. */
ul.plan-list { list-style: none; margin: 0 0 1.2rem; padding: 0; }
ul.plan-list li {
  padding: 0.45rem 0 0.45rem 1.5rem; position: relative; line-height: 1.5;
  border-bottom: 1px solid var(--line);
}
ul.plan-list li:last-child { border-bottom: 0; }
ul.plan-list li::before {
  content: '✓'; position: absolute; left: 0; top: 0.45rem; color: var(--brand-text); font-weight: 700;
}
/* ⚠ Not a tick. Nothing on this list is included, and a ✓ beside "coming soon" would read as
   one more thing you are getting for your R299. */
ul.plan-list.addons li::before { content: '·'; color: var(--muted); }
ul.plan-list.addons .tick { background: var(--sunk); color: var(--muted); }

/* ─── the admin shell ───────────────────────────────────────────────────────────────────
   Sidebar left, one column of work on the right, panels over the top. Quiet on purpose:
   the tenant's brand colour belongs on their shopfront, and an admin painted in it fights
   whatever they chose. Here it marks only what is selected and what is a link. */
.shell-body { margin: 0; background: var(--shell-bg); }
.shell { display: flex; min-height: 100vh; align-items: stretch; }

.shell-nav {
  width: var(--shell-nav-w); flex: 0 0 var(--shell-nav-w); background: var(--shell-nav);
  border-right: 1px solid var(--line); box-shadow: var(--shadow-1);
  padding: 1rem 0.75rem 1.5rem; display: flex; flex-direction: column; gap: 0.15rem;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}
.shell-brand { padding: 0.25rem 0.5rem 0.75rem; }
.shell-brand a { text-decoration: none; color: inherit; font-weight: 700; font-size: 1.05rem; }
.shell-brand img { max-height: 34px; max-width: 100%; display: block; }

/* Not a link, and it must not look like one — it names where you already are. */
.shell-role { margin: 0 0 0.9rem; padding: 0.6rem 0.5rem; border-radius: var(--r-sm); background: var(--bg); }
.shell-role strong { display: block; font-size: 0.86rem; }
.shell-role span { display: block; font-size: 0.78rem; color: var(--muted); line-height: 1.35; margin-top: 0.15rem; }

.shell-new {
  display: block; text-align: center; padding: 0.5rem; margin: 0 0 1rem; border-radius: var(--r-sm);
  background: var(--brand-fill); color: var(--on-brand); text-decoration: none;
  font-weight: var(--fw-medium); font-size: 0.9rem;
  transition: opacity var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.shell-new:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.shell-new:hover { opacity: 0.92; }

.shell-group {
  margin: 0.9rem 0 0.2rem; padding: 0 0.5rem; font-size: 0.68rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted);
}
.shell-nav ul { list-style: none; margin: 0; padding: 0; }
.shell-nav li a {
  display: block; padding: 0.42rem 0.5rem; border-radius: var(--r-sm); text-decoration: none;
  color: inherit; font-size: 0.92rem; line-height: 1.3;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.shell-nav li a:hover { background: var(--bg); }
.shell-nav li a:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.shell-nav li a.here { background: var(--brand-fill); color: var(--on-brand); font-weight: var(--fw-medium); }

.shell-foot { margin-top: auto; padding: 1rem 0.5rem 0; display: flex; flex-direction: column; gap: 0.35rem; }
.shell-foot a { font-size: 0.85rem; color: var(--muted); text-decoration: none; }
.shell-foot a:hover { text-decoration: underline; }

.shell-main { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
/* A reading measure. A cash-up table that runs the full width of a 27-inch monitor is not
   easier to read for being wider. */
.shell-page { width: 100%; max-width: 860px; margin: 0 auto; padding: 1.6rem 1.5rem 4rem; }
.shell-page-chat {
  max-width: none; margin: 0; padding: 0; flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
}
.admin-chat-strip { padding: 1rem 1.25rem 0; max-width: 860px; }
.admin-chat-strip .news { margin-bottom: 0.8rem; }
.librechat-embed {
  flex: 1 1 auto; min-height: 24rem; display: flex; flex-direction: column; margin: 0.4rem 0 0;
}
.librechat-frame {
  flex: 1 1 auto; width: 100%; min-height: 24rem; border: 0; background: var(--surface-raised);
}
.librechat-fallback {
  margin: 1.1rem 1.25rem 1.5rem; padding: 1.15rem 1.3rem; max-width: 40rem;
  border: 1px solid var(--line); border-left: 4px solid var(--brand); border-radius: var(--r-md);
  background: var(--surface-raised);
}
.librechat-fallback .who {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700;
  color: var(--brand-text); margin: 0 0 0.4rem;
}
.librechat-fallback p { margin: 0.4rem 0 0; }
.librechat-fallback p:first-of-type { margin-top: 0; }
.shell-banner { margin: 0; border-radius: 0; }
.shell-burger { display: none; }

/* ─── panels ─────────────────────────────────────────────────────────────────────────── */
.modal-back {
  position: fixed; inset: 0; background: rgba(16, 24, 32, 0.45); z-index: 50;
  display: flex; align-items: flex-start; justify-content: center; padding: 3vh 1rem;
  overflow-y: auto;
}
.modal-back[hidden] { display: none; }
.modal-panel {
  background: var(--surface-raised); border-radius: var(--r-md); width: 100%; max-width: 780px;
  box-shadow: var(--shadow-3); display: flex; flex-direction: column;
  max-height: 94vh;
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.9rem 1.25rem; border-bottom: 1px solid var(--line);
}
.modal-head h2 { margin: 0; font-size: 1.05rem; }
.modal-x {
  background: none; border: 0; font-size: 1.6rem; line-height: 1; cursor: pointer;
  color: var(--muted); padding: 0 0.25rem; width: auto;
}
.modal-body { padding: 1.25rem; overflow-y: auto; }
.modal-body h1 { display: none; } /* the panel header already says what this is */
body.modal-on { overflow: hidden; }

@media (max-width: 820px) {
  .shell-nav {
    position: fixed; z-index: 40; left: 0; top: 0; transform: translateX(-100%);
    transition: transform var(--dur) var(--ease); box-shadow: var(--shadow-3);
  }
  .shell-nav.open { transform: translateX(0); }
  .shell-burger {
    display: block; background: none; border: 1px solid var(--line); border-radius: var(--r-sm);
    color: var(--ink);
    width: auto; font-size: 1.1rem; padding: 0.3rem 0.6rem; margin: 0.9rem 0 0 1rem; cursor: pointer;
  }
  .shell-page { padding: 1rem 1rem 3rem; }
  .shell-page-chat { padding: 0; }
}

/* ─── the composer ──────────────────────────────────────────────────────────────────────
   One card: what you are saying, and everything you can do with it on one row underneath.
   This is the most-used control in the admin now, so it gets to look like it. */
.composer {
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface-raised); padding: 0.6rem;
  margin: 0 0 0.75rem; box-shadow: var(--shadow-1);
}
.composer:focus-within { border-color: var(--brand); box-shadow: var(--focus-ring); }
.composer textarea {
  width: 100%; border: 0; resize: vertical; padding: 0.5rem; font: inherit;
  background: transparent; min-height: 3.2rem;
}
.composer textarea:focus { outline: none; }
.composer-row {
  display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
  padding: 0.35rem 0.5rem 0.15rem; border-top: 1px solid var(--line); margin-top: 0.35rem;
}
.composer-row button[type="submit"] { margin-left: auto; width: auto; padding: 0.45rem 1.4rem; }
.composer-check { font-size: 0.86rem; margin: 0; white-space: nowrap; }
.composer-file { font-size: 0.85rem; max-width: 15rem; }
.composer-file::file-selector-button {
  border: 1px solid var(--line); background: var(--bg); border-radius: var(--r-sm); cursor: pointer;
  padding: 0.3rem 0.7rem; margin-right: 0.6rem; font: inherit; font-size: 0.85rem; color: inherit;
}
.composer-file::file-selector-button:hover { background: var(--sunk); }
.composer + .field-note { margin-top: -0.4rem; }
@media (max-width: 560px) {
  .composer-row button[type="submit"] { margin-left: 0; width: 100%; }
}

/* --- nested shop sections -------------------------------------------------------------
   A parent is a click, not another wall of cards. Closed by default so the front page
   stays a list of names. Drag handles are admin-only. */
.cat-nav { display: flex; flex-direction: column; gap: 0.45rem; margin: 1.25rem 0; }
details.cat {
  background: var(--surface-raised); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 0.15rem 0.85rem 0.15rem;
}
details.cat[open] { padding-bottom: 0.75rem; }
details.cat > summary {
  cursor: pointer; font-weight: 600; padding: 0.7rem 0; list-style: none;
  display: flex; align-items: center; gap: 0.5rem;
}
details.cat > summary::-webkit-details-marker { display: none; }
details.cat > summary::before {
  content: ''; width: 0.45rem; height: 0.45rem; border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted); transform: rotate(-45deg); margin-right: 0.15rem;
}
details.cat[open] > summary::before { transform: rotate(45deg); }
.cat-link { color: inherit; text-decoration: none; }
.cat-link:hover { color: var(--brand-text); text-decoration: underline; }
.cat-kids { display: flex; flex-direction: column; gap: 0.4rem; margin: 0.15rem 0 0.5rem 0.4rem; }
.cat-kids details.cat { background: var(--bg); }
.cat-crumbs { color: var(--muted); font-size: 0.92rem; }

.cat-tree { margin: 1rem 0 2rem; }
.cat-list, .prod-list { list-style: none; margin: 0; padding: 0; }
.cat-list { display: flex; flex-direction: column; gap: 0.45rem; }
.cat-node {
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface-raised);
  padding: 0.55rem 0.75rem;
}
.cat-node > .cat-list { margin: 0.5rem 0 0 1.1rem; }
.cat-row, .prod-row {
  display: flex; align-items: center; gap: 0.55rem; flex-wrap: wrap;
}
.prod-list { margin: 0.4rem 0 0.2rem 1.4rem; }
.prod-row {
  padding: 0.25rem 0; border-bottom: 1px dashed var(--line); font-size: 0.92rem;
}
.prod-row:last-child { border-bottom: 0; }
.cat-handle { color: var(--muted); cursor: grab; letter-spacing: -0.15em; user-select: none; }
.cat-node.dragging, .prod-row.dragging { opacity: 0.45; }
.cat-node.drag-over, .prod-row.drag-over, .prod-list.drag-over {
  outline: none; box-shadow: var(--focus-ring);
}
form.cat-edit { margin: 0.35rem 0.4rem 0.15rem 0; flex-wrap: wrap; }
form.cat-edit input[name="name"] { min-width: 10rem; padding: 0.3rem 0.45rem; }

@media (prefers-reduced-motion: reduce) {
  .card:hover { transform: none; }
  header.site nav a,
  .card, button, .bigbutton, .slots label.slot, a.day-chip, a.order-row,
  .settings-tabs .tab, a.promo, label.night-chip, a.month-chip,
  .shell-nav, .shell-nav li a, .shell-new {
    transition: none;
  }
}
