/* =========================================================================
   LTF Events Calendar, [ltf_schedule] rendering
   Mobile-first. Reuses the events-hub-shell theme's CSS variables
   (--color-bg, --color-surface, --color-text, --space-*, --radius-*) so it
   matches the shell without duplicating tokens. Falls back to literal values
   if those variables are absent (e.g. the shortcode pulled onto an event site
   that does not run this theme).

   THEME-AWARE, not dark-only. The theme carries light as the :root default,
   swaps to dark on prefers-color-scheme, and lets a stored toggle choice
   override both. This stylesheet must therefore never hardcode a colour that
   assumes a dark ground: derive it from a token instead, so the component
   follows the theme rather than fighting it.

   ── THE FALLBACKS ARE LIGHT, AND THAT IS DELIBERATE ──────────────────────
   Every var() below names an events-hub-shell token first and a literal
   second. On the hub the tokens all resolve, so the literals are dead code and
   the component follows the theme, light or dark. The literals only ever fire
   somewhere the shell theme is NOT running, and that place is a Life Time event
   site: Total plus WPBakery, white page, nineteen of them.

   These literals used to be the dark ones (#313131 surface, #FFFFFF text). The
   first time the shortcode was ever rendered on a Total site, on Big Sugar on
   2026-08-06, it produced charcoal cards with white text sitting on a #F5F5F5
   band. It was legible, and it looked like somebody else's component pasted
   onto the page. Nothing was broken, which is exactly why nobody would have
   caught it from the hub: on the hub this file is pixel-identical either way.

   So the fallback describes the common case, an ordinary light event site, and
   the hub keeps overriding all of it with its own tokens.
   ─────────────────────────────────────────────────────────────────────────

   The --ltfhs- prefix predates the rename from ltf-hub-schedule and is purely
   internal. Left alone deliberately to keep this change reviewable as one
   thing; rename it in its own pass.
   ========================================================================= */

.ltf-ec {
	--ltfhs-bg: var(--color-surface, #FFFFFF);
	--ltfhs-bg-hi: var(--color-surface-hi, #F2F2F2);
	--ltfhs-ground: var(--color-bg, #FFFFFF);
	--ltfhs-border: var(--color-border, rgba(0, 0, 0, 0.12));
	--ltfhs-border-strong: var(--color-border-strong, rgba(0, 0, 0, 0.26));
	--ltfhs-text: var(--color-text, #191919);
	--ltfhs-text-muted: var(--color-text-muted, #5F5F63);
	--ltfhs-accent: var(--color-text, #191919);

	/* Text colour on a filled pill. Tracks the page ground, so a filled button
	   reads dark-on-light in light mode and light-on-dark in dark mode without
	   a second rule. */
	--ltfhs-invert: var(--color-bg, #FFFFFF);

	/* Seeded badge, mixed off the accent rather than pinned to two hex values
	   that only worked against a dark card. */
	--ltfhs-seeded-bg: color-mix(in srgb, var(--color-accent, #A3896F) 22%, transparent);
	--ltfhs-seeded-fg: color-mix(in srgb, var(--color-accent, #A3896F) 70%, var(--color-text, #191919));
	--ltfhs-radius-sm: var(--radius-sm, 8px);
	--ltfhs-radius-md: var(--radius-md, 12px);
	--ltfhs-radius-lg: var(--radius-lg, 20px);
	--ltfhs-space-2: var(--space-2, 8px);
	--ltfhs-space-3: var(--space-3, 16px);
	--ltfhs-space-4: var(--space-4, 24px);

	font-family: var(--font-sans, inherit);
	color: var(--ltfhs-text);
}

/* The filter script toggles the `hidden` attribute on day and event groups.
   Guard it explicitly so a theme rule that sets `display` on these elements
   cannot override the UA default and leave a "hidden" group visible. */
.ltf-ec [hidden] {
	display: none !important;
}

/* Visible keyboard focus on every control. Stated here rather than left to the
   UA default so a theme reset that kills outlines cannot make the day and
   category filters unusable by keyboard. */
.ltf-ec__day-tab:focus-visible,
.ltf-ec__chip:focus-visible {
	outline: 2px solid var(--ltfhs-accent);
	outline-offset: 2px;
}

.ltf-ec__demo-banner {
	background: var(--ltfhs-bg);
	border: 1px solid var(--ltfhs-border-strong);
	color: var(--ltfhs-text-muted);
	border-radius: var(--ltfhs-radius-md);
	padding: 10px var(--ltfhs-space-3);
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	margin-bottom: var(--ltfhs-space-3);
}

/* ---------------------------------------------------------------------
   Day switcher
   --------------------------------------------------------------------- */

.ltf-ec__days {
	display: flex;
	gap: 6px;
	overflow-x: auto;
	padding-bottom: 6px;
	margin-bottom: var(--ltfhs-space-3);
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
}

.ltf-ec__days::-webkit-scrollbar {
	display: none;
}

.ltf-ec__day-tab {
	flex: 0 0 auto;
	font-family: inherit;
	font-size: 13px;
	font-weight: 700;
	background: var(--ltfhs-bg);
	color: var(--ltfhs-text-muted);
	border: 1px solid var(--ltfhs-border);
	border-radius: 999px;
	padding: 8px 14px;
	cursor: pointer;
	white-space: nowrap;
}

.ltf-ec__day-tab.is-active {
	background: var(--ltfhs-text);
	border-color: var(--ltfhs-text);
	color: var(--ltfhs-invert);
}

/* A day with nothing left under the active category chips. Dimmed rather than
   removed, so the day list does not reflow while someone is filtering. */
.ltf-ec__day-tab[disabled] {
	opacity: 0.4;
	cursor: default;
}

/* ---------------------------------------------------------------------
   Category filter chips
   --------------------------------------------------------------------- */

.ltf-ec__chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: var(--ltfhs-space-4);
}

.ltf-ec__chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-family: inherit;
	font-size: 12px;
	font-weight: 700;
	background: var(--ltfhs-bg);
	color: var(--ltfhs-text);
	border: 1.5px solid var(--chip-color, var(--ltfhs-border));
	border-radius: 999px;
	padding: 6px 12px;
	cursor: pointer;
}

.ltf-ec__chip.is-active {
	background: var(--chip-color, var(--ltfhs-text));
	border-color: var(--chip-color, var(--ltfhs-text));
	color: var(--ltfhs-invert);
}

.ltf-ec__chip-icon {
	line-height: 1;
}

/* ---------------------------------------------------------------------
   Day groups + session list
   --------------------------------------------------------------------- */

.ltf-ec__event-heading {
	font-size: 20px;
	font-weight: 700;
	margin: var(--ltfhs-space-4) 0 var(--ltfhs-space-3);
}

.ltf-ec__event-heading:first-child {
	margin-top: 0;
}

.ltf-ec__day-heading {
	font-size: 13px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--ltfhs-text-muted);
	margin: var(--ltfhs-space-4) 0 var(--ltfhs-space-2);
}

.ltf-ec__day-group:first-child .ltf-ec__day-heading {
	margin-top: 0;
}

.ltf-ec__sessions {
	display: flex;
	flex-direction: column;
	gap: var(--ltfhs-space-2);
}

/* ---------------------------------------------------------------------
   Session card
   --------------------------------------------------------------------- */

/* Stacked on a phone. The time is a full range ("10:00 am–6:00 pm") and it does
   not wrap, so a side-by-side column claiming `flex: 0 0 64px` was in practice
   ~145px wide, nearly half a 390px card, and every session title wrapped to
   three lines. Time goes on its own row until there is real width to spare. */
.ltf-ec__card {
	display: flex;
	flex-direction: column;
	gap: 6px;
	background: var(--ltfhs-bg);
	/* A card on the hub is a lighter surface on a dark ground and needs no edge.
	   A card on a Total site is white, and on a white band it has no edge at all
	   without this. The token is 10% white on the hub, so it costs a hairline
	   there and earns the card its shape everywhere else. */
	border: 1px solid var(--ltfhs-border);
	border-radius: var(--ltfhs-radius-md);
	padding: var(--ltfhs-space-3);
}

.ltf-ec__card.is-hidden {
	display: none;
}

.ltf-ec__card-time {
	font-size: 12px;
	font-weight: 700;
	color: var(--ltfhs-accent);
	white-space: nowrap;
}

@media (min-width: 480px) {
	.ltf-ec__card {
		flex-direction: row;
		gap: var(--ltfhs-space-3);
	}

	.ltf-ec__card-time {
		flex: 0 0 auto;
		min-width: 92px;
		padding-top: 2px;
	}
}

.ltf-ec__card-body {
	flex: 1;
	min-width: 0;
}

.ltf-ec__card-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	margin-bottom: 6px;
}

.ltf-ec__mini-chip {
	display: inline-flex;
	align-items: center;
	gap: 3px;
	font-size: 10px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	background: color-mix(in srgb, var(--chip-color, var(--ltfhs-text)) 22%, var(--ltfhs-bg-hi));
	color: color-mix(in srgb, var(--chip-color, var(--ltfhs-text)) 60%, var(--ltfhs-text));
	border-radius: 999px;
	padding: 3px 8px;
}

.ltf-ec__mini-chip--demo {
	background: var(--ltfhs-seeded-bg);
	color: var(--ltfhs-seeded-fg);
}

.ltf-ec__card-title {
	font-size: 15px;
	font-weight: 700;
	margin: 0 0 4px;
	color: var(--ltfhs-text);
}

.ltf-ec__card-meta {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 12px;
	font-size: 12px;
	color: var(--ltfhs-text-muted);
	margin: 0 0 6px;
}

.ltf-ec__phase-tag {
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-weight: 700;
}

.ltf-ec__card-desc {
	font-size: 13px;
	color: var(--ltfhs-text-muted);
	margin: 0;
}

/* ---------------------------------------------------------------------
   Empty states
   --------------------------------------------------------------------- */

/* No sessions matched the shortcode's own attributes (server side). */
.ltf-ec--empty {
	background: var(--ltfhs-bg);
	border: 1px solid var(--ltfhs-border);
	border-radius: var(--ltfhs-radius-md);
	padding: var(--ltfhs-space-3);
	color: var(--ltfhs-text-muted);
}

.ltf-ec--empty p {
	margin: 0;
}

/* Everything was filtered out on the client by the chips or the day switcher. */
.ltf-ec__no-match {
	background: var(--ltfhs-bg);
	border: 1px dashed var(--ltfhs-border);
	border-radius: var(--ltfhs-radius-md);
	padding: var(--ltfhs-space-3);
	color: var(--ltfhs-text-muted);
	font-size: 14px;
	margin: 0;
}

/* ---------------------------------------------------------------------
   Multiple embeds on one page
   Each [ltf_schedule] is its own block; keep them from running together
   when a page stacks a master schedule and an expo-only schedule.
   --------------------------------------------------------------------- */

.ltf-ec + .ltf-ec {
	margin-top: var(--space-5, 32px);
}

/* ---------------------------------------------------------------------
   Add to calendar, and subscribe

   The picker is a <details>, so the browser owns the open/close behaviour
   and this file only has to dress it. No script, which matters because most
   of this fleet is Total plus WPBakery where injected JS is against the
   house rules.

   Every colour here derives from a token. Nothing in this block may assume a
   dark ground: that assumption is exactly what shipped black-on-black on
   2026-08-06 and cost a third cache-layer investigation.
   --------------------------------------------------------------------- */

.ltf-ec__addcal {
	margin-top: var(--ltfhs-space-2);
	font-size: 13px;
}

.ltf-ec__addcal-toggle {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	cursor: pointer;
	color: var(--ltfhs-text-muted);
	border: 1px solid var(--ltfhs-border);
	border-radius: var(--ltfhs-radius-lg);
	padding: 4px 12px;
	list-style: none;
	transition: color 120ms ease, border-color 120ms ease;
}

/* Safari renders the default disclosure triangle through a pseudo-element that
   `list-style: none` alone does not reach. */
.ltf-ec__addcal-toggle::-webkit-details-marker {
	display: none;
}

.ltf-ec__addcal-toggle::before {
	content: "＋";
	font-size: 12px;
	line-height: 1;
}

.ltf-ec__addcal[open] .ltf-ec__addcal-toggle::before {
	content: "－";
}

.ltf-ec__addcal-toggle:hover,
.ltf-ec__addcal-toggle:focus-visible {
	color: var(--ltfhs-text);
	border-color: var(--ltfhs-border-strong);
}

.ltf-ec__addcal-toggle:focus-visible {
	outline: 2px solid var(--ltfhs-accent);
	outline-offset: 2px;
}

.ltf-ec__addcal-list {
	list-style: none;
	margin: var(--ltfhs-space-2) 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--ltfhs-space-2);
}

.ltf-ec__addcal-list a {
	display: inline-block;
	padding: 4px 10px;
	border: 1px solid var(--ltfhs-border);
	border-radius: var(--ltfhs-radius-md);
	background: var(--ltfhs-bg-hi);
	color: var(--ltfhs-text);
	text-decoration: none;
}

.ltf-ec__addcal-list a:hover,
.ltf-ec__addcal-list a:focus-visible {
	border-color: var(--ltfhs-border-strong);
	text-decoration: underline;
}

/* The subscribe row sits under the whole list, once, because it describes the
   view rather than any one session. */
.ltf-ec__subscribe {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--ltfhs-space-2);
	margin: var(--ltfhs-space-4) 0 0;
	padding-top: var(--ltfhs-space-3);
	border-top: 1px solid var(--ltfhs-border);
	font-size: 13px;
}

.ltf-ec__subscribe-link {
	color: var(--ltfhs-text);
	font-weight: 600;
	text-decoration: underline;
}

.ltf-ec__subscribe-note {
	color: var(--ltfhs-text-muted);
}

/* Exhibitor attribution and link, both filled in by the Formidable bridge. */
.ltf-ec__card-brand {
	margin: 2px 0 0;
	font-size: 12px;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--ltfhs-text-muted);
}

.ltf-ec__card-link {
	margin: var(--ltfhs-space-2) 0 0;
	font-size: 13px;
}

.ltf-ec__card-link a {
	color: var(--ltfhs-text);
}

/* =========================================================================
   VIEWS: top bar, filter bar, switcher, month grid, day view, single page
   Added 2026-08-20 for The Events Calendar parity.

   Same contract as everything above: every colour comes from a --ltfhs- token,
   which resolves to an events-hub-shell token first and to a LIGHT literal
   second. The literals are dead code on the hub and are the whole story on a
   Total plus WPBakery event site, which is a white page. Nothing in this block
   may assume a dark ground.

   Nothing here uses a viewport-relative width or a fixed pixel width on a
   container. The month grid is the one component that can overflow a 390px
   phone, and minmax(0, 1fr) on its columns is what stops it.
   ========================================================================= */

.ltf-ec {
	max-width: 100%;
}

/* Visible to a screen reader, not to an eye. Used for the day numbers' full
   dates, and for the title on the continuation cells of a multi-day bar. */
.ltf-ec__sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ---------------------------------------------------------------------
   Top bar: search, date, prev / next / today, view switcher
   --------------------------------------------------------------------- */

.ltf-ec__controls {
	margin: 0 0 var(--ltfhs-space-3);
}

.ltf-ec__topbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--ltfhs-space-2);
	padding: var(--ltfhs-space-2) 0;
	border-bottom: 1px solid var(--ltfhs-border);
}

.ltf-ec__search {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--ltfhs-space-2);
	flex: 1 1 240px;
	min-width: 0;
}

.ltf-ec__search-input,
.ltf-ec__date-input,
.ltf-ec__filter-input {
	font-family: inherit;
	font-size: 14px;
	background: var(--ltfhs-bg);
	color: var(--ltfhs-text);
	border: 1px solid var(--ltfhs-border-strong);
	border-radius: var(--ltfhs-radius-md);
	padding: 8px 12px;
	min-width: 0;
	max-width: 100%;
}

.ltf-ec__search-input {
	flex: 1 1 160px;
}

.ltf-ec__submit,
.ltf-ec__apply {
	font-family: inherit;
	font-size: 13px;
	font-weight: 700;
	background: var(--ltfhs-text);
	color: var(--ltfhs-invert);
	border: 1px solid var(--ltfhs-text);
	border-radius: var(--ltfhs-radius-md);
	padding: 9px 16px;
	cursor: pointer;
	white-space: nowrap;
}

.ltf-ec__nav {
	display: flex;
	align-items: center;
	gap: 6px;
	flex-wrap: wrap;
	min-width: 0;
}

.ltf-ec__nav-arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	font-size: 18px;
	line-height: 1;
	color: var(--ltfhs-text);
	text-decoration: none;
	border: 1px solid var(--ltfhs-border);
	border-radius: 999px;
}

.ltf-ec__nav-reset {
	font-size: 12px;
	font-weight: 700;
	color: var(--ltfhs-text);
	text-decoration: none;
	border: 1px solid var(--ltfhs-border-strong);
	border-radius: 999px;
	padding: 6px 12px;
	white-space: nowrap;
}

.ltf-ec__nav-arrow:hover,
.ltf-ec__nav-arrow:focus-visible,
.ltf-ec__nav-reset:hover,
.ltf-ec__nav-reset:focus-visible {
	border-color: var(--ltfhs-border-strong);
	background: var(--ltfhs-bg-hi);
}

.ltf-ec__nav-label {
	font-size: 18px;
	font-weight: 700;
	color: var(--ltfhs-text);
	margin-left: 4px;
	overflow-wrap: anywhere;
}

.ltf-ec__switcher {
	display: flex;
	gap: 2px;
	margin-left: auto;
}

.ltf-ec__switcher-link {
	font-size: 13px;
	font-weight: 700;
	color: var(--ltfhs-text-muted);
	text-decoration: none;
	padding: 8px 12px;
	border-bottom: 2px solid transparent;
	white-space: nowrap;
}

.ltf-ec__switcher-link.is-active {
	color: var(--ltfhs-text);
	border-bottom-color: var(--ltfhs-text);
}

.ltf-ec__switcher-link:focus-visible,
.ltf-ec__filters-toggle:focus-visible,
.ltf-ec__submit:focus-visible,
.ltf-ec__apply:focus-visible,
.ltf-ec__nav-arrow:focus-visible,
.ltf-ec__nav-reset:focus-visible {
	outline: 2px solid var(--ltfhs-accent);
	outline-offset: 2px;
}

/* ---------------------------------------------------------------------
   Filter bar
   Default open, which is what UNBOUND runs. The Hide filters button is
   hidden in the markup and revealed by the script, because a toggle that
   cannot toggle is worse than no toggle at all.
   --------------------------------------------------------------------- */

.ltf-ec__filterbar-wrap {
	padding: var(--ltfhs-space-2) 0;
}

.ltf-ec__filters-toggle {
	font-family: inherit;
	font-size: 12px;
	font-weight: 700;
	background: none;
	color: var(--ltfhs-text-muted);
	border: 1px solid var(--ltfhs-border);
	border-radius: 999px;
	padding: 6px 12px;
	cursor: pointer;
	margin-bottom: var(--ltfhs-space-2);
}

.ltf-ec__filterbar {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: var(--ltfhs-space-2);
	align-items: end;
}

.ltf-ec__filter {
	display: flex;
	flex-direction: column;
	gap: 4px;
	margin: 0;
	min-width: 0;
}

.ltf-ec__filter-label {
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--ltfhs-text-muted);
}

.ltf-ec__filter--actions {
	flex-direction: row;
	align-items: center;
	gap: var(--ltfhs-space-2);
}

.ltf-ec__clear {
	font-size: 12px;
	color: var(--ltfhs-text-muted);
}

/* ---------------------------------------------------------------------
   Month grid
   --------------------------------------------------------------------- */

.ltf-ec__month {
	margin-top: var(--ltfhs-space-3);
}

.ltf-ec__month-head,
.ltf-ec__month-grid {
	display: grid;
	/* minmax(0, 1fr) rather than 1fr. A bare 1fr track refuses to shrink below
	   the widest word inside it, and seven of those on a 390px phone push the
	   whole page sideways. This is the line that keeps the mobile check green. */
	grid-template-columns: repeat(7, minmax(0, 1fr));
}

.ltf-ec__month-head {
	background: var(--ltfhs-bg-hi);
	border: 1px solid var(--ltfhs-border);
	border-bottom: 0;
	border-radius: var(--ltfhs-radius-md) var(--ltfhs-radius-md) 0 0;
}

.ltf-ec__month-dow {
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--ltfhs-text-muted);
	padding: 8px 4px;
	text-align: center;
	overflow: hidden;
}

.ltf-ec__month-grid {
	border-left: 1px solid var(--ltfhs-border);
	border-top: 1px solid var(--ltfhs-border);
	border-radius: 0 0 var(--ltfhs-radius-md) var(--ltfhs-radius-md);
	overflow: hidden;
}

.ltf-ec__month-cell {
	min-width: 0;
	min-height: 52px;
	padding: 4px;
	border-right: 1px solid var(--ltfhs-border);
	border-bottom: 1px solid var(--ltfhs-border);
	background: var(--ltfhs-bg);
}

.ltf-ec__month-cell.is-outside {
	background: var(--ltfhs-bg-hi);
}

.ltf-ec__month-cell.is-today .ltf-ec__month-daynum-text {
	background: var(--ltfhs-text);
	color: var(--ltfhs-invert);
	border-radius: 999px;
	padding: 1px 7px;
}

.ltf-ec__month-daynum {
	display: flex;
	align-items: center;
	gap: 3px;
	font-size: 13px;
	font-weight: 700;
	color: var(--ltfhs-text);
	text-decoration: none;
	padding: 2px;
	min-height: 28px;
}

.ltf-ec__month-cell.is-outside .ltf-ec__month-daynum {
	color: var(--ltfhs-text-muted);
}

.ltf-ec__month-dot {
	display: none;
	width: 6px;
	height: 6px;
	border-radius: 999px;
	background: var(--ltfhs-accent);
}

.ltf-ec__month-items {
	display: flex;
	flex-direction: column;
	gap: 3px;
}

.ltf-ec__month-item {
	font-size: 11px;
	line-height: 1.3;
	overflow-wrap: anywhere;
}

.ltf-ec__month-item-time {
	display: block;
	color: var(--ltfhs-text-muted);
}

.ltf-ec__month-item-title {
	color: var(--ltfhs-text);
	font-weight: 600;
	text-decoration: none;
}

.ltf-ec__month-item-title:hover,
.ltf-ec__month-item-title:focus-visible {
	text-decoration: underline;
}

/* A multi-day or all-day session is drawn once per day it covers, with the
   words only on the first. The negative margins pull each segment out to the
   cell edges so consecutive segments meet and read as one continuous bar,
   which is how The Events Calendar draws them. */
.ltf-ec__month-item.is-bar {
	background: color-mix(in srgb, var(--ltfhs-accent) 16%, var(--ltfhs-bg-hi));
	padding: 2px 6px;
	margin-left: -4px;
	margin-right: -4px;
}

.ltf-ec__month-item.is-bar-start {
	border-radius: var(--ltfhs-radius-sm) 0 0 var(--ltfhs-radius-sm);
	margin-left: 0;
}

.ltf-ec__month-item.is-bar-end {
	border-radius: 0 var(--ltfhs-radius-sm) var(--ltfhs-radius-sm) 0;
	margin-right: 0;
}

.ltf-ec__month-item.is-bar-start.is-bar-end {
	border-radius: var(--ltfhs-radius-sm);
}

/* "+ N More" is a <details>, so the browser expands the cell in place with no
   script and no tooltip library. */
.ltf-ec__month-more {
	font-size: 11px;
}

.ltf-ec__month-more-toggle {
	cursor: pointer;
	color: var(--ltfhs-text-muted);
	font-weight: 700;
	list-style: none;
	padding: 2px 0;
}

.ltf-ec__month-more-toggle::-webkit-details-marker {
	display: none;
}

.ltf-ec__month-more-items {
	display: flex;
	flex-direction: column;
	gap: 3px;
	padding-top: 3px;
}

.ltf-ec__month-day-panel {
	margin-top: var(--ltfhs-space-3);
	padding-top: var(--ltfhs-space-3);
	border-top: 1px solid var(--ltfhs-border);
}

.ltf-ec__month-day-panel-heading {
	font-size: 13px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--ltfhs-text-muted);
	margin: 0 0 var(--ltfhs-space-2);
}

.ltf-ec__month-day-panel-items {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

/* Below 640px seven columns of readable text does not fit and never will. The
   cells become a number and a dot, and the tapped day's sessions appear under
   the grid. With the script off, the day number is a link to the day view,
   which is the same information at a URL that works. */
@media (max-width: 639px) {
	/* Scoped to the CELL, not to the class. The phone panel below the grid is
	   filled by cloning a cell's .ltf-ec__month-items node into it, so an
	   unscoped hide rule reached the clone as well and the panel opened empty
	   every time. The panel is the entire point of the collapsed grid. */
	.ltf-ec__month-cell .ltf-ec__month-items {
		display: none;
	}

	.ltf-ec__month-cell.has-sessions .ltf-ec__month-dot {
		display: block;
	}

	.ltf-ec__month-cell {
		min-height: 40px;
		padding: 2px;
	}

	.ltf-ec__month-daynum {
		flex-direction: column;
		gap: 2px;
		font-size: 12px;
		min-height: 34px;
	}

	.ltf-ec__month-cell.is-selected {
		background: var(--ltfhs-bg-hi);
		box-shadow: inset 0 0 0 2px var(--ltfhs-border-strong);
	}
}

@media (min-width: 640px) {
	.ltf-ec__month-cell {
		min-height: 116px;
	}

	.ltf-ec__month-day-panel {
		display: none;
	}
}

/* ---------------------------------------------------------------------
   Day view
   --------------------------------------------------------------------- */

.ltf-ec__day-view {
	margin-top: var(--ltfhs-space-3);
}

/* ---------------------------------------------------------------------
   List view additions: thumbnail, address, latest-past heading
   --------------------------------------------------------------------- */

.ltf-ec__card-thumb {
	flex: 0 0 auto;
	line-height: 0;
}

.ltf-ec__card-thumb img {
	width: 100%;
	max-width: 100%;
	height: auto;
	border-radius: var(--ltfhs-radius-md);
	display: block;
}

@media (min-width: 480px) {
	.ltf-ec__card-thumb {
		width: 116px;
	}
}

.ltf-ec__card-address {
	display: block;
	color: var(--ltfhs-text-muted);
}

.ltf-ec__card-title a {
	color: inherit;
	text-decoration: none;
}

.ltf-ec__card-title a:hover,
.ltf-ec__card-title a:focus-visible {
	text-decoration: underline;
}

.ltf-ec__latest-past {
	font-size: 16px;
	font-weight: 700;
	margin: 0 0 var(--ltfhs-space-3);
	color: var(--ltfhs-text-muted);
}

.ltf-ec__empty-state {
	background: var(--ltfhs-bg);
	border: 1px solid var(--ltfhs-border);
	border-radius: var(--ltfhs-radius-md);
	padding: var(--ltfhs-space-3);
	color: var(--ltfhs-text-muted);
}

.ltf-ec__empty-state p {
	margin: 0;
}

/* ---------------------------------------------------------------------
   Subscribe dropdown
   --------------------------------------------------------------------- */

.ltf-ec__subscribe-menu {
	display: inline-block;
}

.ltf-ec__subscribe-toggle {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	cursor: pointer;
	font-weight: 700;
	color: var(--ltfhs-text);
	border: 1px solid var(--ltfhs-border-strong);
	border-radius: var(--ltfhs-radius-lg);
	padding: 6px 14px;
	list-style: none;
}

.ltf-ec__subscribe-toggle::-webkit-details-marker {
	display: none;
}

.ltf-ec__subscribe-toggle::after {
	content: "\25BE";
	font-size: 11px;
}

.ltf-ec__subscribe-list {
	list-style: none;
	margin: var(--ltfhs-space-2) 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--ltfhs-space-2);
}

.ltf-ec__subscribe-list a {
	display: inline-block;
	padding: 4px 10px;
	border: 1px solid var(--ltfhs-border);
	border-radius: var(--ltfhs-radius-md);
	background: var(--ltfhs-bg-hi);
	color: var(--ltfhs-text);
	text-decoration: none;
	font-weight: 600;
}

/* ---------------------------------------------------------------------
   Single session page
   --------------------------------------------------------------------- */

.ltf-ec--single {
	max-width: 900px;
	margin: 0 auto;
	padding: var(--ltfhs-space-4) var(--ltfhs-space-3);
}

.ltf-ec__single-passed {
	font-size: 13px;
	color: var(--ltfhs-text-muted);
	padding-bottom: var(--ltfhs-space-3);
	border-bottom: 1px solid var(--ltfhs-border);
	margin: 0 0 var(--ltfhs-space-3);
}

.ltf-ec__single-title {
	font-size: 30px;
	line-height: 1.15;
	font-weight: 700;
	margin: 0 0 var(--ltfhs-space-2);
	color: var(--ltfhs-text);
	overflow-wrap: anywhere;
}

.ltf-ec__single-when {
	font-size: 15px;
	color: var(--ltfhs-text-muted);
	margin: 0 0 var(--ltfhs-space-3);
}

.ltf-ec__single-image {
	margin: 0 0 var(--ltfhs-space-4);
	line-height: 0;
}

.ltf-ec__single-image img {
	width: 100%;
	max-width: 100%;
	height: auto;
	border-radius: var(--ltfhs-radius-md);
	display: block;
}

.ltf-ec__single-body {
	font-size: 15px;
	color: var(--ltfhs-text);
	margin-bottom: var(--ltfhs-space-4);
	overflow-wrap: anywhere;
}

.ltf-ec__single-body img {
	max-width: 100%;
	height: auto;
}

.ltf-ec__single-cols {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: var(--ltfhs-space-4);
	padding: var(--ltfhs-space-4) 0;
	border-top: 1px solid var(--ltfhs-border);
	border-bottom: 1px solid var(--ltfhs-border);
	margin-top: var(--ltfhs-space-4);
}

.ltf-ec__single-col {
	min-width: 0;
}

.ltf-ec__single-col-heading {
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--ltfhs-text-muted);
	margin: 0 0 var(--ltfhs-space-2);
}

.ltf-ec__deflist {
	margin: 0;
	font-size: 14px;
}

.ltf-ec__deflist dt {
	font-weight: 700;
	color: var(--ltfhs-text);
	margin-top: var(--ltfhs-space-2);
}

.ltf-ec__deflist dt:first-child {
	margin-top: 0;
}

.ltf-ec__deflist dd {
	margin: 0;
	color: var(--ltfhs-text-muted);
}

.ltf-ec__deflist a {
	color: var(--ltfhs-text);
}

/* A registration URL is one long unbroken token and will push a 390px page
   sideways on its own if it is allowed to. */
.ltf-ec__deflist-url a {
	word-break: break-all;
}

.ltf-ec__venue-name {
	font-weight: 700;
	margin: 0 0 2px;
	font-size: 14px;
}

.ltf-ec__venue-address {
	margin: 0 0 var(--ltfhs-space-2);
	font-size: 14px;
	color: var(--ltfhs-text-muted);
}

.ltf-ec__venue-map {
	margin: 0;
	font-size: 14px;
}

.ltf-ec__venue-map a {
	color: var(--ltfhs-text);
}

.ltf-ec__venue-embed {
	margin-top: var(--ltfhs-space-2);
	aspect-ratio: 4 / 3;
}

.ltf-ec__venue-embed iframe {
	width: 100%;
	height: 100%;
	border: 0;
	border-radius: var(--ltfhs-radius-md);
}

.ltf-ec__single-nav {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: var(--ltfhs-space-2);
	padding: var(--ltfhs-space-3) 0;
	font-size: 14px;
}

.ltf-ec__single-nav a {
	color: var(--ltfhs-text);
	text-decoration: none;
	max-width: 100%;
	overflow-wrap: anywhere;
}

.ltf-ec__single-nav a:hover,
.ltf-ec__single-nav a:focus-visible {
	text-decoration: underline;
}

.ltf-ec__single-back {
	margin: 0;
	font-size: 14px;
	font-weight: 700;
}

.ltf-ec__single-back a {
	color: var(--ltfhs-text);
}

/* =========================================================================
   WEEK VIEW, and the no-reload filter
   Added 2026-08-21. Same token contract as everything above: light literal
   fallbacks, hub tokens win when present, nothing assumes a dark ground.
   ========================================================================= */

/* Anything the in-browser filter has hidden, in any view. The list card had
   its own rule above; the month and week items share this one. */
.ltf-ec__month-item.is-hidden,
.ltf-ec__week-item.is-hidden {
	display: none;
}

.ltf-ec__no-match {
	margin: var(--ltfhs-space-3) 0 0;
	color: var(--ltfhs-text-muted);
	font-size: 14px;
}

.ltf-ec__week {
	margin-top: var(--ltfhs-space-3);
}

/* One column per day from 640px up. minmax(0, 1fr) for the same reason as the
   month grid: a bare 1fr track will not shrink under its longest word, and a
   race title is a long word. */
.ltf-ec__week-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--ltfhs-space-2);
}

.ltf-ec__week-day {
	min-width: 0;
	background: var(--ltfhs-bg);
	border: 1px solid var(--ltfhs-border);
	border-radius: var(--ltfhs-radius-md);
	overflow: hidden;
}

.ltf-ec__week-dayhead {
	margin: 0;
	font-size: 13px;
	line-height: 1.2;
	background: var(--ltfhs-bg-hi);
	border-bottom: 1px solid var(--ltfhs-border);
}

.ltf-ec__week-daylink {
	display: flex;
	align-items: baseline;
	gap: 6px;
	padding: 8px 10px;
	color: var(--ltfhs-text);
	text-decoration: none;
}

.ltf-ec__week-daylink:hover .ltf-ec__week-daynum,
.ltf-ec__week-daylink:focus-visible .ltf-ec__week-daynum {
	text-decoration: underline;
}

.ltf-ec__week-daylink:focus-visible {
	outline: 2px solid var(--ltfhs-accent);
	outline-offset: -2px;
}

.ltf-ec__week-dow {
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--ltfhs-text-muted);
}

.ltf-ec__week-daynum {
	font-size: 16px;
	font-weight: 700;
}

.ltf-ec__week-day.is-today .ltf-ec__week-daynum {
	background: var(--ltfhs-text);
	color: var(--ltfhs-invert);
	border-radius: 999px;
	padding: 1px 8px;
}

.ltf-ec__week-day.is-empty .ltf-ec__week-dow,
.ltf-ec__week-day.is-empty .ltf-ec__week-daynum {
	color: var(--ltfhs-text-muted);
}

.ltf-ec__week-items {
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: 8px;
}

/* Time, title, venue, stacked. The category colour rides in as a left edge
   from the same --chip-color the list chips use, so the week reads in the
   same colour language as the list without a legend. */
.ltf-ec__week-item {
	display: flex;
	flex-direction: column;
	gap: 1px;
	font-size: 12px;
	line-height: 1.3;
	padding: 4px 8px;
	border-left: 3px solid var(--chip-color, var(--ltfhs-border-strong));
	overflow-wrap: anywhere;
}

.ltf-ec__week-item-time {
	font-size: 11px;
	font-weight: 700;
	color: var(--ltfhs-accent);
}

.ltf-ec__week-item-title {
	color: var(--ltfhs-text);
	font-weight: 600;
	text-decoration: none;
}

.ltf-ec__week-item-title:hover,
.ltf-ec__week-item-title:focus-visible {
	text-decoration: underline;
}

.ltf-ec__week-item-venue {
	font-size: 11px;
	color: var(--ltfhs-text-muted);
}

/* The bar treatment is shared with the month grid: a tint for a multi-day or
   all-day session, rounded at its two ends. In a column it cannot run edge to
   edge the way the month cells allow, so it keeps its own left edge. */
.ltf-ec__week-item.is-bar {
	background: color-mix(in srgb, var(--ltfhs-accent) 12%, var(--ltfhs-bg-hi));
	border-radius: var(--ltfhs-radius-sm);
}

.ltf-ec__week-empty {
	margin: 0;
	padding: 8px 10px 10px;
	font-size: 12px;
	color: var(--ltfhs-text-muted);
}

/* Below 640px the columns stack. An empty day collapses to its heading: the
   range label in the top bar already says which week it is, and five "No
   sessions" rows above a race weekend is noise on a phone. */
@media (max-width: 639px) {
	.ltf-ec__week-day.is-empty .ltf-ec__week-empty {
		display: none;
	}

	.ltf-ec__week-day.is-empty .ltf-ec__week-dayhead {
		border-bottom: 0;
	}
}

@media (min-width: 640px) {
	.ltf-ec__week-grid {
		grid-template-columns: repeat(7, minmax(0, 1fr));
		gap: 0;
		border: 1px solid var(--ltfhs-border);
		border-radius: var(--ltfhs-radius-md);
		overflow: hidden;
		background: var(--ltfhs-bg);
	}

	.ltf-ec__week-day {
		border: 0;
		border-right: 1px solid var(--ltfhs-border);
		border-radius: 0;
		min-height: 220px;
	}

	.ltf-ec__week-day:last-child {
		border-right: 0;
	}

	.ltf-ec__week-dayhead {
		text-align: center;
	}

	.ltf-ec__week-daylink {
		flex-direction: column;
		align-items: center;
		gap: 2px;
		padding: 8px 4px;
	}

	.ltf-ec__week-items {
		padding: 6px;
		gap: 4px;
	}

	.ltf-ec__week-item {
		padding: 4px 6px;
		font-size: 11px;
	}

	.ltf-ec__week-empty {
		text-align: center;
		font-size: 11px;
	}
}

@media (min-width: 1024px) {
	.ltf-ec__week-item {
		font-size: 12px;
	}
}

/* The hub shell is a narrow app-shaped column (about 670px of content at
   1440px wide), so a viewport breakpoint alone put seven columns into a space
   that breaks "Mandatory" across two lines. Measured on torchlightt
   2026-08-21. The week grid therefore also watches its OWN width: under 700px
   of container it stacks, whatever the viewport says. Browsers without
   container queries ignore this block and keep the viewport rule above,
   which is legible, just tighter. Placed after the min-width rules on purpose:
   equal specificity, so source order decides, and this must win. */
.ltf-ec__week {
	container-type: inline-size;
}

@container (max-width: 699px) {
	.ltf-ec__week-grid {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--ltfhs-space-2);
		border: 0;
		border-radius: 0;
		overflow: visible;
		background: transparent;
	}

	.ltf-ec__week-day {
		min-height: 0;
		border: 1px solid var(--ltfhs-border);
		border-radius: var(--ltfhs-radius-md);
	}

	.ltf-ec__week-dayhead {
		text-align: left;
	}

	.ltf-ec__week-daylink {
		flex-direction: row;
		align-items: baseline;
		gap: 6px;
		padding: 8px 10px;
	}

	.ltf-ec__week-items {
		padding: 8px;
		gap: 6px;
	}

	.ltf-ec__week-item {
		padding: 4px 8px;
		font-size: 12px;
	}

	.ltf-ec__week-empty {
		text-align: left;
		font-size: 12px;
	}

	.ltf-ec__week-day.is-empty .ltf-ec__week-empty {
		display: none;
	}

	.ltf-ec__week-day.is-empty .ltf-ec__week-dayhead {
		border-bottom: 0;
	}
}

/* While a view swap is in flight (see initNavigation in schedule.js). A dim
   rather than a spinner: the swap is a cached page fetch and is usually over
   before a spinner would have finished appearing. */
.ltf-ec.is-loading {
	opacity: 0.55;
	transition: opacity 120ms ease;
}

/* =========================================================================
   SOLID CATEGORY BLOCKS (Aaron, 2026-08-21: option B of three mockups)
   Week items and month items are filled with the session's category colour
   and carry white text, the way Google Calendar draws an event. The colour
   is the same chip_color the list chips and the card mini-chips already use,
   so the three views speak one colour language without a legend.

   The block text and the neutral block are fixed values on purpose, not
   theme tokens: the category colours themselves are fixed hexes chosen per
   category in wp-admin and do not change between light and dark, so the text
   that sits on them cannot change either. White on every shipped category
   colour holds in both themes (checked on the hub in dark mode and on Big
   Sugar's white page, 2026-08-21). The neutral is for a session with no
   category and is the same in both themes for the same reason.

   Placed after every earlier week and month item rule so source order wins;
   the earlier rules (left edge, tint, muted time colour) are superseded here
   rather than deleted, so this block can be lifted out in one piece if the
   decision ever changes.
   ========================================================================= */

.ltf-ec {
	--ltfhs-block-text: #FFFFFF;
	--ltfhs-block-neutral: #5F5F63;
}

.ltf-ec__week-item,
.ltf-ec__week-item.is-bar {
	background: var(--chip-color, var(--ltfhs-block-neutral));
	color: var(--ltfhs-block-text);
	border-left: 0;
	border-radius: 6px;
	padding: 6px 8px;
}

.ltf-ec__week-item-time,
.ltf-ec__week-item-title,
.ltf-ec__week-item-venue {
	color: var(--ltfhs-block-text);
}

.ltf-ec__week-item-venue {
	opacity: 0.85;
}

.ltf-ec__week-item-title:focus-visible {
	outline: 2px solid var(--ltfhs-block-text);
	outline-offset: 1px;
}

.ltf-ec__month-item,
.ltf-ec__month-item.is-bar {
	background: var(--chip-color, var(--ltfhs-block-neutral));
	color: var(--ltfhs-block-text);
	border-radius: 4px;
	padding: 2px 6px;
}

/* A multi-day bar keeps its run-to-the-edge margins and its rounded ends from
   the month rules above; only the fill changed. */
.ltf-ec__month-item.is-bar-start {
	border-radius: var(--ltfhs-radius-sm) 0 0 var(--ltfhs-radius-sm);
}

.ltf-ec__month-item.is-bar-end {
	border-radius: 0 var(--ltfhs-radius-sm) var(--ltfhs-radius-sm) 0;
}

.ltf-ec__month-item.is-bar-start.is-bar-end {
	border-radius: var(--ltfhs-radius-sm);
}

.ltf-ec__month-item-time,
.ltf-ec__month-item-title {
	color: var(--ltfhs-block-text);
}

.ltf-ec__month-item-time {
	opacity: 0.9;
}

.ltf-ec__month-item-title:focus-visible {
	outline: 2px solid var(--ltfhs-block-text);
	outline-offset: 1px;
}

/* The cell's stack of blocks needs a hair more air than the plain lines did. */
.ltf-ec__month-items,
.ltf-ec__month-more-items {
	gap: 3px;
}

/* The phone month panel clones the cell's items, so the blocks carry over.
   Give them the week item's size there, where there is room. */
.ltf-ec__month-day-panel-items .ltf-ec__month-item {
	padding: 6px 8px;
	border-radius: 6px;
	font-size: 12px;
}

/* =========================================================================
   POLISH PASS 1 (2026-08-21, after option B landed)
   Three things, all container-aware rather than viewport-aware, because the
   same embed sits in a 980px column on Big Sugar and a 672px column on the
   hub at the same 1440px viewport.
   ========================================================================= */

/* 1. Month cells in a narrow column. Seven cells of 96px cannot hold a time
   range and a race title without breaking words in half. Under 800px of
   container the cell shows the title only; the time is still there for the
   phone panel (which is outside the cell) and for the day view. */
.ltf-ec__month {
	container-type: inline-size;
}

@container (max-width: 799px) {
	.ltf-ec__month-cell .ltf-ec__month-item-time {
		display: none;
	}

	.ltf-ec__month-cell .ltf-ec__month-item {
		font-size: 10px;
		line-height: 1.25;
		padding: 2px 4px;
		hyphens: auto;
	}
}

/* 2. Week items grow a step when the column has the room for it: Big Sugar's
   980px gives each day about 140px, enough for 13px titles. The hub stacks
   under 700px and never reaches this rule. */
@container (min-width: 900px) {
	.ltf-ec__week-item {
		font-size: 13px;
		line-height: 1.3;
		padding: 7px 9px;
	}

	.ltf-ec__week-item-time,
	.ltf-ec__week-item-venue {
		font-size: 12px;
	}

	.ltf-ec__week-items {
		gap: 6px;
		padding: 8px;
	}
}

/* 3. Empty weekdays take the quieter ground, so in the MTB week the five
   blank columns read as the week's shape and the weekend reads as the event.
   Only in the seven-column layout; on a phone an empty day is a heading. */
@media (min-width: 640px) {
	.ltf-ec__week-day.is-empty {
		background: var(--ltfhs-bg-hi);
	}

	.ltf-ec__week-day.is-empty .ltf-ec__week-dayhead {
		background: transparent;
	}

	.ltf-ec__week-empty {
		opacity: 0.7;
	}
}
