/* Create, Developed, and Hosted by Kustom FX Dev */
/* =====================================================================
   Creators — stylesheet
   ---------------------------------------------------------------------
   Dark-first on purpose. This is a video site: a bright page around a
   dark frame makes the frame look washed out and pulls the eye off the
   content. A light theme is still honoured for visitors who ask for one
   (prefers-color-scheme: light), but dark is the designed state.

   ⚠ There are NO inline style="" attributes anywhere in this site, which
   is what lets .htaccess ship style-src 'self' with no 'unsafe-inline'.
   If you add one, the CSP must be relaxed or it silently will not apply.
   Values that must change at runtime go through CSS custom properties
   set from JS (element.style.setProperty), which CSP permits.
   ===================================================================== */

/* ---------- Font ----------
   One variable file covers 100-900, so weights cost nothing extra.
   font-display: swap — text is readable immediately rather than
   invisible while 48KB downloads. */
@font-face {
  font-family: "InterVar";
  src: url("/assets/fonts/inter-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ---------- Design tokens ---------- */
:root {
  --bg:            #0b0d10;
  --bg-raised:     #14171c;
  --bg-hover:      #1c2027;
  --surface-line:  #262b33;

  --text:          #f2f4f7;
  --text-muted:    #9aa3af;
  --text-faint:    #6b7480;

  --accent:        #ff4d3d;
  --accent-hover:  #ff6a5c;
  --accent-ink:    #ffffff;
  --live:          #ff2d20;

  --radius:        14px;
  --radius-sm:     8px;
  --shell:         1240px;
  --gap:           24px;
  --header-h:      64px;

  --shadow:        0 10px 30px rgba(0, 0, 0, .45);
  --focus:         0 0 0 3px rgba(255, 77, 61, .55);

  color-scheme: dark;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg:           #ffffff;
    --bg-raised:    #f4f5f7;
    --bg-hover:     #e9ebef;
    --surface-line: #dfe2e7;
    --text:         #10131a;
    --text-muted:   #5a626e;
    --text-faint:   #808894;
    --accent-ink:   #ffffff;
    --shadow:       0 10px 30px rgba(0, 0, 0, .12);
    color-scheme: light;
  }
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "InterVar", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img, video { max-width: 100%; display: block; }

/* The browser's own [hidden] rule is a plain attribute selector, so ANY
   class that sets `display` outranks it and the element stays visible.
   That bit us for real: the viewer-count badge is .status-badge
   { display: inline-flex }, and it rendered as an empty pill next to the
   LIVE badge on every stream. Anything toggled with .hidden = true in JS
   depends on this rule, so keep it above the component styles. */
[hidden] { display: none !important; }

a { color: inherit; text-decoration: none; }
a:hover { color: var(--accent); }

h1, h2, h3 { line-height: 1.2; margin: 0; font-weight: 700; letter-spacing: -.02em; }

:focus-visible {
  outline: none;
  box-shadow: var(--focus);
  border-radius: var(--radius-sm);
}

/* Screen-reader-only text: present for assistive tech, invisible on screen. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Keyboard users get a way past the nav on every page. */
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 100;
  background: var(--accent); color: var(--accent-ink);
  padding: 10px 16px; border-radius: var(--radius-sm); font-weight: 600;
  transition: top .15s ease;
}
.skip-link:focus { top: 12px; color: var(--accent-ink); }

/* The page gutter. ⚠ .shell is applied to the SAME element as .hero,
   .section, .watch, .live-page, .browse and .prose — so any of those
   setting the `padding` SHORTHAND silently resets this 20px gutter to
   zero. It is invisible on desktop (the max-width leaves margin anyway)
   and flush to the screen edge on a phone. Use padding-block in those
   rules, never padding. */
.shell { max-width: var(--shell); margin: 0 auto; padding: 0 20px; }

/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  height: var(--header-h);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--surface-line);
}
.site-header .shell {
  height: 100%; display: flex; align-items: center; gap: 28px;
}

.wordmark {
  font-weight: 800; font-size: 1.15rem; letter-spacing: -.03em;
  display: inline-flex; align-items: center; gap: 9px; flex-shrink: 0;
}
.wordmark:hover { color: var(--text); }
.wordmark .mark {
  width: 26px; height: 26px; border-radius: 7px;
  background: var(--accent);
  display: grid; place-items: center; flex-shrink: 0;
}
.wordmark .mark svg { width: 13px; height: 13px; fill: var(--accent-ink); }

.site-nav { display: flex; gap: 4px; margin-left: auto; align-items: center; }
.site-nav a {
  padding: 8px 14px; border-radius: 999px;
  color: var(--text-muted); font-weight: 500; font-size: .94rem;
  transition: background .15s ease, color .15s ease;
}
.site-nav a:hover { background: var(--bg-hover); color: var(--text); }
.site-nav a[aria-current="page"] { background: var(--bg-raised); color: var(--text); }

/* The header live pill is hidden until the poller confirms a stream is up,
   so an offline site never advertises a dead link. */
.live-pill {
  display: none; align-items: center; gap: 7px;
  padding: 7px 14px 7px 11px; border-radius: 999px;
  background: var(--live); color: #fff; font-weight: 700;
  font-size: .8rem; letter-spacing: .04em; text-transform: uppercase;
}
.live-pill:hover { color: #fff; filter: brightness(1.08); }
.live-pill.is-live { display: inline-flex; }
.live-pill .dot {
  width: 8px; height: 8px; border-radius: 50%; background: #fff;
  animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* ---------- Hero ---------- */
.hero { padding-block: 44px 8px; }
.hero-inner {
  display: grid; grid-template-columns: 1.35fr 1fr;
  gap: 40px; align-items: center;
}
.hero-art {
  position: relative; border-radius: var(--radius); overflow: hidden;
  background: var(--bg-raised); box-shadow: var(--shadow);
  aspect-ratio: 16 / 9;
}
.hero-art img { width: 100%; height: 100%; object-fit: cover; }
.hero-eyebrow {
  color: var(--accent); font-weight: 700; font-size: .8rem;
  letter-spacing: .11em; text-transform: uppercase; margin: 0 0 12px;
}
.hero h1 { font-size: clamp(1.9rem, 4vw, 3rem); margin-bottom: 14px; }
.hero p.lede { color: var(--text-muted); font-size: 1.05rem; margin: 0 0 24px; }
.hero-meta {
  display: flex; gap: 14px; color: var(--text-faint);
  font-size: .88rem; margin-bottom: 24px; flex-wrap: wrap;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 12px 24px; border-radius: 999px; border: 1px solid transparent;
  font-weight: 650; font-size: .96rem; cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.btn svg { width: 15px; height: 15px; fill: currentColor; }
.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { background: var(--accent-hover); color: var(--accent-ink); }
.btn-ghost { border-color: var(--surface-line); color: var(--text); }
.btn-ghost:hover { background: var(--bg-hover); color: var(--text); }

/* ---------- Live banner (home page) ---------- */
.live-banner {
  display: none; align-items: center; gap: 18px; flex-wrap: wrap;
  margin: 28px 0 0; padding: 18px 22px;
  border: 1px solid var(--live); border-radius: var(--radius);
  background: color-mix(in srgb, var(--live) 12%, var(--bg));
}
.live-banner.is-live { display: flex; }
.live-banner .badge {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--live); color: #fff; font-weight: 700; font-size: .74rem;
  letter-spacing: .07em; text-transform: uppercase;
  padding: 5px 11px; border-radius: 999px;
}
.live-banner .badge .dot {
  width: 7px; height: 7px; border-radius: 50%; background: #fff;
  animation: pulse 2s ease-in-out infinite;
}
.live-banner .txt { font-weight: 600; }
.live-banner .btn { margin-left: auto; }

/* ---------- Sections ---------- */
.section { padding-block: 44px; }
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; margin-bottom: 22px;
}
.section-head h2 { font-size: 1.4rem; }
.section-head p { margin: 4px 0 0; color: var(--text-muted); font-size: .92rem; }
.section-head a { color: var(--text-muted); font-size: .9rem; font-weight: 600; white-space: nowrap; }
.section-head a:hover { color: var(--accent); }

/* ---------- Card grid ---------- */
.grid {
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
}

/* A series row scrolls sideways instead of wrapping, so a long-running
   series does not push the rest of the page off the screen. */
.row {
  display: grid; gap: var(--gap);
  grid-auto-flow: column; grid-auto-columns: minmax(272px, 300px);
  overflow-x: auto; scroll-snap-type: x proximity;
  padding-bottom: 10px; scrollbar-width: thin;
}
.row > * { scroll-snap-align: start; }

.card { display: block; }
.card-thumb {
  position: relative; border-radius: var(--radius); overflow: hidden;
  background: var(--bg-raised); aspect-ratio: 16 / 9; margin-bottom: 11px;
}
.card-thumb img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .35s ease, opacity .2s ease;
}

/* Lift the poster above the .fallback caption underneath it.
   ⚠ DOM order is not enough here: .fallback is position:absolute and the
   image is not, and a positioned element paints above a static one no
   matter which comes first. Without this the fallback title is stamped
   across every thumbnail that DOES load — invisible while the posters
   were missing, glaring the moment they arrived. */
.card-thumb img, .hero-art img { position: relative; z-index: 1; }
.card:hover .card-thumb img { transform: scale(1.045); }

/* Poster fallback. A missing image file leaves an empty grey box with no
   hint of what it was; this keeps the title readable instead. It sits
   UNDER the poster and is simply covered when one loads — and app.js
   removes a broken <img> outright, or the browser's own broken-image icon
   would be painted on top of this.
   Not scoped to .card-thumb: the hero uses the same fallback inside
   .hero-art, and scoping it to cards left the hero's text jammed against
   the top-left corner of the frame. */
.fallback {
  position: absolute; inset: 0; display: grid; place-items: center;
  padding: 16px; text-align: center; color: var(--text-faint);
  font-weight: 600;
}
.card-thumb .fallback { font-size: .82rem; }
.hero-art .fallback  { font-size: 1rem; }

/* z-index 2 puts the badge above the poster (z-index 1), which is itself
   above the .fallback caption (z-index auto). Three layers in one box, and
   the order only holds because all three are stated explicitly. */
.card-duration {
  position: absolute; right: 8px; bottom: 8px; z-index: 2;
  background: rgba(0, 0, 0, .82); color: #fff;
  font-size: .76rem; font-weight: 600; font-variant-numeric: tabular-nums;
  padding: 2px 7px; border-radius: 5px;
}
.card h3 {
  font-size: .99rem; font-weight: 620; margin-bottom: 5px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.card .meta { color: var(--text-faint); font-size: .84rem; }
.card .meta span + span::before { content: "·"; margin: 0 7px; }

/* ---------- Watch page ---------- */
.watch { padding-block: 26px 60px; }
.watch-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 36px; }

.player-frame {
  border-radius: var(--radius); overflow: hidden;
  background: #000; aspect-ratio: 16 / 9; box-shadow: var(--shadow);
}
.player-frame video { width: 100%; height: 100%; }

.watch-title { font-size: 1.6rem; margin: 22px 0 10px; }
.watch-meta {
  display: flex; gap: 14px; flex-wrap: wrap;
  color: var(--text-faint); font-size: .9rem; margin-bottom: 18px;
}
.watch-desc {
  color: var(--text-muted); white-space: pre-wrap;
  padding-top: 18px; border-top: 1px solid var(--surface-line);
}
.watch-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 18px; }

.upnext h2 { font-size: 1.05rem; margin-bottom: 16px; }

/* Side-by-side thumbnail and text. Every cell is placed EXPLICITLY: the
   card has three children (thumb, title, meta), so with only
   grid-template-columns they auto-flow as [thumb][title] on row 1 and
   [meta][ ] on row 2 — which put the meta line underneath the thumbnail
   instead of beside it. The thumbnail spans both rows; the text stacks in
   column two. */
.upnext .card {
  display: grid;
  grid-template-columns: 152px 1fr;
  grid-template-rows: auto auto;
  column-gap: 12px;
  margin-bottom: 16px;
}
.upnext .card-thumb {
  grid-area: 1 / 1 / 3 / 2;
  align-self: start;      /* keep the 16:9 box rather than stretching it
                             to whatever height the text happens to be */
  margin-bottom: 0;
}
.upnext .card h3   { grid-area: 1 / 2 / 2 / 3; font-size: .9rem; }
.upnext .card .meta { grid-area: 2 / 2 / 3 / 3; align-self: start; }

/* ---------- Live page ---------- */
.live-page { padding-block: 26px 60px; }
.live-head { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; flex-wrap: wrap; }
.live-head h1 { font-size: 1.7rem; }

.status-badge {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 13px; border-radius: 999px;
  font-size: .78rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  background: var(--bg-raised); color: var(--text-muted);
  border: 1px solid var(--surface-line);
}
.status-badge .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint); }
.status-badge.is-live { background: var(--live); color: #fff; border-color: var(--live); }
.status-badge.is-live .dot { background: #fff; animation: pulse 2s ease-in-out infinite; }

.offline-card {
  border: 1px solid var(--surface-line); border-radius: var(--radius);
  background: var(--bg-raised); padding: 30px; margin-top: 26px;
}
.offline-card h2 { font-size: 1.15rem; margin-bottom: 10px; }
.offline-card p { color: var(--text-muted); margin: 0 0 20px; }
.schedule { list-style: none; margin: 0; padding: 0; }
.schedule li {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  padding: 13px 0; border-top: 1px solid var(--surface-line);
}
.schedule .when { font-weight: 620; }
.schedule .what { color: var(--text-muted); }

/* ---------- Browse ---------- */
.browse { padding-block: 34px 60px; }
.browse h1 { font-size: 1.9rem; margin-bottom: 8px; }
.browse .lede { color: var(--text-muted); margin: 0 0 26px; }
.filters { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 30px; align-items: center; }
.search-field {
  flex: 1 1 260px; max-width: 380px;
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-raised); border: 1px solid var(--surface-line);
  border-radius: 999px; padding: 9px 17px;
}
.search-field svg { width: 15px; height: 15px; fill: var(--text-faint); flex-shrink: 0; }
.search-field input {
  border: 0; background: none; color: var(--text);
  font: inherit; font-size: .94rem; width: 100%; outline: none;
}
.search-field:focus-within { box-shadow: var(--focus); }

.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chip {
  padding: 8px 16px; border-radius: 999px; cursor: pointer;
  background: var(--bg-raised); border: 1px solid var(--surface-line);
  color: var(--text-muted); font: inherit; font-size: .89rem; font-weight: 550;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.chip:hover { background: var(--bg-hover); color: var(--text); }
.chip[aria-pressed="true"] {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink);
}

.empty {
  text-align: center; padding: 64px 20px; color: var(--text-muted);
  border: 1px dashed var(--surface-line); border-radius: var(--radius);
}
.empty strong { display: block; color: var(--text); margin-bottom: 6px; font-size: 1.05rem; }

/* ---------- Prose (About, 404) ---------- */
.prose { max-width: 68ch; padding-block: 44px 60px; }
.prose h1 { font-size: 2rem; margin-bottom: 18px; }
.prose h2 { font-size: 1.2rem; margin: 34px 0 10px; }
.prose p { color: var(--text-muted); }
.prose a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--surface-line);
  padding: 34px 0; margin-top: 30px;
  color: var(--text-faint); font-size: .88rem;
}
.site-footer .shell { display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.site-footer nav { display: flex; gap: 18px; flex-wrap: wrap; }
.site-footer a:hover { color: var(--accent); }

/* ---------- Responsive ---------- */
@media (max-width: 960px) {
  .hero-inner { grid-template-columns: 1fr; gap: 26px; }
  .hero-art { order: -1; }
  .watch-grid { grid-template-columns: 1fr; gap: 30px; }
}

@media (max-width: 620px) {
  .site-header .shell { gap: 12px; }
  .site-nav { gap: 0; }
  .site-nav a { padding: 8px 10px; font-size: .88rem; }
  .wordmark span { display: none; }   /* mark only; the nav needs the room */
  .hero { padding-block: 28px 0; }
  .section { padding-block: 32px; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 18px; }
  .live-banner .btn { margin-left: 0; width: 100%; }
  .upnext .card { grid-template-columns: 128px 1fr; }
}

/* Honour a reduced-motion preference: kill the decorative movement,
   keep the live dot legible by holding it at full opacity. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .card:hover .card-thumb img { transform: none; }
}
