*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
    /* Near-black with a faint green cast (hue 150) rather than neutral grey,
       so the dark surfaces sit in the same family as the green accent. */
    --bg-primary: #050807;
    --bg-secondary: #080d0b;
    --bg-tertiary: #0b1210;
    --text-primary: #f4f4f5;
    --text-secondary: rgba(255, 255, 255, 0.5);
    --border-color: rgba(255, 255, 255, 0.07);
    --accent-color: #00e676;
    --accent-rgb: 0, 230, 118;
    --surface: #0e1614;
    --border: rgba(255, 255, 255, 0.07);
    --live: #ff3b30;
    --text3: rgba(255, 255, 255, 0.3);
    /* Shared page gutter. Every full-width row uses this so their content
       edges always line up, whatever the viewport. Phones and tablets stay
       tight here so cards get the full screen width; desktop widens it in
       the breakpoint below. */
    --gutter: clamp(16px, 2vw, 32px);
}

/* Desktop gets a visible margin either side so the content reads as a column
   rather than running edge to edge. Deliberately capped at 80px, well below
   the original clamp(40px, 10vw, 200px) whose 10vw growth left wide empty
   bands on large screens while cards were still clipped.

   4.5vw is chosen so that at the 1024px breakpoint it evaluates to ~46px,
   just above the ~20px the tablet rule gives at that width. The small step is
   intentional: it is the point where the layout switches from "fill the
   screen" on tablets to "content column" on desktop. */
@media (min-width: 1024px) {
    :root { --gutter: clamp(46px, 4.5vw, 80px); }
}

@keyframes livepulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: .4; transform: scale(.78); }
}

.sf-btn {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    padding: 10px 18px;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.07);
    transition: all 0.2s ease;
    color: rgba(255, 255, 255, 0.5);
    font-size: 16px;
    font-weight: 500;
    text-decoration: none;
    outline: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

.sf-btn:hover {
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.5);
}

.sf-btn.active {
    background: rgba(255, 255, 255, 0.08);
    font-weight: 600;
}

.sf-btn svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.sf-btn-icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}

body {
    background: var(--bg-primary);
    color: var(--text-primary);
    font-family: 'Hanken Grotesk', -apple-system, sans-serif;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    padding-top: 0;
    overflow-x: hidden;
    width: 100%;
    position: relative;
    /* Sticky footer: main grows to fill the viewport so .footer is pushed to
       the bottom on short pages, and flows normally on long ones. */
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

#main-content {
    flex: 1 0 auto;
    /* Flex items default to min-width:auto, which lets a wide descendant
       (e.g. the category strip) push this — and the whole page — wider
       than the viewport instead of scrolling within itself. */
    min-width: 0;
    width: 100%;
}

html {
    overflow-x: hidden;
    width: 100%;
    overflow-anchor: none;
}

.navbar {
    position: sticky;
    top: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    /* Fixed height so the header is identical on every page, whether or not
       it contains the search box (which is taller than the other items). */
    height: 70px;
    padding: 0 var(--gutter);
    gap: 24px;
    background: rgba(5, 8, 7, .72);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    border-bottom: 1px solid rgba(255, 255, 255, .06);
}

.nav-main-row { display: contents; }

.nav-logo {
    display: flex;
    align-items: center;
    text-decoration: none;
    flex-shrink: 0;
}

.nav-logo-text {
    font-family: 'Archivo', sans-serif;
    font-weight: 800;
    font-size: 20px;
    letter-spacing: -.02em;
    color: #f4f4f5;
}

.logo-free { color: var(--accent-color); }

.nav-links-desktop {
    display: flex;
    gap: 26px;
    align-items: center;
    flex: 1;
    min-width: 0;
}

.nav-link {
    font-size: 14.5px;
    font-weight: 500;
    color: rgba(255, 255, 255, .5);
    text-decoration: none;
    transition: color 0.2s;
    white-space: nowrap;
}

.nav-link:hover { color: #f4f4f5; text-decoration: none; }
.nav-link.active { color: #f4f4f5; font-weight: 600; }

.vip-nav-link { color: #f5c542 !important; }
.vip-nav-link:hover { color: #ffd966 !important; }

.navbar-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 14px;
}

.nav-icon-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 36px;
    padding: 0 12px;
    border-radius: 10px;
    color: rgba(255, 255, 255, .45);
    text-decoration: none;
    transition: color 0.2s, background 0.2s;
    background: transparent;
    border: none;
    cursor: pointer;
    flex-shrink: 0;
    white-space: nowrap;
}

.nav-icon-btn:hover { color: #f4f4f5; background: rgba(255, 255, 255, .06); }
.nav-icon-btn svg { width: 20px; height: 20px; flex-shrink: 0; }

.nav-icon-btn-text {
    font-size: 13px;
    font-weight: 600;
    font-family: 'Hanken Grotesk', sans-serif;
}

.btn-g {
    padding: 8px 16px;
    border: 1px solid rgba(255, 255, 255, .1);
    border-radius: 10px;
    font-size: 13px;
    font-weight: 600;
    color: rgba(255, 255, 255, .65);
    cursor: pointer;
    background: rgba(255, 255, 255, .05);
    transition: all 0.2s;
    text-decoration: none;
    white-space: nowrap;
    display: inline-block;
    line-height: 1;
    font-family: 'Hanken Grotesk', sans-serif;
}

.btn-g:hover {
    background: rgba(255, 255, 255, .09);
    border-color: rgba(255, 255, 255, .16);
    color: #f4f4f5;
    text-decoration: none;
}

.search-container {
    position: relative;
    display: flex;
    align-items: center;
    /* Fixed height keeps the container from collapsing when .search-pill is
       hidden, so the results dropdown's top:100% lands below the input
       instead of overlapping it. */
    height: 38px;
}

.search-pill {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 38px;
    padding: 0 16px;
    border-radius: 10px;
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .07);
    cursor: pointer;
    transition: background 0.2s;
    white-space: nowrap;
    min-width: 190px;
}

.search-pill:hover { background: rgba(255, 255, 255, .09); }

.search-pill-icon {
    width: 14px;
    height: 14px;
    color: rgba(255, 255, 255, .4);
    flex-shrink: 0;
}

.search-pill-text {
    font-size: 13px;
    color: rgba(255, 255, 255, .4);
    font-family: 'Hanken Grotesk', sans-serif;
}

.search-container.active .search-pill { display: none; }

.search-input {
    position: absolute;
    top: 0;
    right: 0;
    height: 38px;
    width: 0;
    padding: 0;
    background: rgba(5, 8, 7, 0.92);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    border: 1px solid rgba(255, 255, 255, .07);
    border-radius: 10px;
    color: #f4f4f5;
    font-size: 13px;
    font-family: 'Hanken Grotesk', sans-serif;
    outline: none;
    opacity: 0;
    transition: all 0.3s ease;
    pointer-events: none;
    z-index: 1001;
}

.search-input::placeholder { color: rgba(255, 255, 255, .3); }

.search-container.active .search-input {
    width: 260px;
    padding: 9px 14px;
    opacity: 1;
    pointer-events: all;
}

.search-container.active .search-input.has-results {
    border-radius: 10px 10px 0 0;
    border-bottom-color: transparent;
}

.search-results {
    position: absolute;
    top: 100%;
    right: 0;
    width: 260px;
    background: rgba(5, 8, 7, 0.96);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    border: 1px solid rgba(255, 255, 255, .07);
    border-top: none;
    border-radius: 0 0 10px 10px;
    max-height: 360px;
    overflow-y: auto;
    z-index: 1000;
    display: none;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.7);
}

.search-results.active { display: block; }

.search-result-item {
    text-decoration: none;
    color: inherit;
    padding: 10px 14px;
    border-bottom: 1px solid rgba(255, 255, 255, .05);
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 10px;
    transition: background 0.15s;
}

.search-result-item:last-child { border-bottom: none; }
.search-result-item:hover { background: rgba(255, 255, 255, .05); }

.search-result-thumbnail {
    width: 56px;
    height: 32px;
    border-radius: 6px;
    object-fit: cover;
    background: #111114;
    flex-shrink: 0;
}

/* Same role as .n-card-ph, at dropdown-thumb scale: a missing or broken
   thumbnail becomes a branded tile rather than a broken-image box.
   The mark is drawn as an SVG data URI background rather than a text child, so
   the same class works whether it lands on the <div> (no thumbnail) or on an
   <img> that failed to load — an <img> cannot render text children. */
.sr-thumb-ph {
    background:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='32'%3E%3Ctext x='28' y='21' text-anchor='middle' font-family='Archivo,Arial,sans-serif' font-size='12' font-weight='800' fill='rgba(255,255,255,0.3)'%3E1B%3C/text%3E%3C/svg%3E") center / auto no-repeat,
        linear-gradient(140deg, #1a1028 0%, #0c0c0d 64%);
}

.search-result-info { flex: 1; min-width: 0; }

.search-result-title {
    color: #f4f4f5;
    font-size: 13px;
    font-weight: 500;
    margin-bottom: 3px;
    line-height: 1.35;
    white-space: normal;
    overflow-wrap: anywhere;
}

.search-result-meta { color: rgba(255, 255, 255, .3); font-size: 11px; }

.search-no-results {
    padding: 16px;
    text-align: center;
    color: rgba(255, 255, 255, .3);
    font-size: 13px;
}

.notice-bar {
    background: rgba(var(--accent-rgb), 0.08);
    border-bottom: 1px solid rgba(var(--accent-rgb), 0.18);
    /* Same horizontal gutter as .navbar so the two line up */
    padding: 7px var(--gutter);
}

.notice-bar-inner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    flex-wrap: wrap;
}

.notice-bar-item {
    font-size: 12.5px;
    color: rgba(255, 255, 255, 0.55);
    font-weight: 500;
}

.notice-bar-link {
    color: var(--accent-color);
    text-decoration: none;
    font-weight: 600;
    transition: color 0.2s;
}

/* Brighten toward white on hover rather than shifting hue — the previous
   #b06aff purple was off-palette on a green-accented site. */
.notice-bar-link:hover { color: #6effab; text-decoration: underline; }

.notice-bar-sep {
    color: rgba(255, 255, 255, 0.2);
    font-size: 12px;
}

@media (max-width: 480px) {
    .notice-bar-item { font-size: 11.5px; }
}

.footer {
    flex-shrink: 0;
    border-top: 1px solid rgba(255, 255, 255, .06);
    margin-top: 40px;
    padding: 16px clamp(16px, 4vw, 40px);
}

.footer-disclaimer {
    max-width: 900px;
    margin: 0 auto;
    text-align: center;
    font-size: 12.5px;
    line-height: 1.65;
    color: rgba(255, 255, 255, .45);
}

.footer-inner {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px;
}

.footer-brand {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.footer-logo-text {
    font-family: 'Archivo', sans-serif;
    font-weight: 800;
    font-size: 14px;
    color: rgba(255, 255, 255, .45);
    letter-spacing: -.02em;
}

.footer-link {
    color: rgba(255, 255, 255, .4);
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
    transition: color 0.2s;
}

.footer-link:hover { color: rgba(255, 255, 255, .7); text-decoration: none; }

.footer-copy {
    display: block;
    text-align: center;
    color: rgba(255, 255, 255, .25);
    font-size: 12px;
    margin: 10px 0 0 0;
}

h2, h3, h4 { color: var(--text-primary) !important; }
small { color: var(--text-secondary) !important; }

.mobile-bottom-nav {
    display: none;
    position: fixed;
    bottom: 0; left: 0; right: 0;
    z-index: 1200;
    background: rgba(5, 8, 7, 0.92);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-top: 1px solid rgba(255, 255, 255, .07);
    padding: 8px 0 max(8px, env(safe-area-inset-bottom));
}

.mbn-inner {
    display: flex;
    align-items: stretch;
    justify-content: space-around;
    width: 100%;
}

.mbn-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 6px 4px;
    text-decoration: none;
    color: rgba(255, 255, 255, .4);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    transition: color 0.15s;
}

.mbn-item svg {
    width: 22px;
    height: 22px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex-shrink: 0;
}

.mbn-item.active,
.mbn-item:hover { color: #fff; }

.mbn-item.active svg { stroke: var(--accent-color); }

@media (max-width: 768px) {
    /* Use the shared gutter so the logo lines up with the card rows below
       instead of sitting 4px further in. */
    .navbar { height: 62px; padding: 0 var(--gutter); gap: 10px; }
    .notice-bar { padding: 7px var(--gutter); }

    /* Home/VIP/Sign In live in the bottom nav, so nothing here is shown. */
    .nav-links-desktop .nav-link { display: none; }

    /* The auto margin absorbs all free space, pinning search + Discord to the
       right edge opposite the logo. It lives here rather than on a preceding
       group so the layout does not depend on that group being present. */
    .navbar-right { display: flex; gap: 4px; min-width: 0; margin-left: auto; }

    .nav-icon-btn { display: flex; padding: 0 8px; gap: 6px; }
    .nav-icon-btn-text { font-size: 12px; }

    .btn-g { padding: 6px 12px; font-size: 12px; }

    /* Keep the search pill from forcing the navbar wider than the viewport */
    .search-container { min-width: 0; }
    .search-pill { min-width: 0; }
    .search-container.active .search-input { width: min(260px, 60vw); }
    .search-results { width: min(260px, 60vw); }

    .footer { margin-top: 32px; padding: 14px 16px; }

    .mobile-bottom-nav { display: flex; }
}

@media (max-width: 480px) {
    /* Gutter-derived, same as the 768px block — keeps the header edge on the
       same vertical line as the rows beneath it. */
    .navbar { height: 62px; padding: 0 var(--gutter); }
    .notice-bar { padding: 7px var(--gutter); }

    /* Below this width the logo, search pill and a labelled Discord button
       cannot share the row, and the label is the least essential part — the
       icon still carries the meaning, and aria-label covers screen readers. */
    .nav-icon-btn-text { display: none; }
    .nav-icon-btn { padding: 0 8px; }
}

/* ========== CATEGORY CHIPS ========== */
/* One single row: the scrollable chip strip takes the free space and the
   scroll arrows sit inline at its right end. They used to live in a separate
   block above the strip, which on mid-width viewports rendered as an
   orphaned band of arrows floating over empty space. */
.cat-tabs-wrap {
    /* Constrain this to the viewport so the horizontally-scrollable strip
       inside it clips its own overflow instead of stretching the page. */
    width: 100%;
    max-width: 100%;
    min-width: 0;
    overflow: hidden;
    position: relative;
    display: flex;
    align-items: center;
    /* No arrows: the strip owns the whole row and scrolls by swipe/wheel/drag.
       Its own left gutter and the ::after spacer supply the edge spacing. */
    padding: 14px 0 0 0;
}

/* Fade the strip out at whichever edge still has chips beyond it, so a
   half-visible chip reads as "keep scrolling" rather than as a clipping bug.
   With no arrows this is the only scroll affordance, so it carries the cue on
   every device. JS toggles .has-prev / .has-next from the scroll position. */
.cat-tabs-wrap::before,
.cat-tabs-wrap::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: 36px;
    pointer-events: none;
    opacity: 0;
    transition: opacity .2s ease;
    z-index: 1;
}

.cat-tabs-wrap::before {
    left: 0;
    background: linear-gradient(to right, var(--bg-primary) 15%, transparent 100%);
}

.cat-tabs-wrap::after {
    /* The strip now runs to the wrapper's edge, so the fade does too. */
    right: 0;
    background: linear-gradient(to left, var(--bg-primary) 15%, transparent 100%);
}

.cat-tabs-wrap.has-prev::before,
.cat-tabs-wrap.has-next::after { opacity: 1; }

.cat-tabs {
    /* Left gutter only. A flex container collapses its *end* padding once the
       content overflows, so a matching right padding would silently vanish
       and let the last chip butt against the viewport edge. The ::after
       spacer below owns the trailing gutter instead, which every browser
       treats as real content and therefore always honours. */
    padding: 0 0 0 var(--gutter);
    /* min-width:0 is what actually lets a flex item shrink below its content
       width and scroll internally rather than stretching the row. */
    flex: 1 1 auto;
    display: flex;
    gap: 9px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-behavior: smooth;
    scrollbar-width: none;
    min-width: 0;
    -webkit-overflow-scrolling: touch;
    /* Snap so a flick settles with a chip aligned to the gutter instead of
       leaving one sliced in half. `proximity` (not `mandatory`) so short
       scrolls near the ends still come to rest naturally. */
    scroll-snap-type: x proximity;
    overscroll-behavior-x: contain;
}

.cat-tabs::-webkit-scrollbar { display: none; }

/* Trailing spacer (see above). With the arrows inline the strip ends beside
   them rather than at the page gutter, so this only needs to keep the last
   chip from touching the fade — not reproduce a full gutter. */
.cat-tabs::after {
    content: '';
    flex: 0 0 4px;
}

.ctab {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 36px;
    padding: 0 17px;
    font-size: 13px;
    font-weight: 600;
    color: rgba(255, 255, 255, .65);
    cursor: pointer;
    border: 1px solid rgba(255, 255, 255, .1);
    background: rgba(255, 255, 255, .03);
    border-radius: 10px;
    transition: background .18s ease, color .18s ease, border-color .18s ease;
    white-space: nowrap;
    font-family: 'Hanken Grotesk', sans-serif;
    scroll-snap-align: start;
    /* Chips are scroll targets on touch — never let a long label wrap or let
       the browser shrink one below its text width. */
    scroll-margin-left: var(--gutter);
    -webkit-tap-highlight-color: transparent;
    user-select: none;
}

/* Emoji icons render at wildly different widths across platforms; a fixed
   box keeps every chip's text starting at the same offset from its edge. */
.ctab > span:first-child {
    flex: 0 0 auto;
    width: 1.15em;
    text-align: center;
    font-size: 13px;
    line-height: 1;
}

.ctab:hover {
    background: rgba(255, 255, 255, .07);
    color: #f4f4f5;
    border-color: rgba(255, 255, 255, .15);
}

.ctab.on {
    background: var(--accent-color);
    border-color: var(--accent-color);
    /* Dark text on the bright green fill — white would be unreadable here. */
    color: #05100b;
    font-weight: 700;
}

/* ========== ROWS SECTION ========== */
.rows-section {
    /* Bottom padding is small because the last .netflix-row already carries a
       32px margin and the following .section-divider adds its own top padding;
       stacking all three left ~72px of dead space above Upcoming Fixtures. */
    padding: 10px 0 8px;
}

.no-streams-message {
    text-align: center;
    padding: 32px var(--gutter);
    color: rgba(255, 255, 255, .3);
    font-size: 14px;
}

.netflix-row {
    margin-bottom: 32px;
}

/* The 32px above sets the rhythm between rows, but on the last one it only
   pads the boundary with Upcoming Fixtures, which has its own spacing. */
.netflix-row:last-child {
    margin-bottom: 8px;
}

.netflix-row-head {
    display: flex;
    align-items: center;
    padding: 24px var(--gutter) 16px;
}

/* Prev/next arrows in the row header, pushed to the right of the title */
.nrow-arrows {
    display: flex;
    gap: 8px;
    margin-left: auto;
    flex-shrink: 0;
}

.nrow-arrow-btn {
    width: 34px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, .1);
    background: rgba(255, 255, 255, .03);
    color: rgba(255, 255, 255, .6);
    cursor: pointer;
    transition: all .18s ease;
}

.nrow-arrow-btn:hover:not([disabled]) {
    background: rgba(255, 255, 255, .08);
    border-color: rgba(255, 255, 255, .18);
    color: #f4f4f5;
}

.nrow-arrow-btn svg { width: 16px; height: 16px; flex-shrink: 0; }

.nrow-arrow-btn[disabled] {
    opacity: .3;
    cursor: default;
}

.netflix-row-head h3 {
    font-family: 'Archivo', sans-serif;
    font-size: clamp(20px, 2.4vw, 26px);
    font-weight: 800;
    letter-spacing: -.02em;
    display: flex;
    align-items: center;
    gap: 10px;
    color: #f4f4f5;
    margin: 0;
    /* Allow the title to shrink so the arrows always fit beside it */
    min-width: 0;
}

.netflix-row-wrap {
    padding: 0 var(--gutter) 10px;
}

.nrow-viewport {
    overflow-x: auto;
    overflow-y: visible;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, .15) transparent;
    padding-bottom: 6px;
}

.nrow-viewport::-webkit-scrollbar { height: 5px; }
.nrow-viewport::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .12); border-radius: 5px; }
.nrow-viewport::-webkit-scrollbar-track { background: transparent; }

.nrow-track {
    display: flex;
    gap: 14px;
    width: max-content;
}

/* ========== STREAM CARD ========== */
.n-card {
    display: block;
    text-decoration: none;
    color: inherit;
    flex-shrink: 0;
    width: min(78vw, 300px);
    cursor: pointer;
    transition: transform 0.2s ease;
    position: relative;
    scroll-snap-align: start;
}

.n-card:hover {
    transform: translateY(-4px);
    z-index: 2;
}

.n-card-thumb {
    width: 100%;
    aspect-ratio: 16 / 10;
    border-radius: 14px;
    overflow: hidden;
    position: relative;
    background: linear-gradient(140deg, #1a1028 0%, #0c0c0d 64%);
    border: 1px solid rgba(255, 255, 255, .07);
    transition: border-color 0.2s;
}

.n-card:hover .n-card-thumb {
    border-color: rgba(var(--accent-rgb), .4);
}

.n-card-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Placeholder for streams the feed gives no thumbnail for (or whose thumbnail
   404s). It is always in the DOM behind the image and only revealed by .ph-on,
   so a thumbnail that loads normally covers it without a flash. */
.n-card-ph {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    background:
        radial-gradient(120% 100% at 50% 0%, rgba(var(--accent-rgb), .16) 0%, transparent 60%),
        linear-gradient(140deg, #1a1028 0%, #0c0c0d 64%);
}

.n-card-thumb.ph-on .n-card-ph { display: flex; }

.n-card-ph-mark {
    font-family: 'Archivo', sans-serif;
    font-size: 25px;
    font-weight: 800;
    letter-spacing: -.02em;
    color: rgba(255, 255, 255, .22);
    user-select: none;
}

.n-card-ph-mark span { color: rgba(var(--accent-rgb), .55); }

.n-card-live {
    position: absolute;
    top: 8px;
    left: 8px;
    background: rgba(255, 59, 48, .92);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    padding: 3px 8px;
    border-radius: 6px;
    letter-spacing: 0.05em;
    z-index: 2;
}

.n-card-soon {
    position: absolute;
    top: 8px;
    left: 8px;
    background: rgba(0, 0, 0, .65);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    color: rgba(255, 255, 255, .7);
    font-size: 11px;
    font-weight: 600;
    padding: 3px 8px;
    border-radius: 6px;
    letter-spacing: 0.04em;
    border: 1px solid rgba(255, 255, 255, .12);
    z-index: 2;
}

.n-card-viewers {
    position: absolute;
    top: 8px;
    right: 8px;
    background: rgba(0, 0, 0, .55);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    color: var(--accent-color);
    font-size: 11px;
    font-weight: 600;
    padding: 3px 8px;
    border-radius: 6px;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 4px;
}

.n-card-viewers .dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent-color);
    flex-shrink: 0;
    animation: livepulse 2s ease-in-out infinite;
}

.n-card-info {
    padding: 10px 2px 0;
}

.n-card-title {
    font-family: 'Archivo', sans-serif;
    font-size: 14.5px;
    font-weight: 700;
    letter-spacing: -.01em;
    line-height: 1.25;
    /* Wrap instead of truncating so full matchups stay readable.
       min-height reserves two lines so meta lines stay aligned across cards. */
    white-space: normal;
    overflow-wrap: anywhere;
    min-height: 2.5em;
    color: #f4f4f5;
}

.n-card-meta {
    font-size: 12px;
    color: rgba(255, 255, 255, .4);
    margin-top: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ========== SECTION DIVIDER ========== */
.section-divider {
    display: flex;
    align-items: center;
    gap: 20px;
    padding: 18px var(--gutter) 16px;
}

/* Toggle beside the "Upcoming Fixtures" heading: filters the list to
   fixtures the API flags as popular. */
.popular-filter-btn {
    flex-shrink: 0;
    height: 28px;
    padding: 0 14px;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, .1);
    background: rgba(255, 255, 255, .03);
    color: rgba(255, 255, 255, .55);
    font-family: 'Hanken Grotesk', sans-serif;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .03em;
    cursor: pointer;
    transition: all .18s ease;
    white-space: nowrap;
}

.popular-filter-btn:hover {
    background: rgba(255, 255, 255, .07);
    color: #f4f4f5;
    border-color: rgba(255, 255, 255, .16);
}

.popular-filter-btn.on {
    background: var(--accent-color);
    border-color: var(--accent-color);
    color: #05100b;
}

.section-divider span {
    font-family: 'Archivo', sans-serif;
    font-size: 13px;
    font-weight: 700;
    color: rgba(255, 255, 255, .45);
    white-space: nowrap;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.sdiv-line {
    flex: 1;
    height: 1px;
    background: rgba(255, 255, 255, .06);
}

/* ========== FIXTURES ========== */
.fix-outer {
    margin-bottom: 60px;
}

.fixtures-list {
    margin: 0 var(--gutter);
    background: rgba(255, 255, 255, .02);
    border: 1px solid rgba(255, 255, 255, .06);
    border-radius: 14px;
    overflow: hidden;
}

.fixture-date-header {
    padding: 9px 18px 8px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .35);
    background: rgba(255, 255, 255, .015);
    border-bottom: 1px solid rgba(255, 255, 255, .05);
}

.fixtures-list + .fixtures-list {
    margin-top: 10px;
}

.fixture-item {
    display: block;
    text-decoration: none;
    color: inherit;
    padding: 12px 18px;
    border-bottom: 1px solid rgba(255, 255, 255, .05);
    transition: background 0.15s;
    cursor: pointer;
}

.fixture-item:last-child { border-bottom: none; }
.fixture-item:hover { background: rgba(255, 255, 255, .03); }

.fixture-content {
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.fix-comp-badge {
    display: block;
    text-align: center;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .3);
}

.fix-teams-row {
    display: flex;
    align-items: center;
    /* Reserve two lines of name height so rows keep a uniform height whether
       the team names wrap or not. */
    min-height: 36px;
}

.fix-team {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
}

.fix-team.t1 { justify-content: flex-end; }
.fix-team.t2 { justify-content: flex-start; }

.fix-team img {
    width: 22px;
    height: 22px;
    object-fit: contain;
    flex-shrink: 0;
}

.fix-team-name {
    font-size: 13px;
    font-weight: 600;
    color: #f4f4f5;
    line-height: 1.35;
    white-space: normal;
    overflow-wrap: anywhere;
}

.fix-event-name {
    font-size: 13px;
    font-weight: 600;
    color: #f4f4f5;
    flex: 1;
}

.fix-cdown {
    font-size: 12px;
    font-weight: 600;
    color: rgba(255, 255, 255, .5);
    padding: 0 14px;
    flex-shrink: 0;
    white-space: nowrap;
}

.fix-cdown.live { color: #ff3b30; }

/* ========== EMPTY STATE ========== */
.empty-state-card {
    text-align: center;
    padding: 48px;
    color: rgba(255, 255, 255, .3);
    font-size: 14px;
}

/* ========== SHOW ALL BUTTON ========== */
.show-all-btn {
    display: block;
    margin: 16px auto 0;
    background: rgba(255, 255, 255, .04);
    border: 1px solid rgba(255, 255, 255, .07);
    color: rgba(255, 255, 255, .5);
    padding: 9px 24px;
    border-radius: 10px;
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    transition: all 0.2s;
    font-family: 'Hanken Grotesk', sans-serif;
}

.show-all-btn:hover {
    background: rgba(255, 255, 255, .08);
    color: #f4f4f5;
}

/* ========== CAROUSEL ARROWS ========== */
.nrow-scroller {
    position: relative;
}

.nrow-arrow {
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 10;
    width: 60px;
    border: none;
    color: rgba(255, 255, 255, 0.9);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s, background 0.18s;
    background: none;
}

.nrow-arrow svg {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    filter: drop-shadow(0 1px 4px rgba(0,0,0,0.7));
}

.nrow-arrow-left {
    left: 0;
    background: linear-gradient(to right, rgba(8, 8, 14, 0.82) 0%, transparent 100%);
}

.nrow-arrow-right {
    right: 0;
    background: linear-gradient(to left, rgba(8, 8, 14, 0.82) 0%, transparent 100%);
}

.netflix-row:hover .nrow-arrow:not(.nrow-arrow--hidden) {
    opacity: 1;
    pointer-events: auto;
}

.nrow-arrow-left:hover {
    background: linear-gradient(to right, rgba(4, 4, 10, 0.96) 0%, transparent 100%);
}

.nrow-arrow-right:hover {
    background: linear-gradient(to left, rgba(4, 4, 10, 0.96) 0%, transparent 100%);
}

@media (max-width: 768px) {
    .nrow-arrow { display: none; }
}

/* ========== LOADING ========== */
.fixtures-loading {
    text-align: center;
    padding: 40px;
    color: rgba(255, 255, 255, .3);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
}

.loading-spinner {
    width: 20px;
    height: 20px;
    border: 2px solid rgba(255, 255, 255, .08);
    border-radius: 50%;
    border-top-color: var(--accent-color);
    animation: spin 1s linear infinite;
    flex-shrink: 0;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* ========== MOBILE ========== */
@media (max-width: 768px) {
    /* Narrow the shared gutter once; every row that uses var(--gutter)
       follows automatically and stays aligned with the others. Slightly
       tighter than the base clamp's 16px floor so phones give as much width
       as possible to the cards without letting them touch the screen edge. */
    :root { --gutter: 14px; }

    .cat-tabs-wrap { padding: 12px 0 0 0; }
    .cat-tabs { padding: 0 0 2px var(--gutter); gap: 8px; }
    .cat-tabs::after { flex: 0 0 calc(var(--gutter) - 8px); }

    .ctab { height: 34px; padding: 0 14px; font-size: 12.5px; gap: 7px; }
    .ctab > span:first-child { font-size: 12.5px; }

    .cat-tabs-wrap::before,
    .cat-tabs-wrap::after { width: 28px; }

    .netflix-row-head { padding: 20px var(--gutter) 12px; gap: 10px; }
    .netflix-row-head h3 { font-size: 18px; }
    .netflix-row-wrap { padding: 0 var(--gutter) 8px; }

    /* Exactly 2 cards per view: viewport minus the gutter on each side,
       minus the 14px gap between the pair, split in half. Derived from
       --gutter rather than a hardcoded 24px, so changing the gutter can't
       silently desync the card width from the row it sits in. */
    .n-card { width: calc((100vw - (var(--gutter) * 2) - 14px) / 2); }
}

@media (max-width: 480px) {
    .fix-team-name { font-size: 12px; }
    .fix-team img { width: 18px; height: 18px; }
    .fix-cdown { font-size: 11px; padding: 0 10px; }

    /* Chips stay the same shape all the way down to the narrowest phones —
       only the internal padding tightens, so "American Football" still fits
       on one line without the strip changing character. */
    .ctab { height: 32px; padding: 0 12px; font-size: 12px; gap: 6px; }
    .ctab > span:first-child { font-size: 12px; }
    .cat-tabs { gap: 7px; }
    .cat-tabs::after { flex: 0 0 calc(var(--gutter) - 7px); }
}

/* On touch there is no real hover, but tapping a chip leaves the hover style
   stuck on it until you tap elsewhere — which reads as a second selected
   chip next to the green one. Neutralise hover where pointers can't hover. */
@media (hover: none) {
    .ctab:hover {
        background: rgba(255, 255, 255, .03);
        color: rgba(255, 255, 255, .65);
        border-color: rgba(255, 255, 255, .1);
    }

    .ctab.on:hover {
        background: var(--accent-color);
        border-color: var(--accent-color);
        color: #05100b;
    }
}

/* ========== WATCH / MATCH PAGE ========== */
/* Moved out of a <style> block in match.html so it is cached with the rest of
   the CSS and picked up by the ?v= asset_version cache-buster. */
.watch-page {
    padding: 0;
    width: 100%;
    margin: 0;
    height: calc(100vh - 100px);
    overflow: hidden;
}

.watch-layout {
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    height: 100%;
}

.watch-player-col {
    flex: 0 1 auto;
    min-width: 0;
    /* Size the player off the available height so a 16:9 frame fits without
       scrolling; the max-width reserves room for the sidebar beside it. */
    width: calc((100vh - 100px - 60px) * 16 / 9);
    max-width: calc(100% - 340px - 40px);
}

.watch-player-wrap {
    background: #000;
    overflow: hidden;
    border-radius: 0;
    border: none;
    border-right: 1px solid rgba(255, 255, 255, .07);
    aspect-ratio: 16 / 9;
    width: 100%;
    max-height: calc(100vh - 100px - 60px);
    margin: 0;
    position: relative;
}

.watch-player-wrap iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

.watch-player-empty {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 10px;
    color: rgba(255, 255, 255, .35);
    font-size: 14px;
    text-align: center;
    padding: 20px;
}

.watch-header {
    margin-top: 20px;
    margin-left: 0;
    margin-right: 20px;
}

.watch-title {
    font-family: 'Archivo', sans-serif;
    font-size: clamp(20px, 2.6vw, 28px);
    font-weight: 800;
    letter-spacing: -.02em;
    color: #f4f4f5;
}

/* ---------- Sidebar: source picker ---------- */
.watch-sidebar {
    width: 340px;
    flex-shrink: 0;
    margin-left: 20px;
    margin-right: 20px;
    max-height: 100%;
    overflow-y: auto;
    background: rgba(255, 255, 255, .02);
    border: 1px solid rgba(255, 255, 255, .06);
    border-radius: 14px;
    padding: 16px;
}

.watch-sidebar h4 {
    font-family: 'Archivo', sans-serif;
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: rgba(255, 255, 255, .45);
    margin-bottom: 12px;
}

.source-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.source-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 10px;
    background: rgba(255, 255, 255, .03);
    border: 1px solid rgba(255, 255, 255, .06);
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease;
}

.source-item:hover {
    background: rgba(255, 255, 255, .06);
    border-color: rgba(255, 255, 255, .12);
}

.source-item.on {
    background: rgba(var(--accent-rgb), .14);
    border-color: rgba(var(--accent-rgb), .4);
}

.source-item-left {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.source-lang {
    font-size: 13px;
    font-weight: 600;
    color: #f4f4f5;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.source-num {
    font-size: 11px;
    color: rgba(255, 255, 255, .35);
}

.source-hd {
    font-size: 10px;
    font-weight: 700;
    color: var(--accent-color);
    background: rgba(var(--accent-rgb), .12);
    padding: 2px 6px;
    border-radius: 5px;
    flex-shrink: 0;
}

.source-empty {
    color: rgba(255, 255, 255, .3);
    font-size: 13px;
    padding: 8px 0;
}

/* Stack the player and sidebar once they no longer fit side by side. */
@media (max-width: 900px) {
    .watch-page {
        height: auto;
        overflow: visible;
    }

    .watch-layout {
        flex-direction: column;
        align-items: stretch;
        height: auto;
    }

    .watch-player-col {
        width: 100%;
        max-width: 100%;
    }

    .watch-player-wrap {
        width: 100%;
        max-width: 100%;
        max-height: none;
        border-right: none;
    }

    .watch-header {
        margin-left: 14px;
        margin-right: 14px;
    }

    .watch-sidebar {
        width: auto;
        flex-shrink: 1;
        max-height: none;
        overflow-y: visible;
        margin: 16px 14px 0;
    }
}

@media (max-width: 768px) {
    /* No nav links in the mobile header on the watch page. With that group
       gone, .navbar-right needs the auto margin to stay right. */
    .watch-body .nav-links-desktop { display: none; }
    .watch-body .navbar-right { margin-left: auto; }

    .watch-page { padding: 0 0 24px; }

    .watch-title {
        /* Scale with viewport so long matchups stay on one line */
        font-size: clamp(11px, 3.6vw, 18px);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
}
