/* Agenda pages (both shells): expand-all view, session cards, concurrent-session groups. */

/* Static since 2026-08-07: a floating switch had to hide itself to avoid
   occluding content (groups, runs, card copy), which meant it was rarely
   visible while stuck anyway. It lives in this row at the top only. */
.agenda-controls {
  min-height: 44px;
}

.agenda-buttons {
  align-items: center;
  justify-content: end;
}

.text-gray {
  color: #5d6b78;
}

/* One ink: the agenda uses the design-system body ink, not Bootstrap's default */
.event-agenda-page h1,
.session-instance-card h3,
.session-instance-card h4,
.session-description,
.session-speakers,
.session-instance-card .session-toggle,
.multi-session-header .session-toggle {
  color: #0e2238;
}

/* Measure control inside wide cards: the description already caps at 68ch;
   titles and speaker role lines must not run the full card width */
.session-instance-card h3,
.session-instance-card h4 {
  max-width: 46ch;
}

.session-speakers .panelist {
  max-width: 68ch;
}

/* Linked speaker names must look like links (Sapphire), not hidden UI marked
   only by the Member chip */
.session-speakers .person-profile-link {
  color: #007bc2;
}

.session-speakers .person-profile-link:hover,
.session-speakers .person-profile-link:focus {
  text-decoration: underline;
}

/* overflow-anchor none: pinning headers changes layout inside this subtree
   (chrome borders, hidden descriptions/badges), and Chrome's scroll anchoring
   otherwise "compensates" by silently moving scrollY - which re-crosses the
   sticky boundary and makes the floating headers strobe. Measured: a single
   is-stuck application moved scrollY 45px without input. */
.agenda-sessions {
  gap: 2rem;
  overflow-anchor: none;
}

@media (min-width: 768px) {
  .agenda-start-time {
    min-width: 94px;
    justify-content: center;
  }
}

/* Concurrent-session group. The box-in-box-in-box route (ice container +
   white header band + white cards) read as blocky, so the container is now
   CHROMELESS: the session cards are the only boxes on the page, and the
   heading, the tighter internal spacing and the shared gutter pill are what
   say "these run at once". Headers sit as plain text on the white page, so
   badge colour washes read without any backing.
   The group still sits in a pill+content row exactly like a single session,
   so the time-pill spine stays unbroken; the group pill shows the slot start */
.multi-session {
  min-width: 0;
}

.multi-session-header {
  margin: 0 0 0.75rem;
}

/* Floating headers follow the agenda's chrome-only-while-stuck motif (like
   the Expand-all pill): flat text at rest, white panel while pinned.
   Constant padding so nothing jumps at the pin moment. */
.multi-session-large .multi-session-header {
  position: sticky;
  top: var(--agenda-header-offset, 72px);
  z-index: 1010;
  padding: 0.375rem 0.75rem;
}

/* At-rest text aligns with the run heads and card boxes (the padding is
   cancelled, so only the pinned panel bleeds past the content edge); below
   992px the mobile padding-left rule aligns to the pill text instead */
@media (min-width: 992px) {
  .multi-session-large .multi-session-header {
    margin-left: -0.75rem;
    margin-right: -0.75rem;
  }
}

.multi-session-large .multi-session-header.is-stuck {
  background-color: #fff;
  border: 1px solid #d6e4ef;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

@media (max-width: 767px) {
  .multi-session-large .multi-session-header .multi-session-heading {
    font-size: 1rem;
  }
}

.multi-session-heading {
  font-size: 1.25rem;
  font-weight: 700;
  color: #0e2238;
  margin: 0;
}

.multi-session-subheading,
.multi-session-location {
  font-size: 0.875rem;
  font-weight: 600;
  color: #5d6b78;
  margin: 0.25rem 0 0;
}

.multi-session-location {
  font-weight: 400;
}

/* Optional group-level introduction (MultiSessionBlock.description); same
   expander behaviour as the card descriptions - hidden in condensed with a
   Show-description toggle in the header, always open in expanded */
.multi-session-description {
  margin: 0.5rem 0 0;
  max-width: 68ch;
  font-size: 1rem;
  font-weight: 400;
  color: #0e2238;
}

.multi-session-description p:last-child {
  margin-bottom: 0;
}

.agenda-condensed .multi-session-description {
  display: none;
}

.agenda-condensed .multi-session-header.session-open .multi-session-description {
  display: block;
}

/* While the header floats it slims to its label lines (same motif as the run
   head hiding its inline badges): no toggle, no description - both return
   when the header releases. The last selector outweighs the session-open
   reveal above, so even a description the user opened hides while pinned. */
.multi-session-header.is-stuck .session-toggle,
.multi-session-header.is-stuck .multi-session-description,
.agenda-condensed .multi-session-header.is-stuck.session-open .multi-session-description {
  display: none;
}

/* Headings that carry a type chip lay out as a wrapping flex row so the chip
   centres on the text line and wraps cleanly instead of dangling with stray
   indents (non-:has browsers keep the inline align-middle fallback) */
.multi-session-heading:has(.badge),
.multi-session-subheading:has(.badge) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem 0.5rem;
}

/* Below 992 the gutter stacks (pill above the group). The pill's own px-3
   gives its text a 1rem inset, so the naked header text hangs from the SAME
   edge: pill text, header text and chips share one left line. Cards keep
   full width (their box edge is the alignment reference instead).
   Mid-scroll the slot time leaves the screen; owner call 2026-08-07: accept
   the half-swipe scroll-up rather than repeat pills/badges per card. If use
   ever proves the gap, the escalation is a sticky slot header line (the
   large-group pattern), NOT per-card repetition. */
@media (max-width: 991.98px) {
  .multi-session-row .multi-session-header {
    padding-left: 1rem;
  }
}

/* A run of 2-option groups repeats the same header line; keep those quiet and
   save the 20px weight for titled and >4-option groups */
.multi-session:not(.multi-session-large) .multi-session-header:not(.multi-session-header--titled) .multi-session-heading {
  font-size: 1rem;
  font-weight: 600;
  color: #5d6b78;
}

/* !important: overrides the fs-lg-26 utility so group headings outrank card titles */
.multi-session .session-instance-card h4 {
  font-size: 1.125rem !important;
}

/* Below 768 the compacted group heading (16px) must not rank under the option
   titles it governs; weight + ink still separate them at equal size */
@media (max-width: 767px) {
  .multi-session .session-instance-card h4 {
    font-size: 1rem !important;
  }
}

.multi-session .session-time {
  display: none;
}

/* A session whose own window differs from the group slot must say so, and must
   read as an exception, not as just another muted time line ("Runs ..." prefix
   comes from the template) */
.multi-session .session-time.session-time--exception {
  display: block;
  font-weight: 600;
  color: #0e2238;
}

/* Track run: consecutive 2-option groups sharing a track pair band together.
   The wrapper carries the one "Two tracks" intro; member groups demote to
   time-only headers and sit tight so the run reads as a single unit. The
   intro pins below the event nav for the whole run (same offset scheme as
   the large-group header; the Expand-all pill suppresses over runs too). */
.multi-session-run {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* The head (intro line + desktop column headers) pins as a unit. Flat text
   at rest on the white page; it grows its white panel chrome only while
   floating (is-stuck from agenda.js), like the Expand-all pill. Constant
   padding so nothing jumps at the pin moment. */
.multi-session-run-head {
  position: sticky;
  top: var(--agenda-header-offset, 72px);
  z-index: 1010;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
}

.multi-session-run-head.is-stuck {
  background-color: #fff;
  border: 1px solid #d6e4ef;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.multi-session-run-intro {
  margin: 0;
  font-size: 1.375rem;
  font-weight: 700;
  color: #0e2238;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
}

.multi-session-run-intro-tracks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Long track names wrap inside the panel instead of overflowing it */
.multi-session-run-head .badge {
  white-space: normal;
  text-align: start;
  line-height: 1.3;
  max-width: 100%;
}

/* While floating (is-stuck from agenda.js) the inline badges hide so the
   pinned band stays one line; below 1200px the cards' own track badges carry
   identity mid-run, at >=1200px the column headers do */
.multi-session-run-head.is-stuck .multi-session-run-intro-tracks {
  display: none;
}

/* Align the head's TEXT with the content column past the pill gutter (pill
   94px + 1.5rem gap-lg-4; only at >=992px). The 1rem padding is subtracted so
   at rest the text lines up with the slot headers below; the stuck panel then
   bleeds 1rem left of the column, wrapping its content. */
@media (min-width: 992px) {
  .multi-session-run-head {
    margin-left: calc(94px + 1.5rem - 1rem);
  }
}

/* Below the gutter breakpoint the same trick keeps at-rest text flush with
   the content edge: padding is cancelled by negative margins (the stuck
   panel bleeds to the container edge) */
@media (max-width: 991.98px) {
  .multi-session-run-head {
    padding-left: 0.75rem;
    padding-right: 0.75rem;
    margin-left: -0.75rem;
    margin-right: -0.75rem;
  }
}

@media (max-width: 767px) {
  .multi-session-run-head {
    padding: 0.375rem 0.75rem;
  }

  .multi-session-run-intro {
    font-size: 1rem;
  }
}

/* Column track headers: only where the pair actually renders as two columns
   (the sessions grid switches at 1200px). They float with the head, so the
   repeated per-card track badges retire at this width; the column position is
   established by the header and stays fixed for the whole run. */
.multi-session-run-columns {
  display: none;
}

@media (min-width: 1200px) {
  /* Mirrors the sessions grid exactly (the -1rem cancels the head's right
     padding), so each cell sits precisely over its card column */
  .multi-session-run-columns {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
    margin-right: -1rem;
  }

  /* Full-column header cells: the track badge stretches to caption its whole
     column, physically connecting the header to the track running beneath it
     (card radius to match the session cards) */
  .multi-session-run-head .multi-session-run-columns .badge {
    display: block;
    width: 100%;
    border-radius: 6px;
  }

  /* Visually retired but kept in the accessibility tree: the column cells
     carry track identity by pixel position only, which a screen reader can't
     use, so each card keeps its track name via the clip pattern */
  .multi-session-run .session-track-badge {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  /* The clipped badge leaves the row zero-height; drop its margins too
     (browsers without :has just leave a small gap - harmless) */
  .multi-session-run .type-and-track:not(:has(.badge:not(.session-track-badge))) {
    margin: 0;
  }

  .multi-session-run-head .multi-session-run-intro-tracks {
    display: none;
  }
}

.multi-session-sessions {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

@media (min-width: 1200px) {
  .multi-session-sessions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
  }
}

.multi-session .agenda-start-time {
  display: none !important;
}

.multi-session .session-instance-card {
  background-color: #fff;
  align-self: stretch !important;
}

.session-instance-card {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.session-speakers {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1rem;
}

.session-description {
  margin-top: 1rem;
  max-width: 68ch;
}

.agenda-condensed .session-description {
  display: none;
}

.agenda-condensed .session-instance-card.session-open .session-description {
  display: block;
}

/* Large groups compact for comparison: tighter cards, shared type badges
   hidden (identical on every option), toggles available when content exists */
.agenda-condensed .multi-session-large .session-instance-card {
  padding: 0.75rem 1rem !important;
}

.agenda-condensed .multi-session-large .type-and-track {
  display: none;
}

.agenda-condensed .multi-session-large .session-speakers {
  gap: 0.375rem;
  margin-top: 0.5rem;
}

.session-toggle {
  margin-top: 0.25rem;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

.agenda-sessions:not(.agenda-condensed) .session-toggle {
  display: none;
}

.session-toggle .session-toggle-less {
  display: none;
}

.session-open .session-toggle .session-toggle-more {
  display: none;
}

.session-open .session-toggle .session-toggle-less {
  display: inline;
}

.session-toggle i {
  transition: transform 0.2s ease;
}

.session-open .session-toggle i {
  transform: rotate(180deg);
}

/* Selector depth is deliberate: style.css loads after this file, so bare
   .agenda-expand-switch rules lose Bootstrap's equal-specificity ties on order */
.agenda-controls .agenda-expand-switch {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  padding: 0 1rem;
}

.agenda-controls .agenda-expand-switch .form-check-input {
  float: none;
  margin: 0;
  width: 2.75em;
  height: 1.5em;
  border-color: #5d6b78;
  flex-shrink: 0;
}

.agenda-controls .agenda-expand-switch .form-check-input,
.agenda-controls .agenda-expand-switch .form-check-label {
  cursor: pointer;
}

.agenda-controls .agenda-expand-switch .form-check-input:focus-visible,
.session-toggle:focus-visible {
  outline: 2px solid #0696d6;
  outline-offset: 2px;
  box-shadow: none;
}

.rounded-avatar {
  width: 35px;
  height: 35px;
  object-fit: cover;
}

.type-and-track {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Long track names must wrap inside narrow cards instead of overflowing them.
   flex-shrink 0 keeps a badge at natural width so the flex row wraps first;
   text only wraps once the badge alone is wider than the card. */
.type-and-track .badge {
  white-space: normal;
  text-align: start;
  line-height: 1.3;
  max-width: 100%;
  flex-shrink: 0;
}

@media (max-width: 767px) {
  .agenda-buttons {
    margin-top: 1.5rem;
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }

  .agenda-buttons a {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .session-toggle i {
    transition: none;
  }
}
