/* =============================================================================
   UI-kit layout CSS — composes the design system into the actual app shell.
   Light theme is default; dark theme tokens cascade from <html data-theme>.
   ============================================================================= */

html, body { height: 100%; }
body { background: var(--bg); color: var(--fg); overflow-x: hidden; }

#root, .bk-app {
  position: relative;
  min-height: 100vh;
  z-index: 1;
}

/* Layout shell: side nav on desktop, drawer on mobile.
   --bk-sidenav-w is the single source of truth for the rail width: both the
   <aside> and the grid column read it, so the content area reflows in lock-step
   when the collapse toggle flips it. Collapsing sets data-sidenav on <html>. */
:root { --bk-sidenav-w: 280px; }
[data-sidenav="collapsed"] { --bk-sidenav-w: 68px; }

.bk-app {
  display: grid;
  grid-template-columns: 1fr;
}
@media (min-width: 1024px) {
  .bk-app {
    grid-template-columns: var(--bk-sidenav-w) 1fr;
    transition: grid-template-columns var(--dur-sheet, 320ms) var(--ease-out);
  }
  .bk-side-nav {
    position: sticky; top: 0; height: 100vh; overflow-y: auto;
    transition: width var(--dur-sheet, 320ms) var(--ease-out);
  }
  .bk-hamburger { display: none !important; }
  .bk-nav-backdrop { display: none !important; }
}

/* ---------- Collapsible sidebar (desktop) -------------------------------- */
/* The collapse toggle is desktop-only chrome; the mobile drawer always opens
   full-width, so hide the control there to avoid a dead-end narrow rail. */
.bk-nav-collapse { display: none; }
@media (min-width: 1024px) {
  .bk-nav-collapse {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: -6px;
    padding: 8px 12px;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--fg-muted);
    font: 600 0.8rem/1 var(--font-display);
    cursor: pointer;
    width: 100%;
    text-align: left;
    transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
  }
  .bk-nav-collapse:hover { background: var(--accent-soft); color: var(--fg-strong); }
  .bk-nav-collapse__icon {
    flex: 0 0 18px;
    /* Points left (toward the edge) when expanded; flips to point right when
       collapsed, the conventional "expand outward" affordance. */
    transform: rotate(180deg);
    transition: transform var(--dur-sheet, 320ms) var(--ease-out);
  }
  .bk-side-nav.is-collapsed .bk-nav-collapse__icon { transform: rotate(0deg); }
  .bk-nav-collapse__label { white-space: nowrap; }

  /* Collapsed rail: centre every icon, fade the text away. We keep the labels
     in the DOM (for screen readers + the fade) but clip them to zero width so
     they don't force the rail wider mid-transition. */
  .bk-side-nav.is-collapsed { padding-left: 10px; padding-right: 10px; align-items: stretch; }
  .bk-side-nav.is-collapsed .bk-nav-link,
  .bk-side-nav.is-collapsed .bk-nav-collapse {
    justify-content: center;
    gap: 0;
    padding-left: 0;
    padding-right: 0;
  }
  .bk-side-nav.is-collapsed .bk-nav-link__label,
  .bk-side-nav.is-collapsed .bk-nav-collapse__label,
  .bk-side-nav.is-collapsed .bk-nav-brand__copy,
  .bk-side-nav.is-collapsed .bk-nav-section__title {
    opacity: 0;
    width: 0;
    max-width: 0;
    overflow: hidden;
    pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease-out);
  }
  /* Collapsed brand: drop the card chrome entirely and show ONLY a clean,
     centred BK monogram sized to the rail. The wordmark + tagline are already
     faded to zero width above (no clipping), so nothing else shows here. */
  .bk-side-nav.is-collapsed .bk-nav-brand {
    justify-content: center;
    gap: 0;
    padding: 4px 0;
    background: transparent;
    border-color: transparent;
  }
  .bk-side-nav.is-collapsed .bk-nav-mark {
    width: 48px;
    height: 48px;
    font-size: 1.15rem;
  }
  /* Section titles collapse their box so groups sit tight without label rows. */
  .bk-side-nav.is-collapsed .bk-nav-section__title { padding: 0; height: 0; margin: 0; }
  /* Even spacing in the icon rail. Expanded, the nav puts a 20px gap between
     sections (each headed by a title); collapsed, those titles vanish, leaving
     uneven gaps. Match the between-section gap to the within-section gap so
     every icon sits evenly spaced down the rail. */
  .bk-side-nav.is-collapsed { gap: 6px; }
  .bk-side-nav.is-collapsed .bk-nav-section { gap: 6px; }
}

/* Reduced motion: snap between states, no width/transform animation. */
@media (prefers-reduced-motion: reduce) {
  .bk-app,
  .bk-side-nav,
  .bk-nav-collapse__icon,
  .bk-side-nav.is-collapsed .bk-nav-link__label,
  .bk-side-nav.is-collapsed .bk-nav-collapse__label,
  .bk-side-nav.is-collapsed .bk-nav-brand__copy,
  .bk-side-nav.is-collapsed .bk-nav-section__title { transition: none !important; }
}

/* Mobile drawer behaviour */
@media (max-width: 1023px) {
  .bk-side-nav {
    position: fixed;
    inset: 0 auto 0 0;
    height: 100vh;
    z-index: 60;
    /* Always full-width as a drawer — ignore a desktop-set collapse so a
       narrow rail never strands a phone user. */
    width: min(280px, 86vw);
    transform: translateX(-104%);
    transition: transform var(--dur-sheet) var(--ease-drawer);
    box-shadow: var(--shadow-lg);
  }
  /* The collapse toggle is desktop-only; never show the collapsed treatment
     inside the mobile drawer even if the persisted flag says collapsed. */
  .bk-side-nav.is-collapsed { padding: 16px; }
  .bk-side-nav.is-collapsed .bk-nav-link,
  .bk-side-nav.is-collapsed .bk-nav-brand { justify-content: flex-start; }
  .bk-side-nav.is-collapsed .bk-nav-link__label,
  .bk-side-nav.is-collapsed .bk-nav-brand__copy,
  .bk-side-nav.is-collapsed .bk-nav-section__title {
    opacity: 1; width: auto; max-width: none; height: auto; overflow: visible; pointer-events: auto;
  }
  .bk-side-nav.is-open { transform: translateX(0); }
  .bk-nav-backdrop {
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.5); backdrop-filter: blur(3px);
    opacity: 0; pointer-events: none;
    transition: opacity var(--dur-med) var(--ease-out);
    z-index: 50;
  }
  .bk-nav-backdrop.is-open { opacity: 1; pointer-events: auto; }
}

.bk-app__main {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-width: 0;
}

.bk-app__content {
  flex: 1;
  padding: 20px 18px 80px;
  max-width: 1280px;
  width: 100%;
  margin: 0 auto;
}
@media (min-width: 768px) {
  .bk-app__content { padding: 24px 28px 96px; }
}

/* App header is now sticky at top with margin */
.bk-app-header {
  margin: 16px 18px 0;
  position: sticky;
  top: 16px;
  z-index: 30;
}
@media (min-width: 1024px) {
  .bk-app-header { margin: 24px 28px 0; }
}

/* ---------- Screen scaffolding -------------------------------------------- */
.bk-screen { display: flex; flex-direction: column; gap: 22px; }

.bk-block { display: flex; flex-direction: column; gap: 12px; }
.bk-block__title {
  font: 700 1rem/1.2 var(--font-display);
  letter-spacing: -0.02em;
  color: var(--fg-strong);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.bk-block__action {
  border: 0;
  background: none;
  cursor: pointer;
  font: 600 0.8rem/1 var(--font-display);
  color: var(--accent-action);
  padding: 2px 4px;
  border-radius: var(--radius-xs);
  transition: opacity var(--dur-fast);
}
.bk-block__action:hover { opacity: 0.7; }

/* ---------- Desktop dashboard (Home) ------------------------------------- */
.bk-dashboard {
  display: grid;
  grid-template-columns: 1fr;
  gap: 22px;
  align-items: start;
}
@media (min-width: 1024px) {
  .bk-dashboard { grid-template-columns: minmax(0, 1.55fr) minmax(320px, 1fr); }
}
.bk-dashboard__main,
.bk-dashboard__aside { display: flex; flex-direction: column; gap: 22px; min-width: 0; }
@media (min-width: 1024px) {
  /* The aside tracks the viewport so the feed/leaderboard stay in view. */
  .bk-dashboard__aside { position: sticky; top: 88px; }
}

.bk-panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xs);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.bk-panel__title {
  font: 700 0.95rem/1.2 var(--font-display);
  letter-spacing: -0.02em;
  color: var(--fg-strong);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}

/* Updates feed */
.bk-feed { display: flex; flex-direction: column; gap: 10px; }
.bk-feed__item {
  padding: 12px 14px 12px 16px;
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
  border-left: 3px solid var(--line-strong);
}
.bk-feed__item--warn  { border-left-color: var(--status-warning); }
.bk-feed__item--batch { border-left-color: var(--spec-batch-stripe); }
.bk-feed__item--full  { border-left-color: var(--spec-full-stripe); }
.bk-feed__head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.bk-feed__title { font: 600 0.875rem/1.35 var(--font-display); color: var(--fg-strong); }
.bk-feed__ago { font: 500 0.72rem/1 var(--font-display); color: var(--fg-subtle); white-space: nowrap; }
.bk-feed__body {
  margin-top: 3px;
  font: 400 0.82rem/1.5 var(--font-body);
  color: var(--fg-muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* Mini leaderboard */
.bk-mini-leader { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.bk-mini-leader__row {
  display: grid;
  grid-template-columns: 22px 28px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 7px 4px;
  border-radius: var(--radius-sm);
  transition: background var(--dur-fast);
}
.bk-mini-leader__row:hover { background: var(--surface-sunken); }
.bk-mini-leader__rank {
  font: 700 0.8rem/1 var(--font-display);
  color: var(--fg-subtle);
  text-align: center;
}
.bk-mini-leader__rank.is-top { color: var(--accent-action); }
.bk-mini-leader__avatar {
  width: 28px; height: 28px; border-radius: var(--radius-pill);
  display: grid; place-items: center;
  font: 700 0.7rem/1 var(--font-display); color: #fff;
}
.bk-mini-leader__name {
  font: 600 0.85rem/1.2 var(--font-display);
  color: var(--fg-strong);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bk-mini-leader__score { font: 700 0.85rem/1 var(--font-display); color: var(--fg-strong); }

/* Shared empty state */
.bk-empty {
  display: flex; flex-direction: column; gap: 4px;
  align-items: center; text-align: center;
  padding: 28px 16px;
  color: var(--fg-muted);
}
.bk-empty--sm { padding: 18px 12px; }
.bk-empty__title { font: 600 0.9rem/1.2 var(--font-display); color: var(--fg-strong); }
.bk-empty__sub { font: 400 0.8rem/1.45 var(--font-body); color: var(--fg-muted); max-width: 32ch; }

/* ---------- Leaderboard (desktop) ---------------------------------------- */
.bk-leader-filters { display: flex; flex-wrap: wrap; gap: 10px; }

/* Podium — 2nd | 1st | 3rd */
.bk-podium {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  align-items: end;
  max-width: 720px;
  margin: 4px auto 6px;
}
.bk-podium__col {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 18px 12px 0;
  text-align: center;
}
.bk-podium__medal {
  width: 26px; height: 26px; border-radius: var(--radius-pill);
  display: grid; place-items: center;
  font: 800 0.8rem/1 var(--font-display); color: #fff;
  background: var(--fg-subtle);
}
.bk-podium__col--1 .bk-podium__medal { background: linear-gradient(135deg, #f59e0b, #fbbf24); }
.bk-podium__col--2 .bk-podium__medal { background: linear-gradient(135deg, #94a3b8, #cbd5e1); color: #0b0e14; }
.bk-podium__col--3 .bk-podium__medal { background: linear-gradient(135deg, #b45309, #d97706); }
.bk-podium__avatar {
  width: 56px; height: 56px; border-radius: var(--radius-pill);
  display: grid; place-items: center;
  font: 800 1.1rem/1 var(--font-display); color: #fff;
  box-shadow: var(--shadow-sm);
  margin-top: 4px;
}
.bk-podium__col--1 .bk-podium__avatar { width: 66px; height: 66px; font-size: 1.3rem; }
.bk-podium__name { font: 700 0.9rem/1.2 var(--font-display); color: var(--fg-strong); margin-top: 4px; }
.bk-podium__role { font: 500 0.72rem/1.2 var(--font-display); color: var(--fg-muted); }
.bk-podium__score { font: 800 1.4rem/1 var(--font-display); color: var(--fg-strong); margin-top: 4px; letter-spacing: -0.02em; }
.bk-podium__col--1 .bk-podium__score { font-size: 1.7rem; color: var(--accent-action); }
.bk-podium__tests { font: 500 0.72rem/1.2 var(--font-display); color: var(--fg-subtle); }
.bk-podium__plinth {
  margin-top: 10px; width: 100%;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-bottom: 0;
  display: grid; place-items: center;
  color: var(--fg-subtle);
  font: 800 1.1rem/1 var(--font-display);
}
.bk-podium__col--1 .bk-podium__plinth { height: 84px; background: var(--accent-action-soft); }
.bk-podium__col--2 .bk-podium__plinth { height: 60px; }
.bk-podium__col--3 .bk-podium__plinth { height: 44px; }
.bk-podium__col.is-me .bk-podium__name { color: var(--accent-action); }

/* Table */
.bk-table-wrap {
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
.bk-table { width: 100%; border-collapse: collapse; }
.bk-table thead th {
  text-align: left;
  font: 700 0.7rem/1 var(--font-display);
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--fg-subtle);
  padding: 12px 16px;
  background: var(--surface-sunken);
  border-bottom: 1px solid var(--line);
}
.bk-table tbody td { padding: 12px 16px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.bk-table tbody tr:last-child td { border-bottom: 0; }
.bk-table tbody tr { transition: background var(--dur-fast); }
.bk-table tbody tr:hover { background: var(--surface-sunken); }
.bk-table tbody tr.is-me { background: var(--accent-action-soft); }
.bk-num { text-align: right; }
.bk-leader-table__rank { width: 48px; color: var(--fg-subtle); font-weight: 700; }
.bk-leader-table__score { font-weight: 700; color: var(--fg-strong); }
.bk-leader-table__trend { width: 90px; color: var(--accent-action); }
.bk-leader-table__last { color: var(--fg-muted); font-size: 0.82rem; white-space: nowrap; }
.bk-leader-cell { display: flex; align-items: center; gap: 12px; }
.bk-leader-cell__avatar {
  width: 34px; height: 34px; border-radius: var(--radius-pill);
  display: grid; place-items: center; flex: 0 0 auto;
  font: 700 0.78rem/1 var(--font-display); color: #fff;
}
.bk-leader-cell__text { display: flex; flex-direction: column; min-width: 0; }
.bk-leader-cell__name { font: 600 0.9rem/1.25 var(--font-display); color: var(--fg-strong); }
.bk-leader-cell__sub { font: 400 0.76rem/1.3 var(--font-body); color: var(--fg-muted); }
.bk-spark { display: block; }

/* ---------- Wide reading column (Tables floor plan) ---------------------- */
.web-ios-column--wide { max-width: 1040px; }
@media (min-width: 1024px) {
  /* Give the floor plan the room it was denied at 680px; the controls above
     it stay readable by capping their width and centring. */
  .web-ios-column--wide .ios-screen__header,
  .web-ios-column--wide .ios-table-search,
  .web-ios-column--wide .ios-segmented,
  .web-ios-column--wide .ios-zone-rail { max-width: 720px; }
  .web-ios-column--wide .ios-floor-plan-wrap {
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
    background: var(--surface);
    box-shadow: var(--shadow-xs);
    padding: 16px;
  }
  .web-ios-column--wide .ios-floor-plan { min-height: 460px; }
}

/* ---------- Admin landing (desktop control panel) ------------------------ */
@media (min-width: 1024px) {
  .ios-admin-landing {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 22px;
    align-items: start;
  }
  /* Back row + page header span both columns; section cards flow two-up. */
  .ios-admin-landing > .ios-back-row,
  .ios-admin-landing > .ios-screen__header { grid-column: 1 / -1; }
  .ios-admin-landing > .ios-back-row { display: none; } /* side nav handles nav on desktop */
  .ios-admin-landing > .ios-section { margin: 0; }
  .ios-admin-landing > .ios-section > .ios-list {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-xs);
    overflow: hidden;
  }
}

/* ---------- Home hero ----------------------------------------------------- */
.bk-home-hero {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 24px 0 6px;
}
.bk-home-hero__title {
  margin: 0;
  font: 700 clamp(1.8rem, 3.6vw, 2.8rem)/1.05 var(--font-display);
  letter-spacing: -0.04em;
  color: var(--fg-strong);
}
.bk-home-hero__sub { color: var(--fg-muted); max-width: 48ch; }

/* Quick-action grid */
.bk-quick-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}

/* Stats grid */
.bk-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
}

/* Card grid (flashcards) */
.bk-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}
/* Gentle entry stagger, mirroring the phone grid. Capped at 10 cards.
   Neutralised by the global prefers-reduced-motion block. */
@keyframes bk-card-enter {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.bk-card-grid > .bk-flashcard {
  animation: bk-card-enter 300ms var(--ease-out) both;
}
.bk-card-grid > .bk-flashcard:nth-child(1)  { animation-delay: 0ms; }
.bk-card-grid > .bk-flashcard:nth-child(2)  { animation-delay: 40ms; }
.bk-card-grid > .bk-flashcard:nth-child(3)  { animation-delay: 80ms; }
.bk-card-grid > .bk-flashcard:nth-child(4)  { animation-delay: 120ms; }
.bk-card-grid > .bk-flashcard:nth-child(5)  { animation-delay: 160ms; }
.bk-card-grid > .bk-flashcard:nth-child(6)  { animation-delay: 200ms; }
.bk-card-grid > .bk-flashcard:nth-child(7)  { animation-delay: 240ms; }
.bk-card-grid > .bk-flashcard:nth-child(8)  { animation-delay: 280ms; }
.bk-card-grid > .bk-flashcard:nth-child(9)  { animation-delay: 320ms; }
.bk-card-grid > .bk-flashcard:nth-child(n+10) { animation-delay: 360ms; }

/* ---------- Search wrap with icon ----------------------------------------- */
.bk-search-wrap {
  position: relative;
  min-width: 260px;
  flex: 1;
  max-width: 360px;
}
.bk-search-wrap svg {
  position: absolute;
  top: 50%; left: 14px;
  transform: translateY(-50%);
  color: var(--fg-muted);
  pointer-events: none;
}

/* ---------- Segmented (Full / Batch / Both) ------------------------------- */
.bk-segmented {
  display: inline-flex;
  padding: 4px;
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  align-self: flex-start;
}
.bk-segmented__pill {
  position: relative;
  cursor: pointer;
}
.bk-segmented__pill input { position: absolute; opacity: 0; pointer-events: none; }
.bk-segmented__pill span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 72px;
  padding: 8px 18px;
  border-radius: var(--radius-pill);
  font: 600 0.85rem/1 var(--font-display);
  color: var(--fg-muted);
  transition: background var(--dur-fast), color var(--dur-fast);
}
.bk-segmented__pill.is-active span {
  background: var(--surface-strong);
  color: var(--fg-strong);
  box-shadow: var(--shadow-xs);
}

/* ---------- Chip row scroll ----------------------------------------------- */
.bk-chip-row {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 4px 0;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.bk-chip-row::-webkit-scrollbar { display: none; }
.bk-chip-row .bk-chip { flex: 0 0 auto; }

/* ---------- Spec-test two-column ------------------------------------------ */
.bk-test-setup {
  display: grid;
  gap: 14px;
  grid-template-columns: 1fr;
}
@media (min-width: 820px) {
  .bk-test-setup { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); }
}
.bk-list {
  margin: 0; padding-left: 16px;
  display: flex; flex-direction: column; gap: 8px;
  color: var(--fg-muted);
}
.bk-list strong { color: var(--fg-strong); font-weight: 600; }

.bk-hint {
  font: 500 0.78rem/1.4 var(--font-display);
  color: var(--fg-muted);
}

/* Nav footer (logout) sits at bottom of drawer */
.bk-nav-footer {
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.bk-nav-link--logout { color: #b91c1c; }
.bk-nav-link--logout svg { color: #b91c1c; }
.bk-nav-link--logout .bk-nav-link__label { color: #b91c1c; -webkit-text-fill-color: #b91c1c; }
.bk-nav-link--logout:hover { background: rgba(185, 28, 28, 0.08); color: #b91c1c; }
[data-theme="dark"] .bk-nav-link--logout,
[data-theme="dark"] .bk-nav-link--logout svg { color: #fca5a5; }
[data-theme="dark"] .bk-nav-link--logout .bk-nav-link__label { color: #fca5a5; -webkit-text-fill-color: #fca5a5; }
[data-theme="dark"] .bk-nav-link--logout:hover { background: rgba(252, 165, 165, 0.10); color: #fecaca; }

/* ---------- Side-nav label colour --------------------------------------- */
/* The label text lives in a <span> rather than directly in the <button>.
   On <button> elements with color-scheme set, `color: var(--fg)` mis-resolves
   to the light-theme value and -webkit-text-fill-color paints it near-black,
   so inactive dark-mode labels failed AA. Painting the colour on the span
   (which resolves the var correctly in both themes) restores ~13:1 contrast. */
.bk-nav-link__label {
  color: var(--fg);
  -webkit-text-fill-color: var(--fg);
}
.bk-nav-link.is-active .bk-nav-link__label {
  color: var(--accent-action);
  -webkit-text-fill-color: var(--accent-action);
}

/* Contrast on glass: the nav now floats on the Liquid Glass material, so the
   active pill is reinforced (more opaque fill + firmer border) to stay clearly
   distinct and keep the blue label/icon >= WCAG AA over a refractive surface.
   Resting labels already use the strong --fg token painted on the span above. */
@media (min-width: 1024px) {
  .bk-side-nav .bk-nav-link.is-active {
    background: var(--accent-action-soft);
    border-color: var(--accent-action);
    box-shadow: inset 0 0 0 1px var(--accent-action-soft);
  }
  [data-theme="dark"] .bk-side-nav .bk-nav-link.is-active {
    background: var(--accent-action-soft);
    border-color: var(--accent-action);
  }
  /* Collapsed rail tooltips rely on the active pill being readable as an icon
     square — keep the icon tinted to the accent so the current screen is
     obvious even without a label. */
  .bk-side-nav.is-collapsed .bk-nav-link.is-active { border-radius: var(--radius-md); }
}

/* ---------- Venue switcher (whole name + chevron clickable) --------------- */
.bk-venue-switcher {
  position: relative;
  display: inline-flex;
  align-items: center;
  max-width: 100%;
}
/* The entire label + chevron is ONE button so a click anywhere on the venue
   name opens the menu (previously only the far-right caret was the target). */
.bk-venue-switcher__trigger {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--fg-strong);
  font: var(--type-h3);
  letter-spacing: -0.02em;
  padding: 2px 8px;
  margin-left: -8px;
  border-radius: var(--radius-md);
  cursor: pointer;
  max-width: 100%;
  transition: background var(--dur-fast), border-color var(--dur-fast);
}
.bk-venue-switcher__trigger:hover { background: var(--accent-action-soft); }
.bk-venue-switcher__trigger:focus-visible {
  outline: none;
  border-color: var(--accent-action);
  background: var(--accent-action-soft);
}
.bk-venue-switcher__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bk-venue-switcher__label--static { padding: 2px 0; }
.bk-venue-switcher__caret {
  flex: 0 0 auto;
  transform: rotate(90deg);
  color: var(--fg-muted);
}
.bk-venue-switcher__trigger[aria-expanded="true"] .bk-venue-switcher__caret {
  transform: rotate(-90deg);
  color: var(--accent-action);
}

/* Grouped dropdown — company/brand headers + selectable venues. Mirrors the
   phone's grouped Active-venue list. */
.bk-venue-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: -8px;
  z-index: 60;
  /* Wide panel anchored under the trigger so many venues show at once instead
     of a narrow scrolling column. Caps to the viewport on small screens. */
  width: min(760px, 92vw);
  max-height: min(70vh, 520px);
  overflow-y: auto;
  padding: 10px;
  border-radius: var(--radius-lg, 16px);
  /* Readable, near-solid surface with only a light blur — the old translucent
     glass made venue names hard to read over busy page content. */
  background: var(--glass-bg-solid);
  border: 1px solid var(--glass-edge);
  box-shadow:
    inset 0 1px 0 var(--glass-spec),
    inset 0 0 0 1px rgba(255, 255, 255, 0.04),
    0 24px 56px -12px rgba(0, 0, 0, 0.28);
  -webkit-backdrop-filter: blur(8px) saturate(140%);
  backdrop-filter: blur(8px) saturate(140%);
}
/* Brand groups flow as columns so several companies sit side by side; each
   group's venues then stack within its column. */
.bk-venue-menu__groups {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 6px 16px;
  align-items: start;
}
.bk-venue-menu__group { min-width: 0; }
/* No top divider/margin in the grid — columns separate the groups visually. */
.bk-venue-menu__group + .bk-venue-menu__group { margin-top: 0; padding-top: 0; border-top: 0; }
/* "All access" sits full-width above the grid; a hairline rule sets it apart. */
.bk-venue-menu__group--all { margin-bottom: 6px; padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.bk-venue-menu__head {
  font: 800 0.66rem/1 var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fg-muted);
  padding: 8px 10px 4px;
}
.bk-venue-menu__item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  border: 0;
  background: transparent;
  color: var(--fg-strong);
  font: 600 0.9rem/1.2 var(--font-display);
  padding: 9px 10px;
  border-radius: var(--radius-md, 10px);
  cursor: pointer;
}
.bk-venue-menu__item:hover { background: var(--accent-action-soft); }
.bk-venue-menu__item.is-active { color: var(--accent-action); background: var(--accent-action-soft); }
.bk-venue-menu__check {
  flex: 0 0 auto;
  width: 14px;
  text-align: center;
  color: var(--accent-action);
  font-weight: 800;
}
/* Search box pinned to the top of the venue dropdown (mirrors the phone's
   Active-venue search). Sticky so it stays visible while the list scrolls. */
.bk-venue-menu__search {
  position: sticky;
  top: -10px;
  z-index: 1;
  margin: -10px -10px 8px;
  padding: 10px 10px 10px;
  background: var(--glass-bg-solid);
  border-bottom: 1px solid var(--line);
}
.bk-venue-menu__search .bk-input--sm {
  height: 36px;
  padding: 6px 10px;
  font: 600 0.88rem/1.2 var(--font-display);
}
.bk-venue-menu__empty {
  padding: 10px;
  color: var(--fg-muted);
  font: 600 0.85rem/1.3 var(--font-display);
}

/* ── Shared phone card on the desktop ──────────────────────────────────────
   The Flash Cards screen opens the SAME FlyingFlashCard component the phone
   uses (photo, spec table, method/glass/ice/garnish, ingredient popover,
   editors). On the phone it positions inside .ios-app-root; in the web shell
   there is no phone frame, so these rules pin the overlay to the viewport. */
.bk-web .ios-modal-backdrop { position: fixed; inset: 0; z-index: 880; }
/* The desktop open-animation hook. display:contents means the stage adds NO
   box — so it can't become the containing block for the card's fixed-position
   editor sheet (the bug the note below guards against). It only carries the
   .is-closing class for the faster exit. */
.bk-web-card-stage { display: contents; }
.bk-web .ios-modal-card {
  /* Centre with inset+margin, NOT a persistent transform: a transformed
     ancestor becomes the containing block for position:fixed children, which
     shoved the ingredient popover and editor sheets off to the side. */
  position: fixed; inset: 0; margin: auto; z-index: 900;
  width: min(450px, 92vw);
  height: min(780px, 90vh);
  transform: none;
  transition: none; /* no fly-from-grid on desktop — it simply presents */
}

/* ── Desktop flash-card OPEN animation ─────────────────────────────────────
   Mirrors the phone's flip energy without touching the shared card internals:
   the card eases in from a slightly turned, smaller, transparent state to
   rest. CRUCIAL: the resting (`to`) state is `transform: none` so that once
   the card has settled it is NOT a transformed ancestor — otherwise it would
   become the containing block for the fixed-position editor sheet and shove
   it off-centre (the bug the note above guards against). Browsers interpolate
   the `perspective()…` start to/from `none` via matrices, so the 3D turn
   still reads. Exit is quicker; the card unmounts straight after. Only
   transform + opacity animate. */
@keyframes bk-webcard-in {
  from { opacity: 0; transform: perspective(1100px) scale(0.92) rotateY(-10deg); }
  to   { opacity: 1; transform: none; }
}
@keyframes bk-webcard-out {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: perspective(1100px) scale(0.96); }
}
.bk-web .ios-modal-card {
  transform-origin: center center;
  animation: bk-webcard-in 260ms var(--ease-out) both;
}
.bk-web-card-stage.is-closing .ios-modal-card {
  animation: bk-webcard-out 160ms var(--ease-out) both;
}
/* Backdrop fades in with the card and out on close. */
.bk-web .ios-modal-backdrop.is-open { animation: ios-sheet-fade var(--dur-med) var(--ease-out) both; }
.bk-web .ios-modal-backdrop.is-open.is-closing { animation: bk-webcard-fade-out 160ms var(--ease-out) both; }
@keyframes bk-webcard-fade-out { from { opacity: 1; } to { opacity: 0; } }

/* Reduced motion: no transform/scale/rotate — a plain fade only, honouring the
   global prefers-reduced-motion contract. */
@media (prefers-reduced-motion: reduce) {
  @keyframes bk-webcard-in  { from { opacity: 0; } to { opacity: 1; } }
  @keyframes bk-webcard-out { from { opacity: 1; } to { opacity: 0; } }
  .bk-web .ios-modal-card,
  .bk-web-card-stage.is-closing .ios-modal-card { transform: none; }
}
/* The ingredient popover is positioned relative to the card (its containing
   block via perspective) with card-relative coordinates from showPopover —
   no override needed; keep its z above the card content. */
.bk-web .ios-bottle-popover { z-index: 950; }
/* Editor sheets (ingredient / glass / colour) become centred dialogs. */
.bk-web .ios-sheet-backdrop { position: fixed; inset: 0; z-index: 960; }
.bk-web .ios-sheet {
  position: fixed; inset: 0; margin: auto; z-index: 970;
  width: min(440px, 92vw);
  height: fit-content;
  max-height: 88vh; overflow-y: auto;
  transform: none;
  border-radius: var(--radius-xl, 22px);
}

/* ── Desktop width: stop wasting the monitor ───────────────────────────────
   Phone-first screens rendered in the web shell were clamped to a 680px
   column — on a large display that reads as a skinny strip with giant gaps.
   Let the column breathe and let photo grids use the width (4-5 cards per
   row instead of 2). Forms (batching, spec test) keep a readable measure. */
.bk-web .web-ios-column { max-width: min(1680px, 96vw); }
.bk-web .web-ios-column--wide { max-width: none; padding-inline: 8px; }
/* Let the shell's content area itself breathe on very large monitors. */
.bk-web .bk-screen { max-width: none; }
.bk-web .ios-photo-grid {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}
/* The flash-card grid on desktop also earns more columns on big monitors. */
.bk-web .bk-card-grid {
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
/* Keep single-column FORM screens at a comfortable reading measure even
   inside the wider column. */
.bk-web .web-ios-column .ios-form,
.bk-web .web-ios-column .bk-field { max-width: 720px; }

/* Bottle / glass catalogue cards: centre the content under the photo. */
.bk-web .ios-photo-card, .ios-photo-card { text-align: center; }
.ios-photo-card__img img { object-position: center; }


/* Food menu lift: clearer rhythm, toned allergen chips, prices right-aligned
   (tabular) when present. */
.ios-food-row, .ios-list__row { scroll-margin-top: 80px; }
.bk-tag--v    { background: rgba(14,159,110,.14) !important; color: #0e9f6e !important; }
.bk-tag--vg   { background: rgba(8,145,178,.14)  !important; color: #0891b2 !important; }
.bk-tag--ngci { background: rgba(217,119,6,.14)  !important; color: #d97706 !important; }

/* Food menu: flow into columns on wide screens. */
.bk-web .bk-menu { columns: 420px 2; column-gap: 40px; max-width: 1200px; }
.bk-web .bk-menu__key { column-span: all; }
