/*
 * Video browse ("Quiet Gallery") and watch ("Single Focus") surfaces.
 *
 * Static design-prototype pass for #309/#316 (see routes.swift for the
 * TEMPORARY fixture-backed routes this styles). Scoped to .videos-*,
 * .watch-*, and .video-tile* classes — deliberately not reusing
 * .course-card/.course-grid from site.css/library.css (tracked duplication
 * in #328; those are fixed 160px-height thumbnails, not aspect-ratio-locked,
 * and not a clean base for a 16:9 video card). The video player itself
 * reuses the existing .video-frame chrome from video-player.css — do not
 * duplicate that here.
 *
 * The browse-grid card class is named .video-tile, not .video-card:
 * video-player.css already defines .video-card as the single-player
 * wrapper (padding/max-width/centering for one player, not a grid item).
 * An earlier pass named the grid card .video-card too, and the two rules
 * silently combined — the player wrapper's `margin-left/right: auto`
 * pulled every grid tile out of stretch alignment into shrink-to-fit
 * sizing, producing uneven card widths across a row. Do not reintroduce
 * that name here; grep Public/css/*.css for a class name before adding it.
 *
 * All colors reference the CSS custom properties defined in site.css :root
 * so both surfaces track light/dark mode automatically.
 */

/* ---------------------------------------------------------------------
   Shared
   --------------------------------------------------------------------- */

.watch-container {
  max-width: 888px; /* matches video-player.css's .video-card 500px-tall 16:9 cap */
  margin: 0 auto;
  padding: 40px 20px 64px;
}

/* .videos-container renders nested inside the library sidebar shell's
   .main-content (issue #412 prep) — .main-content already supplies its own
   horizontal padding and .library-container already caps the shell's
   overall width to 1200px. An outer max-width/margin:auto/full horizontal
   padding here would stack on top of that and double the insets, the same
   way library/course.leaf's own content relies on .main-content alone
   rather than bringing its own outer container padding. Keep only the
   vertical breathing room the grid still needs (.videos-header already
   has its own bottom margin, so the top value here is modest). */
.videos-container {
  padding: 0 0 24px;
}

/* ---------------------------------------------------------------------
   Browse page — "Quiet Gallery"
   --------------------------------------------------------------------- */

.videos-header {
  text-align: center;
  margin-bottom: 40px;
}

.videos-eyebrow {
  margin: 0 0 8px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-primary);
}

.videos-header h1 {
  margin: 0 0 12px;
  color: var(--text-primary);
  font-size: 2.25rem;
}

.videos-subhead {
  margin: 0 auto;
  max-width: 46em;
  color: var(--text-secondary);
}

/* Column count follows the grid's own available width (auto-fill/minmax),
   not fixed viewport-width breakpoints — issue #412 prep nests this grid
   inside the library sidebar shell, where a fixed 240px sidebar (desktop
   only, library.css) eats into the viewport width the old breakpoints
   assumed was fully available. Matches .course-grid's existing
   container-relative pattern in library.css, the established precedent
   for a grid living inside this same shell. */
.videos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 28px;
}

.video-tile {
  display: block;
  /* Matches .video-frame's 20px corner radius (video-player.css) so
     primary cards and the player read as the same shape language. The
     thumbnail's top corners follow automatically via this overflow:
     hidden — no separate radius needed on .video-tile-thumb. */
  border-radius: 20px;
  overflow: hidden;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  color: inherit;
  text-decoration: none;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.video-tile:hover,
.video-tile:focus-visible {
  transform: translateY(-4px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
}

.video-tile:focus-visible {
  outline: 2px solid var(--accent-primary);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .video-tile {
    transition: box-shadow 0.2s ease;
  }

  .video-tile:hover,
  .video-tile:focus-visible {
    transform: none;
  }
}

.video-tile-thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
}

.video-tile-thumb-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* A little hue variety across the grid so cards without real thumbnails
   don't read as one repeated tile. Purely decorative — colors still derive
   from the light/dark-aware custom properties above.

   Excludes .has-poster: once a video has a real thumbnail (#316), this
   hue-rotate would shift the actual poster image's colors, which is a
   real regression, not a decorative flourish — the filter is only for
   the gradient-placeholder cards that have no thumbnail to distort.

   Cycles on nth-child(4n+...) rather than 3n so the pattern lines up
   row-to-row when the fluid auto-fill grid above happens to land on 4
   columns (a 3n cycle against a 4-wide grid drifts diagonally by one card
   per row, which reads as a bug rather than a design choice). At other
   column counts the cycle is purely decorative variety, not meant to
   align row-to-row. Three variants plus the unmodified base gives four
   distinct looks per cycle. */
.videos-grid .video-tile:nth-child(4n+2) .video-tile-thumb:not(.has-poster) {
  filter: hue-rotate(20deg);
}

.videos-grid .video-tile:nth-child(4n+3) .video-tile-thumb:not(.has-poster) {
  filter: hue-rotate(-18deg);
}

.videos-grid .video-tile:nth-child(4n+4) .video-tile-thumb:not(.has-poster) {
  filter: hue-rotate(42deg);
}

.video-tile-duration {
  position: absolute;
  right: 8px;
  bottom: 8px;
  padding: 2px 7px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.video-tile-body {
  padding: 14px 16px 16px;
}

.video-tile-title {
  margin: 0 0 6px;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text-primary);
}

.video-tile-date {
  margin: 0;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.videos-empty-state {
  text-align: center;
  padding: 64px 20px;
  border: 1px dashed var(--border-color);
  border-radius: 14px;
}

.videos-empty-heading {
  margin: 0 0 8px;
  font-size: 1.1rem;
  color: var(--text-primary);
}

.videos-empty-subtext {
  margin: 0;
  color: var(--text-secondary);
}

.videos-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  margin: 40px 0 0;
}

.videos-pagination-link {
  color: var(--accent-primary);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
}

.videos-pagination-link:hover,
.videos-pagination-link:focus-visible {
  text-decoration: underline;
}

.videos-pagination-info {
  color: var(--text-secondary);
  font-size: 0.9rem;
}

/* ---------------------------------------------------------------------
   Watch page — "Single Focus"
   --------------------------------------------------------------------- */

.watch-eyebrow {
  margin: 0 0 10px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-primary);
}

.watch-title {
  margin: 0 0 12px;
  color: var(--text-primary);
  line-height: 1.25;
  font-size: clamp(1.6rem, 1.15rem + 1.8vw, 2.5rem);
  /* No serif/editorial heading stack exists elsewhere in the codebase
     (site.css defines only `sans-serif` on body). Scoped system-serif
     stack here per the spec's request for editorial treatment — not
     introducing this globally, and not loading a web font. */
  font-family: Georgia, 'Iowan Old Style', 'Palatino Linotype', Palatino, serif;
  font-weight: 600;
}

.watch-meta {
  margin: 0 0 24px;
  color: var(--text-secondary);
  font-size: 0.9rem;
}

.watch-meta-sep {
  margin: 0 8px;
}

.watch-player-wrap {
  margin-bottom: 28px;
}

.watch-description {
  position: relative;
}

.watch-description-clamp {
  position: relative;
  max-height: 4.8em; /* ~3 lines at line-height 1.6 */
  overflow: hidden;
  color: var(--text-secondary);
  line-height: 1.6;
  transition: max-height 0.25s ease;
}

.watch-description-clamp p {
  margin: 0 0 1em;
}

.watch-description-clamp p:last-child {
  margin-bottom: 0;
}

.watch-description-clamp:not(.is-expanded)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2.4em;
  background: linear-gradient(to bottom, transparent, var(--bg-primary));
  pointer-events: none;
}

.watch-description-clamp.is-expanded {
  max-height: 2000px;
}

.watch-description-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  padding: 4px 0;
  border: none;
  background: none;
  color: var(--accent-primary);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}

.watch-description-toggle:hover {
  text-decoration: underline;
}

.watch-description-toggle:focus-visible {
  outline: 2px solid var(--accent-primary);
  outline-offset: 2px;
}

.watch-description-toggle-icon {
  font-size: 0.8rem;
}

/* ---------------------------------------------------------------------
   Watch page — "Up Next" panel (issue #412)
   --------------------------------------------------------------------- */

/* Two-column layout: player+description on the left, an always-visible
   "Up Next" panel on the right, YouTube-style. `.watch-container` itself
   is untouched (see this file's own header comment and #412's own
   requirement — share.leaf depends on its current standalone 888px-cap
   shape) — it's simply nested as this grid's left-hand item here. Both
   overrides below are scoped to that nesting only, so share.leaf's own
   `.watch-container` usage (centered in a full-width page, no grid) is
   completely unaffected. */
.watch-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  align-items: start;
  gap: 32px;
}

.watch-layout > .watch-container {
  min-width: 0;
  /* `.watch-container`'s base rule sets `margin: 0 auto` to center itself
     in its standalone (share.leaf) usage. Inside this grid, a `width: auto`
     item with inline-axis auto margins does NOT stretch to fill its track
     (CSS Grid's default `justify-self: stretch`) — the auto margins
     absorb the leftover space instead and the item shrinks to its content
     width, confirmed via getBoundingClientRect()/getComputedStyle(): a
     772px track rendering a 246.5px-wide box with ~263px margins on each
     side. Overriding to `margin: 0` here lets the item stretch to fill
     the track normally, as grid's stretch default intends. */
  margin: 0;
}

/* Nested inside .main-content, itself capped by .library-container's
   ~1200px max-width and narrowed further by the fixed 240px library
   sidebar (library-sidebar.css) — see .videos-grid's own comment above
   for the same fixed-sidebar squeeze. Two real columns only have room to
   breathe above this breakpoint; below it, the panel stacks under the
   player instead of squeezing both into an illegibly narrow player. A
   proper fix for the available width itself is #435's job (full-width/
   theater mode), sequenced after this work, not this task's. */
@media (max-width: 1024px) {
  .watch-layout {
    grid-template-columns: 1fr;
  }
}

/* Theater mode (issue #435) — the video spans full width at the top;
   below it, metadata (left) and Up Next (right, at its original ~300px
   width) sit side by side — Up Next is a rail for "everything under the
   video," not a full-width block stacked beneath it. `display: contents`
   on .watch-container (below) lets its children (.watch-player-wrap,
   .watch-metadata) become direct grid participants without touching the
   default (non-theater) layout at all.

   Row-gap is 0, not the shared 32px column-gap: .watch-player-wrap
   already carries its own margin-bottom: 28px (below), and a nonzero
   row-gap here would double that spacing between the video row and the
   meta/upnext row.

   max-width/margin/padding here — not on .video-frame — cap the whole
   grid (video row AND meta/upnext row) at the same width, centered: the
   video's own height cap (aspect-ratio 16/9 at up to 70vh,
   video-player.css) is almost always the narrower constraint than the
   full window, so capping only the video left the row below it
   stretched to the full window width instead, with dead space next to
   the metadata text before Up Next began. Both rows sharing one capped
   container is what keeps them the same width. */
.library-page.theater-mode .watch-layout {
  grid-template-columns: minmax(0, 1fr) 300px;
  grid-template-areas:
    "video video"
    "meta  upnext";
  gap: 0 32px;
  max-width: calc(70vh * 16 / 9);
  margin: 0 auto;
  padding: 0 20px;
}

.library-page.theater-mode .watch-container {
  display: contents;
}

.library-page.theater-mode .watch-player-wrap {
  grid-area: video;
}

/* .watch-container's own padding (base rule above) disappears for
   layout purposes once it's display: contents — its children render
   with no inherited padding at all. .watch-layout's own padding (above)
   now provides that gutter for both .watch-metadata and .watch-upnext
   equally, so only the top value is still needed here — adding a
   horizontal value too would double it on this column only, offsetting
   .watch-metadata from .watch-upnext instead of aligning them. */
.library-page.theater-mode .watch-metadata {
  grid-area: meta;
  padding: 24px 0 0;
}

.library-page.theater-mode .watch-upnext {
  grid-area: upnext;
}

.watch-upnext-heading {
  margin: 0 0 16px;
  color: var(--text-primary);
  font-size: 1.1rem;
  font-weight: 600;
}

.watch-upnext-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Same .video-tile card the browse grid uses (see this file's header
   comment on why — not a second, near-duplicate card shape for the same
   data) — a vertical list of them reads fine at the panel's ~300px width
   without further overrides, apart from trimming the title down slightly
   for the narrower column. */
.watch-upnext-tile .video-tile-title {
  font-size: 0.95rem;
}

.watch-upnext-empty {
  margin: 0;
  padding: 20px;
  border: 1px dashed var(--border-color);
  border-radius: 14px;
  color: var(--text-secondary);
  font-size: 0.9rem;
  text-align: center;
}
