/* The lesson player on the "dark & brass" watch page: the premium facade,
   the paywall, "What you'll learn", and the self-hosted player chrome that
   js/member-player.js builds. Copied from home.css (the older pages still
   use that copy), with the old tokens pinned to dark & brass values here. */
.player, .outcomes-card, .member-player {
  --space-1: .25rem; --space-2: .5rem; --space-3: .75rem; --space-4: 1rem; --space-5: 1.5rem; --space-6: 2rem;
  --step--1: .75rem; --step-0: .875rem; --step-1: 1rem; --step-2: 1.125rem;
  --radius: 8px; --radius-md: 8px; --radius-lg: 12px; --radius-pill: 999px;
  --color-accent-warm: #C9A45C; --focus: #C9A45C; --accent: #C9A45C;
  --color-semantic-success: #C9A45C; --radius-sm: 4px; --weight-medium: 500;
  --dark: #0F0D0B; --dark-ink: #F2EBDD; --accent-soft: #3A3226;
  --ink: #F2EBDD; --ink-2: #C2B8A8; --muted: #C2B8A8; --surface: #2C2824; --line: rgba(242,235,221,.12);
}
.video-card__facade {
  display: block;
  cursor: pointer;
}
.video-card__thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transform: scale(1);
  transition: transform .5s cubic-bezier(.16,1,.3,1);
}
.video-card__facade:hover .video-card__thumb,
.video-card__facade:focus-visible .video-card__thumb {
  transform: scale(1.06);
}
@media (prefers-reduced-motion: reduce) {
  .video-card__thumb,
  .video-card__link,
  .video-card__scrim,
  .video-card__caption { transition: none; }
}
.video-card__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .65);
  transition: background .15s ease, transform .3s cubic-bezier(.16,1,.3,1);
}
.video-card__play::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 54%;
  transform: translate(-50%, -50%);
  border-style: solid;
  border-width: 10px 0 10px 16px;
  border-color: transparent transparent transparent #fff;
}
.video-card__facade:hover .video-card__play,
.video-card__facade:focus-visible .video-card__play {
  background: var(--accent);
  transform: scale(1.08);
}

.video-card__badge {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  background: rgba(0, 0, 0, .7);
  color: #fff;
  border-radius: var(--radius-sm);
  padding: 0.2em 0.6em;
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
}
/* Structural default (every card, every visitor, at distill time) — the
   badge is only actually true for a visitor who isn't entitled. Once
   curriculum-overview.js confirms a real, entitled session (the same
   body[data-auth="member"] flag the curriculum path's lock icons use),
   it hides here too: an entitled member can already watch these, so the
   badge would just be wrong for them, not merely redundant. */
body[data-auth="member"] .video-card__badge { display: none; }
.video-card__paywall {
  position: relative;
  background: var(--dark);
}
/* The carried-over thumbnail sits behind the scrim, full-bleed — a locked
   video keeps looking like *that* video instead of turning into a blank
   panel the moment it's locked. */
.video-card__paywall > .video-card__thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(.75) brightness(.6);
}
.video-card__paywall-scrim {
  position: relative;
  z-index: 1;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  text-align: center;
  padding: var(--space-5);
  background: linear-gradient(180deg, rgba(15, 13, 10, .1) 0%, rgba(15, 13, 10, .82) 70%);
}
.video-card__paywall-text {
  margin: 0;
  max-width: 32ch;
  color: rgba(250, 248, 244, .88);
  font-size: var(--step-0);
}

/* --- "What you'll learn" (Video.outcomes_list, video_detail.html) -------- */
.outcomes-card {
  background: var(--accent-soft);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.outcomes-card__heading { font-size: var(--step-2); margin: 0 0 var(--space-3); }
.outcomes-card__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.outcomes-card__list li {
  position: relative; padding-left: 1.7em; font-size: var(--step-0); color: var(--ink); line-height: 1.5;
}
.outcomes-card__list li::before {
  content: ""; position: absolute; left: 0; top: .3em; width: 1.1em; height: 1.1em;
  border-radius: 50%; background: var(--accent);
}
.outcomes-card__list li::after {
  content: ""; position: absolute; left: .34em; top: .58em; width: .42em; height: .22em;
  border-left: 1.5px solid #fff; border-bottom: 1.5px solid #fff; transform: rotate(-45deg);
}

/* --- player --------------------------------------------------------------- */
/* YouTube's own player, embedded directly. Nothing to style inside it — we
   only own the frame it sits in. */
.player {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--dark);
}
.player iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
/* The premium facade (video_player_block.html) sits *inside* .player rather
   than carrying the class itself, unlike .video-card__player elsewhere —
   member-player.js needs a stable wrapper to replace only the facade's
   contents on a successful session check, without touching .player itself.
   .video-card__facade alone has no size (display:block, absolutely-
   positioned children only), so without this it collapses to zero height. */
.player > .video-card__facade {
  position: absolute;
  inset: 0;
}

/* --- self-hosted member player --------------------------------------------- */
/* static/js/member-player.js builds this once video_session succeeds — see
   its own comments for what each overlay state means. */
.member-player {
  position: absolute;
  inset: 0;
}
.member-player__video {
  width: 100%;
  height: 100%;
  display: block;
  background: var(--dark);
}
.member-player__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  background: rgba(31, 27, 22, .55);
  color: var(--dark-ink);
  text-align: center;
  padding: var(--space-4);
  pointer-events: none; /* never blocks the native controls beneath it */
}
/* [hidden] and .member-player__overlay are equal specificity (0,1,0 each);
   without this, source order alone decides, and this file's own unconditional
   `display: flex` above silently wins over the browser's native
   `[hidden] { display: none }` — member-player.js's hideOverlay() would set
   the attribute and nothing would actually happen. */
.member-player__overlay[hidden] { display: none; }
.member-player__overlay[data-state="error"] { background: rgba(31, 27, 22, .78); }
/* "playing on another device": the message sits above the big play button instead of behind it */
.member-player__overlay[data-state="elsewhere"] { background: rgba(31, 27, 22, .78); justify-content: flex-start; padding-top: 16%; }
.member-player__overlay[data-state="elsewhere"] .member-player__loader { display: none; }
.member-player__overlay[data-state="ended"] .member-player__loader { display: none; }
.member-player__overlay-text { font-size: var(--step-0); }
.member-player__loader {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  border: 3px solid rgba(250, 248, 244, .3);
  border-top-color: var(--dark-ink);
  animation: member-player-spin 0.8s linear infinite;
}
.member-player__overlay[data-state="error"] .member-player__loader { display: none; }
@media (prefers-reduced-motion: reduce) {
  .member-player__loader { animation: none; }
}
@keyframes member-player-spin {
  to { transform: rotate(360deg); }
}

/* --- custom player chrome (static/js/member-player.js) --------------------- */
.member-player:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.member-player__seek:focus-visible { outline: none; } /* the handle's own scale-up is the focus cue here */
/* Hand-built rather than the browser's native controls — see that file's own
   top comment. Motion throughout uses the same eased curve as the rest of
   the site's interactive elements, just slightly quicker (video chrome reads
   as sluggish at the site's normal transition speed). */
.member-player__big-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 4.5rem;
  height: 4.5rem;
  border: 0;
  border-radius: 50%;
  background: rgba(20, 17, 13, .55);
  color: #fff;
  backdrop-filter: blur(2px);
  cursor: pointer;
  opacity: 1;
  transform: scale(1);
  transition: opacity .18s cubic-bezier(.4,0,.2,1), transform .18s cubic-bezier(.4,0,.2,1), background .15s ease;
}
.member-player__big-play svg { width: 2rem; height: 2rem; fill: currentColor; margin-left: 2px; }
.member-player__big-play:hover { background: var(--color-accent-warm); }
.member-player--active .member-player__big-play {
  opacity: 0;
  transform: scale(.85);
  pointer-events: none;
}

.member-player__controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 1.75rem .85rem .6rem;
  background: linear-gradient(to top, rgba(15, 13, 10, .82), rgba(15, 13, 10, 0));
  opacity: 0;
  transform: translateY(4px);
  transition: opacity .2s cubic-bezier(.4,0,.2,1), transform .2s cubic-bezier(.4,0,.2,1);
  pointer-events: none;
}
.member-player--chrome-visible .member-player__controls,
.member-player:not(.member-player--active) .member-player__controls {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.member-player__seek {
  position: relative;
  height: 16px;
  display: flex;
  align-items: center;
  cursor: pointer;
  touch-action: none;
}
.member-player__seek-track {
  position: relative;
  width: 100%;
  height: 4px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, .28);
  overflow: visible;
  transition: transform .12s ease;
}
.member-player__seek:hover .member-player__seek-track { transform: scaleY(1.5); }
.member-player__seek-buffered,
.member-player__seek-played {
  position: absolute;
  inset: 0;
  border-radius: var(--radius-pill);
  width: 0%;
}
.member-player__seek-buffered { background: rgba(255, 255, 255, .3); }
.member-player__seek-played { background: var(--color-accent-warm); }
.member-player__seek-handle {
  position: absolute;
  top: 50%;
  left: 0%;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-accent-warm);
  transform: translate(-50%, -50%) scale(0);
  transition: transform .12s ease;
  box-shadow: 0 0 0 3px rgba(201, 122, 79, .25);
}
.member-player__seek:hover .member-player__seek-handle,
.member-player__seek:focus-visible .member-player__seek-handle {
  transform: translate(-50%, -50%) scale(1);
}
.member-player__seek-tooltip {
  position: absolute;
  bottom: 100%;
  transform: translateX(-50%);
  margin-bottom: .5rem;
  background: rgba(15, 13, 10, .92);
  color: #fff;
  font-variant-numeric: tabular-nums;
  border-radius: var(--radius-sm);
  white-space: nowrap;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .3rem;
  padding: .3rem;
}
/* Same trap as .reflect-form: a display rule here beat the hidden attribute,
   so the empty preview box sat on the player at rest. */
.member-player__seek-tooltip[hidden] { display: none; }

.member-player__row {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-top: .35rem;
  color: #fff;
}
.member-player__btn {
  min-width: 44px; min-height: 44px; align-items: center; justify-content: center;
  border: 0;
  background: transparent;
  color: #fff;
  padding: .3rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: inline-flex;
  opacity: .9;
  transition: opacity .15s ease, background .15s ease;
}
.member-player__btn:hover { opacity: 1; background: rgba(255, 255, 255, .12); }
.member-player__btn svg { width: 1.35rem; height: 1.35rem; fill: currentColor; }
.member-player__speed {
  font-size: var(--step--1);
  font-weight: 600;
  min-width: 2.6rem;
  padding-inline: .4rem;
}
.member-player__time {
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, .9);
  white-space: nowrap;
}
.member-player__spacer { flex: 1; }
.member-player__volume {
  width: 0;
  opacity: 0;
  transition: opacity .15s ease;
  accent-color: var(--color-accent-warm);
  cursor: pointer;
}
.member-player__mute:hover + .member-player__volume,
.member-player__volume:hover,
.member-player__volume:focus-visible {
  width: 4.5rem;
  opacity: 1;
  margin-inline: .1rem;
}

@media (prefers-reduced-motion: reduce) {
  .member-player__big-play,
  .member-player__controls,
  .member-player__seek-handle,
  .member-player__btn,
  .member-player__volume {
    transition: none;
  }
}

/* --- ambient focus mode (member-player.js) --------------------------------
   Two things happen together when a self-hosted lesson is actually playing:
   the page's own chrome recedes (nothing to do with counseling content
   should compete for attention while someone is mid-technique), and a soft
   glow — the video's own thumbnail color, sampled once, not a decorative
   pick — settled behind the frame; on dark & brass it is a plain black
   shadow instead, since a coloured glow on black reads as a stage light. Both read as "the room got quieter", not
   as a lighting effect; that's the intent for study content, not a stage. */
.player { box-shadow: 0 40px 80px -40px rgba(0,0,0,.9); }
body.watch-focus .top,
body.watch-focus .foot {
  opacity: .38;
  filter: saturate(.75);
  transition: opacity .5s ease, filter .5s ease;
}
body.watch-focus .top:hover,
body.watch-focus .top:focus-within {
  opacity: 1;
  filter: none;
}
@media (prefers-reduced-motion: reduce) {
  .player { transition: none; }
  body.watch-focus .top,
  body.watch-focus .foot { transition: none; }
}

/* --- seek bar: resume marker + filmstrip preview --------------------------
   The resume marker is real data (session.resume_seconds, the same value
   that already resumes playback on load) surfaced on the track itself, not
   an invented "chapter". The filmstrip is a genuine frame from this video —
   drawn from a second, hidden, muted playback of the same manifest — not a
   generic scrubber; member-player.js falls back to the plain time tooltip
   below if the canvas read is ever blocked (see its own comments). */
.member-player__seek-resume {
  position: absolute;
  top: 50%;
  width: 3px;
  height: 10px;
  transform: translate(-50%, -50%);
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, .55);
  pointer-events: none;
}
.member-player__seek-tooltip-frame {
  width: 120px;
  height: 67.5px;
  border-radius: var(--radius-sm);
  background: var(--dark);
  object-fit: cover;
  display: block;
}
.member-player__seek-tooltip-time {
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  padding: 0 .2rem .1rem;
}

/* --- springy control feedback ----------------------------------------------
   A small overshoot on press/release reads as physical rather than as a
   linear opacity fade — used only on the controls actually pressed, once
   each, never a looping effect. */
.member-player__btn,
.member-player__big-play {
  transition: opacity .15s ease, background .15s ease, transform .25s cubic-bezier(.16,1,.3,1);
}
.member-player__btn:active,
.member-player__big-play:active {
  transform: scale(.84);
}
.member-player--active .member-player__big-play:active {
  transform: scale(.78);
}

/* --- "up next" end card (member-player.js reads the page's own already-
   rendered .progress-continue link for this — see that file) -------------- */
.member-player__overlay[data-state="ended"] {
  background: rgba(15, 13, 10, .9);
  pointer-events: auto;
}
.member-player__up-next {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-4);
  max-width: 30rem;
  text-align: left;
}
.member-player__up-next-thumb {
  width: 6rem;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, .08);
  display: block;
  flex: none;
}
.member-player__up-next-text { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
.member-player__up-next-eyebrow {
  font-size: var(--step--1);
  color: rgba(250, 248, 244, .65);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.member-player__up-next-title {
  font-size: var(--step-1);
  font-weight: var(--weight-medium);
  color: #fff;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.member-player__up-next-ring { position: relative; width: 32px; height: 32px; flex: none; }
.member-player__up-next-ring svg { width: 32px; height: 32px; transform: rotate(-90deg); }
.member-player__up-next-ring circle { fill: none; stroke-width: 2.5; }
.member-player__up-next-ring .track { stroke: rgba(255, 255, 255, .2); }
.member-player__up-next-ring .fill { stroke: #fff; stroke-linecap: round; }
.member-player__up-next-count {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: var(--step--1); color: #fff; font-variant-numeric: tabular-nums;
}
.member-player__up-next-go { flex: none; }
.member-player__up-next-cancel {
  flex: none; background: none; border: none; color: rgba(250, 248, 244, .6);
  font-size: var(--step--1); text-decoration: underline; padding: var(--space-2);
}
.member-player__up-next-cancel:hover { color: #fff; }
@media (prefers-reduced-motion: reduce) {
  .member-player__up-next-ring .fill { transition: none !important; }
}
@media (max-width: 620px) {
  .member-player__up-next { flex-wrap: wrap; max-width: 20rem; }
}

/* Quiet member code over the picture (school/video_access.overlay_code): readable if you look, easy to ignore. */
.member-player__mark {
  position: absolute;
  z-index: 2;
  padding: 2px 6px;
  font: 600 12px/1.2 var(--font-mono, ui-monospace, monospace);
  letter-spacing: .08em;
  color: rgba(255, 255, 255, .55);
  background: rgba(0, 0, 0, .18);
  border-radius: 4px;
  pointer-events: none;
  user-select: none;
  transition: left .6s ease, top .6s ease;
}
@media (prefers-reduced-motion: reduce) { .member-player__mark { transition: none; } }
