/* modules/sessionList/sessionsView.css — the dashboard's session cards, the
   sessions title bar/date-picker, the continuous timeline, and the floating "Create
   Session" button. Extracted from index.css to live next to sessionsView.js/sessionCard.js/
   sessionTimeline.js. */

.session-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 6px 14px;
  margin-bottom: 3px;
  border-left: 4px solid var(--primary);
  cursor: pointer;
  transition: background 0.2s, transform 0.2s;
}
/* Pointer feedback — was two mouseenter/mouseleave listeners setting the same two properties
   inline; a plain :hover replaces them with no behaviour left for JS to own. */
.session-card:not(.session-cancelled):hover {
  background: rgba(255, 255, 255, 0.05);
  transform: translateY(-1px);
}
.session-card-info {
  flex: 1;
} /* A finished session is marked with a green edge and its "Completed" badge, not by a faded/greyed
   look — opacity dimming here used to wash out the status-line text (and undo its contrast) along
   with everything else in the card, so completion is signalled by border + badge only, leaving
   every card's text at full strength. */
.session-card.session-completed {
  border-left-color: var(--success);
}
/* A cancelled session stays on the board but reads weaker: its text in the theme's muted colour, its
   edge in the theme's warning colour, and the word "Cancelled" in its bar, so the meaning does not
   rest on colour alone. Both colours are tokens, so every theme restyles it. A tap opens nothing
   (sessionsView.js), so the card does not look tappable: no pointer, no hover lift. */
.session-card.session-cancelled {
  border-left-color: var(--warning);
  color: var(--text-muted);
  cursor: default;
}
.session-card.session-cancelled .session-card-time-badge {
  background: transparent;
  color: inherit;
  border-color: currentColor;
}
.session-live-bar.cancelled {
  background: transparent;
  color: var(--text-muted);
  border-top: 1px dashed var(--warning);
} /* The session in progress is emphasised with an accent-tinted fill + accent ring — the same
   "selected/active" language as a chosen participant tab, so it clearly stands out. */
.session-live {
  /* Stack so the green left bracket can spill into a full-width bottom bar. */
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  border-left-color: var(--primary);
  overflow: hidden;
  background-image: linear-gradient(
      color-mix(in srgb, var(--primary) 8%, transparent),
      color-mix(in srgb, var(--primary) 8%, transparent)
    ), linear-gradient(var(--card-bg), var(--card-bg));
}
/* Bottom bar: the left bracket's green wrapping along the bottom, with the Active-session tag + timer. */
.session-live-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 4px -14px -6px -14px; /* bleed to the card's padded edges (must match .session-card's padding) */
  padding: 4px 14px;
  /* Lightened the same way the upcoming/past bars are below — the raw --primary fill left
     --text-dark's contrast tighter than it needed to be; mixing toward white gives the black
     text more room while the left bracket (border-left-color: var(--primary) on .session-live)
     keeps the full-strength green as the identity accent. */
  background: color-mix(in srgb, var(--primary) 55%, white);
  color: var(--text-dark); /* near-black — better contrast on the accent bar than the previous dark green */
}
/* Overtime: the session ran past its scheduled end without being closed — warn in amber, and turn
   the card's left bracket amber too so it reads as a warning at a glance (follows the bar's state). */
.session-live-bar.overtime {
  background: var(--warning, #f59e0b);
  color: #3d2600;
}
.session-card.session-live:has(.session-live-bar.overtime) {
  border-left-color: var(--warning, #f59e0b);
}
/* Same stacked-card + bottom-bar structure as .session-live, for the two other status-line states
   (2.3: upcoming countdown, past elapsed) — deliberately no tinted background, so a finished or
   not-yet-started card never reads as "currently active" the way .session-live's green wash does. */
.session-status-stack {
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  overflow: hidden;
}
/* Upcoming/past bars share their identity color with the left bracket (see the :has() rules
   below), but lightened toward white at the point of use — the raw --temporal-future/past tokens
   are saturated enough that --text-dark on top of them fell short of WCAG AA (measured ~3.5:1 for
   violet, ~3.8:1 for blue). Lightening only the bar fill (not the border, and not the shared
   variable, which also tints past/future session titles elsewhere) keeps the bracket a strong
   accent while giving the bar's text room to read clearly — same approach the flash-warning/
   flash-ack keyframes already use for tinting a neutral surface toward a color. */
.session-live-bar.upcoming {
  /* Lightened further than the past bar below (35% vs 55% of the identity color into white) — the
     saturated blue read as noticeably darker than the purple at the same mix ratio, so it needed
     more white to land at a comparably light fill. */
  background: color-mix(in srgb, var(--temporal-future, #f59e0b) 35%, white);
  color: var(--text-dark);
}
/* The countdown keeps counting once the scheduled start passes — starting the session is a
   clipboard title-bar action now (sessionTitleBar.js), not a card action, so this bar has nothing
   else to hand off to. Warn instead of silently counting into negative time, matching the live
   bar's own overtime treatment. */
.session-live-bar.upcoming.overtime {
  background: var(--warning, #f59e0b);
  color: #3d2600;
}

/* Both labels ship in the markup and CSS picks one, so the bar can flip from "Starts in" to
   "Overdue" at the moment the start passes without re-rendering the card — the 1s ticker already
   toggles `.overtime` here, and re-rendering a card under a trainer's thumb mid-set is exactly what
   the dashboard avoids doing. The first selector excludes `.overtime`: a late bar carries both
   classes, and without the exclusion it hid "Overdue" too, leaving a bare number. */
.session-live-bar.upcoming:not(.overtime) .when-overdue,
.session-live-bar.upcoming.overtime .when-upcoming {
  display: none;
}
.session-live-bar.past {
  background: color-mix(in srgb, var(--temporal-past, #c084fc) 55%, white);
  /* Pure black (not --text-dark's #09090b) plus heavier weight, so the label/timer read as
     strongly as possible against the purple fill. */
  color: #000;
  font-weight: 800;
}
/* The left bracket always matches whichever status bar the card is showing (live already does via
   .session-live's own border-left-color, and the overtime override above it) — carry the same rule
   to the other two states so the border reads as one continuous accent with the bar beneath it. */
.session-card:has(.session-live-bar.upcoming) {
  border-left-color: var(--temporal-future);
}
.session-card:has(.session-live-bar.upcoming.overtime) {
  border-left-color: var(--warning, #f59e0b);
}
.session-card:has(.session-live-bar.past) {
  border-left-color: var(--temporal-past);
}
.session-status-value {
  cursor: pointer;
}
.session-status-value:hover,
.session-status-value:focus-visible {
  background: rgba(255, 255, 255, 0.45);
  outline: none;
}
.session-status-edit-input {
  font-family: var(--font-mono, monospace);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.3px;
  width: 52px;
  padding: 1px 6px;
  border-radius: 5px;
  border: 1px solid var(--text-dark);
  background: rgba(255, 255, 255, 0.85);
  color: var(--text-dark);
}
.session-live-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 800;
}
.session-live-timer {
  font-family: var(--font-mono, monospace);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.3px;
  padding: 1px 6px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.28); /* chip keeps the countdown legible on any accent */
} /* Card title stays one neutral color regardless of the card's temporal state (past/live/future)
   or theme — only the status bar beneath it carries the past/future tint now. */
.session-card-title {
  color: inherit;
  font-size: 13px;
}
/* Card heading row: time badge, title, edit button — from sessionCard.js's buildSessionCardInfoHTML. */
.session-card-header-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 1px;
}
/* .badge already sets font-size: 11px — chained with .badge here to win over that on specificity. */
.badge.session-card-time-badge {
  font-size: 10px;
  padding: 2px 6px;
  font-weight: 700;
  font-family: monospace;
}
.session-card-edit-btn {
  margin-left: auto;
  padding: 2px 6px;
  font-size: 11px;
}
.session-card-meta-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.3;
}
.session-card-capacity {
  color: var(--primary);
  font-weight: 600;
}
/* Small inline icon shared by the meta row's participant/programme lines (fa-users, fa-clipboard-list). */
.session-card-icon {
  margin-right: 4px;
  font-size: 10px;
}
.session-card-injury-icon {
  margin-left: 4px;
  font-size: 10px;
  color: var(--danger); /* was the literal #ef4444, midnight's --danger */
}
.session-card-dot-sep {
  opacity: 0.45;
}
.session-warning-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: color-mix(in srgb, var(--danger) 10%, transparent); /* was rgba(239,68,68,0.1), midnight's --danger */
  color: var(--danger); /* was the literal #ef4444 */
  border: 1px solid color-mix(in srgb, var(--danger) 20%, transparent); /* was rgba(239,68,68,0.2) */
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 700;
}
.session-warning-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 4px;
} /* --- SESSIONS DAY TITLE BAR --- */
/* Home view title bar. The "Sessions Schedule" label (.view-title-label) is the conceptual view
   title on the left; the Today and expand controls (rendered by sessionTimeline.js into
   #sessions-date-picker) sit on the right. The flush, flat-bar look + grab handle come from
   .view-titlebar; override .section-title's 24px top margin. */
/* Two rows in one sticky header: the title with the day controls, then the filters.
   The bar itself is therefore a COLUMN — .section-title makes it a flex row, and that row moved
   down into .sessions-title-row. */
.sessions-title-bar {
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  margin-top: 0;
}
/* The title and the day buttons. Fixed-size, so the filters beside them (above 600px) get whatever
   width is left. */
.sessions-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
  flex: 0 0 auto;
}

/* Wide enough for one line: the header stops stacking and everything this screen offers — the title
   and the three filters — sits on a single row (asked 2026-09-11). Below this it stacks, because
   measured at 390px the one-row version wrapped into three.

   Measured against THE HEADER'S OWN WIDTH, not the window's (fixed 2026-09-21). This was a
   `@media (min-width: 600px)` query, and on a desktop the board is a 480px column beside the other
   views: the window was 1440px, the header said "plenty of room", and the three chips landed on two
   rows — Datumi and Stranka at y=75, Lokacija at y=112, in a header grown to 99px. A component
   asked about the screen it was on instead of the space it had. The container is the view, because a
   container query styles what is INSIDE the container and never the container itself. */
#view-clients {
  container-type: inline-size;
  container-name: sessions-view;
}
@container sessions-view (min-width: 560px) {
  .sessions-title-bar {
    flex-direction: row;
    align-items: center;
    gap: 12px;
  }
}
.sessions-date-picker {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 1 auto;
  min-width: 0;
}
/* "Today" reset control: jumps the deck back to today. Always occupies its slot (disabled while
   already on today) so the stepper's width — and therefore the arrows — never shift. */
.sessions-today-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 34px;
  padding: 0 12px;
  white-space: nowrap;
  border-radius: 999px;
  background: transparent;
  border: 1px solid var(--border-color);
  color: var(--text-main);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: all 0.2s ease;
}
.sessions-today-btn:hover:not(:disabled) {
  background: var(--border-color);
  color: var(--primary);
  border-color: var(--primary);
}
.sessions-today-btn:disabled {
  opacity: 0.35;
  cursor: default;
}
/* Desktop shows the text label; the icon takes its place only on phones (see mobile query). */
.sessions-today-btn > i {
  display: none;
}
.sessions-nav-arrow {
  flex: 0 0 auto;
  width: 36px;
  height: 34px;
  border-radius: 999px;
  background: transparent;
  border: 1px solid var(--border-color);
  color: var(--text-main);
  font-size: 13px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}
.sessions-nav-arrow:hover:not(:disabled) {
  background: var(--border-color);
  color: var(--primary);
  border-color: var(--primary);
}
.sessions-nav-arrow:disabled {
  opacity: 0.25;
  cursor: default;
}
/* --- OVERLAPPING SESSIONS ---
   sessionsView.js wraps a run of sessions that overlap in time in one block. Two lanes sit side by
   side, each card in its lane's column and pushed down by the minutes between the block's first
   start and its own (1px a minute, at most 64px, so a block never grows by more than that). Three
   or more lanes would leave each card under 90px of text at 390px, so the block stacks them full
   width and every card carries a .session-overlap-note naming the times it overlaps. */
.sessions-overlap-block {
  display: grid;
  gap: 0 8px;
}
.sessions-overlap-block.side-by-side {
  grid-template-columns: repeat(var(--lane-count), minmax(0, 1fr));
  align-items: start;
}
.sessions-overlap-block.side-by-side > .session-card {
  grid-row: 1;
  grid-column: calc(var(--lane) + 1);
  margin-top: min(calc(var(--start-offset) * 1px), 64px);
  min-width: 0;
}
.sessions-overlap-block.stacked {
  grid-template-columns: minmax(0, 1fr);
}
.session-overlap-note {
  margin-top: 2px;
  font-size: 11px;
  color: var(--warning);
  overflow-wrap: anywhere;
}
@media (max-width: 600px) {
  /* Narrow columns: let the time and title wrap and give the status bar room, never an ellipsis. */
  .sessions-overlap-block.side-by-side > .session-card {
    padding-left: 8px;
    padding-right: 8px;
  }
  .sessions-overlap-block.side-by-side .session-live-bar {
    margin-left: -8px;
    margin-right: -8px;
    flex-wrap: wrap;
  }
}
/* --- SESSIONS TIMELINE (continuous, time-ordered) --- */
.sessions-timeline {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  box-sizing: border-box;
}
.sessions-day-group {
  display: flex;
  flex-direction: column;
}
.sessions-day-group-header,
.sessions-day-group-footer {
  z-index: 2;
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 4px;
  background: var(--bg-color);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 700;
  color: inherit;
  cursor: pointer;
}
.sessions-day-group-header:hover,
.sessions-day-group-footer:hover {
  color: var(--primary);
}
.sessions-day-group-header {
  /* Sticks relative to #main-content, the page's real scrolling ancestor — the timeline itself
     has no overflow of its own, so the whole dashboard scrolls as one native page. The offset
     (kept live by sessionTimeline.js's ResizeObserver) is the "Sessions" title bar's own height —
     at top:0 this header would sit exactly under that title bar and be painted over by it (the
     title bar's z-index is higher), so the focused day/date line would vanish while scrolling. */
  position: sticky;
  top: var(--sessions-header-sticky-top, 64px);
  margin-bottom: 6px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
/* Sticks to the bottom of the viewport while this group's cards are still below it, previewing the
   NEXT day (sessionsView.js fills in its content — the successor's weekday/date, not this group's
   own) so a trainer scrolling through a long day always knows what's coming up next, clearing the
   fixed notification-handle bar the same way #main-content's own bottom padding already does
   (notificationArea.css / index.css).
   `bottom` is negative: `position: sticky` resolves its offset against the PADDING-BOX edge of the
   nearest scrolling ancestor (#main-content), which sits --main-content-bottom-gap ABOVE the true
   scrollport edge because of that element's own bottom padding (padding-bottom there is
   notif-handle-height + safe-bottom + that gap). Left as plain var(--notif-handle-height), the
   footer stuck the gap's-worth of extra distance above the bar instead of flush against it
   (measured: 80px above the bar instead of 56px, exactly the 24px gap over-counted). Negating just
   the gap here cancels that surplus algebraically regardless of notif-handle-height's own value:
   padding_bottom(H+S+G) + this_offset(-G) = H+S, i.e. flush with the bar, every time. */
.sessions-day-group-footer {
  position: sticky;
  bottom: calc(-1 * var(--main-content-bottom-gap, 24px));
  margin-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
/* The footer previews its successor day — redundant the instant that day's OWN header is genuinely
   on screen (now there's a real header saying the same thing one edge over). sessionTimeline.js's
   observeGroupFooterVisibility toggles this class from an IntersectionObserver watching every
   header bar, hiding the PRECEDING group's footer for as long as its successor's header is visible
   — visibility (not display) so the footer keeps its layout box/sticky behaviour and only
   disappears from view + the tap target + a11y tree while it would otherwise duplicate that header. */
.sessions-day-group-footer.next-header-visible {
  visibility: hidden;
}
.sessions-day-group-header .sessions-day-group-date,
.sessions-day-group-footer .sessions-day-group-date {
  font-weight: 400;
  color: var(--text-muted);
}
.sessions-day-group-today-tag {
  flex: 0 0 auto;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--primary);
  border: 1px solid color-mix(in srgb, var(--primary) 40%, transparent);
  border-radius: 999px;
  padding: 1px 6px;
}
@media (max-width: 600px) {
  /* Phones keep the "Sessions" label and the day controls on a single row (no wrap). The FILTERS
     stay on their own row underneath at every width — chips wrap, and squeezing them in beside the
     title would be the "ran out of view" problem .filter-chips already exists to avoid. */
  .sessions-title-row {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    flex-wrap: nowrap;
    gap: 8px;
  }
  .sessions-date-picker {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex: 0 0 auto;
    width: auto;
    min-width: 0;
    gap: 6px;
  }
  /* Icon-only Today button reclaims width on narrow screens */
  .sessions-today-btn {
    width: 36px;
    height: 36px;
    padding: 0;
    font-size: 15px;
  }
  .sessions-today-btn > i {
    display: inline;
  }
  .sessions-today-btn .today-btn-label {
    display: none;
  } /* Sweaty-hands tap target: wide enough to hit without looking */
  .sessions-nav-arrow {
    width: 38px;
    height: 36px;
  } /* Stack card contents into a single column so times and names stop wrapping mid-word */
  .session-card {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  .session-card .btn {
    width: 100%;
    justify-content: center;
    padding-top: 10px;
    padding-bottom: 10px;
  }
  .sessions-day-group-header,
  .sessions-day-group-footer {
    padding: 6px 2px;
  } /* Combo active set row mobile adjustments */
  .active-set-row[data-ex-id] {
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 10px !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
    padding-bottom: 12px !important;
    margin-bottom: 6px;
  }
  .active-set-row[data-ex-id] > div:first-child {
    width: 100% !important;
    margin-bottom: 2px;
  }
  .active-set-row[data-ex-id] .stepper-control-group {
    margin-bottom: 2px;
  }
  .active-set-row[data-ex-id] .set-check-col {
    margin-left: auto !important;
  }
}

/* Floating Action Button (Create Session) — stays visible while scrolling the sessions list */
/* Fixed elements are pinned to the VIEWPORT, but the app is a centred column of --app-max-width.
   Offsetting from the viewport edge therefore throws them far outside the app on a wide screen
   (measured 464px clear of it at 1440px). This keeps the inset on a phone, where the column fills
   the viewport, and follows the column's own edge once the screen is wider than it. */
.floating-action-btn {
  position: fixed;
  bottom: calc(72px + var(--safe-bottom));
  right: max(16px, calc((100vw - var(--app-max-width, 480px)) / 2 + 16px));
  z-index: 120;
  border-radius: 9999px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  padding: 12px 20px;
  font-weight: 600;
}
.floating-action-btn:hover {
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
}

/* Integrity error page — a blocking overlay above everything (z-index tops the stack) shown when the
   service worker cannot verify a build. Theme-aware via the shared surface/text vars, with a danger
   accent, so it reads correctly in every theme. */
