/* activeSessionOverlay.css — the fullscreen active-session overlay shell: header/title bar,
   timer block, footer, and the overflow (⋯) menu. Extracted from index.css 2026-07-27
   (a monolithic stylesheet cannot be shared/toggled per behaviour).
   Inherits design tokens, glass-card/button/flex foundations and color scheme from index.css,
   loaded first — this file adds only what activeSessionController.js's overlay chrome owns. */

/* Fullscreen Active Workout Overlay Sheet */
.active-session-overlay {
  position: fixed;
  top: var(--hdr-height);
  left: 0;
  right: 0;
  max-width: var(--app-max-width, 480px);
  margin: 0 auto;
  /* Height tracks the *visual* viewport (dvh), not the layout viewport. With `bottom: 0`
     the overlay sized to the layout viewport, so on mobile the footer and the last exercise
     card sat behind the browser's URL bar — unreachable once an expanded card made the deck
     tall enough to reach that zone. 100vh is the fallback for browsers without dvh support. */
  height: calc(100vh - var(--hdr-height));
  height: calc(100dvh - var(--hdr-height));
  background: var(--bg-color);
  z-index: 120;
  display: flex;
  flex-direction: column;
  animation: slideUpFullscreen 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;
} /* The header and participant tabs stay pinned; the rest of the clipboard scrolls.
   Without this the overlay clips any content past the fold (tall stacks, the historical
   review panel, the Complete/Delete actions) with no way to reach it. */
.clipboard-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* A pull past the top or the bottom stays in the clipboard instead of reaching the page. */
  overscroll-behavior-y: contain;
  display: flex;
  flex-direction: column;
}
/* On a phone, a pull down at the top of the PAGE reloads it. The trainer scrolls the clipboard
   to move the active card, and a short list is at its top at once, so while the
   clipboard is open the page itself refuses to reload on a pull (asked 2026-09-13). */
html:has(#active-session-overlay:not(.hidden)) {
  overscroll-behavior-y: contain;
}
/* The room deckScrollFocus.js measures, so the last card can be scrolled up to where the first
   card rests. */
#active-exercise-scroll-deck {
  padding-bottom: var(--deck-scroll-room, 0px);
}
body:has(#active-session-overlay:not(.hidden)) .clipboard-body {
  padding-bottom: calc(var(--notif-handle-height, 92px) + var(--safe-bottom) + 24px);
}

@keyframes slideUp {
  from {
    transform: translateY(100px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

@keyframes slideUpFullscreen {
  from {
    transform: translateY(100%);
  }
  to {
    transform: translateY(0);
  }
}

/* The reverse of the slide-up open, driven by gestureController.js's slideOverlayDownThenHome
   (the grabber tap and the swipe-down close the same way). Two classes, added one reflow apart:
   is-closing freezes the overlay at its open position and drops the open animation, so the
   transition that follows has a start point instead of racing it; is-sliding-down then drives the
   close. Both stay on the element until the close finishes, and is-sliding-down must win the
   transform tie — it is declared after is-closing here for that reason. */
.active-session-overlay.is-closing {
  animation: none;
  transform: translateY(0);
}
.active-session-overlay.is-sliding-down {
  transition: transform 0.24s ease;
  transform: translateY(100%);
}
.session-title-bar {
  /* Flat-bar look (padding, divider, grab handle) comes from .view-titlebar; the client tabs
     follow immediately, so no bottom margin here. */
  gap: 16px;
  margin-bottom: 0;
} /* Countdown + the session's own controls (options menu, minimize), right-aligned in the bar. */
.session-title-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.collapse-btn {
  background: transparent;
  border: none;
  color: var(--primary);
  font-size: 18px;
  cursor: pointer;
}
.session-title-block {
  flex: 1;
  min-width: 0;
} /* h3 type comes from the unified view-title rule */
/* A primary action carrying only its glyph. The width it gives up goes to the title
   beside it — 171px to 258px for Start on a 390px phone — and the touch target is held at 44px
   rather than shrinking with the label: a control a thumb cannot hit has not been made smaller, it
   has been made worse. */
.btn-glyph {
  min-width: 44px;
  min-height: 44px;
  padding: 0 12px;
  gap: 0;
}
.btn-glyph i {
  font-size: 18px;
}
.session-title-block h3 {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Which session, then when and where. The bar's height is set by the 44px touch row
   its buttons need and the title was using 25px of it, so these two lines cost nothing — measured
   at 390 and 375: same bar height, same actions width, no overflow.

   The h3's own `nowrap` has to be lifted for the column, and `min-width: 0` repeated down the chain
   for the same reason the edit-mode title needs it: a flex item's default `min-width: auto` refuses
   to shrink below its content, which pushes text out of the bar instead of ellipsising it inside. */
.session-title-block h3:has(.clipboard-title) {
  white-space: normal;
  overflow: visible;
  /* The h3 is itself a flex item of .session-title-block, and was the one link in the chain
     without this. A merged clipboard's "Group Strength & Conditioning + Return-to-Play Rehab"
     then made it 379px wide in a 240px block, running under ▶ and ⋮. */
  min-width: 0;
}
.clipboard-title {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
  line-height: 1.2;
}
.clipboard-title > span {
  max-width: 100%;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* A merged clipboard: one dot per session, in the title line and again on the tab of each client
   in that session. Colour only helps the eye; the line's text and the tab's screen-reader text
   carry the same pairing. The four colours are theme tokens (--session-dot-N). */
.session-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid var(--card-border);
  background: var(--session-dot-0);
  box-sizing: content-box;
}
.session-dot[data-session-slot="1"] {
  background: var(--session-dot-1);
}
.session-dot[data-session-slot="2"] {
  background: var(--session-dot-2);
}
.session-dot[data-session-slot="3"] {
  background: var(--session-dot-3);
}
/* One line of the title: the dot (if any) in the bar's left margin, then the name. */
.clipboard-title > .clipboard-title-line {
  position: relative;
  overflow: visible;
}
.clipboard-title-line > .clipboard-title-name {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.clipboard-title-line > .session-dot {
  position: absolute;
  inset-inline-start: -13px;
  top: 50%;
  margin: 0;
  transform: translateY(-50%);
}
.clipboard-title-name {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0;
}
/* Last on the line and first to be cut: the gym is the least identifying thing here, and usually
   the same one every day. */
.clipboard-title-when {
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--text-muted);
}
.session-title-block p {
  font-size: 12px;
  color: var(--text-muted);
}
.session-timer-block span {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 18px;
  color: var(--primary);
}
/* The live countdown that replaces the Start button once tapped — "01h 32m" next to its clock
   icon, same shorthand the dashboard card's own timers use. */
#overlay-session-timer {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
/* The number counts down to the end of the planned slot; the word under it says so. */
.session-timer-text {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.1;
}
/* The narrowest phones (320 px): the name of the session comes before the words on the controls. The
   "Today" button keeps its glyph and its spoken label, and the countdown loses the clock glyph that
   the word "left" now makes redundant. Measured in tests/medium/test_narrow_header.py. */
@media (max-width: 360px) {
  #btn-plan-today > span,
  #overlay-session-duration-icon {
    display: none;
  }
}
.session-timer-block .session-timer-caption {
  font-family: inherit;
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
}
/* Session ran past its scheduled end without being closed: warn in amber (matches the dashboard
   card's own overtime bar, sessionsView.css) so it reads as a warning at a glance, not just a
   number that quietly went negative. */
#overlay-session-timer.overtime {
  background: var(--warning, #f59e0b);
  color: #3d2600;
  padding: 3px 10px;
  border-radius: 999px;
}
#overlay-session-timer.overtime span,
#overlay-session-timer.overtime i {
  color: #3d2600;
}
.session-overlay-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  gap: 16px;
  padding-bottom: calc(40px + var(--safe-bottom));
} /* Current Exercise Navigator */
.active-exercise-navigator {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px;
}
.nav-arrow-btn {
  background: var(--input-bg);
  border: 1px solid var(--border-color);
  color: var(--primary);
  width: 44px;
  height: 44px;
  border-radius: 50%;
}
.nav-arrow-btn:hover {
  background: var(--border-color);
}
.clipboard-empty-state {
  padding: 32px 16px;
  text-align: center;
}
.clipboard-empty-state h4 {
  font-family: var(--font-header);
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 6px;
}
.clipboard-empty-state p {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.4;
}
/* In place of an absent client's deck (activeSessionBoard.js): who is not here, what that means,
   and the way back. */
.clipboard-absent-notice {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 32px 16px;
  text-align: center;
}
.clipboard-absent-notice h4 {
  font-family: var(--font-header);
  font-size: 16px;
  font-weight: 700;
}
.clipboard-absent-notice p {
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.4;
} /* ===== Inline clipboard editor (on-the-fly plan editing) ===== */
.session-actions-footer {
  border-top: 1px solid var(--border-color);
  padding-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: auto;
}
.session-finish-row {
  display: flex;
  gap: 12px;
} /* Overflow menu in the clipboard header — home for destructive Delete Session */
.session-menu-wrap,
.app-menu-wrap {
  position: relative;
} /* First-run Terms modal is mandatory: hide its dismiss (✕) so the only exit is "I agree". */
#dialog-terms.first-run .modal-close-btn {
  display: none;
}
.session-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 180px;
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius-md);
  padding: 6px;
  z-index: 130;
  /* The app menu has grown past a phone's screen, and without this it simply ran off the bottom:
     every item below the fold was unreachable, with nothing on screen to say so. Found 2026-08-17
     when adding one item pushed #menu-terms out of the viewport and failed
     tests/medium/test_header_menu.py — the test caught a real defect that had been latent for
     several items. Capped to the space under the header and scrolled instead.

     dvh, not vh: mobile Safari's vh includes the retracted URL bar, which is exactly the strip a
     bottom item would hide behind. overscroll-behavior keeps a flick inside the menu from scrolling
     the view underneath it, which on the gym floor means the dashboard does not jump while a trainer
     reaches for the last entry. */
  max-height: calc(100dvh - var(--hdr-height, 64px) - 24px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.session-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 14px;
  background: transparent;
  border-radius: var(--border-radius-sm);
  font-size: 14px;
  font-weight: 600;
  color: var(--text-main);
  text-align: left;
  text-decoration: none;
}
.session-menu-item:hover {
  background: var(--input-bg);
}
.session-menu-item-danger {
  color: var(--danger);
}
.session-menu-item-danger:hover {
  background: var(--danger-light);
} /* FLOATING REST TIMER */

/* Active session footer adjustments — thumb-friendly on a phone. */
@media (max-width: 600px) {
  .session-finish-row {
    gap: 16px !important;
  }
  .session-finish-row button {
    flex: 1 !important;
    min-height: 48px !important;
  }
}

/* The "copy to whom" list, unfolded inside the ⋯ menu. Indented so it reads as belonging
   to the item above it rather than as three more session actions. */
.session-menu-sub {
  display: flex;
  flex-direction: column;
  border-left: 2px solid var(--primary);
  margin-left: 10px;
}
.session-menu-empty {
  margin: 0;
  padding: 8px 12px;
  font-size: 12px;
  color: var(--text-muted);
}
