/*
 * Prediction Slip component styles (Task 1.16). Structural/visual styling
 * only, built entirely from existing tokens - no new colors. Breakpoint
 * show/hide switches between the desktop sidecar and the mobile/tablet
 * trigger+sheet live in responsive.css, following this project's existing
 * convention (that file's own header comment already earmarks the slip
 * sidecar as an example of a component with its own tablet/desktop
 * composition). No optional-amount input or third-party wagering UI
 * exists to style here - see CLAUDE.md "Prediction Slip scope
 * correction" (Product rules) for the narrowed, deliberate scope.
 *
 * Both the desktop <aside> and the mobile offcanvas use .surface-analytical
 * (components.css) - always-navy regardless of theme, and that rule uses a
 * literal #ffffff for its own text, not a token, for exactly this reason:
 * --color-text-on-primary/--color-primary-contrast are contrast tokens for
 * whatever --color-primary currently is (navy in light theme, yellow in
 * dark theme) - correct for a button, wrong here, since this surface never
 * swaps to yellow. Every text element below that needs to sit directly on
 * the fixed-navy surface (not on a --color-surface-elevated row - see
 * .prediction-slip__row-match etc. further down, which correctly keep
 * theme-aware tokens) uses the same literal #ffffff, matching
 * .surface-analytical's own convention, rather than a token that would
 * silently go navy-on-navy in dark mode.
 */

.prediction-slip {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  color: #ffffff;
}

.prediction-slip .text-body-sm,
.prediction-slip .text-caption,
.prediction-slip .text-stat-value {
  color: #ffffff;
}

.prediction-slip__muted {
  color: var(--color-intelligence);
}

/* .btn-ghost (components.css) defaults to --color-text-primary, which is
   navy in light theme - invisible against this always-navy surface, so
   both the "Clear all" and "Browse predictions" ghost buttons need an
   explicit override here rather than relying on the shared button style. */
.prediction-slip .btn-ghost {
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.35);
}

.prediction-slip .btn-ghost:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.1);
  color: #ffffff;
}

/* ============ Desktop sticky sidecar ============
   position: fixed (not sticky) - there is no two-column page grid for any
   product page yet (out of scope for Task 1.16), so fixed gives the same
   "always visible while scrolling" effect as a self-contained island,
   without requiring a specific grid from whatever page renders it. */
.prediction-slip--desktop {
  /* Hidden below 1024px (mobile/tablet use the trigger+sheet instead) -
     shown again at the desktop breakpoint by responsive.css, following
     this project's mobile-first convention (that file's own header
     comment already earmarks the slip sidecar as an example). */
  display: none;
  position: fixed;
  top: calc(var(--touch-target-min) + var(--space-48));
  right: var(--space-24);
  bottom: var(--space-24);
  width: var(--slip-width);
  z-index: 20;
  overflow-y: auto;
  border-radius: var(--radius-slip);
  box-shadow: var(--shadow-md); /* Level 2: sticky slip */
}

.prediction-slip__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-12);
}

.prediction-slip__title {
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-semibold);
  margin: 0;
}

.prediction-slip__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
}

.prediction-slip__row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-12);
  padding: var(--space-12);
  background: var(--color-surface-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-input);
}

.prediction-slip__row-main {
  min-width: 0; /* lets the row wrap instead of overflowing a flex child */
  flex: 1;
}

/* Task 1.72A V2 (Stage 8): never truncate a slip matchup/selection with
   an ellipsis (as `.fixture-row__team-name`/`.league-card__name`/
   `.match-header__team-name`). A long team/competition name or selection
   label wraps onto another line instead; `.prediction-slip__row-main`'s
   existing `min-width: 0` above is what lets it shrink below its own
   text's min-content width. (Prediction cards are the one deliberate
   exception: on a phone their shared one-line `.matchup-row` shows a
   human-readable compact label of each club's name - see
   sports-components.css.) */
.prediction-slip__row-match,
.prediction-slip__row-selection {
  margin: 0;
  font-size: var(--font-size-body-sm);
  color: var(--color-text-primary);
  overflow-wrap: break-word;
}

.prediction-slip__row-selection {
  color: var(--color-text-secondary);
}

.prediction-slip__row-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  margin-top: var(--space-4);
}

.prediction-slip__row-confidence {
  font-size: var(--font-size-caption);
  color: var(--color-text-muted);
}

.prediction-slip__row-odds {
  font-weight: var(--font-weight-bold);
  color: var(--color-text-primary);
}

.prediction-slip__row-odds--unavailable {
  font-weight: var(--font-weight-regular);
  font-variant-numeric: normal;
  color: var(--color-text-muted);
}

/* Task 1.62 (ADR 0005): the ONE selection currently preventing
   cumulative-odds calculation - a left accent border only, never color
   alone (WCAG 2.1 AA) - the row's own "Odds unavailable" text already
   communicates the underlying reason in words. */
.prediction-slip__row--blocking {
  border-left: 3px solid var(--color-warning);
}

.prediction-slip__row-remove {
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
  min-height: 0;
  color: var(--color-text-secondary);
}

.prediction-slip__row-remove svg {
  width: 1rem;
  height: 1rem;
}

/* ============ Empty state ============ */
.prediction-slip__empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-8);
  padding: var(--space-16) 0;
}

.prediction-slip__empty-icon {
  width: 2rem;
  height: 2rem;
  color: var(--color-intelligence);
}

.prediction-slip__empty-title {
  font-size: var(--font-size-h4);
  font-weight: var(--font-weight-semibold);
  margin: 0;
}

.prediction-slip__empty-cta {
  margin-top: var(--space-8);
}

/* ============ Summary: clear all / combined odds / disclaimer ============ */
.prediction-slip__clear {
  align-self: flex-start;
}

/* Task 1.72 Group 5: Save action - .btn-secondary already carries its own
   opaque background/contrast-text pair (components.css), so it's visible
   against this surface with no override needed here, unlike .btn-ghost
   above. The anonymous login link and the post-save "View saved slips"
   link both reuse .btn-ghost and are covered by the existing override. */
.prediction-slip__save,
.prediction-slip__save-success {
  align-self: flex-start;
}

.prediction-slip__combined-odds {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-12);
  padding-top: var(--space-12);
  border-top: 1px solid rgba(255, 255, 255, 0.16);
}

/* Launch polish: when the combination cannot be shown, the word "Unavailable" reads as a quiet status at body size
   rather than a headline figure; a real combined value keeps the stat size. */
.prediction-slip__combined-odds .is-unavailable {
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-semibold);
}

.prediction-slip__disclaimer {
  font-size: var(--font-size-caption);
  margin: 0;
  color: var(--color-intelligence);
}

/* ============ Mobile/tablet persistent trigger ============ */
.prediction-slip__mobile-trigger {
  position: fixed;
  left: var(--space-16);
  right: var(--space-16);
  bottom: var(--space-16);
  z-index: 25;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  min-height: var(--touch-target-min);
  padding: var(--space-12) var(--space-16);
  background: var(--brand-navy);
  color: #ffffff;
  border: none;
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-lg); /* Level 3: mobile bottom-sheet trigger */
  font-family: var(--font-family-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}

.prediction-slip__mobile-trigger-cta {
  color: var(--brand-yellow-green);
}

/* ============ Mobile/tablet bottom sheet (Bootstrap Offcanvas) ============ */
.prediction-slip--mobile.offcanvas-bottom {
  /* Bootstrap's own `.offcanvas.offcanvas-bottom` (two classes,
     specificity 0,0,2,0) hard-codes `height: var(--bs-offcanvas-height)`
     (its default is a fixed 30vh) and `max-height: 100%` - a single-class
     `.prediction-slip--mobile { max-height: 85vh }` rule has LOWER
     specificity (0,0,1,0) and can never win regardless of source order,
     so the sheet always opened at a cramped fixed 30vh ignoring its own
     content (found during Task 1.72A V2 Stage 8: the empty state's
     title/message/CTA button were clipped below the visible fold -
     `offcanvas-body.scrollHeight` 384px vs. its actual `clientHeight` of
     only 126px at a 844px-tall viewport - reachable only via an
     unlabelled internal scroll). Matching Bootstrap's own two-class
     specificity here (never `!important`, since Bootstrap's own rule
     doesn't use it either) is what lets `height: auto` actually apply -
     the sheet now sizes itself to its real content, still bounded by
     `max-height: 85vh` so it never grows past a sensible ceiling on a
     short viewport or with many selections (the already-correct
     `overflow-y: auto` on `.offcanvas-body` remains the backstop for
     that case). */
  height: auto;
  max-height: 85vh;
  /* Flush with the viewport bottom edge - only the top corners round,
     overriding .surface-analytical's all-corner --radius-card shorthand. */
  border-radius: var(--radius-slip) var(--radius-slip) 0 0;
}

.prediction-slip--mobile .offcanvas-header {
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}

.prediction-slip--mobile .offcanvas-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
}
