/* ═══════════════════════════════════════════════════════════════════════════
   WEBSITE RENDER - Layout Width Model + Block Breakout
   Loaded on both public website pages and admin editor previews.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Layout Width Model ───────────────────────────────────────────────────
   Themeable custom properties + utility classes for section bleed,
   inner content width, and content padding.
   ──────────────────────────────────────────────────────────────────────── */

:root {
	--rosterli-content-max-width: 1140px;
	--rosterli-content-narrow-max-width: 720px;
	--rosterli-padding-compact: 1rem;
	--rosterli-padding-default: 2.5rem;
	--rosterli-padding-spacious: 5rem;
}

/* Section bleed - applied to the outer .rosterli-layout wrapper.
   On the public site, `<body>` has no max-width, and every section
   (page layouts and the site `<header>`/`<footer>`) is a body-level
   block, so the parent is already viewport-width. `width:100%` is
   therefore equivalent to "full-bleed" visually, *without* the
   scrollbar-overshoot bug that the earlier `100vw + margin-inline:
   calc(-50vw + 50%)` recipe produced whenever the page had a vertical
   scrollbar (100vw is wider than clientWidth by the scrollbar's
   width — typically 15px — and showed up as a horizontal scrollbar).
   The old recipe also fought Bootstrap utility classes emitted by
   `compute_style_classes_and_styles()` like `m-0` (`margin: 0
   !important`), which neutralized the negative margin-inline and
   pinned the 100vw box at left:0 — full 15px overshoot on the right.
   `max-width:100%` guards against any descendant trying to widen the
   wrapper past its parent. */
.rosterli-section--contained {
	max-width: 100%;
}
.rosterli-section--full-bleed {
	width: 100%;
	max-width: 100%;
}

/* Video / random-video backgrounds carry an absolutely-positioned
   video container (`position:absolute; inset:0;`). `overflow-x: clip`
   prevents any minor overshoot from that child from leaking out, while
   not creating a scroll container (so descendants with `position:
   sticky` continue to work). */
.rosterli-layout.rosterli-bg-video {
	overflow-x: clip;
}

/* Content width - applied to the inner container div within .rosterli-layout */
.rosterli-content--contained {
	max-width: var(--rosterli-content-max-width);
	margin-inline: auto;
	width: 100%;
	padding-inline: var(--bs-gutter-x, 0.75rem);
}
.rosterli-content--narrow {
	max-width: var(--rosterli-content-narrow-max-width);
	margin-inline: auto;
	width: 100%;
	padding-inline: var(--bs-gutter-x, 0.75rem);
}
.rosterli-content--full {
	width: 100%;
}
.rosterli-content--inherit {
	width: 100%;
}

/* Content padding - vertical spacing applied to the outer .rosterli-layout wrapper */
.rosterli-padding--none {
	padding-block: 0;
}
.rosterli-padding--compact {
	padding-block: var(--rosterli-padding-compact);
}
.rosterli-padding--default {
	padding-block: var(--rosterli-padding-default);
}
.rosterli-padding--spacious {
	padding-block: var(--rosterli-padding-spacious);
}

/* ── Split Content Breakout ───────────────────────────────────────────────
   Block-level breakout behavior for the Split Content block.
   The outer wrapper controls overflow/width; the inner row holds the
   two-column media + text structure.
   ──────────────────────────────────────────────────────────────────────── */

.rosterli-split-breakout {
	position: relative;
}

.rosterli-split-breakout--none {
	/* Normal: stays inside the layout's resolved inner width */
}

.rosterli-split-breakout--media-left {
	width: 100vw;
	margin-inline-start: calc(-50vw + 50%);
	margin-inline-end: 0;
}

.rosterli-split-breakout--media-right {
	width: 100vw;
	margin-inline-start: 0;
	margin-inline-end: calc(-50vw + 50%);
}

.rosterli-split-breakout--full {
	width: 100vw;
	margin-inline: calc(-50vw + 50%);
}

/* Text column width constraint within a breakout */
.rosterli-split-text--inherit {
	/* Inherits the column width from the grid - no constraint */
}

.rosterli-split-text--contained {
	max-width: var(--rosterli-content-max-width);
}

.rosterli-split-text--narrow {
	max-width: var(--rosterli-content-narrow-max-width);
}

.rosterli-split-text--full {
	/* No constraint - fills available column space */
}

/*
 * Grid-aligned text inside directional breakout.
 *
 * When the breakout wrapper is 100vw, each Bootstrap column is 50vw.
 * The viewport-facing edge of the text column extends beyond the site
 * grid. Padding on that edge pushes the text inward so it aligns to
 * the contained (or narrow) grid boundary.
 *
 * calc(50vw - <grid-half-width>) = distance from the grid edge to
 * the viewport edge on the text side.
 */
.rosterli-split-breakout--media-left .rosterli-split-text--contained {
	max-width: none;
	padding-inline-end: max(var(--bs-gutter-x, 0.75rem), calc(50vw - var(--rosterli-content-max-width) / 2));
}
.rosterli-split-breakout--media-left .rosterli-split-text--narrow {
	max-width: none;
	padding-inline-end: max(var(--bs-gutter-x, 0.75rem), calc(50vw - var(--rosterli-content-narrow-max-width) / 2));
}

.rosterli-split-breakout--media-right .rosterli-split-text--contained {
	max-width: none;
	padding-inline-start: max(var(--bs-gutter-x, 0.75rem), calc(50vw - var(--rosterli-content-max-width) / 2));
}
.rosterli-split-breakout--media-right .rosterli-split-text--narrow {
	max-width: none;
	padding-inline-start: max(var(--bs-gutter-x, 0.75rem), calc(50vw - var(--rosterli-content-narrow-max-width) / 2));
}

/* ── Hero Banner Content Width ────────────────────────────────────────────
   Block-level content width for the Hero Banner block.
   Applied to the .rosterli-hero-banner__content wrapper inside the hero flex
   container. Reuses the shared width custom properties.
   ──────────────────────────────────────────────────────────────────────── */

.rosterli-hero-content--contained {
	max-width: var(--rosterli-content-max-width);
	margin-inline: auto;
}

.rosterli-hero-content--narrow {
	max-width: var(--rosterli-content-narrow-max-width);
	margin-inline: auto;
}

/* ── Contact Information Block Icons ─────────────────────────────────────
   Icons inherit the block's text color so they remain visible on both
   light and dark backgrounds.  Opacity provides the subdued look that
   Bootstrap's text-muted would give on a light background.
   ──────────────────────────────────────────────────────────────────────── */

.rosterli-contact-block__icon {
	color: inherit;
	opacity: 0.65;
}

/* ── Block-level Font Size Scale ─────────────────────────────────────────
   Applied to the .rosterli-block envelope by website_renderer_service when
   style.typography.font_size is set to a non-md value. The wrapper-level
   font-size cascades to text content inside the block; Bootstrap children
   that hard-code their own font-size (accordion-button, nav-link, table)
   are forced to inherit so the cascade actually reaches them. Default md
   intentionally emits no class so existing blocks render unchanged.
   ──────────────────────────────────────────────────────────────────────── */

.rosterli-block.rosterli-block-font-size-xs  { font-size: 0.8rem; }
.rosterli-block.rosterli-block-font-size-sm  { font-size: 0.9rem; }
.rosterli-block.rosterli-block-font-size-lg  { font-size: 1.15rem; }
.rosterli-block.rosterli-block-font-size-xl  { font-size: 1.3rem; }
.rosterli-block.rosterli-block-font-size-xxl { font-size: 1.5rem; }

/* Rich-text inline typography classes. Emitted by the TipTap custom
   Paragraph node when the editor format dropdown picks Small or Fine print.
   Both are em-based so they scale with the parent block font-size. */
.rosterli-text-small      { font-size: 0.875em; }
.rosterli-text-fine-print { font-size: 0.75em; color: var(--bs-secondary-color, #6c757d); }

.rosterli-block[class*="rosterli-block-font-size-"] .accordion-button,
.rosterli-block[class*="rosterli-block-font-size-"] .accordion-body,
.rosterli-block[class*="rosterli-block-font-size-"] .nav-link,
.rosterli-block[class*="rosterli-block-font-size-"] .navbar-nav .nav-link,
.rosterli-block[class*="rosterli-block-font-size-"] table,
.rosterli-block[class*="rosterli-block-font-size-"] .table {
	font-size: inherit;
}

/* ── Gallery block lightbox ─────────────────────────────────────────── */
.rosterli-gallery-lightbox-trigger { cursor: zoom-in; }
.rosterli-gallery-lightbox-content { background-color: rgba(0, 0, 0, 0.92); }
.rosterli-gallery-lightbox .modal-body { overflow: hidden; }
.rosterli-gallery-lightbox .carousel,
.rosterli-gallery-lightbox .carousel-inner,
.rosterli-gallery-lightbox .carousel-item { height: 100%; }
.rosterli-gallery-lightbox-img {
	max-width: 100%;
	max-height: calc(100vh - 8rem);
	width: auto;
	height: auto;
	object-fit: contain;
	display: block;
}
.rosterli-gallery-lightbox-caption {
	max-width: 60ch;
	font-size: 0.95rem;
}
.rosterli-gallery-lightbox .carousel-control-prev,
.rosterli-gallery-lightbox .carousel-control-next { width: 8%; }

/* ── Gallery block layout: photo + caption alignment ──────────────── */
.rosterli-gallery-block .rosterli-gallery-item {
	display: flex;
	flex-direction: column;
	height: 100%;
}
.rosterli-gallery-block .rosterli-gallery-item > .figure {
	display: flex;
	flex-direction: column;
	height: 100%;
}
.rosterli-gallery-block .rosterli-gallery-media {
	display: flex;
	width: 100%;
}
.rosterli-gallery-block .rosterli-gallery-media > a,
.rosterli-gallery-block .rosterli-gallery-media > img {
	width: 100%;
}
.rosterli-gallery-photo-align-top    .rosterli-gallery-media { align-items: flex-start; }
.rosterli-gallery-photo-align-middle .rosterli-gallery-media { align-items: center; }
.rosterli-gallery-photo-align-bottom .rosterli-gallery-media { align-items: flex-end; }
.rosterli-gallery-photo-align-middle .rosterli-gallery-media > a,
.rosterli-gallery-photo-align-middle .rosterli-gallery-media > img,
.rosterli-gallery-photo-align-bottom .rosterli-gallery-media > a,
.rosterli-gallery-photo-align-bottom .rosterli-gallery-media > img {
	align-self: inherit;
}
.rosterli-gallery-caption-bottom .figure-caption { margin-top: auto; }

/* ── Multi-Column Row: Configurable Gap + Optional Vertical Rule ───────────
   Applied to every multi-column row wrapper across blocks, page/header/footer
   layout regions, and footer navigation columns. Maps a named gap scale to
   Bootstrap's gutter custom properties so the standard grid keeps working.
   Vertical rules render only between columns (never on outer edges) and only
   at the md breakpoint or wider, so stacked mobile layouts do not show an
   awkward border. Uses theme-aware Bootstrap border variables.

   Selectors qualify on `.row` so the rules carry (0,2,0) specificity that
   beats the inline theme-generated `.row { --bs-gutter-x: <theme-spacing> }`
   declaration emitted by website_theme_service.generate_css(). That rule
   loads inside a <style> tag after this stylesheet, so a bare `.rosterli-row`
   selector would tie on specificity (0,1,0) and lose on source order — the
   column padding then stays pinned to the theme default no matter which gap
   class is set.
   ──────────────────────────────────────────────────────────────────────── */
.row.rosterli-row {
	--rosterli-col-gap: 1.5rem;
	--bs-gutter-x: var(--rosterli-col-gap);
	--bs-gutter-y: var(--rosterli-col-gap);
}
.row.rosterli-col-gap-none { --rosterli-col-gap: 0; }
.row.rosterli-col-gap-xs   { --rosterli-col-gap: 0.25rem; }
.row.rosterli-col-gap-sm   { --rosterli-col-gap: 0.5rem; }
.row.rosterli-col-gap-md   { --rosterli-col-gap: 1.5rem; }
.row.rosterli-col-gap-lg   { --rosterli-col-gap: 2.5rem; }
.row.rosterli-col-gap-xl   { --rosterli-col-gap: 4rem; }
.row.rosterli-col-gap-xxl  { --rosterli-col-gap: 6rem; }

@media (min-width: 768px) {
	.rosterli-col-rule > [class*="col-"]:not(:first-child) {
		border-left: var(--bs-border-width, 1px) solid var(--bs-border-color);
	}
}

/* ── Navigation hamburger toggle ──────────────────────────────────────────
   Bootstrap's default `.navbar-toggler-icon` is a background-image SVG that
   isn't reliably colorable. The navigation renderer rewrites the toggle
   markup to use the .hamburger / .hamburger-box / .hamburger-inner
   structure shared with the admin preview so the bars paint with
   `currentColor`. Setting `color` on `.navbar-toggler` via the per-nav
   scoped <style> emitted by website_renderer_service.wrap_navigation_with_style
   then drives the bar color (and ::before / ::after) for the mobile menu
   icon. Animation transforms only apply when the toggler also carries
   `.is-active`; without the optional JS shim that mirrors aria-expanded
   onto `.is-active`, the icon still renders and toggles the menu open
   correctly — only the squeeze/cross animation goes unrendered.
   ──────────────────────────────────────────────────────────────────────── */
.hamburger { display: inline-flex; align-items: center; justify-content: center; padding: 4px; cursor: pointer; background: transparent; border: 0; color: inherit; outline: none; box-shadow: none; }
.navbar-toggler.hamburger { border: 0; }
.navbar-toggler.hamburger:focus { outline: none; box-shadow: none; }
.hamburger-box { width: 30px; height: 24px; display: inline-block; position: relative; transition: transform 0.3s ease; }
.hamburger-inner,
.hamburger-inner::before,
.hamburger-inner::after { width: 100%; height: 3px; background-color: currentColor; border-radius: 2px; position: absolute; left: 0; transition: all 0.2s ease; }
.hamburger-inner { top: 50%; margin-top: -1.5px; }
.hamburger-inner::before { content: ''; top: -8px; }
.hamburger-inner::after { content: ''; bottom: -8px; }
.hamburger--sm .hamburger-box { width: 24px; height: 18px; }
.hamburger--sm .hamburger-inner,
.hamburger--sm .hamburger-inner::before,
.hamburger--sm .hamburger-inner::after { height: 2px; }
.hamburger--sm .hamburger-inner { margin-top: -1px; }
.hamburger--sm .hamburger-inner::before { top: -6px; }
.hamburger--sm .hamburger-inner::after { bottom: -6px; }
.hamburger--squeeze.is-active .hamburger-inner { background-color: transparent; }
.hamburger--squeeze.is-active .hamburger-inner::before { top: 0; transform: rotate(45deg); }
.hamburger--squeeze.is-active .hamburger-inner::after { bottom: 0; transform: rotate(-45deg); }
.hamburger--spin.is-active .hamburger-box { transform: rotate(180deg); }
.hamburger--spin.is-active .hamburger-inner { background-color: transparent; }
.hamburger--spin.is-active .hamburger-inner::before { top: 0; transform: rotate(45deg); }
.hamburger--spin.is-active .hamburger-inner::after { bottom: 0; transform: rotate(-45deg); }
.hamburger--spin-r.is-active .hamburger-box { transform: rotate(-180deg); }
.hamburger--spin-r.is-active .hamburger-inner { background-color: transparent; }
.hamburger--spin-r.is-active .hamburger-inner::before { top: 0; transform: rotate(45deg); }
.hamburger--spin-r.is-active .hamburger-inner::after { bottom: 0; transform: rotate(-45deg); }
.hamburger--elastic .hamburger-inner,
.hamburger--elastic .hamburger-inner::before,
.hamburger--elastic .hamburger-inner::after { transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); transition-duration: 0.3s; }
.hamburger--elastic.is-active .hamburger-inner { background-color: transparent; }
.hamburger--elastic.is-active .hamburger-inner::before { top: 0; transform: rotate(45deg); }
.hamburger--elastic.is-active .hamburger-inner::after { bottom: 0; transform: rotate(-45deg); }
.hamburger--arrow.is-active .hamburger-inner { background-color: transparent; }
.hamburger--arrow.is-active .hamburger-inner::before { top: 0; width: 50%; transform: rotate(-40deg); transform-origin: 0 50%; }
.hamburger--arrow.is-active .hamburger-inner::after { bottom: 0; width: 50%; transform: rotate(40deg); transform-origin: 0 50%; }
.hamburger--arrow-r.is-active .hamburger-inner { background-color: transparent; }
.hamburger--arrow-r.is-active .hamburger-inner::before { top: 0; width: 50%; left: 50%; transform: rotate(40deg); transform-origin: 100% 50%; }
.hamburger--arrow-r.is-active .hamburger-inner::after { bottom: 0; width: 50%; left: 50%; transform: rotate(-40deg); transform-origin: 100% 50%; }
.hamburger--collapse .hamburger-inner::before { transition: top 0.15s 0.15s ease, transform 0.15s ease; }
.hamburger--collapse .hamburger-inner::after { transition: bottom 0.15s 0.15s ease, transform 0.15s ease; }
.hamburger--collapse.is-active .hamburger-inner { background-color: transparent; }
.hamburger--collapse.is-active .hamburger-inner::before { top: 0; transform: rotate(45deg); transition: top 0.15s ease, transform 0.15s 0.15s ease; }
.hamburger--collapse.is-active .hamburger-inner::after { bottom: 0; transform: rotate(-45deg); transition: bottom 0.15s ease, transform 0.15s 0.15s ease; }
.hamburger--vortex .hamburger-box { transition: transform 0.4s ease; }
.hamburger--vortex.is-active .hamburger-box { transform: rotate(360deg); }
.hamburger--vortex.is-active .hamburger-inner { background-color: transparent; }
.hamburger--vortex.is-active .hamburger-inner::before { top: 0; transform: rotate(45deg); }
.hamburger--vortex.is-active .hamburger-inner::after { bottom: 0; transform: rotate(-45deg); }
.hamburger--slider .hamburger-inner::before { transition: top 0.15s 0.15s ease, background-color 0.15s ease; }
.hamburger--slider .hamburger-inner::after { transition: bottom 0.15s 0.15s ease, transform 0.15s ease; }
.hamburger--slider.is-active .hamburger-inner { transform: rotate(45deg); }
.hamburger--slider.is-active .hamburger-inner::before { top: 0; background-color: transparent; transition: top 0.15s ease, background-color 0.15s 0.15s ease; }
.hamburger--slider.is-active .hamburger-inner::after { bottom: 0; transform: rotate(-90deg); transition: bottom 0.15s ease, transform 0.15s 0.15s ease; }
.hamburger--minus.is-active .hamburger-inner::before { top: 0; background-color: transparent; }
.hamburger--minus.is-active .hamburger-inner::after { bottom: 0; background-color: transparent; }
.hamburger--flipx { perspective: 80px; }
.hamburger--flipx .hamburger-box { transition: transform 0.3s ease; }
.hamburger--flipx.is-active .hamburger-box { transform: rotateX(180deg); }
.hamburger--flipx.is-active .hamburger-inner { background-color: transparent; }
.hamburger--flipx.is-active .hamburger-inner::before { top: 0; transform: rotate(45deg); }
.hamburger--flipx.is-active .hamburger-inner::after { bottom: 0; transform: rotate(-45deg); }
.hamburger--flipy { perspective: 80px; }
.hamburger--flipy .hamburger-box { transition: transform 0.3s ease; }
.hamburger--flipy.is-active .hamburger-box { transform: rotateY(180deg); }
.hamburger--flipy.is-active .hamburger-inner { background-color: transparent; }
.hamburger--flipy.is-active .hamburger-inner::before { top: 0; transform: rotate(45deg); }
.hamburger--flipy.is-active .hamburger-inner::after { bottom: 0; transform: rotate(-45deg); }

/* ── Calendar block ───────────────────────────────────────────────────────
   Static layout/visual CSS for the website Calendar block. Previously emitted
   as a per-instance inline <style> from shared/views/blocks/calendar.cfm — the
   identical rules were re-sent in the page source for every calendar block and
   never cached. The block view now carries only the dynamic per-event color
   inline style attributes (style="background-color: …"); everything below is
   static, so it lives here and is served once from this cached stylesheet
   across every public page and admin editor preview. The Bootstrap-default
   hex colors below are intentional literals (focus rings, borders, muted
   text) — they were hard-coded in the original block and are reproduced
   verbatim so rendering is byte-identical.
   ──────────────────────────────────────────────────────────────────────── */
.rosterli-calendar-block { font-size: 0.95rem; box-sizing: border-box; }
.rosterli-calendar-block *, .rosterli-calendar-block *::before, .rosterli-calendar-block *::after { box-sizing: inherit; }
.rosterli-calendar-block-title { margin: 0 0 0.5rem 0; font-size: 1.25rem; font-weight: 600; }
.rosterli-calendar-block-header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.75rem; flex-wrap: wrap; }
.rosterli-calendar-block-header-label-group { display: inline-flex; flex-direction: column; gap: 0.25rem; margin-right: auto; min-width: 0; }
.rosterli-calendar-block-window-label { margin: 0; font-size: 1rem; color: #6c757d; font-weight: 600; text-align: left; }
.rosterli-calendar-block-month-nav { display: inline-flex; gap: 0.25rem; }
.rosterli-calendar-block-month-nav a { display: inline-flex; align-items: center; justify-content: center; min-width: 2rem; height: 2rem; padding: 0 0.5rem; border: 1px solid #dee2e6; border-radius: 0.25rem; text-decoration: none; color: #495057; background: #fff; transition: background-color 0.15s ease, border-color 0.15s ease; }
.rosterli-calendar-block-month-nav a:hover { background: #f1f3f5; border-color: #adb5bd; }
.rosterli-calendar-block-month-nav a:focus-visible { outline: 2px solid #0d6efd; outline-offset: 2px; }
.rosterli-calendar-block-empty { padding: 1rem; text-align: center; color: #6c757d; }
.rosterli-calendar-block-legend { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; margin-bottom: 0.75rem; font-size: 0.85rem; }
.rosterli-calendar-block-legend-item { display: inline-flex; align-items: center; gap: 0.35rem; }
.rosterli-calendar-block-color-swatch { display: inline-block; width: 0.75rem; height: 0.75rem; border-radius: 50%; flex-shrink: 0; }

.rosterli-calendar-block-layout { display: flex; align-items: stretch; }
.rosterli-calendar-block-main { flex: 1 1 100%; min-width: 0; transition: flex-basis 0.25s ease; }
.rosterli-calendar-block-side { flex: 0 0 0; min-width: 0; max-width: 0; padding-left: 0; overflow: hidden; opacity: 0; transition: flex-basis 0.25s ease, max-width 0.25s ease, padding-left 0.25s ease, opacity 0.2s ease; }
.rosterli-calendar-block--has-selected-event.rosterli-calendar-block--details-side .rosterli-calendar-block-main { flex-basis: 66.6667%; }
.rosterli-calendar-block--has-selected-event.rosterli-calendar-block--details-side .rosterli-calendar-block-side { flex-basis: 33.3333%; min-width: 14rem; max-width: 100%; padding-left: 1rem; opacity: 1; overflow: visible; }
.rosterli-calendar-block-below { margin-top: 1rem; }
.rosterli-calendar-block-below[hidden] { display: none; }

.rosterli-calendar-block-list { margin: 0; padding: 0; list-style: none; }
.rosterli-calendar-block-list-day { padding: 0.5rem 0; border-bottom: 1px solid #e9ecef; }
.rosterli-calendar-block-list-day:last-child { border-bottom: 0; }
.rosterli-calendar-block-list-date { font-weight: 600; margin-bottom: 0.35rem; }
.rosterli-calendar-block-list-event-row { display: flex; align-items: flex-start; gap: 0.5rem; padding: 0.35rem 0.4rem; width: 100%; background: transparent; border: 1px solid transparent; border-radius: 0.25rem; text-align: left; cursor: pointer; color: inherit; font: inherit; transition: background-color 0.15s ease, border-color 0.15s ease; }
.rosterli-calendar-block-list-event-row:hover { background: #f8f9fa; }
.rosterli-calendar-block-list-event-row:focus-visible { outline: 2px solid #0d6efd; outline-offset: 2px; }
.rosterli-calendar-block-list-event-row[aria-expanded="true"] { background: #e7f1ff; border-color: #b6d4fe; }
.rosterli-calendar-block-list-event-time { color: #6c757d; flex-shrink: 0; font-variant-numeric: tabular-nums; min-width: 7rem; }
.rosterli-calendar-block-list-event-title { font-weight: 500; word-break: break-word; }
.rosterli-calendar-block-list-event-location { color: #6c757d; font-size: 0.85em; word-break: break-word; }

.rosterli-calendar-block-inline-detail { max-height: 0; overflow: hidden; transition: max-height 0.25s ease; }
.rosterli-calendar-block-inline-detail[data-rosterli-open="true"] { max-height: 32rem; }
.rosterli-calendar-block-inline-detail-inner { padding: 0.5rem 0.75rem 0.75rem 1.25rem; }

.rosterli-calendar-block-grid { width: 100%; border-collapse: collapse; table-layout: fixed; }
.rosterli-calendar-block-grid th, .rosterli-calendar-block-grid td { border: 1px solid #dee2e6; padding: 0.25rem; vertical-align: top; }
.rosterli-calendar-block-grid th { background: #f8f9fa; text-align: center; font-weight: 600; font-size: 0.85rem; padding: 0.4rem 0.25rem; }
.rosterli-calendar-block-grid-day-number { font-size: 0.8rem; color: #6c757d; margin-bottom: 0.15rem; }
.rosterli-calendar-block-grid-day { height: 5.5rem; }
.rosterli-calendar-block-grid-day-out { background-color: #fafafa; }
.rosterli-calendar-block-grid-day-out .rosterli-calendar-block-grid-day-number { opacity: 0.45; }
/* Past day cells: dimmer than in-month cells but still visible so the
   calendar grid stays complete. The day number is muted; events on the
   day are rendered as non-interactive spans (.is-past). */
.rosterli-calendar-block-grid-day-past { background-color: #f5f5f5; }
.rosterli-calendar-block-grid-day-past .rosterli-calendar-block-grid-day-number { opacity: 0.55; }
.rosterli-calendar-block-grid-event { display: block; width: 100%; font-size: 0.78rem; line-height: 1.2; padding: 0.1rem 0.3rem; margin-bottom: 0.1rem; border-radius: 0.2rem; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; border: 0; cursor: pointer; }
.rosterli-calendar-block-grid-event:focus-visible { outline: 2px solid #0d6efd; outline-offset: 1px; }
.rosterli-calendar-block-grid-event[aria-pressed="true"] { box-shadow: 0 0 0 2px #0d6efd; }
.rosterli-calendar-block-grid-event.is-past { opacity: 0.55; cursor: default; pointer-events: none; }
.rosterli-calendar-block-list-event-row.is-past { opacity: 0.55; cursor: default; pointer-events: none; }
.rosterli-calendar-block-grid-more { display: block; font-size: 0.75rem; color: #6c757d; padding: 0 0.2rem; }

.rosterli-calendar-block-detail-bank { display: none; }
/* The detail panel uses Bootstrap .card / .card-body / .card-img-top / .card-title /
   .card-text / .btn / .btn-close. Only namespaced sizing + spacing overrides live
   here so the block does not redefine Bootstrap's card visual treatment. */
.rosterli-calendar-block-detail-title { word-break: break-word; }
.rosterli-calendar-block-detail-row { display: flex; gap: 0.5rem; font-size: 0.9rem; margin-bottom: 0.25rem; flex-wrap: wrap; }
.rosterli-calendar-block-detail-label { color: #6c757d; min-width: 5rem; }
.rosterli-calendar-block-detail-summary { white-space: pre-wrap; word-break: break-word; }
.rosterli-calendar-block-detail-meta { display: inline-flex; align-items: center; gap: 0.35rem; }
.rosterli-calendar-block-detail-banner { width: 100%; height: auto; max-height: 16rem; object-fit: cover; }

.rosterli-calendar-block-list-only { display: none; }
.rosterli-calendar-block-grid-only { display: block; }
.rosterli-calendar-block--mode-list .rosterli-calendar-block-grid-only { display: none; }
.rosterli-calendar-block--mode-list .rosterli-calendar-block-list-only { display: block; }

@media (max-width: 480px) {
	.rosterli-calendar-block-grid-only { display: none; }
	.rosterli-calendar-block-list-only { display: block; }
	.rosterli-calendar-block-side { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
	.rosterli-calendar-block, .rosterli-calendar-block * { transition: none !important; }
}

/* ── Card hover lift ───────────────────────────────────────────────────────
   Applied to the Card / Card Builder blocks when "hover effect" is enabled.
   The .rosterli-card-hover class is added by block_renderer_service ONLY when
   hover_effect is true, so a single global rule reproduces exactly what the
   per-instance, id-scoped inline <style> emitted from card.cfm / card_builder.cfm
   used to do — without duplicating the identical rule into the page source for
   every hover-enabled card grid.
   ──────────────────────────────────────────────────────────────────────── */
.rosterli-card-hover { transition: transform 0.2s ease, box-shadow 0.2s ease; }
.rosterli-card-hover:hover { transform: translateY(-4px); box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .12) !important; }

/* ── Testimonial carousel ───────────────────────────────────────────────────
   testimonial_quote block, layout = "carousel". Progressive enhancement: the
   server renders the first slide active (display:block); testimonial_carousel.js
   rotates slides and wires the prev / play-pause / next controls. Everything is
   class-namespaced so it cannot leak into other blocks, and the controls use
   Bootstrap CSS variables so they stay legible on light, dark, and brand-coloured
   sections.
   ──────────────────────────────────────────────────────────────────────── */
.rosterli-testimonial-carousel { position: relative; }
.rosterli-tc-viewport { position: relative; overflow: hidden; }
.rosterli-tc-slide { display: none; }
.rosterli-tc-slide.is-active { display: block; }

@media (prefers-reduced-motion: no-preference) {
	.rosterli-tc-slide.is-active { animation: rosterli-tc-fade 0.4s ease; }
}
@keyframes rosterli-tc-fade {
	from { opacity: 0; }
	to { opacity: 1; }
}

.rosterli-tc-controls {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	margin-top: 1rem;
}
.rosterli-tc-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	padding: 0;
	border-radius: 50%;
	border: 1px solid var(--bs-border-color, rgba(0, 0, 0, 0.15));
	background-color: var(--bs-body-bg, #fff);
	color: var(--bs-body-color, #212529);
	box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.15);
	cursor: pointer;
	line-height: 1;
	transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.rosterli-tc-btn:hover { background-color: var(--bs-secondary-bg, #e9ecef); }
.rosterli-tc-btn:focus-visible {
	outline: 2px solid var(--bs-primary, #0d6efd);
	outline-offset: 2px;
}
