/* BreamBay.nz — hand-maintained overrides layered on top of vendored,
   unmodified Bootstrap + Bootstrap Icons (see _Layout.cshtml for load
   order — this file loads last, so it wins on equal selector specificity).
   No build step: edit this file directly and refresh, same as fisho/browse.

   Structure:
   1. BreamBay design tokens (CSS custom properties)
   2. Bootstrap theme overrides — colours/fonts/radius Bootstrap itself
      doesn't expose as a root-level custom property, so these are explicit
      rules targeting the same classes stock Bootstrap defines
   3. BreamBay's own custom component classes (bb-*)
*/

/* ── 1. Design tokens ─────────────────────────────────────────── */
:root {
  --bb-ink: #16232E;      /* primary text — cool navy-black */
  --bb-sky: #FBF3E4;      /* page/card background — warm cream */
  --bb-iron: #5A6B78;     /* secondary text — cool slate */
  --bb-navy: #0C2438;     /* dark ink-navy neutral — nav/footer/hero bg, not an accent */
  --bb-green: #0E7C6B;    /* secondary accent — bay teal */
  --bb-maroon: #D8331F;   /* primary accent — pōhutukawa crimson */
  --bb-gold: #C98A12;     /* secondary accent — golden sand (category chips) */
  --bb-thistle: #7C5A96;  /* secondary accent (category chips) */
  --bb-line: #DEE3E7;     /* hairline borders */
  --bb-sand: #F2E1BD;     /* warm structural surface (currently unused) */
}

/* ── 2. Bootstrap theme overrides ─────────────────────────────── */

/* Root design tokens Bootstrap 5.3 components consume directly via
   var(--bs-*) at the point of use — overriding this block retheme
   body/borders/links/focus-ring/etc. sitewide without touching every
   individual component class. */
:root, [data-bs-theme=light] {
  --bs-primary: var(--bb-maroon);
  --bs-secondary: var(--bb-green);
  --bs-primary-rgb: 216, 51, 31;
  --bs-secondary-rgb: 14, 124, 107;
  --bs-body-font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --bs-body-line-height: 1.6;
  --bs-body-color: var(--bb-ink);
  --bs-body-color-rgb: 22, 35, 46;
  --bs-body-bg: var(--bb-sky);
  --bs-body-bg-rgb: 251, 243, 228;
  --bs-secondary-color: rgba(22, 35, 46, .75);
  --bs-tertiary-color: rgba(22, 35, 46, .5);
  --bs-link-color: var(--bb-navy);
  --bs-link-color-rgb: 12, 36, 56;
  --bs-link-hover-color: var(--bb-maroon);
  --bs-link-hover-color-rgb: 216, 51, 31;
  --bs-border-color: var(--bb-line);
  --bs-border-radius: .5rem;
  --bs-border-radius-sm: .375rem;
  --bs-border-radius-lg: .75rem;
  --bs-focus-ring-color: rgba(216, 51, 31, .25);
}

/* Buttons are fully pill-shaped, not just rounded — applies to every
   .btn/.btn-sm/.btn-lg via this one custom property. */
.btn {
  --bs-btn-border-radius: 50rem;
}

/* .btn-primary/.btn-secondary bake concrete hex colours at the class
   level rather than referencing --bs-primary/--bs-secondary, so they need
   their own explicit override. Hover/active shades are the same values
   Bootstrap's own Sass colour functions previously computed for these
   hexes — kept identical so nothing shifts visually. */
.btn-primary {
  --bs-btn-color: #fff;
  --bs-btn-bg: var(--bb-maroon);
  --bs-btn-border-color: var(--bb-maroon);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: rgb(183.6, 43.35, 26.35);
  --bs-btn-hover-border-color: rgb(172.8, 40.8, 24.8);
  --bs-btn-focus-shadow-rgb: 222, 82, 65;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: rgb(172.8, 40.8, 24.8);
  --bs-btn-active-border-color: rgb(162, 38.25, 23.25);
  --bs-btn-disabled-color: #fff;
  --bs-btn-disabled-bg: var(--bb-maroon);
  --bs-btn-disabled-border-color: var(--bb-maroon);
}

.btn-secondary {
  --bs-btn-color: #fff;
  --bs-btn-bg: var(--bb-green);
  --bs-btn-border-color: var(--bb-green);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: rgb(11.9, 105.4, 90.95);
  --bs-btn-hover-border-color: rgb(11.2, 99.2, 85.6);
  --bs-btn-focus-shadow-rgb: 50, 144, 129;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: rgb(11.2, 99.2, 85.6);
  --bs-btn-active-border-color: rgb(10.5, 93, 80.25);
  --bs-btn-disabled-color: #fff;
  --bs-btn-disabled-bg: var(--bb-green);
  --bs-btn-disabled-border-color: var(--bb-green);
}

/* $input-border-color/$input-focus-border-color/$card-border-color — a
   more visible border than the faint --bs-border-color hairline, since
   form fields and cards need to actually read as a box against the page.
   Stock Bootstrap's .form-control/.form-select reference var(--bs-body-bg)
   for their background, which would otherwise pick up the page's cream
   colour once --bs-body-bg is overridden above — fields need their own
   white surface instead, per $input-bg in the original design-system doc. */
.form-control,
.form-select {
  background-color: #fff;
  border-color: #C2A46E;
}

/* Stock Bootstrap hardcodes its focus border/box-shadow to a fixed blue
   rather than referencing --bs-focus-ring-color, so these need an explicit
   override too, not just border-color. */
.form-control:focus,
.form-select:focus,
.form-check-input:focus {
  border-color: var(--bb-navy);
  box-shadow: 0 0 0 .25rem rgba(216, 51, 31, .25);
}

.form-control:focus {
  background-color: #fff;
}

.form-check-input {
  border-color: #C2A46E;
}

.form-check-input:checked {
  background-color: var(--bb-maroon);
  border-color: var(--bb-maroon);
}

.card {
  --bs-card-border-color: #C2A46E;
  --bs-card-bg: #fff;
}

/* Business details hero photo — see _BusinessListingBody.cshtml. Two
   layers: a blurred/darkened cover-fit copy behind (fills the box
   completely, so it's never obviously "the wrong shape"), and the real
   image on top at object-fit-contain, which never crops it. */
.bb-hero-photo {
  position: relative;
}

.bb-hero-photo-backdrop {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  /* Scaled up past 100% so the blur's own soft edge falls outside the
     visible box instead of showing as a lighter halo around the edge. */
  transform: scale(1.15);
  filter: blur(24px) brightness(0.55);
}

.bb-hero-photo-fg {
  /* No position here — Bootstrap's .ratio > * rule already makes this
     absolute + 100% width/height, at the same specificity as anything
     declared here; setting position: relative on this class overrode that
     and broke the image's sizing entirely (that's the bug that just went
     to production). z-index alone is enough since it's already positioned. */
  z-index: 1;
}

/* Headings — Bricolage Grotesque, weight 800, replacing Bootstrap's default
   sans stack. Bootstrap bakes font-family into this combined selector
   rather than exposing it as a root custom property. */
h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 {
  font-family: "Bricolage Grotesque", system-ui, sans-serif;
  font-weight: 800;
}

h1, .h1 { font-size: 3.5rem; }
h2, .h2 { font-size: 2.25rem; }
h3, .h3 { font-size: 1.5rem; }

/* ── 3. BreamBay custom components ────────────────────────────── */

/* Utility/data face — Inter at smaller size with wider letter-spacing,
   for metadata (event dates, category tags, addresses) — deliberately
   not a third font family. */
.bb-meta {
  font-size: .875rem;
  font-weight: 500;
  letter-spacing: 0.02em;
}

/* Event card fallback when there's no cover photo — see
   Views/Shared/_EventCardImage.cshtml. Flat colour block (picked per-event
   from the brand accents) with an icon and the suburb, standing in for a
   stock hero photo we don't want to curate per listing. */
.bb-event-placeholder {
  width: 100%;
  height: 100%;
  gap: .25rem;
}
.bb-event-placeholder .bi {
  font-size: 2rem;
  opacity: .85;
}
.bb-event-placeholder .bb-meta {
  opacity: .9;
}

/* Footer nav — labels ("Suburbs"/"Categories") in full ink rather than the
   muted text-body-secondary grey, so they read as solid section headings
   rather than washed-out metadata. Links fill solid on hover/focus like a
   button rather than just underlining, padding is reserved at rest so the
   fill doesn't shift surrounding layout. */
.bb-footer-heading {
  font-size: .875rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--bb-ink);
  margin-bottom: 0.75rem;
}

.bb-footer-link {
  display: inline-block;
  color: var(--bb-iron);
  text-decoration: none;
  padding: 0.3rem 0.65rem;
  margin: 0.05rem 0 0.05rem -0.65rem;
  border-radius: .375rem;
  transition: background-color .15s ease, color .15s ease;
}

.bb-footer-link:hover,
.bb-footer-link:focus {
  background-color: var(--bb-maroon);
  color: #fff;
}

.bb-footer-cta {
  display: inline-block;
  color: var(--bb-maroon);
  font-weight: 600;
  text-decoration: none;
  padding: 0.55rem 1.1rem;
  margin-left: -1.1rem;
  border: 1px solid var(--bb-maroon);
  border-radius: .5rem;
  transition: background-color .15s ease, color .15s ease;
}

.bb-footer-cta:hover,
.bb-footer-cta:focus {
  background-color: var(--bb-maroon);
  color: #fff;
}

/* H2s within long-form content (Featured Stories) get a solid underline in
   the primary accent colour. */
.bb-story-body h2 {
  padding-bottom: 0.5rem;
  border-bottom: 2px solid rgba(216, 51, 31, 0.3);
}

/* jquery.validate.unobtrusive toggles this class on asp-validation-summary
   when there are no errors — hide it rather than showing an empty alert box. */
.validation-summary-valid {
  display: none;
}

/* Scoped to submission-style forms (Add Your Business, Manage), not applied
   to .card globally — the plain white .card base is right for directory/
   story/event cards, but a long form panel needed more presence than a flat
   white box with a hairline border, per feedback that it read as
   "underwhelming". A crimson top edge reuses the one dominant accent colour
   already established elsewhere rather than introducing a second one; the
   shadow is warm-tinted (ink, not grey) to match the palette. */
.bb-form-card {
  border-top: 3px solid var(--bb-maroon);
  box-shadow: 0 4px 20px rgba(22, 35, 46, 0.09);
}

/* Submit-time overlay for forms with a file upload — see site.js. Users were
   navigating away mid-upload because a disabled button alone gave no visible
   sign the page was working, losing a couple of submissions to it. Anchored
   to the form itself (not the whole viewport) so it only covers the card
   being submitted. */
form[enctype="multipart/form-data"] {
  position: relative;
}

.bb-submit-overlay {
  position: absolute;
  inset: 0;
  z-index: 10;
  background: rgba(255, 255, 255, 0.95);
  border-radius: inherit;
}

/* Fixed to the viewport rather than flex-centered within the overlay
   above — the overlay spans the whole form, which on these long forms is
   taller than the screen, so centering within it put the spinner off
   whatever part of the form the user had scrolled to (usually the bottom,
   right where the submit button is). Fixed positioning keeps it on-screen
   regardless of scroll position. */
.bb-submit-overlay-content {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 11;
  text-align: center;
  padding: 1rem;
}

/* Suburb navigation as a row of pill-shaped chips (not a full-width bar) —
   per the "Bream Bay Directory" theme concept. Each suburb gets its own
   rounded, teal-filled pill with a gap between them; wraps to multiple rows
   on narrow screens instead of stacking full-bleed. */
.bb-suburb-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.bb-suburb-strip a {
  color: #fff;
  background-color: var(--bb-green);
  padding: 0.6rem 1.25rem;
  border-radius: 999px;
  transition: background-color .15s ease;
}

.bb-suburb-strip a:hover,
.bb-suburb-strip a:focus {
  background-color: var(--bb-maroon);
  color: #fff;
}

/* Category card icon — a filled rounded colour chip behind the glyph,
   cycling through the theme's four accent colours, instead of a plain
   tinted line icon on white. See Home/Index.cshtml. */
.bb-cat-chip {
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: .75rem;
  flex-shrink: 0;
}

.bb-cat-chip--teal {
  background-color: rgba(14, 124, 107, 0.14);
  color: var(--bb-green);
}

.bb-cat-chip--crimson {
  background-color: rgba(216, 51, 31, 0.12);
  color: var(--bb-maroon);
}

.bb-cat-chip--gold {
  background-color: rgba(201, 138, 18, 0.18);
  color: var(--bb-gold);
}

.bb-cat-chip--thistle {
  background-color: rgba(124, 90, 150, 0.14);
  color: var(--bb-thistle);
}

/* Small uppercase label above section H2s (e.g. "BROWSE THE DIRECTORY"),
   per the reference theme concept — a lightweight signpost that doesn't
   depend on a divider rule to separate sections. */
.bb-eyebrow {
  display: inline-block;
  color: var(--bb-maroon);
  font-weight: 700;
  font-size: .875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 0.4rem;
}

/* Gold nav CTA ("Add Your Business") — the one button on the (dark) nav
   that isn't crimson, so it reads against the dark background the way the
   reference theme's sand-coloured button does. */
.bb-nav-cta {
  background-color: var(--bb-gold);
  color: var(--bb-navy);
  border: none;
}

.bb-nav-cta:hover,
.bb-nav-cta:focus {
  background-color: #b57c0f;
  color: var(--bb-navy);
}

/* Translucent badge above the hero H1 (e.g. "WAIPU TO MARSDEN BAY"). */
.bb-hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background-color: rgba(255, 255, 255, 0.15);
  color: #fff;
  font-weight: 700;
  font-size: .875rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0.45rem 1rem;
  border-radius: 999px;
  margin-bottom: 1.25rem;
}

/* Hero search bar — a white pill housing the input and a crimson submit
   button, floating over the hero photo. */
.bb-hero-search {
  background-color: #fff;
  border-radius: 999px;
  padding: 0.4rem;
  display: flex;
  gap: 0.4rem;
  max-width: 34rem;
  box-shadow: 0 16px 34px rgba(12, 36, 56, 0.28);
}

.bb-hero-search input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  padding: 0.5rem 1rem;
  color: var(--bb-ink);
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

.bb-hero-search button {
  border: none;
  border-radius: 999px;
  background-color: var(--bb-maroon);
  color: #fff;
  font-weight: 700;
  padding: 0 1.4rem;
}

/* Translucent quick-link chips beneath the hero search bar. */
.bb-hero-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1.25rem;
}

.bb-hero-chips a {
  background-color: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: #fff;
  font-size: .875rem;
  font-weight: 600;
  padding: 0.5rem 1rem;
  border-radius: 999px;
  text-decoration: none;
  transition: background-color .15s ease;
}

.bb-hero-chips a:hover,
.bb-hero-chips a:focus {
  background-color: rgba(255, 255, 255, 0.22);
  color: #fff;
}

/* Footer goes dark navy (matching the nav) rather than the pale
   bg-body-tertiary grey it used before — nav and footer bookend the page
   in the same dark chrome. Scoped overrides for the Bootstrap secondary-
   text/link utilities used inside, which otherwise assume a light
   background. */
.bb-footer-dark {
  background-color: var(--bb-navy);
  color: rgba(255, 255, 255, 0.72);
}

.bb-footer-dark h2.h5 {
  color: #fff;
}

.bb-footer-dark .bb-footer-heading {
  color: #fff;
}

.bb-footer-dark .bb-footer-link {
  color: rgba(255, 255, 255, 0.72);
}

.bb-footer-dark .bb-footer-cta {
  color: var(--bb-gold);
  border-color: var(--bb-gold);
}

.bb-footer-dark .bb-footer-cta:hover,
.bb-footer-dark .bb-footer-cta:focus {
  background-color: var(--bb-gold);
  color: var(--bb-navy);
}

.bb-footer-dark .text-body-secondary {
  color: rgba(255, 255, 255, 0.6) !important;
}

.bb-footer-dark a.link-secondary {
  color: rgba(255, 255, 255, 0.75) !important;
}

.bb-footer-dark hr {
  border-color: rgba(255, 255, 255, 0.15);
  opacity: 1;
}

/* ── Admin shell — left sidebar + light grey content, deliberately not
   the warm cream public-site background, so it reads as a distinct
   backend rather than another marketing page. Pattern matches fisho's
   own admin dashboard (dark sidebar, white topbar, light grey content,
   page content wrapped in a white card) — see _LayoutAdmin.cshtml. */
.admin-wrapper {
  display: flex;
  min-height: 100vh;
}

.admin-sidebar {
  width: 240px;
  min-height: 100vh;
  flex-shrink: 0;
  background-color: var(--bb-navy);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

.admin-sidebar-brand {
  display: block;
  padding: .75rem 1.5rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  color: #fff;
  text-decoration: none;
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  margin-bottom: .5rem;
}

.admin-nav-link {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .55rem 1.5rem;
  color: rgba(255, 255, 255, 0.65);
  font-size: .9rem;
  text-decoration: none;
  border-left: 3px solid transparent;
  transition: background-color .15s ease, color .15s ease;
}

.admin-nav-link i {
  width: 1.1rem;
  text-align: center;
}

.admin-nav-link:hover {
  color: #fff;
  background-color: rgba(255, 255, 255, 0.06);
}

.admin-nav-link.active {
  color: #fff;
  background-color: rgba(255, 255, 255, 0.06);
  border-left-color: var(--bb-green);
}

.admin-sidebar-footer {
  margin-top: auto;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding-top: .5rem;
}

.admin-main {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background-color: #F4F6F9;
}

.admin-topbar {
  background-color: #fff;
  border-bottom: 1px solid #E8ECEF;
  padding: .75rem 1.5rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.admin-content {
  padding: 1.5rem;
  flex-grow: 1;
}

.admin-content > .card:first-child {
  margin-top: 0;
}

/* Bootstrap's own .tab-content > .tab-pane rule only matches direct
   children — the admin Business edit page wraps some panes in a <form> so
   a single submit covers Details+Hours together, which breaks that direct
   -child match. This descendant version works at any nesting depth. */
.tab-content .tab-pane {
  display: none;
}

.tab-content .tab-pane.active {
  display: block;
}

@media (max-width: 767px) {
  .admin-wrapper {
    flex-direction: column;
  }

  .admin-sidebar {
    width: 100%;
    min-height: auto;
  }
}

/* Category picker on the business submission/manage forms — a plain
   checkbox list (nested children indented under their parent), wrapped in
   a fixed-height 2-column scrolling box so a long category tree doesn't
   push the rest of the form down the page. break-inside: avoid-column on
   each group keeps a parent + its children together rather than splitting
   across the column break. See _CategoryCheckboxes.cshtml. */
.bb-category-scroll {
  max-height: 22rem;
  overflow-y: auto;
  border: 1px solid var(--bb-line);
  border-radius: 0.5rem;
  padding: 0.9rem 1.1rem;
  columns: 2;
  column-gap: 2rem;
}

.bb-category-group {
  break-inside: avoid-column;
  margin-bottom: 0.5rem;
}

@media (max-width: 575.98px) {
  .bb-category-scroll {
    columns: 1;
  }
}

/* House banner ad — see docs/banner-ad-spec.md and _BannerAd.cshtml. Fixed
   aspect-ratio per breakpoint so the container reserves its space before
   the image loads (no layout shift). 640px matches the spec's own default
   cutoff — none of the site's existing Bootstrap breakpoints (768/992)
   land where the spec's two ad sizes actually split, so this introduces
   the one the spec calls for rather than forcing an ill-fitting existing
   one. */
.bb-banner-ad {
  text-align: center;
  flex-shrink: 0;
}

.bb-banner-ad-label {
  display: block;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--bb-iron);
  margin-bottom: 0.35rem;
}

/* Space is reserved on the LINK wrapper (aspect-ratio per breakpoint), not
   the <img> — that's the spec's CLS requirement. The <img> itself renders
   naturally (width:100%, height:auto, no object-fit): the <picture> already
   swaps in the correctly-proportioned SVG per breakpoint (300x250 mobile,
   728x90 desktop) so it fills the wrapper exactly with nothing to fit.
   Forcing aspect-ratio + object-fit:cover on the <img> itself distorted the
   SVG on mobile Safari (object-fit on an <img> pointing at an SVG that also
   carries width/height attributes). Revisit the object-fit question once
   real advertiser raster creative of unknown proportions is involved. */
.bb-banner-ad-link {
  display: block;
  margin: 0 auto;
  max-width: 300px;
  aspect-ratio: 300 / 250;
}

.bb-banner-ad-img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 0.5rem;
}

@media (min-width: 640px) {
  .bb-banner-ad-link {
    max-width: 728px;
    aspect-ratio: 728 / 90;
  }
}

/* ── Events calendar — see docs/12-events-calendar.md ─────────────
   Hand-built month grid + agenda list, no third-party calendar library.
   The grid and the agenda are mutually exclusive by viewport width: the
   grid is unusable on a phone, so below 768px only the agenda shows. Both
   render from the same server-side data. */
.bb-cal { display: none; }
.bb-cal-agenda { display: block; }

@media (min-width: 768px) {
  .bb-cal {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 1px;
    background: var(--bb-line);
    border: 1px solid var(--bb-line);
    border-radius: 0.5rem;
    overflow: hidden;
  }
  .bb-cal-agenda { display: none; }
}

.bb-cal-head {
  background: var(--bb-navy);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-align: center;
  padding: 0.5rem 0.25rem;
}

.bb-cal-cell {
  background: #fff;
  min-height: 7.5rem;
  padding: 0.35rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

/* Days spilling in from the previous/next month — dimmed, not hidden, so
   the grid stays a full rectangle. */
.bb-cal-cell-out { background: var(--bb-sky); }
.bb-cal-cell-out .bb-cal-date { opacity: 0.5; }

.bb-cal-cell-today { outline: 2px solid var(--bb-maroon); outline-offset: -2px; }

.bb-cal-date {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--bb-iron);
}
.bb-cal-cell-today .bb-cal-date { color: var(--bb-maroon); }

.bb-cal-event {
  display: block;
  font-size: 0.78rem;
  line-height: 1.25;
  padding: 0.15rem 0.3rem;
  border-radius: 0.25rem;
  background: var(--bb-green);
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bb-cal-event:hover,
.bb-cal-event:focus { filter: brightness(1.1); color: #fff; }
.bb-cal-event-recurring { background: var(--bb-thistle); }
.bb-cal-event-time { font-weight: 700; margin-right: 0.2rem; }

.bb-agenda-day + .bb-agenda-day { margin-top: 1.25rem; }
.bb-agenda-date {
  border-bottom: 2px solid var(--bb-line);
  padding-bottom: 0.25rem;
  margin-bottom: 0.5rem;
}

/* Colour key under the grid. */
.bb-cal-key {
  display: inline-block;
  width: 0.9rem;
  height: 0.9rem;
  border-radius: 0.2rem;
  vertical-align: -0.1rem;
  margin-right: 0.3rem;
}
.bb-cal-key-oneoff { background: var(--bb-green); }
.bb-cal-key-recurring { background: var(--bb-thistle); }

/* "Regular events" pointer column on /events — a left rule on desktop,
   flipping to a top rule once it stacks under the cards. */
.bb-regular-events {
  border-left: 3px solid var(--bb-green);
  padding-left: 1rem;
}
@media (max-width: 991.98px) {
  .bb-regular-events {
    border-left: 0;
    border-top: 3px solid var(--bb-green);
    padding-left: 0;
    padding-top: 1rem;
    margin-top: 1rem;
  }
}
