/* =====================================================================
   BILLIARDS CLUB — floor board, tabs, café counter and admin screens.
   =====================================================================
   Every colour is a token resolved from gym.css (the --club-* layer, which
   is bridged from the active theme's --c-* primitives). Re-theming the club
   touches gym.css only; this file never writes a colour literal.

   Weight ceiling: 500. Type ceiling: 1.32rem. State is carried by BOTH the
   stripe/label AND colour, so the board reads for a colour-blind operator.
   ===================================================================== */

/* The palette lives on :root, NOT on .bc-page.
   DxPopup, DxDropDown and every DevExpress flyout portal their markup to the end of
   <body>, outside the page element entirely. Scoping these tokens to .bc-page meant a
   dialog resolved var(--line-2) to nothing, so `border: 1px solid var(--line-2)`
   collapsed to 0px and every background fell back to transparent — the dialogs rendered
   black-and-white with no borders. Anchoring at the root is the only scope a portal
   cannot escape. Do not narrow this selector again. */
:root {
  --bg:      var(--club-bg);
  --panel:   var(--club-panel);
  --panel-2: var(--club-panel-2);
  --line:    var(--club-line);
  --line-2:  var(--club-line-strong);
  --ink:     var(--club-ink);
  --ink-2:   var(--club-ink-soft);
  --ink-3:   var(--club-ink-mute);
  --accent:     var(--club-accent);
  --accent-ink: var(--club-accent-ink);
  --accent-tx:  var(--club-accent-text);
  --accent-bg:  var(--club-accent-bg);

  --st-success: var(--club-success);  --st-success-bg: var(--club-success-bg);
  --st-warning: var(--club-warn);     --st-warning-bg: var(--club-warn-bg);
  --st-info:    var(--club-info);      --st-info-bg:    var(--club-info-bg);
  --st-danger:  var(--club-danger);    --st-danger-bg:  var(--club-danger-bg);
  --st-neutral: var(--club-neutral);   --st-neutral-bg: var(--club-neutral-bg);
}

.bc-page {
  background: var(--bg);
  color: var(--ink);
  /* Tight at the top: the page name moved into the module bar, so what is left up
     here is the action row and it should not reserve a block of its own. */
  padding: 12px 22px 24px;
  border-radius: var(--gym-radius, 12px);
  font-size: 11.5px;
  line-height: 1.55;
  min-height: calc(100vh - 30px);   /* app-content padding: 10px top + 20px bottom */
}

.bc-page h2, .bc-page h3, .bc-page b, .bc-page strong { font-weight: 500; }

/* ── header ───────────────────────────────────────────────────────────
   The page NAME and its line of detail moved into the module bar (.mod-page in
   gym.css), where they sit beside the menu instead of costing the page a block
   of its own. What is left here is the action row.

   The h2/p stay in the markup on the other pages and are hidden rather than
   deleted: the bar renders the same name from AppModules, and one hidden pair of
   elements beats editing twenty-one files to say the same thing.

   flex-end, not space-between: FloorBoard has already dropped its title block, so
   its .bc-head holds only the actions, and space-between would strand those on the
   left while every other page kept them right. */
.bc-head {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 14px; flex-wrap: wrap; margin-bottom: 8px; min-height: 0;
}
.bc-head .bc-title, .bc-head .bc-sub { display: none; }
.bc-head-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* An action row with nothing in it must not leave a gap. */
.bc-head:empty, .bc-head > div:only-child:empty { display: none; }

/* ── buttons ──────────────────────────────────────────────── */
.bc-btn {
  font: inherit; font-size: 11px; font-weight: 500;
  padding: 8px 15px; border-radius: 8px;
  border: 1px solid var(--line-2); background: var(--panel-2); color: var(--ink-2);
  cursor: pointer; transition: border-color .12s ease, color .12s ease, background .12s ease;
}
.bc-btn:hover { border-color: var(--accent); color: var(--ink); }
.bc-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.bc-btn:disabled { opacity: .45; cursor: not-allowed; }
.bc-btn.bc-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 500; }
.bc-btn.bc-primary:hover { filter: brightness(1.05); }
.bc-btn.bc-wide { grid-column: 1 / -1; }
.bc-btn.bc-ghost { background: transparent; }
.bc-x { background: none; border: none; color: inherit; font-size: 13px; cursor: pointer; line-height: 1; padding: 2px 4px; }
.bc-x:hover { color: var(--accent); }

/* ── alert ────────────────────────────────────────────────── */
.bc-alert {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; border-radius: 8px; margin: 12px 0;
  border: 1px solid var(--line); background: var(--panel-2); font-size: 11px;
}
.bc-alert span { flex: 1; }
.bc-alert-ok { background: var(--st-success-bg); border-color: var(--st-success); color: var(--st-success); }
.bc-alert-danger { background: var(--st-danger-bg); border-color: var(--st-danger); color: var(--st-danger); }
/* Not an error — something the operator must take in before they commit, e.g. that
   charging to an account takes no money now. */
.bc-alert-warn { background: var(--st-warning-bg); border-color: var(--st-warning); color: var(--st-warning); }

/* ── summary cards (KPIs) ─────────────────────────────────── */
.bc-kpis {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px; margin: 16px 0;
}
.bc-kpi {
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 13px 16px; display: flex; flex-direction: column; gap: 2px;
}
.bc-kpi-label { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); font-weight: 500; }
.bc-kpi-val { font-size: 1.23rem; font-weight: 500; line-height: 1.15; font-variant-numeric: tabular-nums; color: var(--ink); }
.bc-kpi-val.bc-accent { color: var(--accent-tx); }
.bc-kpi-sub { font-size: 10px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

/* ── layout ───────────────────────────────────────────────── */
.bc-layout { display: grid; grid-template-columns: minmax(0,1fr) 340px; gap: 18px; align-items: start; }
.bc-board { display: flex; flex-direction: column; gap: 20px; }

.bc-area { display: flex; flex-direction: column; gap: 11px; }
.bc-area-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.bc-area-name { font-size: 10px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2); }
.bc-area-rule { flex: 1; height: 1px; background: var(--line); min-width: 20px; }
.bc-area-meta { font-size: 10px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

/* ── tiles ────────────────────────────────────────────────── */
.bc-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 12px; }

.bc-tile {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 7px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 13px 14px; min-height: 138px;
  text-align: left; font: inherit; color: var(--ink); cursor: pointer;
  transition: border-color .12s ease, transform .12s ease, box-shadow .12s ease;
}
.bc-tile::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--st-neutral); }
.bc-tile:hover { border-color: var(--accent); transform: translateY(-1px); }
.bc-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.bc-tile.bc-selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }

.bc-tile-head { display: flex; align-items: baseline; justify-content: space-between; gap: 6px; }
.bc-tile-name { font-size: 12.5px; font-weight: 500; }
.bc-tile-type { font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); font-weight: 500; }

.bc-pill {
  align-self: flex-start;
  font-size: 10px; letter-spacing: .09em; text-transform: uppercase; font-weight: 500;
  padding: 3px 8px; border-radius: 5px;
  background: var(--st-neutral-bg); color: var(--ink-3); white-space: nowrap;
}

.bc-timer {
  font-size: 1.41rem; font-weight: 500; line-height: 1; letter-spacing: -.02em; margin-top: auto;
  color: var(--ink-3); font-variant-numeric: tabular-nums;
}

.bc-tile-foot {
  display: flex; justify-content: space-between; gap: 6px;
  padding-top: 8px; border-top: 1px solid var(--line);
  font-size: 10px; color: var(--ink-3); font-variant-numeric: tabular-nums;
}
.bc-tile-foot b { color: var(--ink); font-weight: 500; }

/* state — stripe, pill and timer key off one token */
.bc-tile.bc-success::before { background: var(--st-success); }
.bc-tile.bc-success .bc-pill { background: var(--st-success-bg); color: var(--st-success); }
.bc-tile.bc-success .bc-timer { color: var(--st-success); }
.bc-tile.bc-warning::before { background: var(--st-warning); }
.bc-tile.bc-warning .bc-pill { background: var(--st-warning-bg); color: var(--st-warning); }
.bc-tile.bc-warning .bc-timer { color: var(--st-warning); }
.bc-tile.bc-info::before { background: var(--st-info); }
.bc-tile.bc-info .bc-pill { background: var(--st-info-bg); color: var(--st-info); }
.bc-tile.bc-danger::before { background: var(--st-danger); }
.bc-tile.bc-danger .bc-pill { background: var(--st-danger-bg); color: var(--st-danger); }
.bc-tile.bc-neutral { border-style: dashed; }

.bc-pill-success { background: var(--st-success-bg); color: var(--st-success); }
.bc-pill-warning { background: var(--st-warning-bg); color: var(--st-warning); }
.bc-pill-info    { background: var(--st-info-bg);    color: var(--st-info); }
.bc-pill-danger  { background: var(--st-danger-bg);  color: var(--st-danger); }
.bc-pill-neutral { background: var(--st-neutral-bg); color: var(--ink-3); }

/* Timer glow on the dark themes only (var(--c-glow):1). */
[data-club-theme="felt"] .bc-timer,
[data-club-theme="midnight"] .bc-timer,
[data-club-theme="graphite"] .bc-timer,
[data-club-theme="felt"] .bc-dock-big,
[data-club-theme="midnight"] .bc-dock-big,
[data-club-theme="graphite"] .bc-dock-big { text-shadow: 0 0 16px currentColor; }
/* Felt table-felt gradient on the page + tiles. */
[data-club-theme="felt"] .bc-page { background: radial-gradient(1200px 420px at 30% -10%, #16241c 0%, var(--bg) 62%); }
[data-club-theme="felt"] .bc-tile { background: linear-gradient(180deg, #18231d 0%, #141d18 100%); }

/* ── dock ─────────────────────────────────────────────────── */
.bc-dock {
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 15px 17px; display: flex; flex-direction: column; min-width: 0;
}
.bc-dock-head { display: flex; flex-direction: column; gap: 3px; padding-bottom: 11px; border-bottom: 1px solid var(--line); }
.bc-dock-title { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 13px; font-weight: 500; }
.bc-dock-meta { font-size: 10px; color: var(--ink-3); }
.bc-dock-timer { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 13px 0; border-bottom: 1px solid var(--line); }
.bc-dock-big { font-size: 1.76rem; font-weight: 500; line-height: 1; letter-spacing: -.02em; color: var(--st-success); font-variant-numeric: tabular-nums; }
.bc-dock-big.bc-warn { color: var(--st-warning); }
.bc-dock-rules { font-size: 10px; color: var(--ink-3); text-align: right; line-height: 1.6; font-variant-numeric: tabular-nums; }

.bc-lines { flex: 1; overflow: auto; min-height: 50px; padding: 2px 0; }
.bc-line { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 11px; }
.bc-line-time { background: var(--accent-bg); margin: 0 -9px; padding: 8px 9px; border-radius: 6px; }
.bc-line-sub { display: block; font-size: 10px; color: var(--ink-3); }
.bc-amt { font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 500; color: var(--ink); }

.bc-totals { padding-top: 11px; }
.bc-trow { display: flex; justify-content: space-between; gap: 10px; padding: 2px 0; font-size: 10.5px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.bc-trow.bc-grand { font-size: 0.97rem; font-weight: 500; color: var(--accent-tx); padding-top: 7px; margin-top: 4px; border-top: 1px solid var(--line-2); }

.bc-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding-top: 13px; }
/* Pause · Transfer · Café share one line on a running table; Stop session keeps its own
   full-width row below (it carries .bc-wide, which already spans 1 / -1). */
.bc-actions.bc-actions-3 { grid-template-columns: repeat(3, 1fr); }
.bc-actions.bc-actions-3 .bc-btn { justify-content: center; padding-left: 6px; padding-right: 6px; }

.bc-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 34px 20px; color: var(--ink-3); text-align: center; font-size: 11px;
}

/* ── modals ───────────────────────────────────────────────── */
.bc-modal-back { position: fixed; inset: 0; background: var(--club-overlay); z-index: 900; backdrop-filter: blur(2px); }
.bc-modal {
  position: fixed; z-index: 901; top: 50%; left: 50%; transform: translate(-50%,-50%);
  width: min(420px, calc(100vw - 32px)); max-height: 88vh; overflow: auto;
  background: var(--panel); color: var(--ink);
  border: 1px solid var(--line-2); border-radius: 12px; padding: 18px 20px;
  display: flex; flex-direction: column; gap: 10px;
  box-shadow: 0 18px 50px rgba(0,0,0,.4);
}
.bc-modal h3 { margin: 0 0 4px; font-size: 0.92rem; font-weight: 500; }

/* ── DxPopup dialogs (.bc-popup) ──────────────────────────────
   DevExpress paints the surface itself from --dxbl-popup-* (bridged to the theme in
   gym.css). What it does NOT do is give the body the club's vertical rhythm, so
   without this a dialog was a stack of controls jammed against each other. Everything
   below is spacing and separators only — the colours stay DevExpress's. */
.bc-popup .dxbl-modal-body,
.bc-popup .dxbl-popup-body { display: flex; flex-direction: column; gap: 10px; }

/* The title sits on an accent tint, so the dialog re-colours with the skin like
   everything else. This goes through DevExpress's own --dxbl-popup-header-bg, declared
   HERE on the popup root because DevExpress declares it on .dxbl-modal — an ancestor —
   and the nearer declaration is the one that wins.

   No border-bottom here on purpose: DevExpress already draws a themed 1px divider under
   the header, and an added accent rule loses to its own deeper selectors anyway. The
   tint plus that divider is enough to read as header + content. */
.bc-popup {
  --dxbl-popup-header-bg: var(--accent-bg);
  --dxbl-popup-header-color: var(--ink);
}

/* Actions sit below a divider, hard right, sized to their text — a full-width 50/50
   split made "Cancel" as loud as "Start". */
.bc-popup .bc-actions {
  display: flex; justify-content: flex-end; gap: 8px;
  margin-top: 4px; padding-top: 13px;
  border-top: 1px solid var(--line);
}
.bc-popup .bc-actions .bc-btn { min-width: 92px; justify-content: center; }

/* Segmented pickers (player count, and anything else offering a small fixed set):
   the selected one is filled with the accent, the rest are outlined. */
.bc-players .bc-btn { justify-content: center; }
.bc-label { font-size: 10px; font-weight: 500; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-2); }
/* .bc-input wraps a DevExpress editor (DxTextBox/DxComboBox/DxSpinEdit/DxMemo), which
   draws its OWN themed field. So the wrapper only sizes it — no second border or
   background, which is what made fields look doubled-up before. */
.bc-input { width: 100%; font: inherit; }
/* Plain <input>/<textarea> that carry .bc-input directly (rare) still get full chrome. */
input.bc-input, textarea.bc-input, select.bc-input {
  font: inherit; font-size: 11.5px; padding: 8px 11px; border-radius: 8px;
  border: 1px solid var(--line-2); background: var(--panel-2); color: var(--ink);
}
input.bc-input:focus-visible, textarea.bc-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.bc-row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.bc-players { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.bc-hint { font-size: 10px; color: var(--ink-3); line-height: 1.5; margin: 0; }

.bc-quote { background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 12px 14px; display: flex; flex-direction: column; gap: 4px; }
.bc-qrow { display: flex; justify-content: space-between; gap: 12px; font-size: 11px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.bc-qtotal { font-size: 0.92rem; font-weight: 500; color: var(--accent-tx); padding-top: 6px; margin-top: 4px; border-top: 1px dashed var(--line-2); }

/* ── responsive ───────────────────────────────────────────── */
@media (max-width: 1100px) {
  .bc-layout { grid-template-columns: 1fr; }
  .bc-tiles { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
}
@media (max-width: 640px) {
  .bc-tiles { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .bc-tile { min-height: 120px; }
  .bc-timer { font-size: 1.23rem; }
}

/* ── open tabs ────────────────────────────────────────────── */
.bc-tabs-list { display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.bc-tabcard {
  display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start;
  gap: 5px; width: 100%; text-align: left; padding: 12px 15px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px; color: var(--ink);
  cursor: pointer; transition: border-color .12s ease, transform .12s ease;
}
.bc-tabcard:hover { border-color: var(--accent); transform: translateY(-1px); }
.bc-tabcard.bc-selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.bc-tabcard-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.bc-tabcard-name { font-size: 12px; font-weight: 500; }
.bc-tabcard-meta { font-size: 10px; color: var(--ink-3); }
.bc-tabcard-foot {
  display: flex; align-items: baseline; gap: 14px; padding-top: 7px;
  border-top: 1px solid var(--line); font-size: 10px; color: var(--ink-3); font-variant-numeric: tabular-nums;
}
.bc-tabcard-foot b { color: var(--ink); font-weight: 500; }
.bc-tabcard-total { margin-left: auto; font-size: 11.5px; font-weight: 500; color: var(--accent-tx); }

/* ── café counter ─────────────────────────────────────────── */
.bc-menu { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.bc-cats { display: flex; flex-wrap: wrap; gap: 6px; }
.bc-menu-search { max-width: 340px; }

.bc-items { display: grid; grid-template-columns: repeat(auto-fill, minmax(138px, 1fr)); gap: 10px; }
.bc-item {
  display: flex; flex-direction: column; align-items: flex-start; justify-content: space-between;
  gap: 4px; padding: 12px 13px; min-height: 72px; width: 100%; text-align: left;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px; color: var(--ink);
  cursor: pointer; transition: border-color .12s ease, transform .12s ease;
}
.bc-item:hover { border-color: var(--accent); transform: translateY(-1px); }
.bc-item-name { font-size: 11px; font-weight: 500; line-height: 1.25; }
.bc-item-price { font-size: 10px; font-weight: 500; color: var(--accent-tx); font-variant-numeric: tabular-nums; }

.bc-line-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.bc-qty { display: inline-flex; align-items: center; gap: 4px; }
.bc-qty-val { min-width: 22px; text-align: center; font-variant-numeric: tabular-nums; font-weight: 500; }

.bc-pick-row {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  width: 100%; text-align: left; padding: 10px 13px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; color: var(--ink);
  cursor: pointer; transition: border-color .12s ease;
}
.bc-pick-row:hover { border-color: var(--accent); }

/* add-item row (purchase invoice line editor) */
.bc-additem { display: grid; grid-template-columns: 1fr 88px 108px auto; gap: 8px; align-items: center; margin-bottom: 10px; }
.bc-additem-prod, .bc-additem-qty, .bc-additem-cost { min-width: 0; }
@media (max-width: 560px) { .bc-additem { grid-template-columns: 1fr 1fr; } }

/* ── admin screens ────────────────────────────────────────── */
.bc-filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 12px 0; }
.bc-filter-grow { flex: 1 1 220px; min-width: 180px; }
.bc-filter-w { width: 170px; }
.bc-row3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
.bc-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.bc-rowbtns { display: flex; gap: 6px; }
.bc-inherit { color: var(--ink-3); }
.bc-modal-wide { width: min(560px, calc(100vw - 32px)); }
.bc-test-result { font-size: 11px; color: var(--ink-2); padding: 5px 10px; background: var(--accent-bg); border-radius: 6px; white-space: nowrap; }
.bc-test-result b { color: var(--accent-tx); font-weight: 500; }

/* grids on the club ground */
.bc-grid { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; }
.bc-page .dxbl-grid { --dxbl-grid-bg: var(--panel); --dxbl-grid-color: var(--ink); }

/* ── forms: field layout + DevExpress editor alignment ────── */
/* Two- and three-up field rows stack each label above its editor with a steady gap,
   so every dialog reads the same. */
.bc-row2 > div, .bc-row3 > div { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bc-row2 .bc-label, .bc-row3 .bc-label { margin: 0; }

/* A label sitting directly above a field in a modal — keep them visually paired. */
.bc-modal .bc-label { margin-bottom: -4px; }
.bc-modal .bc-label + .bc-input { margin-top: 0; }

/* DevExpress editors adopt the club field metrics: full width, rounded, our surface. */
.bc-page .bc-input, .bc-modal .bc-input { width: 100%; }
.bc-input .dxbl-edit-outer,
.bc-input .dxbl-textbox,
.bc-input .dxbl-combobox,
.bc-input .dxbl-spinedit,
.bc-input .dxbl-memo { border-radius: 8px; }

/* Checkboxes get a little air so they don't crowd the field above. */
.bc-modal .dxbl-checkbox { margin: 2px 0; }

/* ── VAT return ───────────────────────────────────────────── */
.bc-vat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px,1fr)); gap: 12px; margin: 14px 0; }
.bc-vat-block { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 14px 16px; display: flex; flex-direction: column; gap: 3px; }
.bc-vat-head { font-size: 10px; font-weight: 500; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); padding-bottom: 8px; margin-bottom: 4px; border-bottom: 1px solid var(--line); }
.bc-vat-total { font-weight: 500; color: var(--ink); padding-top: 7px; margin-top: 4px; border-top: 1px dashed var(--line-2); }
.bc-vat-net { border-color: var(--accent); }

/* ── motion: expo-out easing + subtle press scale (design-system guidance) ── */
.bc-btn, .bc-tile, .bc-item, .bc-tabcard, .bc-pick-row { transition-timing-function: var(--gym-ease, ease); }
.bc-btn:active, .bc-tile:active, .bc-item:active, .bc-tabcard:active, .bc-pick-row:active { transform: scale(.985); }
.bc-btn.bc-primary:active { transform: scale(.985); filter: brightness(1.03); }

/* ── peak-hours heatmap ────────────────────────────────────────────────
   Day-of-week down, hour-of-day across.

   Built from divs, not <table>: this codebase renders every matrix that way to
   keep the DevExpress-only rule (the same reason the receipt lays its lines out
   with flex). ARIA roles carry the grid semantics a table element would have
   given us, so a screen reader still reads it as rows and cells.

   The cell fill is a SEQUENTIAL scale — one hue stepping light->dark, because
   what is being encoded is magnitude. Colour is never the only channel: every
   cell carries its numbers in a tooltip, the busiest cell is labelled on the
   face of the chart, and a full table view sits beside it. */
.bc-heat-wrap { overflow-x: auto; padding-bottom: 4px; }
.bc-heat { display: inline-grid; gap: 2px; margin: 4px 0 2px; }
.bc-heat-row { display: contents; }
.bc-heat-hh, .bc-heat-day {
  font-size: 10px; font-weight: 500; color: var(--ink-3);
  display: flex; align-items: center; white-space: nowrap;
}
.bc-heat-hh { justify-content: center; padding: 2px 0; }
.bc-heat-day { justify-content: flex-end; padding-right: 8px; }
.bc-heat-cell {
  width: 30px; height: 26px; border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; font-variant-numeric: tabular-nums; color: var(--ink-3);
  background: var(--panel-2); border: 1px solid var(--line);
}
/* The four magnitude steps. Ink flips to the accent's own contrast colour on the
   fills, where body ink would not hold up. */
.bc-heat-cell.h1 { background: var(--club-heat-1); border-color: var(--club-heat-1); color: var(--accent-ink); }
.bc-heat-cell.h2 { background: var(--club-heat-2); border-color: var(--club-heat-2); color: var(--accent-ink); }
.bc-heat-cell.h3 { background: var(--club-heat-3); border-color: var(--club-heat-3); color: var(--accent-ink); }
.bc-heat-cell.h4 { background: var(--club-heat-4); border-color: var(--club-heat-4); color: var(--accent-ink); }
.bc-heat-cell.h0 { color: transparent; }
/* The busiest hour is called out directly rather than left for the reader to hunt. */
.bc-heat-cell.bc-heat-peak { outline: 2px solid var(--ink); outline-offset: 1px; font-weight: 500; }
.bc-heat-cell:hover { outline: 2px solid var(--accent-tx); outline-offset: 1px; }

.bc-heat-legend { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 10px; font-size: 10px; color: var(--ink-3); }
.bc-heat-key { display: inline-flex; align-items: center; gap: 5px; }
.bc-heat-sw { width: 16px; height: 12px; border-radius: 3px; border: 1px solid var(--line); display: inline-block; }
.bc-heat-sw.h0 { background: var(--panel-2); }
.bc-heat-sw.h1 { background: var(--club-heat-1); border-color: var(--club-heat-1); }
.bc-heat-sw.h2 { background: var(--club-heat-2); border-color: var(--club-heat-2); }
.bc-heat-sw.h3 { background: var(--club-heat-3); border-color: var(--club-heat-3); }
.bc-heat-sw.h4 { background: var(--club-heat-4); border-color: var(--club-heat-4); }

/* Forced-colours / high-contrast: fills stop carrying meaning, so show the number
   in every cell rather than a grid of identical boxes. */
@media (forced-colors: active) {
  .bc-heat-cell.h1, .bc-heat-cell.h2, .bc-heat-cell.h3, .bc-heat-cell.h4 {
    background: Canvas; color: CanvasText; border-color: CanvasText;
  }
  .bc-heat-cell.h0 { color: CanvasText; }
}

/* Boot splash: what fills the page while the saved session is being restored.
   Centres in the viewport because at this point there is no layout around it yet. */
.bc-boot { display: flex; align-items: center; justify-content: center; min-height: 60vh; background: var(--bg); }

/* ── floor-board insight card ──────────────────────────────────────────
   The floor board's five figures, moved out of the top band and into the right
   rail so the tables start at the top of the page.

   Deliberately NOT restyling .bc-kpi: six other screens use those cards and the
   top band is right for them — it is only the floor board, where the tiles are
   the whole point, that could not afford the height. */
.bc-rail { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

.bc-insight {
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 13px 16px 15px; display: flex; flex-direction: column; gap: 3px;
}
.bc-insight-head {
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-3); font-weight: 500; padding-bottom: 9px;
  border-bottom: 1px solid var(--line); margin-bottom: 10px;
}
.bc-insight-occ { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.bc-insight-big {
  font-size: 1.58rem; font-weight: 500; line-height: 1; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.bc-insight-of { font-size: 0.92rem; font-weight: 500; color: var(--ink-3); }
.bc-insight-occ-sub { font-size: 10px; color: var(--ink-3); }

/* Occupancy restated as a bar. It never carries meaning on its own — the count
   and the percentage sit directly above it. */
.bc-insight-bar {
  height: 5px; border-radius: 3px; background: var(--panel-2);
  border: 1px solid var(--line); overflow: hidden; margin: 9px 0 12px;
}
.bc-insight-bar > span { display: block; height: 100%; background: var(--accent); }

.bc-insight-rows { display: flex; flex-direction: column; gap: 1px; }
.bc-insight-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-size: 11px; color: var(--ink-2); padding: 4px 0;
  font-variant-numeric: tabular-nums;
}
.bc-insight-row > span:last-child { color: var(--ink); font-weight: 500; }
.bc-insight-lead { padding-bottom: 1px; }
.bc-insight-lead > span:last-child { font-size: 1.01rem; color: var(--accent-tx); }
.bc-insight-note { font-size: 10px; color: var(--ink-3); padding-bottom: 7px; border-bottom: 1px dashed var(--line-2); margin-bottom: 4px; }

/* On one column the rail drops under the board, so the card must not stretch. */
@media (max-width: 1100px) {
  .bc-insight-big { font-size: 1.41rem; }
}

/* ── the diary on the tile ─────────────────────────────────────────────
   A free table can still be spoken for. This is the only thing on a tile that
   is about the future, so it sits apart from the money row. */
.bc-tile-booking {
  display: flex; align-items: center; gap: 5px;
  margin-top: 2px; padding-top: 6px; border-top: 1px dashed var(--line-2);
  font-size: 10px; color: var(--ink-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Inside half an hour it stops being a note and becomes a warning. Colour is not
   carrying it alone — the label itself changes to "in 12m". */
.bc-tile-booking-soon { color: var(--st-warning); font-weight: 500; }

/* ── flat rate on the tile ─────────────────────────────────────────────
   A table on an agreed price is not running a meter, and the money figure above
   is not what they will pay. Saying "flat 200" next to it is what stops an
   operator quoting the metered number by mistake. */
.bc-tile-flat {
  display: flex; align-items: center; gap: 5px;
  margin-top: 2px; padding-top: 6px; border-top: 1px dashed var(--line-2);
  font-size: 10px; font-weight: 500; color: var(--st-info);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── a reminder that has come due ──────────────────────────────────────
   Only rendered once the minute has passed AND nobody has acknowledged it, so
   its presence is the whole signal. It stays until somebody deals with the
   table, which is the point — a nudge that clears itself teaches staff to
   ignore nudges. */
.bc-tile-remind {
  display: flex; align-items: center; gap: 5px;
  margin-top: 2px; padding-top: 6px; border-top: 1px dashed var(--line-2);
  font-size: 10px; font-weight: 600; color: var(--st-warning);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── undo bar on the cafe tab ──────────────────────────────────────────
   Sits between the tab header and its lines, where the line just vanished from. */
.bc-undo { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.bc-undo-actions { display: flex; gap: 6px; flex-shrink: 0; }

/* ── bought time on the tile ───────────────────────────────────────────
   Sits directly under the clock, because the two are read together: how long
   they have played, and how long they have left. The words carry the state —
   "18 min left" becomes "over by 2 min" — so colour is only reinforcing it. */
.bc-tile-countdown {
  font-size: 10px; color: var(--ink-3); font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
}
.bc-tile-countdown-soon { color: var(--st-warning); font-weight: 600; }

/* The light did not answer. Rare, and worth interrupting the tile for: a lamp
   left on over an empty table is money burning quietly. */
.bc-tile-lightfail {
  display: flex; align-items: center; gap: 5px;
  margin-top: 2px; font-size: 10px; color: var(--st-danger);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* A quote row that has turned into a warning — running out of bought time. */
.bc-qwarn, .bc-qwarn > span:last-child { color: var(--st-warning); font-weight: 500; }

/* ── bookings page ─────────────────────────────────────────────────────── */
.bc-bookings { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.bc-booking {
  display: grid; grid-template-columns: 86px minmax(0,1fr) auto; gap: 14px; align-items: center;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 11px 14px;
}
/* Past its time and still holding a table. */
.bc-booking-late { border-color: var(--st-warning); background: var(--st-warning-bg); }
/* Seated, cancelled or a no-show — done with, so it recedes. */
.bc-booking-done { opacity: .62; }

.bc-booking-when { display: flex; flex-direction: column; gap: 1px; }
.bc-booking-time { font-size: 1.01rem; font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.1; }
.bc-booking-mins { font-size: 10px; color: var(--ink-3); }

.bc-booking-who { min-width: 0; }
.bc-booking-name { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 500; color: var(--ink); flex-wrap: wrap; }
.bc-booking-meta { font-size: 10px; color: var(--ink-3); margin-top: 2px; }
.bc-booking-note { font-size: 10px; color: var(--ink-2); margin-top: 3px; font-style: italic; }

.bc-booking-do { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }

@media (max-width: 760px) {
  .bc-booking { grid-template-columns: 1fr; gap: 8px; }
  .bc-booking-do { justify-content: flex-start; }
}

/* ── printing a report ─────────────────────────────────────────────────
   Until now Print sent the whole application to the printer: module bar, buttons,
   filter row, the lot. What a report needs on paper is the club's name, what the
   report is, the period, and the figures — nothing else.

   The masthead is hidden on screen (the module bar already says all of it) and
   only appears on paper, where none of that chrome survives. */
.bc-printhead { display: none; }

@media print {
  /* Ink and paper: force the light end regardless of the club's screen theme.
     A dark theme printed literally is a black rectangle and an empty cartridge. */
  :root {
    --bg:#fff; --panel:#fff; --panel-2:#fff;
    --ink:#000; --ink-2:#222; --ink-3:#555;
    --line:#bbb; --line-2:#888;
    --accent:#000; --accent-tx:#000; --accent-bg:transparent; --accent-ink:#fff;
  }
  /* Page size and margin now come from ReportPrintHead, which knows the club's
     setting. Nothing here, or it would fight the rule that does. */

  html, body { background:#fff !important; color:#000 !important; height:auto !important; overflow:visible !important; }
  .app-shell { display:block !important; height:auto !important; overflow:visible !important; }
  .app-content { padding:0 !important; overflow:visible !important; height:auto !important; }

  /* Chrome that means nothing on paper. */
  .bc-printhead-logo { max-height:52px; max-width:180px; object-fit:contain; display:block; margin-bottom:4px; }

  .mod-bar, .bc-head, .bc-filters, .bc-head-actions, .bc-x,
  .dxbl-pager, .dxbl-modal, .dxbl-popup, #blazor-error-ui { display:none !important; }

  .bc-page { padding:0 !important; min-height:0 !important; border-radius:0 !important; background:#fff !important; }

  /* The masthead, paper only. */
  .bc-printhead {
    display:flex !important; justify-content:space-between; align-items:flex-start; gap:16px;
    padding-bottom:8px; margin-bottom:12px; border-bottom:1.5px solid #000;
  }
  .bc-printhead-club, .bc-printhead-doc { display:flex; flex-direction:column; gap:1px; }
  .bc-printhead-doc { text-align:right; }
  .bc-printhead-name  { font-size:13px; font-weight:500; }
  .bc-printhead-title { font-size:13px; font-weight:500; }
  .bc-printhead-addr, .bc-printhead-period, .bc-printhead-when { font-size:9.5px; color:#444; }

  /* Cards flatten to a plain row of figures; borders cost ink and say nothing. */
  .bc-vat-grid { display:grid !important; grid-template-columns:repeat(3,1fr) !important; gap:8px !important; margin:0 0 10px !important; }
  .bc-vat-block { border:1px solid #999 !important; background:#fff !important; padding:6px 8px !important; break-inside:avoid; }
  .bc-insight, .bc-dock, .bc-tile { background:#fff !important; border-color:#999 !important; }

  /* Grids: repeat the header on every sheet and never split a row across pages. */
  .dxbl-grid { border:1px solid #999 !important; border-radius:0 !important; }
  .dxbl-grid .dxbl-grid-table { width:100% !important; }
  .dxbl-grid .dxbl-grid-table thead { display:table-header-group; }
  .dxbl-grid .dxbl-grid-table tr { break-inside:avoid; page-break-inside:avoid; }
  .dxbl-grid, .dxbl-grid .dxbl-grid-table { font-size:9.5px !important; }
  .dxbl-grid .dxbl-grid-table > tbody > tr > td,
  .dxbl-grid .dxbl-grid-table > thead > tr > th { border-color:#ccc !important; padding:2px 5px !important; }
  /* The virtualised grid clips to a scroll box on screen; on paper it must run on. */
  .dxbl-grid, .dxbl-grid * { max-height:none !important; overflow:visible !important; }

  .bc-heat-wrap { overflow:visible !important; }
  .bc-alert { border:1px solid #999 !important; background:#fff !important; color:#000 !important; }
  .bc-hint { color:#444 !important; }
  a[href]::after { content:""; }   /* no URL footnotes */
}

/* ── the station, drawn as the thing it is ─────────────────────────────
   A table on the tile so the floor reads as a floor. Colours come from the
   --club-felt / --club-ball-* tokens in gym.css; nothing is written here. */
.bc-felt { display: block; width: 100%; line-height: 0; margin-bottom: 1px; }
.bc-felt-svg { display: block; width: 100%; height: auto; border-radius: 6px; }

.bc-felt-rail   { fill: var(--club-rail); }
.bc-felt-cloth  { fill: var(--club-felt); }
.bc-felt-pocket { fill: var(--club-pocket); }
.bc-felt-line   { stroke: var(--club-felt-line); stroke-width: 1.1; }
.bc-felt-mark   { fill: var(--club-pocket); opacity: .75; }

/* Console: its own materials, so it cannot be mistaken for a table. */
.bc-felt-screen  { fill: var(--club-console-2); }
.bc-felt-pad     { fill: var(--club-console); }
.bc-felt-padmark { fill: var(--club-console-mk); }
.bc-felt-stick   { fill: var(--club-console-2); stroke: var(--club-console-mk); stroke-width: 1; }

.bc-felt-cue    { fill: var(--club-ball-cue); }
.bc-felt-ball-1 { fill: var(--club-ball-1); }
.bc-felt-ball-2 { fill: var(--club-ball-2); }
.bc-felt-ball-3 { fill: var(--club-ball-3); }
.bc-felt-ball-4 { fill: var(--club-ball-4); }

/* Snooker keeps the darker cloth its name implies. */
.bc-felt-snooker .bc-felt-cloth { fill: var(--club-felt-snooker); }

/* State on the cloth as well as on the pill:
   a free table sits quietly, a running one is at full strength, an out-of-service
   one drains to grey so it cannot be mistaken for playable. */
.bc-felt-free   .bc-felt-svg { opacity: .72; }
.bc-felt-paused .bc-felt-svg { opacity: .8; filter: saturate(.55); }
.bc-felt-down   .bc-felt-svg { filter: grayscale(1); opacity: .38; }

/* The tile grows to fit the picture; the timer and the money keep their place. */
.bc-tile { min-height: 172px; }

@media (max-width: 640px) {
  /* On a phone the numbers matter more than the picture. */
  .bc-felt { display: none; }
  .bc-tile { min-height: 138px; }
}

/* ── waiting list ──────────────────────────────────────────────────────
   A queue is read top-down and acted on from the top, so each row leads with
   how long they have stood there — that is the number that decides who gets
   the next table, and it belongs where the eye lands first. */
.bc-waitlist { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }

.bc-wait {
  display: flex; align-items: center; gap: 16px;
  padding: 12px 16px; background: var(--panel);
  border: 1px solid var(--line); border-left: 3px solid var(--line-2);
  border-radius: 10px;
}

/* Past twenty minutes a party starts wondering whether they were forgotten. The
   rail carries it rather than the whole row, so the list stays readable when
   several are overdue at once. */
.bc-wait-overdue { border-left-color: var(--st-warning); }

.bc-wait-when { min-width: 92px; display: flex; flex-direction: column; gap: 2px; }
.bc-wait-mins {
  font-size: 17px; font-weight: 650; font-variant-numeric: tabular-nums;
  line-height: 1.1; color: var(--ink);
}
.bc-wait-since { font-size: 10.5px; color: var(--ink-3); }

.bc-wait-who { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.bc-wait-name {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-weight: 600; font-size: 14.5px;
}
.bc-wait-meta {
  display: flex; gap: 6px; flex-wrap: wrap;
  font-size: 12px; color: var(--ink-3);
}

.bc-wait-actions { display: flex; gap: 6px; flex-shrink: 0; }

@media (max-width: 720px) {
  .bc-wait { flex-wrap: wrap; }
  .bc-wait-actions { width: 100%; justify-content: flex-end; }
}

/* ── detail charges ────────────────────────────────────────────────────
   A statement, not a diary: every step priced, so it can be read aloud to a
   guest querying a bill. The running total is the column that answers them, so
   it is the one that is emphasised. */
.bc-history { display: flex; flex-direction: column; gap: 0; margin-top: 6px; }

.bc-hist {
  display: grid; grid-template-columns: 62px 1fr auto;
  gap: 12px; align-items: baseline;
  padding: 10px 2px; border-bottom: 1px solid var(--line);
}
.bc-hist:last-child { border-bottom: 0; }

.bc-hist-time {
  font-size: 12px; font-variant-numeric: tabular-nums; color: var(--ink-3);
}
.bc-hist-what { min-width: 0; }
.bc-hist-reason { font-size: 13.5px; font-weight: 550; }
.bc-hist-detail { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }

.bc-hist-money { text-align: right; font-variant-numeric: tabular-nums; }
.bc-hist-total { font-size: 14px; font-weight: 650; }
.bc-hist-added { font-size: 11px; color: var(--ink-3); margin-top: 2px; }

/* Events written before the charge columns existed carry no figures. Saying so
   is better than printing 0.00, which would read as "this step was free". */
.bc-hist-nofig { font-size: 11px; color: var(--ink-3); font-style: italic; }

/* Each table on the bill gets its own block, so a two-table tab reads as two
   statements rather than one interleaved list. */
.bc-hist-sess { padding: 4px 0 10px; border-bottom: 1px solid var(--line); margin-bottom: 10px; }
.bc-hist-sess:last-of-type { border-bottom: 0; margin-bottom: 0; }

/* ── splitting a bill by seat ──────────────────────────────────────────
   Each seat is a block with its own total, because the question being answered
   is "what does this person owe" — not "what is on the bill", which the tab
   already shows. */
.bc-seat {
  border: 1px solid var(--line); border-radius: 9px;
  padding: 10px 12px; margin-bottom: 8px; background: var(--panel-2);
}
.bc-seat-head {
  display: flex; align-items: center; gap: 10px;
  padding-bottom: 6px; margin-bottom: 6px; border-bottom: 1px solid var(--line);
}
.bc-seat-name { font-weight: 600; font-size: 12px; }
.bc-seat-total {
  margin-left: auto; font-variant-numeric: tabular-nums;
  font-weight: 600; font-size: 12.5px;
}
.bc-seat-line {
  display: flex; gap: 10px; padding: 5px 4px; border-radius: 5px;
  cursor: pointer; font-size: 11.5px;
}
.bc-seat-line:hover { background: var(--panel); }
.bc-seat-item { flex: 1; min-width: 0; }
.bc-seat-amt { font-variant-numeric: tabular-nums; color: var(--ink-2); }

.bc-btn-sm { padding: 4px 10px; font-size: 10px; }

/* ── a picture on a café tile ──────────────────────────────────────────
   Optional by design: a product without one keeps exactly the tile it has
   today, so the counter never shows a hole where an image would be. */
.bc-item-pic { padding-top: 8px; }
.bc-item-img {
  width: 100%; height: 62px; object-fit: cover;
  border-radius: 6px; margin-bottom: 6px; display: block;
}

/* ── a face beside a name ──────────────────────────────────────────────
   Initials when there is no photo, so the column never shifts width and an
   unphotographed member does not read as a missing one. */
.bc-who { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.bc-avatar {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  object-fit: cover; background: var(--panel-2); border: 1px solid var(--line);
}
.bc-avatar-txt {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 9.5px; font-weight: 600; letter-spacing: .02em; color: var(--ink-2);
}

/* A regular who has stopped coming — the one row on the hours report the club
   can act on tonight. */
.bc-lapsed { color: var(--st-warning); font-weight: 500; }
.bc-lapsed small, .bc-who small { display: block; font-size: 9.5px; color: var(--ink-3); }

/* ── the light switchboard ─────────────────────────────────────────────
   Big targets: this is used with one hand while carrying something, during a
   party or at closing time. */
.bc-lights {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px; margin: 14px 0;
}
.bc-light {
  display: flex; flex-direction: column; gap: 3px; align-items: flex-start;
  padding: 12px 14px; min-height: 62px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  text-align: left; font: inherit; color: var(--ink); cursor: pointer;
}
.bc-light:hover { border-color: var(--accent); }
.bc-light-sel { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); background: var(--accent-bg); }
.bc-light-name { font-weight: 600; font-size: 12px; }
.bc-light-state { font-size: 10px; color: var(--ink-3); }

/* ── the counter's two departments ─────────────────────────────────────
   A row above the categories, spaced apart from them: switching department is
   a different kind of decision from filtering within one. */
.bc-depts { margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid var(--line); }

/* An item that comes back rather than being sold. */
.bc-item-hire {
  display: inline-block; margin-left: 5px; font-size: 9px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--st-info);
}

/* ── a chart on a report ───────────────────────────────────────────────
   Sits between the print head and the figures: the shape first, then the
   numbers that explain it. */
.bc-chart {
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 14px 12px 6px; margin: 14px 0 4px;
}

/* ── the floor plan ────────────────────────────────────────────────────
   A fixed aspect box standing in for the room. Positions are percentages of
   this surface, so the plan survives a different monitor — which is the whole
   reason it is not stored in pixels. */
.bc-plan {
  position: relative; width: 100%; max-width: 900px; aspect-ratio: 900 / 480;
  margin: 12px 0 18px;
  background:
    linear-gradient(var(--line) 1px, transparent 1px) 0 0 / 100% 10%,
    linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0 / 10% 100%,
    var(--panel);
  border: 1px solid var(--line-2); border-radius: 10px; overflow: hidden;
}

.bc-plan-empty {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--ink-3); font-size: 11px; text-align: center; padding: 0 20px;
}

/* Translated by half its own size so the table centres on where it was dropped,
   rather than hanging below and right of the pointer. */
.bc-plan-table {
  position: absolute; transform: translate(-50%, -50%);
  width: 92px; display: flex; flex-direction: column; align-items: center; gap: 3px;
  cursor: grab; padding: 4px; border-radius: 8px;
  background: var(--panel-2); border: 1px solid var(--line);
}
.bc-plan-table:active { cursor: grabbing; }
.bc-plan-busy { border-color: var(--st-success); box-shadow: 0 0 0 1px var(--st-success); }
.bc-plan-name { font-size: 9.5px; font-weight: 600; white-space: nowrap; }

.bc-plan-h { font-size: 11px; font-weight: 500; margin: 4px 0 8px; color: var(--ink-2); }
.bc-plan-tray { display: flex; flex-wrap: wrap; gap: 8px; }
.bc-plan-chip {
  padding: 7px 13px; border-radius: 8px; cursor: grab; font-size: 11px;
  background: var(--panel-2); border: 1px dashed var(--line-2); color: var(--ink-2);
}
.bc-plan-chip:active { cursor: grabbing; }

/* ── the note board ────────────────────────────────────────────────────
   A board is scanned, not read line by line, so the tick box sits in a fixed
   column down the left and the body carries the weight. Everything else about
   a note — table, deadline, who wrote it — is small, because it only matters
   once the note itself has caught somebody's eye. */
.bc-note-add {
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 12px 14px; margin: 14px 0 4px;
  display: flex; flex-direction: column; gap: 8px;
}
.bc-note-body { width: 100%; }
.bc-note-w { width: 150px; }

.bc-notes { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }

.bc-note {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 11px 14px; background: var(--panel);
  border: 1px solid var(--line); border-left: 3px solid var(--line-2);
  border-radius: 10px;
}

/* Pinned is a standing instruction, so it is marked by the rail rather than by
   colouring the text — several can be up at once without the board shouting. */
.bc-note-pinned { border-left-color: var(--accent); background: var(--panel-2); }
.bc-note-due    { border-left-color: var(--st-warning); }

/* A ticked note is kept visible only so the shift can see what was cleared. It
   is deliberately quiet: it is history, not work. */
.bc-note-done { opacity: .55; }
.bc-note-done .bc-note-text { text-decoration: line-through; color: var(--ink-3); }

.bc-note-mark, .bc-note-tick {
  flex-shrink: 0; width: 30px; min-width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; padding: 0;
}
.bc-note-pin { color: var(--accent); }
.bc-note-ticked { color: var(--st-success); }

.bc-note-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.bc-note-text { font-size: 13.5px; font-weight: 500; line-height: 1.45; color: var(--ink); overflow-wrap: anywhere; }
.bc-note-meta {
  display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
  font-size: 10.5px; color: var(--ink-3);
}

/* ── table service ─────────────────────────────────────────────────────
   Wear is a proportion, not a date, so each row leads with hours played and
   carries a bar for it. The bar is what makes "which table is worst" a glance
   rather than a comparison of four numbers. */
.bc-svc-w { width: 110px; }

.bc-svc-list { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }

.bc-svc {
  display: flex; align-items: center; gap: 16px;
  padding: 12px 16px; background: var(--panel);
  border: 1px solid var(--line); border-left: 3px solid var(--line-2);
  border-radius: 10px;
}

.bc-svc-due  { border-left-color: var(--st-danger); }
.bc-svc-soon { border-left-color: var(--st-warning); }

.bc-svc-hours { min-width: 88px; display: flex; flex-direction: column; gap: 2px; }
.bc-svc-num {
  font-size: 17px; font-weight: 650; font-variant-numeric: tabular-nums;
  line-height: 1.1; color: var(--ink);
}
.bc-svc-of { font-size: 10.5px; color: var(--ink-3); }

.bc-svc-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.bc-svc-name {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-weight: 600; font-size: 14.5px;
}

.bc-svc-bar {
  height: 5px; border-radius: 3px; background: var(--line);
  overflow: hidden; max-width: 340px;
}
.bc-svc-fill { display: block; height: 100%; background: var(--st-success); }
.bc-svc-soon .bc-svc-fill { background: var(--st-warning); }
.bc-svc-due  .bc-svc-fill { background: var(--st-danger); }

.bc-svc-meta {
  display: flex; gap: 6px; flex-wrap: wrap;
  font-size: 12px; color: var(--ink-3);
}

.bc-svc-actions { display: flex; gap: 6px; flex-shrink: 0; }

@media (max-width: 720px) {
  .bc-svc { flex-wrap: wrap; }
  .bc-svc-actions { width: 100%; justify-content: flex-end; }
  .bc-note-w { width: 100%; }
}

/* ── section heading ───────────────────────────────────────────────────
   A page that carries two or three separate lists needs to name them. Sized
   between .bc-vat-head and the page title so it separates without competing. */
.bc-sec {
  font-size: 11.5px; font-weight: 500; color: var(--ink-2);
  margin: 20px 0 8px; padding-bottom: 6px; border-bottom: 1px solid var(--line);
}

/* ── kitchen board ─────────────────────────────────────────────────────
   Read from across a room by somebody holding a pan, so this is the one screen
   in the app that breaks the 11.5px type rule on purpose. Everything is bigger,
   there is one button per row, and the button is large enough to hit without
   looking at it. */
.bc-kit-board { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }

.bc-kit {
  display: grid; grid-template-columns: 78px 1fr auto; align-items: center; gap: 14px;
  padding: 12px 14px; background: var(--panel); border: 1px solid var(--line);
  border-left: 4px solid var(--st-info); border-radius: 10px;
}

/* Late is carried by the stripe, the number's colour AND the pill on the row, so
   it survives a colour-blind reader and a badly calibrated wall monitor alike. */
.bc-kit-late { border-left-color: var(--st-warning); background: var(--panel-2); }
.bc-kit-late .bc-kit-mins { color: var(--st-warning); }

.bc-kit-wait { display: flex; flex-direction: column; align-items: center; line-height: 1; }
.bc-kit-mins { font-size: 26px; font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }
.bc-kit-unit { font-size: 10px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .06em; }

.bc-kit-item { font-size: 16px; font-weight: 500; color: var(--ink); }
.bc-kit-qty { color: var(--accent); margin-right: 4px; }
.bc-kit-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 5px; }
.bc-kit-at { font-size: 10px; color: var(--ink-3); }

/* Deliberately oversized: it is pressed with a knuckle or the side of a thumb. */
.bc-kit-btn { min-width: 104px; min-height: 46px; font-size: 13px; }

.bc-kit-clock { font-size: 10px; color: var(--ink-3); font-variant-numeric: tabular-nums; align-self: center; }

.bc-kit-undo {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 12px; padding: 8px 12px; font-size: 11px; color: var(--ink-2);
  background: var(--panel-2); border: 1px dashed var(--line-2); border-radius: 8px;
}

/* ── drawer count ──────────────────────────────────────────────────────
   Three columns: notes, coins, and the reconciliation. The count boxes are
   narrow on purpose — the number typed in is a quantity, never an amount. */
.bc-cash-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px,1fr)); gap: 12px; margin: 14px 0; }

.bc-cash-row {
  display: grid; grid-template-columns: 56px 1fr 86px; align-items: center; gap: 8px;
  padding: 4px 0; border-bottom: 1px solid var(--line);
}
.bc-cash-row:last-of-type { border-bottom: 0; }

.bc-cash-face { font-size: 12px; font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }
.bc-cash-in { width: 100%; }
.bc-cash-line { font-size: 11px; color: var(--ink-2); text-align: right; font-variant-numeric: tabular-nums; }

/* A drawer that does not balance says so in the panel border as well as the figure,
   because the figure is the thing an operator in a hurry reads past. */
.bc-cash-out { border-color: var(--st-danger); }
.bc-cash-bad { color: var(--st-danger); font-weight: 500; }

/* ── league fixtures ───────────────────────────────────────────────────
   One row per fixture. A bye keeps its row rather than being filtered out — the
   player is owed the information that they are not playing this round. */
.bc-fix-list { display: flex; flex-direction: column; gap: 6px; margin: 10px 0; }

.bc-fix {
  display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 12px;
  padding: 10px 14px; background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px;
}
.bc-fix-done { background: var(--panel-2); }
.bc-fix-bye  { border-style: dashed; color: var(--ink-3); }

.bc-fix-who { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.bc-fix-name { font-size: 12px; font-weight: 500; color: var(--ink); }
.bc-fix-bye .bc-fix-name { color: var(--ink-2); }
.bc-fix-v { font-size: 10px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .08em; }

.bc-fix-mid { display: flex; align-items: center; gap: 6px; }
.bc-fix-note { font-size: 10px; color: var(--ink-3); }
.bc-fix-do { display: flex; align-items: center; gap: 6px; }

/* ── touch mode ────────────────────────────────────────────────────────
   The same screen with bigger targets, not a separate layout. One screen to
   maintain, and the operator keeps the muscle memory they already have.

   Sized from the practical floor for a fingertip — roughly 44px — rather than
   from a design scale, because the constraint here is a hand, not a grid. */
.bc-touch .bc-btn { padding: 14px 22px; font-size: 13px; min-height: 46px; }
.bc-touch .bc-item { min-height: 96px; padding: 14px; }
.bc-touch .bc-item-name { font-size: 13.5px; }
.bc-touch .bc-item-price { font-size: 15px; font-weight: 600; }
.bc-touch .bc-items { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.bc-touch .bc-line { padding: 12px 6px; font-size: 13px; }
.bc-touch .bc-x { font-size: 20px; padding: 8px 12px; min-width: 40px; }
.bc-touch .bc-qty-val { font-size: 15px; min-width: 32px; }
.bc-touch .bc-input { min-height: 46px; font-size: 13px; }

/* ── the customer-facing display ───────────────────────────────────────
   Read from two metres by somebody who is not looking for it. Enormous, almost
   empty, and carrying only the line just rung and what is owed. Dark because it
   sits in a room lit for playing, not for reading. */
.bc-pole {
  position: fixed; inset: 0; display: flex; flex-direction: column;
  justify-content: center; gap: 6vh; padding: 6vh 6vw;
  background: #0F1A15; color: #ECE7DA;
  font-family: ui-sans-serif, system-ui, sans-serif;
}
.bc-pole-idle { text-align: center; }
.bc-pole-club { font-size: 6vh; font-weight: 600; letter-spacing: .02em; }
.bc-pole-welcome { font-size: 3vh; color: #7C8B82; margin-top: 2vh; }

.bc-pole-item { display: flex; justify-content: space-between; align-items: baseline; gap: 4vw; }
.bc-pole-name { font-size: 5vh; font-weight: 500; }
.bc-pole-line { font-size: 5vh; font-variant-numeric: tabular-nums; color: #A9B5AC; }

.bc-pole-total {
  display: flex; justify-content: space-between; align-items: baseline; gap: 4vw;
  border-top: 2px solid #2C463A; padding-top: 4vh;
}
.bc-pole-label { font-size: 3vh; letter-spacing: .2em; color: #7C8B82; }
.bc-pole-amt { font-size: 11vh; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1; }

/* ── Print layout screen ──────────────────────────────────────────────────
   Settings on the left, the paper on the right. Side by side because the
   whole point is watching the receipt change as you edit it; stacked, you
   would be scrolling between a control and its effect. Collapses on a
   narrow screen, where side-by-side would make both halves unusable. */
.bc-print-split { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,340px); gap:16px; align-items:start; }
@media (max-width: 1100px) { .bc-print-split { grid-template-columns:minmax(0,1fr); } }

.bc-print-preview { position:sticky; top:12px; }

/* The preview stands in for paper, so it gets a paper-coloured card whatever
   the club's theme is -- a dark-themed preview would tell you nothing about
   what comes out of the printer. */
.bc-paper { background:#fff; color:#111; padding:10px; border:1px solid var(--line,#ddd);
            border-radius:6px; overflow-x:auto; }
.bc-paper-roll  { max-width:320px; margin:0 auto; }
.bc-paper-sheet { max-width:100%; }

.bc-tokens { display:flex; flex-wrap:wrap; gap:6px; margin-bottom:8px; }
.bc-token { font-family:ui-monospace,Consolas,monospace; font-size:11.5px; padding:3px 7px;
            border:1px solid var(--line,#ccc); border-radius:999px; background:transparent;
            color:var(--tx,inherit); cursor:pointer; }
.bc-token:hover { border-color:var(--accent,#888); }

.bc-logo-preview { display:flex; align-items:center; gap:12px; margin-bottom:10px; }
.bc-logo-preview img { background:#fff; padding:4px; border:1px solid var(--line,#ddd); border-radius:4px; }

.bc-w-full { width:100%; }

/* ── Side navigation (optional; the top bar remains the default) ──────────
   Only rendered when the user has chosen it. Both navigations read the same
   AppModules definition, so a page added there appears in whichever one is
   in use.

   COLOURS ARE DERIVED, NOT LITERAL. An earlier version of this block invented
   a --gym-surface-3 token that does not exist and fell back to a hardcoded
   dark green, which turned every hover into an unreadable slab under the six
   light themes. The rule the rest of the app follows is color-mix against the
   ink colour: it darkens a light theme and lightens a dark one, from a single
   declaration, because it is defined in terms of the theme's own text colour. */
.side-menu { flex: 0 0 240px; width: 240px; display: flex; flex-direction: column;
             background: var(--gym-surface-2, var(--panel)); color: var(--gym-ink, var(--tx));
             border-right: 1px solid var(--gym-border, var(--line));
             height: 100vh; overflow: hidden; }
.side-menu.side-collapsed { flex-basis: 56px; width: 56px; }

.side-brand { display: flex; align-items: center; gap: 8px; padding: 12px 10px;
              border-bottom: 1px solid var(--gym-border, var(--line)); min-height: 52px; }
.side-brand-mark { display: inline-flex; flex: 0 0 auto; }
.side-brand-text { font-weight: 500; font-size: .95rem; white-space: nowrap;
                   overflow: hidden; text-overflow: ellipsis; }
.side-toggle { margin-left: auto; background: transparent; border: 0; cursor: pointer;
               color: inherit; opacity: .7; padding: 4px 6px; border-radius: 4px; }
.side-toggle:hover { background: color-mix(in srgb, currentColor 12%, transparent); opacity: 1; }
.side-collapsed .side-toggle { margin-left: 0; }

/* Only this scrolls, so the brand and the switcher stay put on a long menu. */
.side-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 6px 0; }

.side-head { display: flex; align-items: center; gap: 10px; width: 100%;
             background: transparent; border: 0; cursor: pointer; text-align: left;
             padding: 8px 12px; color: inherit; font-size: .88rem; }
.side-head:hover { background: color-mix(in srgb, currentColor 10%, transparent); }
.side-icon { flex: 0 0 18px; font-size: 1rem; opacity: .85; }
.side-label { flex: 1 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.side-caret { flex: 0 0 auto; font-size: .7rem; opacity: .6; }
.side-group-active > .side-head { color: var(--gym-accent, var(--accent)); font-weight: 500; }

.side-pages { display: flex; flex-direction: column; }
.side-page { display: flex; align-items: center; gap: 8px; padding: 6px 12px 6px 40px;
             color: inherit; opacity: .78; text-decoration: none; font-size: .84rem; }
.side-page:hover { background: color-mix(in srgb, currentColor 10%, transparent); opacity: 1; }
.side-page.active { color: var(--gym-accent, var(--accent)); opacity: 1;
                    background: color-mix(in srgb, var(--gym-accent, var(--accent)) 12%, transparent); }
.side-page-icon { flex: 0 0 14px; font-size: .85rem; opacity: .7; }

.side-foot { border-top: 1px solid var(--gym-border, var(--line)); padding: 8px; display: flex;
             justify-content: center; }

/* The switcher itself — three states, shown in both navigations. */
.nav-switch { display: inline-flex; gap: 2px; }
.nav-switch-btn { background: transparent; border: 1px solid transparent; cursor: pointer;
                  color: inherit; opacity: .7; padding: 4px 7px; border-radius: 5px;
                  font-size: .9rem; line-height: 1; }
.nav-switch-btn:hover { background: color-mix(in srgb, currentColor 12%, transparent); opacity: 1; }
.nav-switch-btn.is-on { color: var(--gym-accent, var(--accent)); opacity: 1;
                        border-color: color-mix(in srgb, var(--gym-accent, var(--accent)) 40%, transparent);
                        background: color-mix(in srgb, var(--gym-accent, var(--accent)) 12%, transparent); }

/* A rail costs width a narrow window does not have; fall back to icons only. */
@media (max-width: 820px) {
  .side-menu { flex-basis: 56px; width: 56px; }
  .side-brand-text, .side-label, .side-caret, .side-pages { display: none; }
}

@media print { .side-menu { display: none !important; } }
