/* roya chain HQ console — brand teal on beige, matching the roya chrome rules
   (teal #075859 + beige #FAF6EE are the only chromatic chrome colours; status
   colours appear only inside content). */
:root {
  --teal: #075859;
  --teal-dark: #054445;
  --beige: #FAF6EE;
  --ink: #1d2a2a;
  --muted: #6b7a7a;
  --line: #e5ddcd;
  --line-soft: #f1ece0;
  --card: #ffffff;
  --ok: #157347;
  --warn: #b45309;
  --bad: #b3261e;
  --hover: #faf7f0;
  /* Elevation + radius scale — one soft-shadow language for cards/tiles/
     dialogs so surfaces separate from the beige page without hard borders
     doing all the work. */
  --shadow-card: 0 10px 26px rgba(20, 32, 30, 0.05);
  --shadow-pop: 0 16px 44px rgba(7, 88, 89, 0.16);
  --radius-card: 14px;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background:
    radial-gradient(circle at top left, rgba(7, 88, 89, 0.045), transparent 30%),
    var(--beige);
  background-attachment: fixed;
  color: var(--ink);
  font-size: 15px;
}
.hidden { display: none !important; }

/* Selects: strip the native OS chrome so every dropdown reads as part of the
   console — a beige box with a teal chevron, matching the themed inputs —
   instead of the platform's grey widget. (The open option list is
   OS-native and can't be restyled; the closed control now fits the theme.)
   Context rules below keep their sizes but use background-COLOR (not the
   shorthand) so this chevron image survives, and add end-padding for it. */
select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1.5 1.5 6 6l4.5-4.5' stroke='%23075859' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-inline-end: 28px;
  cursor: pointer;
}
[dir="rtl"] select { background-position: left 10px center; }
.muted { color: var(--muted); }
.error { color: var(--bad); font-size: 13px; margin: 6px 0; }
.nowrap { white-space: nowrap; }

/* One visible focus convention for every interactive control. */
button:focus-visible, select:focus-visible, input:focus-visible,
.chip:focus-visible, .tile.link:focus-visible, a:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}

/* Login */
.login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.login-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 32px; width: 340px; box-shadow: 0 18px 50px rgba(7, 88, 89, 0.10); }
.login-card h1 { margin: 0 0 4px; color: var(--teal); font-size: 26px; }
.login-card h1 span { font-weight: 400; }
.login-card p { margin: 0 0 18px; }
.login-card label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 12px; }
.login-card input { width: 100%; margin-top: 4px; padding: 9px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 15px; background: var(--beige); }
.login-card .powered-by { margin: 16px 0 0; text-align: center; }

/* "powered by roya" — the only roya branding on this customer-facing console */
.powered-by { font-size: 11.5px; letter-spacing: 0.02em; color: var(--muted); }
.sidebar-foot .powered-by { color: rgba(243, 239, 228, 0.45); }

/* Language picker — one on the login card, one in the sidebar foot */
.lang-picker { border: 1px solid var(--line); border-radius: 7px; padding: 5px 8px; padding-inline-end: 26px; font-size: 13px; background-color: var(--beige); color: var(--ink); }
.sidebar-foot .lang-picker { background-color: rgba(255, 255, 255, 0.08); border-color: rgba(243, 239, 228, 0.35); color: #f3efe4;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1.5 1.5 6 6l4.5-4.5' stroke='%23f3efe4' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.sidebar-foot .lang-picker option { color: var(--ink); }
.login-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 16px; }
.login-foot .powered-by { margin: 0; }

/* Shell */
.shell { display: flex; min-height: 100vh; }
.sidebar { width: 216px; background: linear-gradient(165deg, var(--teal) 0%, var(--teal-dark) 100%); color: #f3efe4; display: flex; flex-direction: column; padding: 18px 0; position: sticky; top: 0; height: 100vh; }
/* Brand row — the roya mark badge + chain name block, mirroring the top-left
   brand treatment of the restaurant sidebar and the roya HQ console. */
.brand-row { display: flex; align-items: center; gap: 12px; padding: 0 18px 18px; }
.brand-badge { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; overflow: hidden; border-radius: 16px; }
.brand-badge--teal { width: 58px; height: 58px; background: var(--teal); box-shadow: inset 0 0 0 1px rgba(255,255,255,0.12); }
.brand-badge--ghost { width: 46px; height: 46px; background: rgba(255,255,255,0.12); box-shadow: inset 0 0 0 1px rgba(255,255,255,0.22); }
.brand-mark { width: 100%; height: 100%; object-fit: contain; transform: scale(1.22); }
.brand-text { display: grid; min-width: 0; }
.brand { font-size: 19px; font-weight: 700; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brand span { font-weight: 400; opacity: 0.85; }
.brand-kicker { font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(243,239,228,0.7); margin-top: 2px; }
.login-brand-row { display: flex; align-items: center; gap: 14px; margin-bottom: 6px; }
.login-brand-row h1 { margin: 0; }
/* Nav items are rounded pills (the roya HQ sidebar grammar) with an
   inline-start accent bar on the active one so the current tab reads at a
   glance even in a seven-item list. */
.sidebar nav { display: flex; flex-direction: column; gap: 3px; padding: 0 10px; }
.sidebar nav a { position: relative; color: #e8e2d2; text-decoration: none; padding: 9px 12px; font-size: 14.5px; font-weight: 500; border-radius: 10px; }
.sidebar nav a:hover { background: rgba(255, 255, 255, 0.08); }
.sidebar nav a.active { background: rgba(255, 255, 255, 0.15); color: #fff; font-weight: 600; }
.sidebar nav a.active::before { content: ''; position: absolute; inset-inline-start: -10px; top: 9px; bottom: 9px; width: 3px; border-radius: 3px; background: #f3efe4; }
.sidebar-foot { margin-top: auto; padding: 14px 18px 0; display: flex; flex-direction: column; gap: 8px; font-size: 13px; }
.sidebar-foot .muted { color: rgba(243, 239, 228, 0.7); }
.main { flex: 1; padding: 28px 32px 56px; max-width: 1200px; }
.main h2 { margin: 0 0 4px; color: var(--teal); font-size: 23px; letter-spacing: -0.015em; }
/* Page header row: title + freshness stamp + the chain-wide Refresh control.
   Every level wraps: long FR/AR titles push the side group to a second
   line, and inside it the stamp may take its own line above bell + Refresh
   (a nowrap stamp pushed every FR tab past a phone's width). The stamp's
   two facts ("Updated …" / "… behind") are each atomic (.nowrap spans) and
   break only at the separator. */
.page-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 4px; flex-wrap: wrap; }
.page-head h2 { margin: 0; min-width: 0; overflow-wrap: break-word; }
.page-head .page-side { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 8px 10px; min-width: 0; }
.page-fresh { font-size: 12.5px; color: var(--muted); min-width: 0; }
/* Bell + Refresh move as one unit when the side group wraps. */
.page-actions { display: inline-flex; align-items: center; gap: 10px; }
.main .sub { margin: 0 0 20px; color: var(--muted); font-size: 14px; }

/* Buttons — hierarchy: solid teal = the one primary act; ghost = secondary;
   quiet = routine row action; danger = destructive only. */
.btn-primary { background: var(--teal); color: #fff; border: 0; border-radius: 8px; padding: 10px 16px; font-size: 14.5px; cursor: pointer; width: 100%; }
.btn-primary:hover { background: var(--teal-dark); }
.btn-small { background: var(--teal); color: #fff; border: 0; border-radius: 7px; padding: 6px 12px; font-size: 13px; cursor: pointer; white-space: nowrap; }
.btn-small:hover { background: var(--teal-dark); }
/* Bordered variants shave 1px of padding so every .btn-small is the same
   box height as the borderless solid one (aligned rows, no 1px jig). */
.btn-small.ghost { background: transparent; color: var(--teal); border: 1px solid var(--teal); padding: 5px 11px; }
.btn-small.ghost:hover { background: rgba(7, 88, 89, 0.06); }
.btn-small.quiet { background: transparent; color: var(--teal); border: 1px solid transparent; padding: 5px 11px; }
.btn-small.quiet:hover { background: rgba(7, 88, 89, 0.08); }
.btn-small.danger { background: transparent; color: var(--bad); border: 1px solid var(--bad); padding: 5px 11px; }
.btn-small.danger:hover { background: rgba(179, 38, 30, 0.06); }
.btn-small:disabled { opacity: 0.5; cursor: default; }
.form-grid .btn-small.ghost, .form-grid .btn-small.danger { padding: 0 14px; }
.btn-ghost { background: transparent; color: #f3efe4; border: 1px solid rgba(243, 239, 228, 0.4); border-radius: 7px; padding: 6px 10px; font-size: 13px; cursor: pointer; }

/* Cards / KPI tiles. A tile never pushes the page wider than its column:
   long figures wrap at their spaces (a split total is one currency per
   .money-line), and break-word is the last resort for a lone long number. */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; margin-bottom: 22px; }
.tile { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 15px 17px; box-shadow: var(--shadow-card); min-width: 0; overflow-wrap: break-word; }
/* One currency per line inside a figure (a mixed-currency total). */
.money-line { display: block; white-space: nowrap; }
.tile .k { font-size: 12px; color: var(--muted); font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; }
.tile .v { font-size: 23px; font-weight: 700; color: var(--teal); margin-top: 3px; font-variant-numeric: tabular-nums; }
.tile .s { font-size: 12px; color: var(--muted); margin-top: 2px; }
.tile.link { cursor: pointer; transition: border-color 0.12s ease, box-shadow 0.12s ease, transform 0.12s ease; }
.tile.link:hover { border-color: var(--teal); box-shadow: 0 6px 18px rgba(7, 88, 89, 0.14); transform: translateY(-1px); }
.tile.zero .v { color: var(--muted); }
/* An attention tile carries its warning in the CONTENT (value colour),
   never in the chrome. */
.tile.attn .v { color: var(--warn); }
/* The hero figure (Overview "Collected today") is the one teal-filled card —
   the same accent treatment as the roya HQ MRR hero; still brand chrome. */
.tile.hero { background: linear-gradient(150deg, var(--teal) 0%, var(--teal-dark) 100%); border-color: transparent; }
.tile.hero .k, .tile.hero .s { color: rgba(250, 246, 238, 0.78); }
.tile.hero .v { color: #fff; }
.panel { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 18px 20px; margin-bottom: 20px; box-shadow: var(--shadow-card); }
.panel h3 { margin: 0 0 12px; font-size: 15px; color: var(--teal); }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.panel-head h3 { margin: 0; }
.panel-head .panel-actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* Warehouse alert bell — lives in every page head, mirrors the restaurant
   topbar bells: icon button + red count badge + a themed dropdown panel. */
.bell-wrap { position: relative; display: inline-flex; }
.bell-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; padding: 0; border: 1px solid var(--line); border-radius: 999px; background: var(--card); color: var(--teal); cursor: pointer; }
.bell-btn:hover { border-color: var(--teal); }
.bell-btn svg { width: 19px; height: 19px; }
.bell-count { position: absolute; top: -5px; inset-inline-end: -5px; min-width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; padding: 0 5px; border-radius: 999px; background: #d8584a; color: #fff; font-size: 11px; font-weight: 800; }
.bell-panel { position: absolute; top: calc(100% + 8px); inset-inline-end: 0; z-index: 60; width: 300px; max-height: 380px; overflow-y: auto; background: var(--card); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 16px 44px rgba(7, 88, 89, 0.16); }
.bell-head { padding: 12px 14px 8px; font-size: 12px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.bell-row { display: flex; align-items: center; gap: 10px; padding: 10px 14px; color: var(--ink); text-decoration: none; border-top: 1px solid var(--line); font-size: 14px; }
.bell-row:hover { background: var(--beige); }
.bell-row .dot { width: 8px; height: 8px; border-radius: 999px; flex: none; }
.bell-row-main { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bell-row-side { flex: none; font-size: 12.5px; color: var(--muted); }
.bell-empty { padding: 14px; font-size: 13.5px; color: var(--muted); border-top: 1px solid var(--line); }
.bell-foot { display: block; padding: 10px 14px; border-top: 1px solid var(--line); text-align: center; font-size: 13.5px; font-weight: 700; color: var(--teal); text-decoration: none; }
.bell-foot:hover { background: var(--beige); }

/* Stock toolbar — search across the whole catalog + the show-all toggle. */
.stock-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.list-search { flex: 1 1 220px; max-width: 340px; min-width: 180px; min-height: 38px; padding: 6px 14px; border: 1px solid var(--line); border-radius: 999px; background: var(--beige); color: var(--ink); font: inherit; font-size: 14px; -webkit-appearance: none; appearance: none; }
.list-search:focus { outline: none; border-color: var(--teal); }
/* A one-line plain-language caption inside a panel (explanations, legends,
   verdicts). Quieter than .sub, sits close to its table. */
.panel-note { margin: 0 0 10px; font-size: 12.5px; color: var(--muted); line-height: 1.45; }

/* Tables — a quiet header band separates labels from data, rows get a touch
   more air, and numbers stay tabular. */
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th { text-align: start; color: var(--muted); font-weight: 700; font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.06em; padding: 8px 10px; border-bottom: 1px solid var(--line); background: #fbf8f1; white-space: nowrap; }
td { padding: 10px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
tbody tr:hover > td { background: var(--hover); }
tbody tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
tfoot td { border-top: 1px solid var(--line); border-bottom: 0; font-weight: 600; background: none; }
.table-scroll { overflow-x: auto; }
/* Row rank (#) column: quiet, narrow */
td.rank, th.rank { color: var(--muted); width: 30px; font-variant-numeric: tabular-nums; }

/* Trailing action column: stays a real table cell (display:flex on a <td>
   detaches it from the row grid — collapsed borders, floating fragments).
   Buttons sit inline, end-aligned, spaced by margin. */
td.row-actions { text-align: end; white-space: nowrap; }
td.row-actions .btn-small { margin-inline-start: 6px; }

/* Entity cell: name + quiet second line (code, freshness, note) */
.cell-sub { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; font-weight: 400; letter-spacing: normal; text-transform: none; font-variant-numeric: tabular-nums; }
.cell-sub:empty { display: none; }

/* In-table entity links (Overview "Today by branch" → that branch's Sales):
   themed, never the UA's blue/purple. */
.row-link { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-decoration-color: rgba(7, 88, 89, 0.4); text-underline-offset: 2px; }
.row-link:hover { color: var(--teal); text-decoration-color: currentColor; }

/* Status cell: coloured dot + sentence-case label. Pills (.badge) are
   reserved for genuine alerts; routine states render as dot + text.
   nowrap is for table cells (inside .table-scroll) — free-flowing rows
   that must wrap use their own layout (see .attn-main). */
.cell-status { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 999px; flex: none; }
.cell-sub .dot { margin-inline-end: 5px; vertical-align: 1px; }
.dot.ok { background: var(--ok); }
.dot.warn { background: var(--warn); }
.dot.bad { background: var(--bad); }
.dot.dim { background: #c9c1ae; }

/* Badges — alerts and exceptional states only */
.badge { display: inline-block; border-radius: 999px; padding: 2px 9px; font-size: 12px; font-weight: 600; white-space: nowrap; }
.badge.ok { background: #e2f3ea; color: var(--ok); }
.badge.bad { background: #fbe9e7; color: var(--bad); }
.badge.warn { background: #fdf0e0; color: var(--warn); }
.badge.dim { background: #eee9dd; color: var(--muted); }

/* Value chip — a quiet labeled money/count fact as an element, not floating
   prose. Span-based ON PURPOSE: also renders inside <p class="sheet-sub">. */
.vchip { display: inline-flex; align-items: center; max-width: 100%; border: 1px solid rgba(7, 88, 89, 0.16); background: rgba(7, 88, 89, 0.05); color: var(--teal-dark); border-radius: 999px; padding: 2px 10px; font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.vchip.dim { color: var(--muted); background: rgba(28, 38, 40, 0.04); border-color: var(--line); }
.vchip.warn { color: var(--warn); background: rgba(180, 83, 9, 0.06); border-color: #f0d9b8; }

/* Composer summary strip — live facts under a form as one designed row. */
.form-summary { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 10px 0 0; padding: 8px 12px; background: rgba(7, 88, 89, 0.04); border: 1px solid var(--line); border-radius: 10px; }
.form-summary .note { font-size: 12.5px; color: var(--muted); margin: 0; }

/* Filter chips (segmented) — Inventory status filter, Sales quick ranges */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
.chip { border: 1px solid var(--line); background: var(--card); color: var(--ink); border-radius: 999px; padding: 6px 14px; font-size: 13px; font-weight: 500; cursor: pointer; white-space: nowrap; text-decoration: none; transition: border-color 0.12s ease, background-color 0.12s ease; }
.chip:hover { border-color: var(--teal); }
.chip.active { background: var(--teal); border-color: var(--teal); color: #fff; font-weight: 600; box-shadow: 0 3px 10px rgba(7, 88, 89, 0.18); }

/* Inline share-of-total meter (content colour = teal, it's data) */
.share { display: inline-flex; align-items: center; gap: 8px; min-width: 110px; }
.share-track { display: block; flex: 1; height: 6px; min-width: 60px; border-radius: 999px; background: var(--line-soft); overflow: hidden; }
.share-fill { display: block; height: 100%; background: var(--teal); opacity: 0.85; border-radius: 999px; }
.share-pct { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; width: 34px; text-align: end; }

/* Inventory branch-matrix cells: tint = open low-stock alert, red = out */
td.cell-warn { background: #fdf6ec; color: var(--warn); font-weight: 600; }
td.cell-bad { background: #fdf0ef; color: var(--bad); font-weight: 600; }
tbody tr:hover > td.cell-warn { background: #fbeedd; }
tbody tr:hover > td.cell-bad { background: #fbe6e4; }

/* Branch status cards (Branches tab — a health dashboard, not a data table) */
.branch-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.branch-card { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; display: flex; flex-direction: column; gap: 8px; }
.branch-card .bc-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.branch-card .bc-name { font-weight: 700; font-size: 15px; }
.branch-card .bc-note { font-size: 12.5px; color: var(--muted); line-height: 1.4; }
.branch-card .bc-note.warn { color: var(--warn); }
.branch-card .bc-money { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 8px 0 2px; }
.branch-card .bc-money .k { font-size: 12px; color: var(--muted); }
.branch-card .bc-money .v { font-size: 17px; font-weight: 700; color: var(--teal); font-variant-numeric: tabular-nums; }
.branch-card .bc-money .s { font-size: 11.5px; color: var(--muted); }
.branch-card .bc-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: auto; padding-top: 6px; border-top: 1px solid var(--line-soft); }
.branch-card .bc-foot .when { font-size: 12px; color: var(--muted); white-space: nowrap; }
.branch-card .bc-actions { display: flex; gap: 6px; }

/* Bars (daily money series) — always LTR (time axis), labelled at the ends */
.chart { direction: ltr; }
.bars { display: flex; align-items: flex-end; gap: 3px; height: 120px; padding-top: 8px; }
.bars .bar { flex: 1; background: var(--teal); opacity: 0.85; border-radius: 3px 3px 0 0; min-height: 2px; cursor: pointer; }
.bars .bar:hover { opacity: 1; }
/* Today is still trading — render it visibly provisional so a mid-afternoon
   short bar doesn't read as a crash. */
.bars .bar.today { opacity: 0.4; }
.bars .bar.today:hover { opacity: 0.6; }
.bars-axis { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--muted); margin-top: 5px; font-variant-numeric: tabular-nums; }
.bars-caption { margin: 8px 0 0; font-size: 12.5px; color: var(--muted); min-height: 1.2em; }
.chart-meta { font-size: 12.5px; color: var(--muted); font-weight: 400; }

/* Forms — fields and their action buttons share one grid, bottom-aligned:
   a wrapping label makes its cell taller, and every input/button hugs the
   same baseline row instead of floating at random heights. */
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin-bottom: 12px; align-items: end; }
.form-grid label { font-size: 12.5px; color: var(--muted); display: block; }
.form-grid input, .form-grid select { width: 100%; margin-top: 4px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; background-color: var(--beige); }
.form-grid select { padding-inline-end: 30px; }
.form-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
/* Form buttons match the field height exactly (inputs land at 34px:
   8px padding + 14px text + 1px border per side) so the action cell sits
   flush with the inputs beside it. */
.form-grid .btn-small { height: 34px; padding: 0 14px; font-size: 14px; border-radius: 8px; }
/* A quiet live hint under a form (Team: the name a login will be saved as). */
.field-hint { margin: -4px 0 8px; font-size: 12.5px; color: var(--muted); }
/* Second page-level section on one tab (Team: head office vs branches) */
.section-gap { margin-top: 26px; }

/* Empty state — replaces a bare header row over one grey sentence */
.empty-state { text-align: center; padding: 22px 12px; color: var(--muted); font-size: 13.5px; line-height: 1.5; }

/* Collapsible panel section — a long table folded behind its heading
   (Sales "By day" / "What sold", Warehouse activity). Styled like the h3. */
.panel-fold summary { cursor: pointer; font-size: 15px; font-weight: 600; color: var(--teal); }
.panel-fold summary:hover { color: var(--teal-dark); }
.panel-fold[open] summary { margin-bottom: 12px; }
.panel-fold summary .fold-meta, .form-fold summary .fold-meta { font-size: 12.5px; color: var(--muted); font-weight: 400; }
/* Quiet headline meta inside a panel title (e.g. the stock panel's total
   value) — visibly subordinate to the h3 it follows. */
.panel-head h3 .fold-meta { font-size: 12.5px; color: var(--muted); font-weight: 500; margin-inline-start: 10px; }

/* Collapsible add-form — repeated forms fold behind one quiet line instead
   of filling every panel. */
.form-fold { margin-top: 10px; }
.form-fold summary { cursor: pointer; font-size: 13.5px; font-weight: 600; color: var(--teal); padding: 4px 0; list-style: none; }
.form-fold summary::-webkit-details-marker { display: none; }
.form-fold summary:hover { color: var(--teal-dark); }
.form-fold[open] summary { margin-bottom: 8px; }
.form-fold .fold-note { font-size: 12.5px; color: var(--muted); margin: 0 0 10px; }


/* Menu preview ("What's on the menu") — collapsible categories + item rows */
.menu-group { margin-bottom: 6px; }
.menu-group summary { cursor: pointer; font-size: 14px; font-weight: 600; color: var(--teal); border-bottom: 1px solid var(--line); padding: 8px 0 7px; }
.menu-group summary:hover { color: var(--teal-dark); }
.menu-group[open] { margin-bottom: 14px; }
.menu-subcat { margin: 10px 0 4px; font-size: 12.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.03em; }
.menu-item-row { display: flex; align-items: center; gap: 12px; padding: 6px 0; border-bottom: 1px solid var(--line-soft); }
.menu-item-row:last-child { border-bottom: 0; }
.menu-item-main { flex: 1; min-width: 0; }
.menu-item-name { font-size: 14px; }
.menu-item-desc { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu-item-opts { font-size: 12px; white-space: nowrap; }
.menu-item-price { font-variant-numeric: tabular-nums; white-space: nowrap; }
.menu-thumb { width: 36px; height: 36px; border-radius: 8px; object-fit: cover; background: var(--beige); border: 1px solid var(--line); flex: none; }
.menu-thumb-empty { display: inline-block; }
/* The master-menu headline (one plain sentence instead of three tiles) */
.master-line { font-size: 16px; font-weight: 700; color: var(--teal); margin: 0 0 2px; }
.master-meta { font-size: 12.5px; color: var(--muted); margin: 0 0 14px; }

/* Inline warning text (e.g. the Team page's branch-offline note) */
.warn-text { color: var(--warn); font-size: 12.5px; }
.warn-text a { color: inherit; }

/* Packing-slip list — the Items cell mirrors the delivery note the same
   people sign: one aligned line per item (name start, labeled quantity end,
   packaging equivalent tucked under the quantity). Alignment does the work
   the old chip borders/backgrounds faked, so a realistic order stays fully
   visible AND calm ("too busy" and "the +N more isn't obvious" were the two
   failure modes this replaced). Span-based (block/grid via CSS) so the SAME
   renderer drops into the action sheet's <p class="sheet-sub"> unchanged;
   34ch keeps the end-aligned quantity near its name on wide cells, and
   overflow-wrap keeps a long item name inside the dialog card. */
.slip { display: block; max-width: 34ch; font-weight: 400; }
.slip-line { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; align-items: baseline; padding-block: 3px; }
.slip-line + .slip-line { border-block-start: 1px solid rgba(28, 38, 40, 0.08); }
/* break-word, NOT anywhere: `anywhere` collapses the grid column's
   min-content to one character, shattering names letter-by-letter in a
   narrow cell; break-word wraps at spaces and only splits a single word
   wider than the whole column. */
.slip-name { overflow-wrap: break-word; font-size: 13.5px; color: var(--ink); }
.slip-qty { justify-self: end; font-weight: 700; font-size: 12.5px; color: var(--teal-dark); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* The equivalent is subordinate to the quantity it decomposes: its own
   full-width grid row, end-aligned directly under the number, small and
   muted. Full-width (1 / -1), NOT column 2 — a wide nowrap equivalent in
   the qty column would inflate that column's min-content and starve the
   name column into letter-splitting at narrow widths. */
.slip-eq { grid-column: 1 / -1; justify-self: end; font-size: 11.5px; color: var(--muted); white-space: nowrap; margin-block-start: -2px; font-variant-numeric: tabular-nums; }
/* The money sub (cost per unit · line value) is longer than a case
   equivalent — let it wrap inside the dialog card instead of overflowing. */
.slip-eq.slip-cost { white-space: normal; text-align: end; }
/* Overflow control for 8+ line orders — a real bordered button (the stock
   table's own "Show all items (N)" grammar), never a quiet token. */
.slip .slip-toggle { margin-block-start: 6px; }

/* A branch's request note — a MESSAGE from a person, styled as a labeled
   quote so it can't be mistaken for data. Span-based so it can render inside
   the action sheet's <p class="sheet-sub"> (a div would close the <p>). The
   clamp lives on the TEXT span only — clamping the container would let the
   block label eat a visible line. Full-ink text: a message must be read, not
   skimmed. border-inline-start flips under RTL; 36ch + overflow-wrap bound a
   1000-char note inside .table-scroll at phone widths. */
.branch-note { display: block; margin-top: 6px; padding: 6px 10px; background: rgba(7, 88, 89, 0.05); border-inline-start: 3px solid var(--teal); border-radius: 8px; max-width: 36ch; font-weight: 400; }
.branch-note-k { display: block; font-size: 11.5px; font-weight: 600; color: var(--teal); margin-bottom: 1px; }
.branch-note-t { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; font-size: 13px; color: var(--ink); overflow-wrap: anywhere; white-space: normal; }
.branch-note.full { max-width: none; margin-top: 10px; }
.branch-note.full .branch-note-t { display: block; -webkit-line-clamp: unset; }

/* Blocked-order shortfall — the amber sibling of .branch-note: a labeled
   warn block ("Not enough in stock") with one name + label:value line per
   uncovered item, and the restock jump link as the block's action. Span-only
   for the same reason (it also renders inside the action sheet's
   <p class="sheet-sub">). Warn colour stays on the label/figures/link;
   item names keep full ink so they stay the readable subject. */
.short-note { display: block; margin-top: 6px; padding: 6px 10px; background: rgba(180, 83, 9, 0.06); border-inline-start: 3px solid var(--warn); border-radius: 8px; max-width: 36ch; font-weight: 400; font-size: 13px; }
.short-note-k { display: block; font-size: 11.5px; font-weight: 600; color: var(--warn); margin-bottom: 1px; }
.short-line { display: block; color: var(--ink); overflow-wrap: anywhere; }
.short-line + .short-line { margin-top: 4px; }
/* Values always sit on their own line under the item name — inline, a
   wrapped long name lets its tail word visually bind to the values ("…
   Tray ordered: 10" reads as an item called "Tray"). */
.short-line .short-vals { display: block; color: var(--warn); font-variant-numeric: tabular-nums; }
/* Each label:value pair stays atomic — narrow cells wrap at the separator,
   never inside a label ("in / stock: 6"). */
.short-vals .short-pair { white-space: nowrap; }
/* The shortfall's money line (Short n · amount) is informative, not the
   alarm — muted so the ordered/in-stock figures stay the loud part. */
.short-line .short-vals.short-cost { color: var(--muted); }
.short-jump { display: inline-block; margin-top: 3px; font-size: 12.5px; font-weight: 600; color: var(--warn); }

/* Home "Needs attention" / set-up rows: one sentence + one labeled jump per
   line. The action keeps to the end edge like td.row-actions does in tables.
   The sentence WRAPS — it is NOT a .cell-status (whose nowrap ran Home off a
   phone screen): the dot hangs beside the first line, the text takes the
   remaining width, and value chips flow after it (wrapping to their own
   line when the row is narrow). */
.attn-list { display: flex; flex-direction: column; }
.attn-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 2px; border-bottom: 1px solid var(--line-soft); }
.attn-row:last-child { border-bottom: 0; }
.attn-main { display: flex; align-items: flex-start; gap: 7px; flex: 1 1 auto; min-width: 0; line-height: 1.45; }
.attn-main > .dot { margin-top: calc(0.725em - 4px); }
.attn-text { min-width: 0; overflow-wrap: break-word; }
.attn-text .vchip { margin-inline-start: 4px; white-space: normal; vertical-align: 1px; }
.attn-act { flex-shrink: 0; }
.attn-clear { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 13.5px; padding: 6px 2px; }

/* The request's tracking number (RQ-000042) — a quiet mono chip; the SAME
   number renders on the branch's Supply page and the delivery note, so the
   two ends of the workflow can quote one code at each other. */
.ref-chip { display: inline-block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; font-weight: 700; letter-spacing: 0.04em; color: var(--teal); background: rgba(7, 88, 89, 0.06); border: 1px solid rgba(7, 88, 89, 0.18); border-radius: 999px; padding: 1px 8px; }

/* Pipeline band headers — the supply table's three sections (ready to ship /
   waiting on stock / on its way) get real labeled dividers; the dot colours
   alone read as one undifferentiated list. */
.band-row td { background: #f3efe4; color: var(--teal); font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; padding-top: 6px; padding-bottom: 6px; border-bottom: 1px solid var(--line); }

/* Jump-target highlight: the shortfall's "restock below" link lights up the
   short items' rows so the eye lands on them, not a wall of stock rows. */
@keyframes row-flash-fade { 0% { background: rgba(180, 83, 9, 0.22); } 100% { background: transparent; } }
.row-flash td { animation: row-flash-fade 2.4s ease-out 1; }

/* The row's labeled sheet opener ("Manage…"): quiet by default; hovering
   anywhere on the row highlights it, tying the button to its row — and a
   row press tints its cells, the only touch feedback for the tap-anywhere
   accelerator on hoverless tablets. */
.menu-btn { font-weight: 600; }
tr.row-sheet:hover .menu-btn, .branch-card.row-sheet:hover .menu-btn { background: rgba(7, 88, 89, 0.08); }
tbody tr.row-sheet:active > td, .branch-card.row-sheet:active { background: var(--hover); }

/* Action sheet — THE one row affordance: full name, one facts line,
   stacked actions. Shares the dialog chrome. Every action renders as a
   real button on the console's hierarchy: solid teal = the one suggested
   act, beige bordered = routine, red = destructive. */
.sheet-sub { margin: -4px 0 14px; font-size: 13px; color: var(--muted); line-height: 1.5; }
.sheet-items { display: flex; flex-direction: column; gap: 8px; margin: 0 0 14px; }
.sheet-items:empty { display: none; margin: 0; }
.sheet-item { display: block; width: 100%; text-align: start; background: var(--beige); border: 1px solid var(--line); border-radius: 10px; padding: 11px 14px; font-size: 14.5px; font-weight: 600; color: var(--teal); cursor: pointer; transition: background-color 0.12s ease, border-color 0.12s ease; }
.sheet-item:hover { background: rgba(7, 88, 89, 0.06); border-color: var(--teal); }
.sheet-item.primary { background: var(--teal); border-color: var(--teal); color: #fff; }
.sheet-item.primary:hover { background: var(--teal-dark); border-color: var(--teal-dark); }
.sheet-item.danger { color: var(--bad); }
.sheet-item.danger:hover { background: rgba(179, 38, 30, 0.06); border-color: var(--bad); }
.row-sheet { cursor: pointer; }
tr.dim-row > td { opacity: 0.55; }
tr.dim-row .row-actions { opacity: 1; }

/* ⓘ — relocates a long explanation behind a tap (one per panel at most) */
.info-dot { width: 18px; height: 18px; border-radius: 999px; border: 1px solid var(--teal); color: var(--teal); background: none; font-size: 11px; font-style: italic; font-weight: 700; font-family: Georgia, serif; line-height: 1; cursor: pointer; vertical-align: 2px; margin-inline-start: 7px; padding: 0; }
.info-dot:hover { background: rgba(7, 88, 89, 0.08); }

/* Hero tile (Overview "Collected today") spans two grid cells on desktop
   and takes the whole row on a phone (a one-column-wide hero clipped its
   own figure). */
.tile.hero { grid-column: span 2; }
.tile.hero .v { font-size: 28px; }
@media (max-width: 640px) { .tile.hero { grid-column: 1 / -1; } }

/* Non-interactive summary chips (Branches header counts) */
.chip.static { cursor: default; background: var(--card); }
.chip.static.bad { color: var(--bad); border-color: #f3c8c5; }
.chip.static.warn { color: var(--warn); border-color: #f0d9b8; }
.chip.static.dim { color: var(--muted); }

/* Team branch accordion — one line per branch until opened */
.team-branch { border-bottom: 1px solid var(--line-soft); padding: 2px 0; }
.team-branch:last-of-type { border-bottom: 0; }
.team-branch > summary { padding: 8px 0; }
.team-branch[open] { padding-bottom: 10px; }

/* Themed dialogs — every confirm/prompt/alert renders as this box (never
   the browser-native popups). */
.dialog-overlay { position: fixed; inset: 0; background: rgba(29, 42, 42, 0.45); display: flex; align-items: center; justify-content: center; z-index: 100; padding: 20px; }
/* max-height + scroll: dialog content is no longer always short (the action
   sheet renders a branch's FULL note, up to 1000 chars) — a centered flex
   child taller than the fixed overlay would otherwise clip at BOTH ends with
   the buttons unreachable. */
.dialog-card { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 22px 24px; width: 440px; max-width: 100%; max-height: calc(100dvh - 40px); overflow-y: auto; box-shadow: 0 12px 40px rgba(7, 88, 89, 0.25); }
.dialog-card h3 { margin: 0 0 8px; color: var(--teal); font-size: 16px; }
.dialog-message { margin: 0 0 16px; font-size: 14px; line-height: 1.45; white-space: pre-line; color: var(--ink); }
.dialog-input { width: 100%; padding: 9px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 14.5px; background: var(--beige); margin-bottom: 16px; }
/* Labelled input inside a dialog (the packaging box) — label text above its
   field, tighter than the bare .dialog-input spacing. */
.dialog-field { display: block; font-size: 13px; color: var(--muted); margin: 0 0 4px; }
.dialog-field .dialog-input { margin: 4px 0 10px; }
.dialog-actions { display: flex; justify-content: flex-end; gap: 8px; }
.btn-small.danger-solid { background: var(--bad); color: #fff; border: 0; }
.btn-small.danger-solid:hover { background: #99201a; }
.notice { font-size: 13px; margin: 8px 0; }
.notice.ok { color: var(--ok); }
.notice.bad { color: var(--bad); }

@media (max-width: 860px) {
  .shell { flex-direction: column; }
  /* Two-row header: brand + account controls on top, a scrollable nav strip
     below — nothing clipped off-screen. Pills carry the active state (the
     desktop accent bar is hidden — it would float mid-strip horizontally). */
  .sidebar { width: 100%; height: auto; position: static; flex-direction: row; flex-wrap: wrap; align-items: center; padding: 10px 0; row-gap: 6px; }
  .brand-row { padding: 0 14px; }
  .sidebar nav { order: 3; flex-direction: row; flex-basis: 100%; overflow-x: auto; padding: 0 8px; -webkit-overflow-scrolling: touch; }
  .sidebar nav a { padding: 8px 12px; }
  .sidebar nav a.active::before { display: none; }
  .sidebar-foot { margin-top: 0; margin-inline-start: auto; flex-direction: row; flex-wrap: wrap; justify-content: flex-end; align-items: center; padding: 0 12px; }
  .main { padding: 18px 14px 40px; }
  .branch-cards { grid-template-columns: 1fr; }
}

/* The roya wordmark set inline in copy (i18n tBrand / data-i18n-brand). Sized
   in em so it tracks the surrounding text: x-height to x-height, baseline on
   the text baseline (the tight crop's descender is ~34% of its height). */
.brand-word { display: inline-block; height: 1.18em; width: auto; max-width: none; vertical-align: -0.4em; margin-inline: 0.06em; }
