/* =============================================================================
   SalesBoard — Rep App (phone input) stylesheet
   Mobile-first. Interactive language from SALESBOARD_BLUEPRINT.md §4.6:
   colored category buttons, inverted-pill "active" motif, green toast.
   Touch discipline (§4.6): nothing interactive under 44px; most controls 60–96px.
   Palette + font come from ../shared/theme.css.
   ============================================================================= */

body {
  /* Respect the phone's safe areas (notch / home indicator) in standalone PWA. */
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
           env(safe-area-inset-bottom) env(safe-area-inset-left);
  -webkit-tap-highlight-color: transparent;
}

/* Hard document lock (D57): the installed app must never pan as a page — even
   with zero scroll range iOS still rubber-bands the document on a drag.
   overflow:hidden removes any scroll range (vertical AND horizontal),
   overscroll-behavior:none kills the elastic bounce, and the fixed-position
   body is the classic WebKit belt-and-suspenders. Only the opted-in inner
   containers (.home-scroll.scroll-on, .log-scroll, .board-scroll) scroll. */
html, body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}
body {
  position: fixed;
  inset: 0;
}

.view {
  max-width: 560px;
  margin: 0 auto;
  padding: 20px 20px 48px;
  min-height: 100vh;
}

/* -----------------------------------------------------------------------------
   Top bar (home + log views)
   --------------------------------------------------------------------------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 24px;
}
.brand {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.01em;
}
/* Wordmark links home (D46). Inherit the brand look; 44px tap height (§4.6). */
.brand-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: inherit;
  text-decoration: none;
}
.who {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-dim);
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 45%;
}

/* -----------------------------------------------------------------------------
   Buttons (§4.6): primary = white bg / dark text / 800; secondary = card-border;
   danger = --mini red; disabled = 0.35 opacity. Press feedback = scale(0.98).
   --------------------------------------------------------------------------- */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 60px;
  padding: 0 20px;
  font-family: inherit;
  font-size: 20px;
  font-weight: 800;
  border: none;
  border-radius: 14px;
  cursor: pointer;
  transition: transform 0.08s ease, opacity 0.12s ease, background 0.12s ease;
}
.btn:active { transform: scale(0.98); }
.btn:disabled { opacity: 0.35; cursor: default; }
.btn:disabled:active { transform: none; }

.btn-primary   { background: var(--text); color: var(--bg); }
.btn-secondary { background: var(--card-border); color: var(--text); }
.btn-danger    { background: var(--new-mini); color: #fff; }
.btn-link {
  background: none;
  color: var(--text-dim);
  min-height: 44px;
  width: auto;
  padding: 8px 4px;
  font-size: 16px;
  font-weight: 700;
}

/* -----------------------------------------------------------------------------
   Pinned thumb-zone dock (D46, lifted D57): Log a Deal fixed near the bottom of
   the viewport, raised clear of the iPhone swipe bar — always reachable
   one-handed, never inside the home-indicator zone.
   --------------------------------------------------------------------------- */
.view-docked {
  /* App shell: the section fills the viewport and never scrolls — only
     .home-scroll does. A page that can't scroll can't make iOS Safari's
     toolbar collapse, so the fixed dock stays truly static under the thumb.
     (dvh tracks the live viewport; the body's safe-area paddings are
     subtracted so the shell + paddings sum to exactly one screen.) */
  height: 100vh;   /* fallback for browsers without dvh */
  height: calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  /* Neutralize .view's min-height:100vh (D57 fix). In standalone PWA the safe
     areas are real (~93px on an iPhone), so a 100vh min-height overrides the
     calc above and makes the BODY scrollable by exactly the safe-area sum —
     the page-slide Curtis saw on the installed app. */
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding-bottom: 0;
}
.home-scroll {
  flex: 1 1 auto;
  min-height: 0;
  /* Scroll-locked until History opens (D57): rep.js toggles .scroll-on when
     History expands, or whenever the collapsed content genuinely overflows
     (small phone / A2HS card showing) so nothing is ever clipped. */
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  /* Keep the last content (Sign out) clear of the overlaying dock. */
  padding-bottom: calc(168px + env(safe-area-inset-bottom));
}
.home-scroll.scroll-on { overflow-y: auto; }
.dock {
  position: fixed;
  left: 12px;
  right: 12px;
  /* One full button-height (72px) above the D57 first-cut spot (owner call):
     12px gap + 72px riser above the safe area. */
  bottom: calc(84px + env(safe-area-inset-bottom));
  z-index: 30;
  max-width: 560px;
  margin: 0 auto;
}
.btn-dock {
  min-height: 72px;
  font-size: 26px;
  letter-spacing: -0.01em;
  border-radius: 16px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5);
}

/* -----------------------------------------------------------------------------
   Login view
   --------------------------------------------------------------------------- */
.login-wrap {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
}
.login-title {
  font-size: 40px;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0 0 4px;
}
.login-sub {
  font-size: 17px;
  font-weight: 600;
  color: var(--text-dim);
  margin: 0 0 28px;
}
.field { margin-bottom: 16px; }
.field label {
  display: block;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--text-dim);
}
/* Inputs (§4.6): --bg fill, 2px card-border, white border on focus, 12px radius.
   Font ≥16px so iOS Safari doesn't zoom the page on focus. */
.field input {
  width: 100%;
  min-height: 60px;
  padding: 0 16px;
  font-family: inherit;
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
  background: var(--bg);
  border: 2px solid var(--card-border);
  border-radius: 12px;
  outline: none;
  transition: border-color 0.12s ease;
}
.field input:focus { border-color: var(--text); }

.form-error {
  min-height: 22px;
  margin: 4px 0 16px;
  font-size: 15px;
  font-weight: 700;
  color: var(--new-mini);
}

/* Passwordless login (D21): code entry hint + wide-spaced code digits. */
.code-hint {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-dim);
  margin: 8px 0 0;
}
#code { letter-spacing: 0.35em; font-variant-numeric: tabular-nums; }

/* -----------------------------------------------------------------------------
   Home — My Month scoreboard (D46: promoted to the top, board-style numbers)
   --------------------------------------------------------------------------- */
.card {
  background: var(--card);
  border: 2px solid var(--grid-line);
  border-radius: 16px;
  padding: 20px;
  margin-bottom: 24px;
}
.scoreboard { margin-bottom: 16px; }
.score-label {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-dim);
  margin-bottom: 4px;
}
.month-tag { text-transform: uppercase; }
.score-total {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 14px;
}
.score-total > span:first-child {
  font-size: 56px;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.score-units {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-dim);
}

/* Per-category unit lines. */
.cat-line {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-top: 1px solid var(--card-border);
}
.cat-swatch {
  width: 16px;
  height: 16px;
  border-radius: 4px;
  flex: 0 0 auto;
  background: var(--sw, var(--card-border));
}
.cat-line .lbl { flex: 1 1 auto; font-size: 17px; font-weight: 700; }
.cat-line .cnt {
  font-size: 20px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

/* -----------------------------------------------------------------------------
   Add to Home Screen (D54): walkthrough card (top of Home on first sight) +
   quiet banner (below History, after "Not now"). House card language; the
   share chip is iOS-Share blue on purpose — it mirrors the real glyph the rep
   is about to look for, so it stays hardcoded and outside the store theme.
   --------------------------------------------------------------------------- */
.a2hs-card { margin-bottom: 16px; }
.a2hs-title {
  font-size: 19px;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.a2hs-sub {
  margin: 4px 0 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-dim);
  line-height: 1.5;
}
.a2hs-step {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 14px;
}
.a2hs-chip {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
  background: var(--bg);
  border: 2px solid var(--card-border);
  border-radius: 10px;
}
.a2hs-chip-share { color: #4da3ff; }
.a2hs-chip-add {
  font-size: 13px;
  font-weight: 800;
  color: #4da3ff;
}
.a2hs-step-txt {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--text);
}
.a2hs-step-txt strong { font-weight: 800; }
.a2hs-n { color: var(--text-dim); font-weight: 800; }
.a2hs-note {
  margin: 16px 0 0;
  padding: 12px 14px;
  background: var(--bg);
  border: 1px solid var(--card-border);
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-dim);
  line-height: 1.55;
}
.a2hs-note strong { color: var(--text); }
.a2hs-install { margin-top: 14px; min-height: 64px; font-size: 19px; }
.a2hs-later { margin: 6px auto 0; display: flex; }

/* The quiet banner: one dashed container, two buttons inside (open + never). */
.a2hs-banner {
  display: flex;
  align-items: stretch;
  border: 2px dashed var(--grid-line);
  border-radius: 12px;
  margin-bottom: 16px;
}
.a2hs-banner-open {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 52px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 4px 0 12px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-dim);
  text-align: left;
  background: none;
  border: none;
  cursor: pointer;
}
.a2hs-banner-open svg { flex: 0 0 auto; }
.a2hs-banner-lbl {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.a2hs-banner-chev { font-size: 18px; font-weight: 800; opacity: 0.6; }
.a2hs-banner-x {
  flex: 0 0 auto;
  width: 48px;
  min-height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  font-size: 20px;
  font-weight: 800;
  color: var(--text-dim);
  background: none;
  border: none;
  border-left: 2px dashed var(--grid-line);
  cursor: pointer;
}

/* -----------------------------------------------------------------------------
   Home — history (D46: collapsed by default behind a tappable header row)
   --------------------------------------------------------------------------- */
.hist-toggle {
  width: 100%;
  min-height: 56px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 16px;
  font-family: inherit;
  font-size: 17px;
  font-weight: 800;
  color: var(--text);
  background: var(--card);
  border: 2px solid var(--grid-line);
  border-radius: 12px;
  cursor: pointer;
  margin-bottom: 12px;
  transition: transform 0.08s ease, border-color 0.12s ease;
}
.hist-toggle:active { transform: scale(0.99); }
.hist-count { color: var(--text-dim); font-weight: 700; }
.hist-chev {
  display: inline-block;   /* inline boxes ignore transforms */
  color: var(--text-dim);
  font-size: 16px;
  transition: transform 0.12s ease;
}
.hist-toggle[aria-expanded="true"] .hist-chev { transform: rotate(180deg); }
.empty {
  color: var(--text-dim);
  font-size: 16px;
  font-weight: 600;
  padding: 8px 4px;
}
.hist-item {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--card);
  border: 2px solid var(--grid-line);
  border-radius: 12px;
  padding: 14px 16px;
  margin-bottom: 10px;
}
.hist-swatch {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  flex: 0 0 auto;
  background: var(--sw, var(--card-border));
}
.hist-body { flex: 1 1 auto; min-width: 0; }
.hist-title {
  font-size: 17px;
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hist-meta {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-dim);
  margin-top: 2px;
}
.badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--acq);
  border: 1.5px solid var(--acq);
  border-radius: 6px;
  padding: 1px 6px;
  margin-left: 6px;
  vertical-align: 1px;
}
/* Same-day self-delete (§2.2). Only today's own deals show this. */
.hist-del {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  font-weight: 800;
  color: var(--text-dim);
  background: var(--bg);
  border: 2px solid var(--card-border);
  border-radius: 10px;
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease, transform 0.08s ease;
}
.hist-del:active { transform: scale(0.94); }
.hist-del:hover { color: var(--new-mini); border-color: var(--new-mini); }

/* -----------------------------------------------------------------------------
   Log-a-Deal flow
   --------------------------------------------------------------------------- */
.log-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
/* Scrolling middle of the log shell (D46): choices center in the free space
   (auto vertical margins collapse to 0 once content overflows, so a long
   partner list scrolls instead of clipping); Confirm stays docked below. */
.log-scroll {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  padding-bottom: calc(168px + env(safe-area-inset-bottom));
}
.log-steps { margin: auto 0; }
.log-head h1 {
  margin: 0;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.step-label {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-dim);
  margin: 0 4px 12px;
}
.step-label .opt { color: var(--card-border); text-transform: none; letter-spacing: 0; }
.step { margin-bottom: 28px; }

/* Category buttons (§4.6): filled with the category color, white 26px/800 label,
   14px radius, min-height 88px, 4px transparent border → white when selected. */
.cat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.cat-btn {
  min-height: 88px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 10px 14px;
  font-family: inherit;
  font-size: 22px;
  font-weight: 800;
  color: #fff;
  background: var(--c, var(--card));
  border: 4px solid transparent;
  border-radius: 14px;
  cursor: pointer;
  transition: transform 0.08s ease, border-color 0.12s ease;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}
.cat-btn:active { transform: scale(0.98); }
.cat-btn.selected { border-color: #fff; }
/* A single (auto-selected, D46) category fills the row — no half-width orphan. */
.cat-btn:only-child { grid-column: 1 / -1; }

/* Credit pills (§4.6): 28px/800, min-height 84px, 3px borders; inverted-pill
   active motif (white bg / dark text / white border when selected). */
.credit-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.pill {
  min-height: 84px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  font-size: 28px;
  font-weight: 800;
  color: var(--text);
  background: var(--card);
  border: 3px solid var(--card-border);
  border-radius: 14px;
  cursor: pointer;
  transition: transform 0.08s ease, background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.pill:active { transform: scale(0.98); }
.pill.selected { background: var(--text); color: var(--bg); border-color: var(--text); }

/* Split-partner list — same inverted-pill active motif, sized for a name row. */
.partner-list { display: flex; flex-direction: column; gap: 10px; }
.partner {
  min-height: 60px;
  display: flex;
  align-items: center;
  padding: 0 18px;
  font-family: inherit;
  font-size: 19px;
  font-weight: 700;
  text-align: left;
  color: var(--text);
  background: var(--card);
  border: 3px solid var(--card-border);
  border-radius: 12px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: transform 0.08s ease, background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.partner:active { transform: scale(0.99); }
.partner.selected { background: var(--text); color: var(--bg); border-color: var(--text); }

/* -----------------------------------------------------------------------------
   Toast (§4.6): fixed bottom-center, green (--used) success / red error,
   white 22px/700, 12px radius, 0.2s fade. The rep app's "Deal logged ✓" moment.
   --------------------------------------------------------------------------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(24px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  max-width: 90vw;
  padding: 16px 24px;
  font-size: 22px;
  font-weight: 700;
  color: #fff;
  background: var(--used);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  z-index: 50;
  opacity: 1;
  transition: opacity 0.2s ease;
}
.toast.err { background: var(--new-mini); }
.toast.fade { opacity: 0; }

/* -----------------------------------------------------------------------------
   Remove-deal confirm modal (D46). §4.6 modal language, mirroring the admin
   app: --card bg, 2px border, 20px radius, 0.78 backdrop, hairline-split foot.
   --------------------------------------------------------------------------- */
.modal-backdrop {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(0, 0, 0, 0.78);
  z-index: 60;
}
.modal {
  width: 100%;
  max-width: 480px;
  background: var(--card);
  border: 2px solid var(--card-border);
  border-radius: 20px;
  padding: 24px;
}
.modal-title {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.01em;
  margin: 0 0 16px;
}
/* The deal being removed, restated so the rep confirms the right one. */
.rm-deal {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--bg);
  border: 2px solid var(--card-border);
  border-radius: 12px;
  padding: 14px 16px;
}
.rm-swatch {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  flex: 0 0 auto;
  background: var(--sw, var(--card-border));
}
.rm-body { min-width: 0; }
.rm-label {
  font-size: 17px;
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rm-meta {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-dim);
  margin-top: 2px;
}
.rm-split-warn {
  font-size: 14px;
  font-weight: 700;
  color: var(--new-mini);
  line-height: 1.45;
  margin: 14px 2px 0;
}
.modal-foot {
  display: flex;
  gap: 10px;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--card-border);
}
.modal-foot .btn { flex: 1 1 0; }

/* Full-screen loading veil during sign-in / first load. */
.veil {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  color: var(--text-dim);
  font-size: 18px;
  font-weight: 700;
  z-index: 40;
}

/* -----------------------------------------------------------------------------
   Board view (D49) — the §4.9 portrait board, scaled to the phone.
   Grid rules mirror board/board.css §4.6/§4.9 VERBATIM at natural size (the
   whole grid is transform-scaled to fit); pacing renders as native cards.
   --------------------------------------------------------------------------- */
/* Home entry, near My Month. */
.board-entry {
  width: 100%;
  min-height: 56px;
  margin-top: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 18px;
  background: var(--card);
  border: 2px solid var(--card-border);
  border-radius: 14px;
  color: var(--text);
  font-family: inherit;
  font-size: 17px;
  font-weight: 800;
  cursor: pointer;
}
.board-entry-chev { color: var(--text-dim); font-size: 22px; font-weight: 800; }

/* App shell (D46 pattern): the page never scrolls; the inner container does. */
.view-board {
  display: flex;
  flex-direction: column;
  height: 100vh;
  /* Same standalone-PWA math as .view-docked (D57 fix): subtract the safe
     areas the body already pads, and neutralize .view's min-height:100vh —
     otherwise the page itself scrolls by the safe-area sum on the phone. */
  height: calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  min-height: 0;
}
.view-board[hidden] { display: none; }
.board-store {
  margin-left: auto;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 40%;
}
.board-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 4px 14px calc(24px + env(safe-area-inset-bottom));
}
.board-error {
  background: var(--card);
  border: 2px solid var(--card-border);
  border-radius: 12px;
  padding: 14px 16px;
  font-size: 15px;
  font-weight: 700;
  color: var(--text-dim);
  margin-bottom: 12px;
}

/* The scale stage: natural-size grid inside, scaled as one piece (JS sets the
   transform + the wrapper's scaled height). */
#board-scale { overflow: hidden; }
#board-grid  { transform-origin: top left; }

/* ---- Grid (§4.6/§4.9 values, natural size — scaled by the wrapper) -------- */
#view-board .grid-panel {
  display: grid;
  grid-template-columns: repeat(var(--cols), var(--cell-size));
  width: fit-content;
  background: var(--card);
  border: 2px solid var(--grid-line);
  border-radius: 12px;
  overflow: hidden;
}
#view-board .colnum {
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  border-right: 1px solid var(--grid-line);
  border-bottom: 1px solid var(--grid-line);
}
#view-board .nameband {
  grid-column: 1 / -1;
  height: 44px;
  display: flex;
  align-items: center;
  padding: 0 18px;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  background: var(--bg);
  border-bottom: 1px solid var(--grid-line);
}
#view-board .nameband.dim { opacity: 0.55; }
/* Hot streak (§4.10, D56) — scoped copy of the board rules. */
#view-board .name-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
#view-board .streak-flame {
  flex: none;
  margin-left: 10px;
  font-size: 0.8em;
  line-height: 1;
  animation: bv-streak-flicker 1.6s ease-in-out infinite;
}
@keyframes bv-streak-flicker {
  0%, 100% { transform: scale(1);    opacity: 1; }
  50%      { transform: scale(0.86); opacity: 0.75; }
}
#view-board .cell {
  position: relative;
  height: var(--cell-size);
  width: var(--cell-size);
  border-right: 1px solid var(--grid-line);
  border-bottom: 1px solid var(--grid-line);
}
#view-board .cell.half-cell {
  background: linear-gradient(to bottom right,
    var(--tl-color, transparent) 50%,
    var(--br-color, transparent) 50%);
}
#view-board .cell.half-cell.split::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 141.42%;
  height: 1px;
  background: var(--grid-line);
  transform: translate(-50%, -50%) rotate(-45deg);
  pointer-events: none;
}
#view-board .divider {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 20px;
  background: var(--bg);
  padding: 14px 24px;
  font-size: 18px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--text-dim);
  border-bottom: 1px solid var(--grid-line);
}
#view-board .divider::before,
#view-board .divider::after {
  content: "";
  flex: 1;
  height: 2px;
  background: var(--card-border);
}

/* Deal-landing moment (§4.7) on the phone too. */
#view-board .cell.pop {
  animation: bv-pop 300ms ease-out both;
  transform-origin: center;
}
@keyframes bv-pop {
  0%   { transform: scale(0.2); opacity: 0; }
  60%  { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
#view-board .flash { animation: bv-flash 2s ease-out both; }
@keyframes bv-flash {
  0%   { background: transparent; }
  15%  { background: var(--flash-color); }
  100% { background: transparent; }
}
/* Name bands own a --bg background — end the flash back on it, not transparent. */
#view-board .nameband.flash { animation: bv-flash-band 2s ease-out both; }
@keyframes bv-flash-band {
  0%   { background: var(--bg); }
  15%  { background: var(--flash-color); }
  100% { background: var(--bg); }
}

/* ---- Pacing cards (shared §4.4 math, readable at phone size) -------------- */
.bv-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding-top: 14px;
}
.bv-card {
  background: var(--card);
  border: 2px solid var(--card-border);
  border-left: 4px solid var(--card-border);
  border-radius: 12px;
  padding: 12px 14px;
}
.bv-card-label {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  margin-bottom: 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bv-card-stats { display: flex; gap: 18px; }
.bv-stat-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-dim);
  margin-bottom: 4px;
}
.bv-stat-value {
  font-size: 24px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.bv-dim { color: var(--text-dim); }
