/* vrc.dj TV's guide, /tv/guide (views/tv_guide.php, tv-guide.js;
   _specs/vrcdj-tv.md 10.8): channels down, time across, each set a block as
   wide as it is long.

   The markup speaks in minutes from the window's start - a block's --s and
   --d, a tick's --m, the now line's --m - and --epg-ppm is how many pixels a
   minute takes here, so one drawing serves a phone and a desktop. The frame
   scrolls both ways inside the viewport (the room the player takes left
   free, --pb-room): the ruler stays on top and the channels on the left while
   it does. A row wears its channel's colours (tv_channel_style()), --tv-tone
   and the ink tv.css derives from it. The red of the now line is a TV
   guide's own, the same in both themes. */

.epg { --epg-ch: 236px; --epg-ppm: 4px; --epg-row: 60px; --epg-ruler: 42px; --epg-now: #ff3b55;
  width: min(1320px, 100% - 48px); margin: 0 auto; padding: 16px 0 24px; }

/* the head: the title, the day in view, Earlier / Now / Later, Channels */
.epg-head { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.epg-title { margin: 0; font-size: 1.6rem; font-weight: 900; letter-spacing: -.02em; color: var(--white); }
.epg-day { min-width: 10ch; font-size: .95rem; font-weight: 700; color: color-mix(in srgb, var(--text) 66%, transparent); }
.epg-sp { flex: 1; }
.epg-nav { display: flex; gap: 6px; }
.epg-go { justify-content: center; min-width: 34px; padding: 0 10px; transition: opacity .2s, border-color .15s; }
.epg-go:disabled { opacity: .35; pointer-events: none; }
.epg-go--now { color: var(--white); border-color: color-mix(in srgb, var(--epg-now) 55%, transparent); }
.epg-go--now.is-here { color: var(--text); border-color: var(--border-bright); }

/* the frame: scrolls both ways, fits the viewport */
.epg-frame { position: relative; overflow: auto; overscroll-behavior: contain; max-height: calc(100dvh - 176px - var(--pb-room, 0px));
  border: 1px solid var(--border); border-radius: 12px; background: var(--bg-elevated); scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--text) 25%, transparent) transparent; }
.epg-frame.is-panning { cursor: grabbing; user-select: none; }
.epg-frame.is-panning .epg-p, .epg-frame.is-panning .epg-ch { pointer-events: none; }
.epg-canvas { position: relative; width: calc(var(--epg-ch) + var(--epg-min) * var(--epg-ppm)); }

/* the ruler: a tick each half hour, the hour's label stronger; the line above
   the times holds the viewer's day where it turns over, and now */
.epg-ruler { position: sticky; top: 0; z-index: 5; display: flex; height: var(--epg-ruler); background: var(--bg-elevated); border-bottom: 1px solid var(--border); }
.epg-corner { position: sticky; left: 0; z-index: 2; flex: 0 0 var(--epg-ch); background: var(--bg-elevated); border-right: 1px solid var(--border); }
.epg-ticks { position: relative; flex: 1; overflow: hidden; }
.epg-tick { position: absolute; top: 0; bottom: 0; left: calc(var(--m) * var(--epg-ppm)); display: flex; align-items: flex-end; padding: 0 0 8px 7px;
  border-left: 1px solid color-mix(in srgb, var(--text) 14%, transparent); font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: color-mix(in srgb, var(--text) 72%, transparent); white-space: nowrap; }
.epg-tick--half { border-left-color: color-mix(in srgb, var(--text) 7%, transparent); font-weight: 500; color: color-mix(in srgb, var(--text) 48%, transparent); }
.epg-tick--day { border-left: 2px solid color-mix(in srgb, var(--text) 40%, transparent); }
.epg-tick-day { position: absolute; left: 7px; top: 6px; font-size: 9.5px; font-weight: 900; letter-spacing: .14em; text-transform: uppercase; color: var(--white); }
.epg-now-t { position: absolute; top: 4px; z-index: 1; left: calc(var(--m, 0) * var(--epg-ppm)); translate: -50% 0; padding: 3px 6px; border-radius: 3px;
  background: var(--epg-now); color: #fff; font-size: 11px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; white-space: nowrap; }
.epg-now-t[hidden], .epg-now[hidden] { display: none; }

/* a row: the channel's band (its logo on a phone), then its sets */
.epg-row { position: relative; display: flex; height: var(--epg-row); border-bottom: 1px solid color-mix(in srgb, var(--text) 7%, transparent);
  animation: epg-row-in .42s cubic-bezier(.2,.8,.2,1) backwards; animation-delay: calc(var(--i, 0) * 24ms); }
.epg-row:last-child { border-bottom: 0; }
.epg-ch { position: sticky; left: 0; z-index: 4; flex: 0 0 var(--epg-ch); box-sizing: border-box; display: flex; align-items: center; gap: 8px; padding: 0 10px 0 8px;
  background: var(--bg-elevated); border-right: 1px solid var(--border); text-decoration: none; }
.epg-n { flex: 0 0 22px; font-size: 14px; font-weight: 900; text-align: center; font-variant-numeric: tabular-nums; color: var(--tv-tone-ink); }
/* a card band's proportions (tv-menu.css .tvs-band), so the wordmark fits as it does there */
.epg-band { position: relative; display: block; flex: 1; aspect-ratio: 6.4; border-radius: 4px; overflow: hidden; transition: filter .15s, box-shadow .15s; }
.epg-ch:hover .epg-band { filter: brightness(1.12); box-shadow: 0 0 0 2px color-mix(in srgb, var(--tv-tone) 60%, transparent); }
.epg-ch:focus-visible { outline: none; }
.epg-ch:focus-visible .epg-band { box-shadow: 0 0 0 2px var(--tv-tone); }
.epg-logo { display: none; }
.epg-row.is-tuned .epg-ch::after { content: ''; position: absolute; left: 0; top: 10px; bottom: 10px; width: 3px; border-radius: 0 2px 2px 0; background: var(--tv-tone); }
.epg-row.is-tuned .epg-track { background-color: color-mix(in srgb, var(--tv-tone) 5%, transparent); }
.epg-track { position: relative; flex: 1; cursor: grab;
  background-image: repeating-linear-gradient(90deg, color-mix(in srgb, var(--text) 5%, transparent) 0 1px, transparent 1px calc(30 * var(--epg-ppm))); }
.epg-row:hover .epg-track { background-color: color-mix(in srgb, var(--text) 2.5%, transparent); }

/* a set */
.epg-p { position: absolute; top: 5px; bottom: 5px; left: calc(var(--s) * var(--epg-ppm) + 2px); width: max(3px, calc(var(--d) * var(--epg-ppm) - 4px));
  box-sizing: border-box; display: flex; flex-direction: column; justify-content: center; padding: 0 10px; border-radius: 6px; overflow: hidden; text-decoration: none; color: inherit;
  background: color-mix(in srgb, var(--tv-tone) 9%, var(--bg-elevated)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tv-tone) 20%, transparent);
  transition: background-color .15s, box-shadow .15s, opacity .3s; }
.epg-p:hover { background: color-mix(in srgb, var(--tv-tone) 19%, var(--bg-elevated)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tv-tone) 45%, transparent); }
.epg-p:focus-visible { z-index: 2; outline: 2px solid var(--tv-tone); outline-offset: 1px; }
.epg-p > * { position: relative; }
.epg-t { font-size: 13px; font-weight: 700; line-height: 1.3; color: var(--white); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.epg-a { font-size: 11.5px; line-height: 1.3; color: color-mix(in srgb, var(--text) 68%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.epg-k { font-size: 9.5px; font-weight: 900; letter-spacing: .12em; text-transform: uppercase; color: var(--tv-tone-ink); }
/* on air: brighter, an edge in the channel's colour, how far in, a live dot */
.epg-p.is-on { background: color-mix(in srgb, var(--tv-tone) 15%, var(--bg-elevated)); box-shadow: inset 3px 0 0 var(--tv-tone), inset 0 0 0 1px color-mix(in srgb, var(--tv-tone) 40%, transparent); }
.epg-p.is-on::before { content: ''; position: absolute; inset: 0 auto 0 0; width: var(--p, 0%); background: color-mix(in srgb, var(--tv-tone) 14%, transparent); transition: width 1s linear; }
.epg-p.is-on .epg-t::before { content: ''; display: inline-block; width: 7px; height: 7px; margin: 0 6px 1px 0; border-radius: 50%; background: var(--tv-tone); animation: epg-live 2.2s ease-in-out infinite; }
.epg-p.is-prem { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tv-tone) 55%, transparent); }
.epg-p.is-past { opacity: .5; }
.epg-p.is-past:hover, .epg-p.is-past:focus-visible { opacity: .85; }
.epg-p.is-off { opacity: .3; }

/* NIGHT BUS outside the viewer's night (tv-guide.js) */
.epg-off { position: absolute; top: 0; bottom: 0; z-index: 1; left: calc(var(--s) * var(--epg-ppm)); width: calc(var(--d) * var(--epg-ppm)); pointer-events: none;
  background: repeating-linear-gradient(-45deg, color-mix(in srgb, var(--text) 7%, transparent) 0 2px, transparent 2px 9px); display: flex; align-items: center; }
.epg-off span { position: sticky; left: calc(var(--epg-ch) + 10px); padding: 0 10px; font-size: 10px; font-weight: 900; letter-spacing: .16em; text-transform: uppercase; color: color-mix(in srgb, var(--text) 55%, transparent); white-space: nowrap; }

/* now */
.epg-now { position: absolute; top: var(--epg-ruler); bottom: 0; z-index: 3; left: calc(var(--epg-ch) + var(--m, 0) * var(--epg-ppm)); width: 2px; margin-left: -1px;
  background: var(--epg-now); pointer-events: none; transform-origin: top; animation: epg-drop .6s .25s cubic-bezier(.2,.8,.2,1) backwards; }

@keyframes epg-row-in { from { opacity: 0; translate: 10px 0; } }
@keyframes epg-drop { from { transform: scaleY(0); } }
@keyframes epg-live { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

:root[data-motion="reduce"] :is(.epg-row, .epg-now, .epg-p.is-on .epg-t::before) { animation: none; }
:root[data-motion="reduce"] :is(.epg-p, .epg-p::before, .epg-band, .epg-go) { transition: none; }

@media (max-width: 767px) {
  .epg { --epg-ch: 58px; --epg-ppm: 3px; --epg-row: 56px; --epg-ruler: 40px; width: 100%; padding: 10px 0 16px; }
  .epg-head { flex-wrap: wrap; gap: 8px 10px; padding: 0 12px; }
  .epg-title { font-size: 1.3rem; }
  .epg-day { order: 3; flex-basis: 100%; min-width: 0; font-size: .85rem; }
  .epg-channels span, .epg-channels { display: none; }
  .epg-frame { border-radius: 0; border-left: 0; border-right: 0; max-height: calc(100dvh - 160px - var(--pb-room, 0px)); }
  .epg-ch { padding: 8px; }
  .epg-n, .epg-band { display: none; }
  .epg-logo { position: relative; display: block; width: 40px; height: 40px; border-radius: 6px; overflow: hidden; }
  .epg-p { padding: 0 8px; }
  .epg-t { font-size: 12.5px; }
}
