/* ============================================================
   DEOGI v3 — Liquid Glass theme (blue/white, light + dark)
   ============================================================ */

/* ----- Light (default) tokens — warm sand palette --------- */
:root {
  color-scheme: light;

  /* Warm sand surfaces */
  --bg:          #efe6d2;   /* page background — warm sand */
  --bg-1:        #faf4e3;   /* cards, panels — cream */
  --bg-2:        #e6dbc0;   /* hover / subtle fill */
  --bg-3:        #d8c9a4;   /* chip backgrounds */
  --bg-card:     #faf4e3;

  /* Warm borders */
  --line:        #d8c9a4;
  --line-2:      #b8a578;

  /* Warm dark text for contrast on sand */
  --text:        #2a2317;
  --text-dim:    #5a4d35;
  --muted:       #8a7a5c;

  /* Accent — one primary + hover */
  --accent:      #00aff0;
  --accent-2:    #0096d6;
  --accent-soft: rgba(0, 175, 240, .12);

  /* Quality badge colors (flat, no gradients) */
  --hd:          #00aff0;
  --fhd:         #0086c3;
  --4k:          #e91e63;

  /* Glass is used ONLY on the sticky header now */
  --glass-bg:    rgba(255, 255, 255, .78);
  --glass-blur:  blur(18px) saturate(160%);

  /* Shadows — minimal, single-layer */
  --shadow-sm:   0 1px 3px rgba(15, 23, 42, .06);
  --shadow:      0 2px 8px rgba(15, 23, 42, .08);
  --shadow-lg:   0 10px 30px rgba(15, 23, 42, .14);

  /* Radii + motion */
  --radius:      10px;
  --radius-sm:   6px;
  --radius-lg:   14px;
  --t-fast:      .15s ease;
  --t-mid:       .25s ease;
}

/* ----- Dark theme override -------------------------------- */
[data-theme="dark"] {
  color-scheme: dark;

  --bg:          #0a1422;
  --bg-1:        #111e2f;
  --bg-2:        #182940;
  --bg-3:        #1f334d;
  --bg-card:     #111e2f;

  --line:        #1f334d;
  --line-2:      #2a4466;

  --text:        #e6edf5;
  --text-dim:    #aab8c8;
  --muted:       #6e8193;

  --accent:      #33c2f3;
  --accent-2:    #00aff0;
  --accent-soft: rgba(51, 194, 243, .14);

  --hd:          #33c2f3;
  --fhd:         #0096d6;

  --glass-bg:    rgba(17, 30, 47, .82);
  --glass-blur:  blur(18px) saturate(160%);

  --shadow-sm:   0 1px 3px rgba(0, 0, 0, .35);
  --shadow:      0 2px 8px rgba(0, 0, 0, .40);
  --shadow-lg:   0 10px 30px rgba(0, 0, 0, .55);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI",
               Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  scroll-behavior: smooth;
  min-height: 100vh;
  position: relative;
  /* No transition on body bg — theme flip must be instant so the
     glass layers composited on top reveal the new color immediately. */
}

/* Flat page background — simpler, easier on the eyes than blob gradients */

a { color: var(--text); text-decoration: none; transition: color var(--t-fast); }
a:hover { color: var(--accent); }
img { display: block; max-width: 100%; }
button { font-family: inherit; }
code {
  background: var(--bg-2);
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 12px;
  color: var(--accent);
}

/* The container hugs the viewport (minus a small gutter) so the
   header, category strip, main content, and footer ALL share the
   same width on every page. Previously the container was capped at
   1760 px which made list pages look centred inside whitespace on
   wide screens while the video detail page (which breaks out of
   the container via negative margin) extended further — producing
   a visible mismatch where the header looked narrower than the
   video cards below. Removing the cap keeps every band aligned. */
.container {
  width: 100%;
  max-width: none;
  margin: 0 auto;
  padding: 0 24px;
}

/* ============================================================
   Header (sticky, subtle glass)
   ============================================================ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}
/* Desktop shorts viewer: header auto-hides and reappears on hover.
   A pseudo-element hover zone extends below the hidden header so
   users can trigger it by mousing towards the top of the screen.
   Force dark-theme header to match the dark shorts viewer. */
@media (min-width: 901px) {
  body:has(.shorts-viewer) .site-header {
    position: fixed;
    left: 0; right: 0;
    transform: translateY(-100%);
    transition: transform .3s ease, opacity .3s ease;
    opacity: 0;
    background: rgba(17, 30, 47, .92);
    border-bottom-color: rgba(255, 255, 255, .08);
    color: #e8eaed;
  }
  body:has(.shorts-viewer) .site-header::after {
    content: "";
    position: absolute;
    left: 0; right: 0;
    top: 100%;
    height: 32px;
  }
  body:has(.shorts-viewer) .site-header:hover,
  body:has(.shorts-viewer) .site-header:focus-within {
    transform: translateY(0);
    opacity: 1;
  }
  /* Force dark text/icon colors inside shorts header */
  body:has(.shorts-viewer) .site-header .logo,
  body:has(.shorts-viewer) .site-header .strip-link,
  body:has(.shorts-viewer) .site-header .search-input {
    color: #e8eaed;
  }
  body:has(.shorts-viewer) .site-header .search-pill {
    background: rgba(255, 255, 255, .08);
    border-color: rgba(255, 255, 255, .15);
  }
}

/* --- top strip --- */
.top-strip {
  border-bottom: 1px solid var(--line);
  font-size: 11px;
}
.top-strip-inner {
  display: flex;
  align-items: center;
  height: 30px;
  gap: 14px;
}
.strip-spacer { flex: 1; }
.strip-link {
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 1px;
  font-weight: 600;
  font-size: 10px;
  padding: 5px 10px;
  border-radius: 999px;
  transition: all var(--t-fast);
}
.strip-link:hover {
  background: var(--accent-soft);
  color: var(--accent);
}

/* --- main bar --- */
.main-bar-inner {
  display: flex;
  align-items: center;
  gap: 22px;
  height: 66px;
}
.logo {
  font-size: 28px;
  font-weight: 900;
  letter-spacing: -1px;
  color: var(--text);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.logo-icon {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .1);
}
.logo span { color: var(--accent); margin-left: -0.15em; }

.search-form {
  flex: 1 1 0;
  /* Floor the search field at 280 px so it never collapses to a
     tiny nub even when the inline nav pills are eating most of
     the row. The inner ``input`` has ``min-width: 0`` so this
     min only applies to the outer pill, not the text input. */
  min-width: 280px;
  display: flex;
  max-width: 720px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  overflow: hidden;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.search-form:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.search-form input {
  flex: 1;
  padding: 11px 20px;
  border: 0;
  background: transparent;
  color: var(--text);
  font-size: 14px;
  outline: none;
}
.search-form input::placeholder { color: var(--muted); }
.search-form button {
  background: var(--accent);
  color: #fff;
  border: 0;
  padding: 0 22px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--t-fast);
}
.search-form button:hover { background: var(--accent-2); }

/* ``margin-left: auto`` pushes the nav + user menu + theme
   toggle cluster all the way to the right edge of the header,
   closing the whitespace gap that was making the header look
   narrower than the content grid below on wide viewports. */
/* Wide desktop default: render the nav pills INLINE in the
   top bar (Home / Trending / Tags / Channels / Stars / Playlists).
   The burger + drawer kicks in at the narrow breakpoint below
   (≤ 900 px) where horizontal space is too tight for the pills
   to coexist with the search field. */
.main-nav {
  display: flex;
  gap: 2px;
  margin-left: auto;
  flex: 0 0 auto;     /* never expand past intrinsic size */
  flex-wrap: nowrap;
}
.main-nav a {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  font-size: 13px;
  color: var(--text-dim);
  padding: 8px 12px;
  border-radius: 8px;
  transition: background var(--t-fast), color var(--t-fast);
  white-space: nowrap;
}
/* Hide the text labels on intermediate desktop widths so the
   nav row collapses to icon-only. Search bar stays roomy and
   the icons still convey enough meaning. The full text comes
   back at the wider breakpoint below where there's room.
   Only applies between 901px and 1280px — at ≤900px the nav
   becomes a slide-out drawer (handled in the mobile @media
   block) where the labels MUST be visible. */
@media (min-width: 901px) and (max-width: 1280px) {
  .main-nav a span { display: none; }
  .main-nav a { padding: 8px 10px; }
}
.main-nav a:hover {
  background: var(--bg-2);
  color: var(--accent);
}
.main-nav svg { flex-shrink: 0; }

.burger {
  /* Burger is hidden on wide desktop (inline nav handles it),
     shown again on narrow viewports via the mobile media query
     below. ``order: 99`` parks it at the far right whenever it
     IS visible. */
  display: none;
  background: transparent;
  border: 0;
  cursor: pointer;
  flex-direction: column;
  gap: 5px;
  padding: 8px;
  order: 99;
  margin-left: 8px;
}
.burger span {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--text);
  border-radius: 2px;
}

/* Theme toggle button */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text);
  cursor: pointer;
  transition: all var(--t-fast);
  flex-shrink: 0;
}
.theme-toggle:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-soft);
}
.theme-toggle .icon-moon { display: none; }
.theme-toggle .icon-sun { display: block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
[data-theme="dark"] .theme-toggle .icon-sun { display: none; }

/* --- category strip --- */
/* Cat-strip is no longer a header extension — it lives at the
   top of the main content area as its own standalone band. The
   outer ``.cat-strip`` is a margin wrapper; the inner
   ``.container`` carries the actual white liquid-glass panel
   so the blur + rounded corners stay aligned with the content
   grid below. */
/* Default: the cat-strip is a thin, fully transparent band of
   pills. When it lives INSIDE .site-header (homepage, tag pages,
   etc.) the header's own ``var(--glass-bg)`` already provides the
   glass tint — stacking another layer would double up the opacity
   and kill the "liquid" feel, so we just let the chips sit on
   whatever the header draws behind them. */
.cat-strip {
  background: transparent;
  border-top: none;
  padding: 4px 0;
  margin: 0;
}
.cat-strip .container {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 2px 0;
  position: relative;
  overflow: hidden;
}
/* On the watch page the cat-strip lives OUTSIDE the sticky
   header (it's a direct child of <body>). There's no parent
   glass to borrow from, so we paint the band itself with the
   exact same liquid-glass tokens as ``.site-header`` — same
   translucent bg, same blur, same hairline bottom border,
   same shadow — producing one continuous chrome surface that
   looks like a second row of the header without being sticky. */
body > .cat-strip {
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  /* Zero top gap so the glass butts straight up against the
     underside of the (thinner) sticky header — the two bands
     read as a single unified chrome surface. */
  margin-top: 0;
}
.cat-strip-scroll {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 6px 2px 10px;
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
  /* With ~32 pills the natural flow already fills the row, so we
     drop the ``space-between`` justification. Narrow viewports
     scroll horizontally as before. */
}
.cat-strip-scroll::-webkit-scrollbar { height: 4px; }
.cat-strip-scroll::-webkit-scrollbar-thumb {
  background: var(--line-2);
  border-radius: 3px;
}
.cat-pill {
  flex-shrink: 0;
  padding: 6px 16px;
  background: var(--bg-2);
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--text-dim);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  transition: background var(--t-fast), color var(--t-fast);
}
.cat-pill:hover {
  background: var(--accent-soft);
  color: var(--accent);
}
.cat-pill.active {
  background: var(--accent);
  color: #fff;
}

/* ============================================================
   Main area
   ============================================================ */
.main-area { padding: 26px 18px 60px; }

.page-head { margin-bottom: 18px; }
.page-head h1 {
  font-size: 24px;
  margin: 0 0 6px;
  color: var(--text);
  font-weight: 700;
  letter-spacing: -.4px;
}
.muted { color: var(--muted); margin: 0; font-size: 13px; }

/* ============================================================
   Hero featured strip
   ============================================================ */
.hero-featured { margin-bottom: 30px; }
.hero-grid {
  display: grid;
  grid-template-columns: 1.7fr 1fr;
  gap: 14px;
  height: 460px;
}
.hero-sides {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 14px;
}
.hero-card {
  position: relative;
  display: block;
  border-radius: var(--radius);
  overflow: hidden;
  background-color: #000;
  background-size: cover;
  background-position: center;
  transition: transform var(--t-fast), box-shadow var(--t-fast);
  box-shadow: var(--shadow-sm);
}
.hero-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}
.hero-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    transparent 0%,
    transparent 45%,
    rgba(0, 15, 30, .92) 100%
  );
  padding: 16px;
  display: flex;
  flex-direction: column;
}
.hero-meta { margin-top: auto; }
.hero-title {
  font-size: 16px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 2px 6px rgba(0, 0, 0, .9);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.hero-big .hero-title { font-size: 22px; }
.hero-stats {
  font-size: 12px;
  color: rgba(255, 255, 255, .85);
  margin-top: 4px;
}
.hero-card .badge-q,
.hero-card .badge-dur { z-index: 2; }

@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; height: auto; }
  .hero-big { aspect-ratio: 16/9; }
  .hero-sides { grid-template-columns: 1fr 1fr; }
}

/* ============================================================
   Category sections — themed horizontal rows on homepage
   ============================================================ */
.cat-section {
  margin-bottom: 28px;
}
.cat-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 14px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--line);
}
.cat-section-title {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  margin: 0;
}
.cat-section-link {
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  white-space: nowrap;
}
.cat-section-link:hover { text-decoration: underline; }
.cat-row {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
  padding-bottom: 6px;
}
.cat-row::-webkit-scrollbar { height: 6px; }
.cat-row::-webkit-scrollbar-track { background: transparent; }
.cat-row::-webkit-scrollbar-thumb {
  background: var(--line-2);
  border-radius: 3px;
}
.cat-row .card {
  flex: 0 0 240px;
  scroll-snap-align: start;
}
@media (min-width: 1200px) {
  .cat-row .card { flex: 0 0 260px; }
}
@media (max-width: 600px) {
  .cat-row .card { flex: 0 0 200px; }
  .cat-section-title { font-size: 15px; }
}

/* ============================================================
   Chips (legacy tag cloud + actors + playlists)
   ============================================================ */
.tag-cloud { margin: 14px 0 24px; }
.tag-cloud h3 {
  margin: 0 0 10px;
  font-size: 12px;
  text-transform: uppercase;
  color: var(--muted);
  letter-spacing: 1px;
}
.chips { display: flex; flex-wrap: wrap; gap: 6px; }

.chip {
  display: inline-block;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--bg-2);
  color: var(--text-dim);
  font-size: 11px;
  border: 1px solid transparent;
  transition: background var(--t-fast), color var(--t-fast);
}
.chip:hover {
  background: var(--accent-soft);
  color: var(--accent);
}
.chip-actor {
  background: var(--bg-2);
}
.chip-pl {
  background: var(--accent-soft);
  color: var(--accent);
}
.chip-pl:hover { background: var(--accent); color: #fff; }

/* ============================================================
   Filter bar
   ============================================================ */
.filter-bar {
  margin: 0 0 24px;
  padding: 14px 18px;
  background: var(--bg-1);
  border-radius: var(--radius);
  border: 1px solid var(--line);
}
.filter-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}
.filter-row:last-child { margin-bottom: 0; }
.filter-label {
  font-size: 11px;
  text-transform: uppercase;
  color: var(--muted);
  letter-spacing: 1.2px;
  margin-right: 12px;
  min-width: 64px;
  font-weight: 600;
}
.filter-chip {
  display: inline-block;
  padding: 6px 13px;
  background: var(--bg-2);
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--text-dim);
  font-size: 12px;
  font-weight: 600;
  transition: background var(--t-fast), color var(--t-fast);
}
.filter-chip:hover {
  background: var(--accent-soft);
  color: var(--accent);
}
.filter-chip.active {
  background: var(--accent);
  color: #fff;
}

/* ============================================================
   Video grid + cards
   ============================================================ */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(288px, 1fr));
  gap: 20px;
  align-items: start;
}

.card {
  display: block;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform var(--t-fast), box-shadow var(--t-fast);
  color: var(--text);
  box-shadow: var(--shadow-sm);
}
.card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}

.card-link {
  display: block;
  color: var(--text);
}
.card-link:hover { color: var(--text); }

.card .thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--bg-2, #1a1c20);
  overflow: hidden;
}
/* Short cards use portrait 9:16 aspect and narrower grid columns */
.card-short .thumb { aspect-ratio: 9 / 16; }
.grid:has(.card-short) {
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
/* Skeleton shimmer — visible until the <img> loads on top */
@keyframes shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position: 400px 0; }
}
.card .thumb::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    var(--bg-2, #1a1c20) 0%,
    var(--bg-3, #2a2d33) 40%,
    var(--bg-2, #1a1c20) 80%
  );
  background-size: 800px 100%;
  animation: shimmer 1.5s ease-in-out infinite;
  z-index: 0;
}
.card .thumb img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .4s ease, opacity .3s ease;
  z-index: 1;
}
.card:hover .thumb img { transform: scale(1.05); }
/* Hover video preview — layered above img, below badges */
.card .thumb video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 2;
  opacity: 0;
  transition: opacity .3s ease;
}
.card .thumb video.is-active { opacity: 1; }

.badge-q {
  position: absolute;
  top: 8px;
  left: 8px;
  background: var(--accent);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 3px;
  letter-spacing: .3px;
  z-index: 3;
}
.badge-q-hd  { background: #00aff0; }
.badge-q-fhd { background: #0086c3; }
.badge-q-4k  { background: #e91e63; }

.badge-dur {
  position: absolute;
  bottom: 8px;
  right: 8px;
  background: rgba(0, 0, 0, .75);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 3px;
  z-index: 3;
}

/* Like-percentage badge on the video thumbnail. Sits in the
   bottom-left corner so it can't collide with the duration
   badge in the bottom-right. Colour shifts from "muted" →
   accent blue at 80%+ and a warm red below 50% so the value
   is readable at a glance. */
.badge-pct {
  position: absolute;
  bottom: 8px;
  left: 8px;
  background: rgba(0, 0, 0, .78);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 3px;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  letter-spacing: .2px;
}
.badge-pct svg { display: block; }
.badge-pct-good { background: var(--accent); color: #fff; }
.badge-pct-bad  { background: #e53935; color: #fff; }

.badge-src {
  position: absolute;
  top: 8px;
  right: 8px;
  font-size: 10px;
  font-weight: 800;
  padding: 3px 8px;
  border-radius: 999px;
  letter-spacing: 1px;
  z-index: 3;
  color: #fff;
  backdrop-filter: blur(6px);
}
.badge-src.source-sb { background: linear-gradient(135deg, #3b82f6, #1d4ed8); }
.badge-src.source-xv { background: linear-gradient(135deg, #dc2626, #991b1b); }
.badge-src.source-xn { background: linear-gradient(135deg, #16a34a, #15803d); }
.badge-src-inline {
  position: static;
  display: inline-block;
  vertical-align: middle;
  margin-left: 4px;
}

.play-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 56px;
  color: rgba(255, 255, 255, .95);
  text-shadow: 0 4px 18px rgba(0, 0, 0, .8);
  opacity: 0;
  transition: opacity var(--t-fast);
  pointer-events: none;
  z-index: 2;
}
.card:hover .play-overlay { opacity: 1; }

.card-meta { padding: 13px 14px 15px; }
.card-body { padding: 14px 15px 7px; }

.card-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.35;
  word-break: break-word;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  height: 2.7em;
  max-height: 2.7em;
}

.card-info {
  padding: 0 15px 15px;
  font-size: 13px;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
}
.views-pill {
  color: var(--text-dim);
  font-weight: 600;
}
.likes-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--text-dim);
  font-weight: 700;
  font-size: 12px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--bg-2);
}
.likes-pill svg { display: block; opacity: .9; }
.likes-pill-good {
  color: var(--accent);
  background: var(--accent-soft);
}
.likes-pill-bad {
  color: #e53935;
  background: rgba(229, 57, 53, .1);
}
.card-channel {
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 160px;
}
.card-channel:hover { color: var(--accent-2); text-decoration: underline; }

.card .thumb::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--preview-bg, none);
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity .35s;
  z-index: 1;
  pointer-events: none;
}
.card:hover .thumb::after { opacity: 1; }

/* ============================================================
   Pager
   ============================================================ */
.pager {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin: 40px 0 0;
  flex-wrap: wrap;
}
.pager a, .pager .dots {
  display: inline-block;
  padding: 8px 14px;
  border-radius: 8px;
  background: var(--bg-1);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  border: 1px solid var(--line);
  transition: all var(--t-fast);
}
.pager a:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-soft);
}
.pager a.active {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.pager .dots { background: transparent; border: 0; color: var(--muted); }

/* ============================================================
   Empty / error
   ============================================================ */
.empty {
  text-align: center;
  padding: 60px 0;
  color: var(--muted);
  font-size: 15px;
}
.error-page { text-align: center; padding: 80px 20px; }
.error-page h1 {
  font-size: 96px;
  margin: 0;
  color: var(--accent);
  font-weight: 900;
  letter-spacing: -2px;
}
.btn {
  display: inline-block;
  margin-top: 24px;
  padding: 11px 26px;
  background: var(--accent);
  color: #fff;
  border-radius: 999px;
  font-weight: 600;
  transition: background var(--t-fast);
}
.btn:hover { background: var(--accent-2); }

/* ============================================================
   Video page — full-width 2-col layout (main + sidebar)
   ============================================================ */
/* The parent .container is now full-viewport width (no max-width
   cap), so we no longer need the negative-margin break-out trick.
   The video page just fills whatever width the container gives it
   and stays perfectly aligned with the header + footer. */
.video-page {
  max-width: none;
  padding: 0;
}

/* Related Videos section inside the video main column. The grid
   uses ``auto-fit`` (not ``auto-fill``) so columns stretch to
   fill the row — this prevents the "last row has 2 cards and the
   rest of the row is empty" look the previous config produced. */
.related-section {
  margin-top: 26px;
  width: 100%;
}
.related-section .grid {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
  width: 100%;
}
.related-head {
  font-size: 16px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text);
  margin: 0 0 14px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--line);
}

.video-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 440px;
  gap: 24px;
  align-items: start;
}

/* Wider sidebar on ultra-wide displays */
@media (min-width: 1600px) {
  .video-layout {
    grid-template-columns: minmax(0, 1fr) 500px;
    gap: 28px;
  }
}
@media (min-width: 1920px) {
  .video-layout {
    grid-template-columns: minmax(0, 1fr) 540px;
    gap: 32px;
  }
}
.video-main { min-width: 0; }

/* Transparent sidebar — no panel wrapper, NOT sticky, NO separate
   scrollbar. Just a vertical column of regular full-size cards
   that flows next to the main content and scrolls with the page,
   exactly like Spankbang's "Up Next" column. */
.video-sidebar {
  background: transparent;
  border: none;
  padding: 0;
}
.video-sidebar-head {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--text);
  padding: 0 0 14px;
  margin-bottom: 4px;
  border-bottom: 2px solid var(--line);
}
/* Single-column stack of full-size `.card`s. The card width is
   constrained by the sidebar column width (380-460px depending on
   breakpoint) so each card renders at the SAME visual size as the
   main grid cards, no longer tiny. */
.video-sidebar-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 18px;
  padding-top: 14px;
  position: relative;
}
/* Collapsed state: the list is capped so its bottom lines up
   with the bottom of the shorts strip on the left column. The
   ``--sidebar-cap`` variable is set by ``main.js`` on load +
   resize (measured as the distance from the sidebar list's top
   to the shorts-row's bottom). Fallback value large enough that
   the sidebar still extends well past the player if JS hasn't
   run yet.
   A bottom gradient fade softens the clip edge; the "Xem thêm"
   button below the list lifts the cap when clicked. */
.video-sidebar-list.collapsed {
  max-height: var(--sidebar-cap, 1600px);
  overflow: hidden;
}
.video-sidebar-list.collapsed .video-sidebar-fade {
  display: block;
}
.video-sidebar-fade {
  display: none;
  position: sticky;
  bottom: 0;
  left: 0;
  right: 0;
  height: 80px;
  margin-top: -80px;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    rgba(var(--bg-rgb, 255, 255, 255), 0) 0%,
    var(--bg) 100%
  );
  z-index: 2;
}
[data-theme="dark"] .video-sidebar-fade {
  background: linear-gradient(
    to bottom,
    rgba(15, 16, 18, 0) 0%,
    var(--bg) 100%
  );
}
.video-sidebar-more {
  display: block;
  width: 100%;
  margin: 14px 0 0;
  padding: 12px 16px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .3px;
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.video-sidebar-more:hover {
  background: var(--bg-3, var(--bg-2));
  border-color: var(--accent);
  color: var(--accent);
}

/* --- horizontal sidebar card (thumb left, info right) --- */
.card-h {
  display: flex;
  gap: 10px;
  padding: 4px;
  border-radius: var(--radius-sm);
  color: var(--text);
  transition: background var(--t-fast);
}
.card-h:hover { background: var(--bg-2); }
.card-h-thumb {
  flex: 0 0 200px;
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.card-h-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.card-h-thumb .badge-q,
.card-h-thumb .badge-dur {
  font-size: 9px;
  padding: 1px 5px;
}
.card-h-meta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 2px 4px 2px 0;
}
.card-h-title {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card-h-info {
  font-size: 12px;
  color: var(--muted);
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.ch-meta-channel {
  color: var(--accent);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 140px;
}

/* --- channel card (uploader block under stats) --- */
.channel-card {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  margin: 14px 0;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text);
  transition: all var(--t-fast);
}
.channel-card:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.channel-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 18px;
  flex-shrink: 0;
}
.channel-info {
  display: flex;
  flex-direction: column;
}
.channel-name {
  font-weight: 700;
  font-size: 14px;
  color: var(--text);
}
.channel-label {
  font-size: 11px;
  color: var(--muted);
  letter-spacing: .5px;
}

/* mobile: stack to single column */
@media (max-width: 1100px) {
  .video-layout {
    grid-template-columns: 1fr;
    gap: 20px;
  }
  .video-sidebar {
    position: static;
    max-height: none;
  }
}

.player-wrap {
  position: relative;
  background: #000;
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 16 / 9;
  box-shadow: var(--shadow-lg);
  border: 1px solid var(--line);
}
#player {
  width: 100%;
  height: 100%;
  display: block;
  background: #000;
}
#player video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
}

/* Mobile: player full-width edge-to-edge.
   Structure: .container(padding:12px) > .video-page > .video-layout
              > .video-main > .player-wrap
   We zero out the container padding when a video-page is inside,
   then re-pad all non-player content so text stays inset.
   MUST come after the base .player-wrap rule to win the cascade. */
@media (max-width: 768px) {
  .container:has(.video-page) {
    padding-left: 0;
    padding-right: 0;
  }
  .video-page .video-main > *:not(.player-wrap) {
    padding-left: 12px;
    padding-right: 12px;
  }
  .player-wrap {
    border-radius: 0;
    border: none;
    box-shadow: none;
  }
  /* ArtPlayer controls overflow on narrow screens — hide
     non-essential buttons so play/time/quality/fullscreen fit. */
  .art-control-screenshot,
  .art-control-pip,
  .art-control-fullscreenWeb {
    display: none !important;
  }
  .video-page .video-sidebar {
    padding-left: 12px;
    padding-right: 12px;
  }
}

.no-stream {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .85);
  color: var(--accent);
  font-size: 16px;
  text-align: center;
  padding: 20px;
  z-index: 5;
  pointer-events: none;
}

/* ArtPlayer overrides */
.art-video-player { font-family: inherit !important; }

/* Xóa lớp màng đen (overlay) gây cản trở hình ảnh trên player khi pause hoặc load */
.art-video-player .art-state,
.art-video-player .art-mask,
.art-video-player .art-layers {
  background: transparent !important;
  background-color: transparent !important;
}

/* ============================================================
   Chapters grid (10 evenly-spaced frame previews below player)
   ============================================================ */
.chapters-row {
  margin: 20px 0 14px;
  padding: 14px 16px;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.chapters-head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 14px;
}
.chapters-head strong {
  color: var(--accent);
  font-size: 11px;
  letter-spacing: 2px;
  font-weight: 800;
  text-transform: uppercase;
}
.chapters-head .muted {
  font-size: 11px;
  letter-spacing: .5px;
}
.chapters-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}
.chapter {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: var(--radius-sm);
  overflow: hidden;
  cursor: pointer;
  border: 1px solid var(--line);
  transition: transform var(--t-fast), border-color var(--t-fast);
}
.chapter:hover {
  transform: translateY(-1px);
  border-color: var(--accent);
}
/* Sprite-based chapter — single shared image cropped via CSS */
.chapter-sprite {
  background-repeat: no-repeat;
  /* background-image / -size / -position set inline by JS */
}
.chapter .ch-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  background: #000;
}
.chapter .ch-time {
  position: absolute;
  bottom: 6px;
  right: 6px;
  background: rgba(0, 0, 0, .78);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 3px;
  z-index: 2;
}
.chapter .ch-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 36px;
  color: rgba(255, 255, 255, .92);
  text-shadow: 0 4px 14px rgba(0, 0, 0, .85);
  opacity: 0;
  transition: opacity var(--t-fast);
  pointer-events: none;
  z-index: 2;
}
.chapter:hover .ch-play { opacity: 1; }

/* Mobile: 10 chapters as a 2×5 grid eats a huge chunk of vertical
   space above the "IN N PLAYLISTS" row. Convert to a horizontal
   strip (flex + overflow-x) so each chapter is ~160px wide and
   the user swipes sideways — mirrors the playlists row below it
   so both sections visually echo each other on mobile. */
@media (max-width: 900px) {
  .chapters-row { padding: 12px 0 10px; }
  .chapters-head { padding: 0 16px; margin-bottom: 10px; }
  .chapters-grid {
    display: flex;
    grid-template-columns: none;
    gap: 10px;
    overflow-x: auto;
    padding: 2px 16px 10px;
    scrollbar-width: thin;
    scrollbar-color: var(--accent) transparent;
    /* Snap so each chapter lands at the left edge after a swipe */
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
  }
  .chapters-grid::-webkit-scrollbar { height: 4px; }
  .chapters-grid::-webkit-scrollbar-thumb {
    background: var(--accent);
    border-radius: 2px;
  }
  .chapters-grid .chapter {
    flex: 0 0 160px;
    scroll-snap-align: start;
  }
}
@media (max-width: 600px) {
  .chapters-grid .chapter { flex-basis: 150px; }
}
.art-video-player .art-bottom {
  background: transparent !important;
}
.art-video-player .art-control-progress .art-progress-played,
.art-video-player .art-control-progress .art-progress-indicator,
.art-video-player .art-volume-slider-handle,
.art-video-player .art-mini-progress-bar {
  background-color: var(--accent) !important;
}
.art-video-player .art-icon {
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .8));
}

.loading-spinner {
  width: 48px;
  height: 48px;
  border: 4px solid var(--accent-soft);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ----- Lazy-load grid sentinel ----- */
.grid-sentinel {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 36px 0 60px;
  color: var(--muted);
  font-size: 13px;
  letter-spacing: .5px;
  min-height: 80px;
}
.grid-sentinel .loading-spinner {
  width: 28px;
  height: 28px;
  border-width: 3px;
}
.grid-sentinel[data-state="done"] { color: var(--accent); font-weight: 700; }
.grid-sentinel[data-state="done"] .loading-spinner,
.grid-sentinel[data-state="error"] .loading-spinner { display: none; }
.grid-sentinel[data-state="error"] { color: #e53935; }
.grid-sentinel[data-state="idle"] .loading-spinner { opacity: .5; }

.video-title {
  font-size: 26px;
  margin: 26px 0 14px;
  color: var(--text);
  line-height: 1.25;
  font-weight: 700;
  letter-spacing: -.4px;
}
.video-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  font-size: 13px;
  color: var(--text-dim);
  padding: 12px 18px;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: 999px;
}
.video-stats > span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

/* Shared inline-SVG icon alignment: `_ui_icon()` output gets
   middle-aligned with its neighbouring text no matter where it
   lands (card views-pill, video stats row, channel link, etc.),
   and always picks up the parent's color for correct dark-mode
   rendering. */
.ui-icon {
  display: inline-block;
  vertical-align: -2px;
  flex-shrink: 0;
}
.actors-row, .tags-row {
  margin: 18px 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.actors-row strong, .tags-row strong {
  color: var(--muted);
  margin-right: 6px;
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 1px;
  font-weight: 700;
}
.desc-row {
  margin: 18px 0;
  padding: 14px 18px;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  border-left: 3px solid var(--accent);
  font-size: 14px;
  line-height: 1.65;
  color: var(--text-dim);
}
.desc-row p { margin: 0; }

.related { margin-top: 40px; }
.related h2 {
  font-size: 20px;
  margin: 0 0 18px;
  color: var(--text);
  border-left: 3px solid var(--accent);
  padding-left: 12px;
  font-weight: 700;
}

/* ============================================================
   Playlist cards (stacked effect)
   ============================================================ */
.pl-card { background: transparent; border: 0; box-shadow: none; }
.pl-stack {
  position: relative;
  aspect-ratio: 16 / 9;
  margin: 8px 8px 16px;
  transition: transform var(--t-fast);
}
.pl-card:hover .pl-stack { transform: translateY(-2px); }
.pl-stack-back-2 {
  position: absolute;
  top: -6px; left: 6px; right: 6px; bottom: 12px;
  background: var(--bg-3);
  border-radius: var(--radius);
  z-index: 0;
}
.pl-stack-back-1 {
  position: absolute;
  top: -3px; left: 3px; right: 3px; bottom: 6px;
  background: var(--bg-2);
  border-radius: var(--radius);
  z-index: 1;
}
.pl-stack-front {
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
  background-color: #000;
  background-size: cover;
  background-position: center;
  box-shadow: var(--shadow-sm);
  z-index: 2;
  overflow: hidden;
  border: 1px solid var(--line);
  transition: box-shadow var(--t-fast);
}
.pl-card:hover .pl-stack-front {
  box-shadow: var(--shadow);
}
.pl-badge {
  position: absolute;
  bottom: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(0, 0, 0, .75);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 3px;
  z-index: 3;
}
.pl-tag {
  position: absolute;
  top: 8px;
  left: 8px;
  background: var(--accent);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 3px;
  letter-spacing: 1px;
  z-index: 3;
}
.pl-avail {
  color: var(--accent);
  font-weight: 700;
}

/* --- Mini playlist horizontal scroller (video detail) --- */
.playlists-row {
  margin: 18px 0;
  padding: 16px 0;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  border-left: 3px solid var(--accent);
}
.playlists-row-head { padding: 0 22px 14px; }
.playlists-row-head strong {
  color: var(--accent);
  font-size: 11px;
  letter-spacing: 2px;
  font-weight: 800;
}
.pl-mini-scroll {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  padding: 4px 22px 14px;
  scrollbar-width: thin;
  scrollbar-color: var(--accent) transparent;
}
.pl-mini-scroll::-webkit-scrollbar { height: 6px; }
.pl-mini-scroll::-webkit-scrollbar-thumb {
  background: var(--accent);
  border-radius: 3px;
}
.pl-mini {
  flex: 0 0 220px;
  display: block;
  color: var(--text);
  transition: transform var(--t-fast);
}
.pl-mini:hover { transform: translateY(-3px); }

.pl-mini-stack {
  position: relative;
  aspect-ratio: 16 / 9;
  margin-bottom: 8px;
}
.pl-mini-stack::before,
.pl-mini-stack::after {
  content: "";
  position: absolute;
  border-radius: var(--radius-sm);
}
.pl-mini-stack::before {
  top: -4px; left: 4px; right: 4px; bottom: 8px;
  background: var(--bg-3);
  z-index: 0;
}
.pl-mini-stack::after {
  top: -2px; left: 2px; right: 2px; bottom: 4px;
  background: var(--bg-2);
  z-index: 1;
}
.pl-mini-thumb {
  position: absolute;
  inset: 0;
  background-color: #000;
  background-size: cover;
  background-position: center;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  z-index: 2;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: border-color var(--t-fast);
}
.pl-mini:hover .pl-mini-thumb {
  border-color: var(--accent);
}
.pl-mini-count {
  position: absolute;
  bottom: 6px;
  right: 6px;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  background: rgba(0, 0, 0, .75);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 3px;
  z-index: 3;
}
.pl-mini-title {
  font-size: 12px;
  color: var(--text);
  font-weight: 600;
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  height: 2.7em;
  padding: 0 4px;
}

.pl-progress {
  margin-bottom: 24px;
  padding: 12px 18px;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  position: relative;
  overflow: hidden;
  font-size: 13px;
  color: var(--text-dim);
}
.pl-progress-bar {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  background: linear-gradient(90deg,
    var(--accent-soft),
    transparent);
  z-index: 0;
}
.pl-progress span {
  position: relative;
  z-index: 1;
}

/* ============================================================
   Entity index pages
   ============================================================ */
.entity-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 10px;
}
.entity-chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 14px 8px 8px;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  transition: background var(--t-fast), color var(--t-fast),
              border-color var(--t-fast);
  min-height: 48px;
}
.entity-chip:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}
.entity-left {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex: 1;
}
.entity-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}
.entity-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 14px;
  font-weight: 700;
  flex-shrink: 0;
}
.entity-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg-3);
  flex-shrink: 0;
  border: 2px solid var(--line);
  transition: border-color var(--t-fast);
}
.entity-chip:hover .entity-avatar { border-color: var(--accent); }
.entity-count {
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  padding: 2px 9px;
  border-radius: 999px;
  flex-shrink: 0;
}

/* ============================================================
   Entity detail hero — channel / pornstar page header
   ============================================================
   Mirrors xhamster's creator page: a 64px circular avatar on the
   left with the name + subtitle stacked on the right. Falls back
   to a cream-colored initial circle when no avatar is known. */
.entity-hero {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 20px 0 24px;
}
.entity-hero-avatar {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--bg-2);
  border: 2px solid var(--line);
  box-shadow: var(--shadow-sm);
}
.entity-hero-initial {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  background: var(--accent-soft);
  border-color: var(--accent-soft);
  font-weight: 800;
  font-size: 28px;
  letter-spacing: -.5px;
  text-transform: uppercase;
}
.entity-hero-text { flex: 1; min-width: 0; }
.entity-hero-text h1 {
  margin: 0 0 4px;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -.5px;
  color: var(--text);
}
.entity-hero-text .muted {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
}
@media (max-width: 600px) {
  .entity-hero { gap: 14px; padding: 14px 0 18px; }
  .entity-hero-avatar { width: 56px; height: 56px; }
  .entity-hero-initial { font-size: 22px; }
  .entity-hero-text h1 { font-size: 20px; }
}

/* ----- Entity page tabs ----- */
/* Renders between the hero and the grid on channel / pornstar
   detail pages: two pill-style links that swap the ``?tab=``
   querystring between "videos" and "shorts". Matches the
   xhamster creator-page layout. */
.entity-tabs {
  display: flex;
  gap: 8px;
  margin: 0 0 18px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.entity-tabs::-webkit-scrollbar { display: none; }
.entity-tab {
  padding: 10px 18px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-dim);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color var(--t-fast), border-color var(--t-fast);
  white-space: nowrap;
}
.entity-tab:hover { color: var(--text); }
.entity-tab.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.entity-tab-count {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .08);
  color: inherit;
  font-size: 11px;
  font-weight: 700;
  vertical-align: middle;
}
[data-theme="dark"] .entity-tab-count {
  background: rgba(255, 255, 255, .1);
}
.entity-tab.active .entity-tab-count {
  background: var(--accent);
  color: #fff;
}

/* ============================================================
   Footer
   ============================================================ */
.site-footer {
  margin-top: 80px;
  background: var(--bg-1);
  border-top: 1px solid var(--line);
  padding: 40px 0 20px;
}
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 36px;
  margin-bottom: 30px;
}
.footer-col h4 {
  font-size: 13px;
  color: var(--text);
  text-transform: uppercase;
  display: flex;
  align-items: center;
}
.footer-col h4 img {
  flex-shrink: 0;
}
.footer-col h4 span {
  font-size: 32px !important;
  letter-spacing: 1px;
  margin: 0 0 14px;
  font-weight: 700;
}
.footer-col a, .footer-col span {
  display: block;
  color: var(--muted);
  font-size: 13px;
  margin-bottom: 8px;
  transition: color var(--t-fast);
}
.footer-col a:hover { color: var(--accent); }
.footer-col p {
  color: var(--muted);
  font-size: 13px;
  line-height: 1.7;
  margin: 0;
}
.footer-bottom {
  padding-top: 18px;
  border-top: 1px solid var(--line);
  text-align: center;
  font-size: 12px;
  color: var(--muted);
}

/* ============================================================
   Mobile
   ============================================================ */
@media (max-width: 900px) {
  /* CRITICAL: the desktop ``.site-header`` has ``backdrop-filter``,
     which per CSS spec creates a new containing block for any
     descendant with ``position: fixed``. That breaks the slide-in
     nav drawer — it gets anchored to the 66px-tall header box
     instead of the viewport, collapsing its height and spilling
     items across the page. On mobile we don't need the glass
     effect on the header (it barely reads on a tiny screen),
     so kill backdrop-filter to restore the viewport as the
     containing block for ``position: fixed`` children. */
  .site-header {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: var(--bg-1);
  }
  /* Show the burger button at narrow viewports — wide desktop
     keeps the inline nav pills, mobile collapses them into a
     slide-out drawer. */
  .burger { display: flex; }

  /* Mobile: keep the logo visible but TIGHTEN it so the search
     bar gets more horizontal room without pushing chrome out
     of the header. The search input also bumps up its font
     size + vertical padding so the field FEELS bigger to the
     thumb without needing the full bar width. */
  .site-header .logo {
    font-size: 20px;
    margin-right: 4px;
  }
  .site-header .search-form {
    flex: 1 1 0;
    min-width: 0;
    max-width: none;
  }
  .site-header .search-form input {
    font-size: 16px;       /* prevents iOS auto-zoom on focus */
    padding: 13px 16px;
  }
  .site-header .search-form button {
    padding: 0 16px;
  }
  .main-bar-inner {
    gap: 10px;
  }

  /* Drawer: anchored BELOW the header band so the header
     chrome stays visible at the top of the viewport while
     the drawer fills the remaining height. ``--header-h`` is
     written by main.js to match the actual rendered header
     height (including the cat-strip when present), with a
     66 px fallback for the brief window before the JS runs. */
  .main-nav {
    position: fixed;
    top: var(--header-h, 66px);
    right: 0;
    height: calc(100vh - var(--header-h, 66px));
    height: calc(100svh - var(--header-h, 66px));
    width: 260px;
    background: var(--bg-1);
    flex-direction: column;
    padding: 18px;
    border-left: 1px solid var(--line);
    z-index: 200;
    box-shadow: var(--shadow-lg);
    overflow-y: auto;
    visibility: hidden;
    transform: translateX(100%);
    transition: transform var(--t-mid);
    margin-left: 0;
    gap: 4px;
  }
  body.nav-open .main-nav {
    visibility: visible;
    transform: translateX(0);
  }
  .main-nav a {
    padding: 14px;
    font-size: 14px;
    gap: 10px;
  }

  /* (Backdrop dimming was removed per UX request — opening
     the drawer now leaves the page content untouched. The
     outside-click dismiss handler in main.js still closes the
     drawer when the user taps anywhere outside it.) */
  /* Close any other floating overlays (notably the search
     autocomplete dropdown) when the drawer opens, so they
     don't sit on top of the menu items. */
  body.nav-open .search-dropdown {
    display: none !important;
  }

  /* ---- Mobile: collapse theme + auth into the drawer ----
     Per UX: the search bar needs every horizontal pixel on
     mobile, so the theme toggle and auth button get dropped
     out of the top bar and re-anchored at the BOTTOM of the
     slide-out drawer (right above the safe-area inset). The
     two circles sit side-by-side as a footer row of the menu.
     ``position: fixed`` keeps them out of flow; the drawer's
     own visibility / transform rules animate them in/out with
     the rest of the nav. */
  .site-header .theme-toggle,
  .site-header .auth-menu,
  .site-header .auth-avatar-btn {
    position: fixed;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 20px);
    z-index: 201;
    visibility: hidden;
    pointer-events: none;
    transform: translateX(260px);
    transition: transform var(--t-mid);
  }
  /* Theme toggle in the right corner of the drawer footer,
     auth circle to its left — matches Figma sketch the user
     shared. The 260px drawer width is the anchor: theme sits
     at right:20px, auth at right:76px (= 20 + 48 + gap). */
  .site-header .theme-toggle { right: 20px; }
  .site-header .auth-menu,
  .site-header .auth-avatar-btn { right: 76px; }
  body.nav-open .site-header .theme-toggle,
  body.nav-open .site-header .auth-menu,
  body.nav-open .site-header .auth-avatar-btn {
    visibility: visible;
    pointer-events: auto;
    transform: translateX(0);
  }

  .top-strip { display: none; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(192px, 1fr)); gap: 14px; }
  .card-title { font-size: 14px; }
  .video-title { font-size: 18px; }

  /* Search form takes the freed horizontal space on mobile
     now that theme + auth moved out of the top bar. */
  .search-form { flex: 1 1 auto; min-width: 0; max-width: none; }
}

/* Theme + auth circles get explicit ``order`` values so the
   burger (order: 99) always lands at the far right of the
   top bar with the two circles immediately to its left when
   the burger is showing (mobile + shorts page). */
.site-header .theme-toggle { order: 50; }
.site-header .auth-menu,
.site-header .auth-avatar-btn { order: 51; }

/* Shorts viewer: header layout is identical to the normal page.
   Only visual overrides (dark theme, auto-hide) are applied —
   see the @media (min-width: 901px) block in the header section.
   No nav collapse, no search expansion, no burger force-show. */

@media (max-width: 600px) {
  .footer-grid { grid-template-columns: 1fr; gap: 20px; }
  .container { padding: 0 12px; }
  .main-bar-inner { gap: 10px; height: 56px; }
  .logo { font-size: 22px; }
  .grid { grid-template-columns: 1fr 1fr; gap: 10px; }
  .hero-grid { grid-template-columns: 1fr; }
  .hero-sides { grid-template-columns: 1fr; }
  .filter-row { flex-direction: column; align-items: flex-start; }
  .filter-label { min-width: auto; margin-bottom: 4px; }
}

/* ============================================================
   Header search autocomplete dropdown
   ============================================================ */
.search-dropdown {
  position: fixed;
  z-index: 500;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 18px 42px rgba(0, 0, 0, .25),
              0 2px 10px rgba(0, 0, 0, .08);
  overflow: hidden;
  max-height: calc(100vh - 140px);
  overflow-y: auto;
  font-size: 13px;
  color: var(--text);
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
}
.search-dropdown::-webkit-scrollbar { width: 8px; }
.search-dropdown::-webkit-scrollbar-track { background: transparent; }
.search-dropdown::-webkit-scrollbar-thumb {
  background: var(--line-2);
  border-radius: 4px;
}
.search-dropdown b {
  color: var(--accent);
  font-weight: 700;
}

/* -- "Search all videos containing X" shortcut row -- */
.sd-submit-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  cursor: pointer;
  color: var(--text);
  background: var(--bg-1);
  border-bottom: 1px solid var(--line);
  font-size: 13px;
  transition: background var(--t-fast);
}
.sd-submit-row:hover,
.sd-submit-row.active {
  background: var(--accent-soft);
  color: var(--accent);
}
.sd-submit-row svg { color: var(--accent); flex-shrink: 0; }

/* -- empty state -- */
.sd-empty {
  padding: 18px 16px 10px;
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}

/* -- sections -- */
.sd-section {
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}
.sd-section:last-child { border-bottom: none; }
.sd-section-head {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--muted);
  padding: 6px 16px 8px;
}

/* -- generic row (pornstar / channel / recent) -- */
.sd-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px;
  cursor: pointer;
  color: var(--text);
  text-decoration: none;
  transition: background var(--t-fast);
}
.sd-row:hover,
.sd-row.active {
  background: var(--bg-2);
}
.sd-row.active {
  background: var(--accent-soft);
}
.sd-main {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sd-count {
  font-size: 11px;
  color: var(--muted);
  flex-shrink: 0;
}

/* -- avatar for pornstar / channel / placeholder -- */
.sd-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--bg-2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
}
.sd-avatar-placeholder {
  background: var(--accent-soft);
  color: var(--accent);
}

/* -- tag chips row -- */
.sd-tag-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 16px 6px;
}
.sd-tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text);
  font-size: 12px;
  text-decoration: none;
  transition: all var(--t-fast);
  cursor: pointer;
}
.sd-tag-chip:hover,
.sd-tag-chip.active {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}
.sd-tag-chip .sd-count {
  background: rgba(0, 0, 0, .08);
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 10px;
}

/* -- video row (thumb + title + views) -- */
.sd-row-video {
  align-items: flex-start;
  padding: 8px 16px;
}
.sd-thumb {
  position: relative;
  flex-shrink: 0;
  width: 112px;
  aspect-ratio: 16 / 9;
  border-radius: 6px;
  overflow: hidden;
  background: #000;
}
.sd-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.sd-thumb .sd-q {
  position: absolute;
  top: 4px;
  left: 4px;
  background: var(--accent);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 3px;
  letter-spacing: .3px;
}
.sd-thumb .sd-dur {
  position: absolute;
  bottom: 4px;
  right: 4px;
  background: rgba(0, 0, 0, .75);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: 3px;
}
.sd-v-meta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 2px;
}
.sd-v-title {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.sd-v-stats {
  font-size: 11px;
  color: var(--muted);
}

/* -- recent searches row -- */
.sd-row-recent .sd-recent-icon {
  color: var(--muted);
  flex-shrink: 0;
}
.sd-recent-x {
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 14px;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
  transition: all var(--t-fast);
}
.sd-recent-x:hover {
  background: var(--bg-2);
  color: var(--text);
}

@media (max-width: 600px) {
  .search-dropdown { font-size: 12px; }
  .sd-thumb { width: 92px; }
}

/* ============================================================
   Header user-menu — circular avatar button + popover
   ============================================================ */
/* ``<details>`` element wraps the button (<summary>) and the
   popover (<div>). ::before is a transparent full-screen layer
   used to close the menu when the user clicks anywhere else. */
.auth-menu {
  position: relative;
  flex-shrink: 0;
}
.auth-menu > summary {
  list-style: none;
}
.auth-menu > summary::-webkit-details-marker,
.auth-menu > summary::marker {
  display: none;
}
/* Match .theme-toggle footprint exactly (38×38) so the two
   round icons in the header sit on the same baseline. */
.auth-avatar-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--bg-2);
  border: 1px solid var(--line);
  color: var(--text);
  cursor: pointer;
  transition: all var(--t-fast);
  flex-shrink: 0;
  text-decoration: none;  /* anchor variant used on logged-out state */
}
.auth-avatar-btn:hover,
.auth-menu[open] .auth-avatar-btn {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-soft);
  transform: scale(1.02);
}
.auth-avatar-btn svg { display: block; }

/* Popover card — appears below and right-aligned to the button. */
.auth-pop {
  position: absolute;
  right: 0;
  top: calc(100% + 10px);
  min-width: 240px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg), 0 2px 6px rgba(0, 0, 0, .08);
  padding: 6px;
  z-index: 150;
  display: flex;
  flex-direction: column;
  gap: 2px;
  animation: authPopIn .14s ease-out;
  transform-origin: top right;
}
@keyframes authPopIn {
  from { opacity: 0; transform: translateY(-4px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* Little arrow that points back at the avatar button */
.auth-pop::before {
  content: "";
  position: absolute;
  top: -6px;
  right: 14px;
  width: 12px;
  height: 12px;
  background: var(--bg-card);
  border-left: 1px solid var(--line);
  border-top: 1px solid var(--line);
  transform: rotate(45deg);
}

/* Menu items — link, button or wrapped-in-form, same look. */
.auth-pop-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  color: var(--text);
  background: transparent;
  border: 0;
  width: 100%;
  text-align: left;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--t-fast), color var(--t-fast);
  box-sizing: border-box;
  white-space: nowrap;
}
.auth-pop-item:hover {
  background: var(--bg-2);
  color: var(--accent);
}
.auth-pop-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 13px;
  font-weight: 800;
  flex-shrink: 0;
}
.auth-pop-logout { color: #e53935; }
.auth-pop-logout:hover {
  background: rgba(229, 57, 53, .08);
  color: #e53935;
}
.auth-pop-logout .auth-pop-icon {
  background: rgba(229, 57, 53, .12);
  color: #e53935;
}
.auth-pop-form { margin: 0; width: 100%; }

/* Logged-in header card: avatar + username above the menu. */
.auth-pop-user {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 14px 12px;
}
.auth-pop-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  flex-shrink: 0;
}
.auth-pop-uname {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 180px;
}
.auth-pop-sep {
  height: 1px;
  background: var(--line);
  margin: 2px 4px;
}

/* NO backdrop layer. A previous revision used
   ``.auth-menu[open]::before { position: fixed; inset: 0 }`` to
   catch outside clicks, but:
   1. A pseudo-element can't actually wire its own click handler
      (clicks bubble up through the owning element), so the menu
      never auto-closed.
   2. The transparent full-viewport layer intercepted every click
      below it — cards, buttons, search bar — making the whole
      page feel frozen while the popup was open.
   Instead, main.js attaches a document-level click-outside
   listener that closes any open ``<details class="auth-menu">``
   when the user taps anywhere outside it. */

@media (max-width: 600px) {
  .auth-pop { min-width: 200px; right: -8px; }
  .auth-pop::before { right: 20px; }
}

/* ============================================================
   Auth page (login / register card)
   ============================================================ */
.auth-wrap {
  display: flex;
  justify-content: center;
  padding: 40px 20px 80px;
}
.auth-card {
  width: 100%;
  max-width: 420px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 36px 32px 32px;
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  gap: 16px;
}
/* Centered heading + subtitle, matches the reference design
   where both are horizontally centred over the form stack. */
.auth-title {
  font-size: 28px;
  font-weight: 800;
  color: var(--text);
  margin: 0;
  text-align: center;
  letter-spacing: -.5px;
}
.auth-sub {
  font-size: 14px;
  color: var(--muted);
  margin: -6px 0 10px;
  text-align: center;
}
.auth-error {
  background: rgba(229, 57, 53, .08);
  border: 1px solid rgba(229, 57, 53, .3);
  color: #e53935;
  padding: 10px 14px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.4;
  text-align: center;
}
/* Each field is a rounded "pill" with a leading monochrome icon
   flush-left, the <input> filling the rest, and (for password
   fields) a trailing eye-toggle. The whole row is the
   interactive surface — clicking the icon still focuses the
   input because the wrapper is a <label>. */
.auth-field {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 18px;
  height: 52px;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: 999px;
  transition: border-color var(--t-fast), box-shadow var(--t-fast),
              background var(--t-fast);
  position: relative;
}
.auth-field:focus-within {
  border-color: var(--accent);
  background: var(--bg-card);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
.auth-field .af-icon {
  width: 20px;
  height: 20px;
  color: var(--muted);
  flex-shrink: 0;
}
.auth-field:focus-within .af-icon { color: var(--accent); }
.auth-field input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--text);
  font-size: 15px;
  font-family: inherit;
  outline: none;
  padding: 0;
  height: 100%;
}
.auth-field input::placeholder {
  color: var(--muted);
  opacity: 1;
}

/* --- password eye toggle (CSS-only via sibling checkbox) --- */
.auth-field-pw .af-pw-toggle {
  /* Visually-hidden checkbox, still in the DOM so its state
     drives sibling selectors. Keep it focusable for keyboard
     users. */
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}
.auth-field-pw .af-eye-wrap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: var(--muted);
  cursor: pointer;
  flex-shrink: 0;
  transition: background var(--t-fast), color var(--t-fast);
}
.auth-field-pw .af-eye-wrap:hover {
  background: var(--bg-2);
  color: var(--accent);
}
.auth-field-pw .af-eye {
  width: 18px;
  height: 18px;
}
/* Default: show the open eye, hide the slashed one. */
.auth-field-pw .af-eye-closed { display: none; }
/* When the hidden checkbox is checked, swap the icon AND
   flip the input type from password → text via a sibling
   attribute selector. The input itself is the PREVIOUS sibling
   so we use a "has" workaround: we mirror the checked state
   onto the input via a CSS-only trick below. */
.auth-field-pw:has(.af-pw-toggle:checked) .af-eye-open  { display: none; }
.auth-field-pw:has(.af-pw-toggle:checked) .af-eye-closed { display: block; }
.auth-field-pw:has(.af-pw-toggle:checked) input[type="password"] {
  /* Can't literally change the type attr from CSS, so we rely
     on the minimal JS in main.js to toggle ``type``. The CSS
     :has() selector above only handles the icon swap. */
}

.auth-captcha {
  display: flex;
  justify-content: center;
  margin: 6px 0 2px;
  min-height: 65px;
}
.auth-submit {
  background: var(--accent);
  color: #fff;
  border: 0;
  padding: 14px 18px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--t-fast), transform var(--t-fast),
              box-shadow var(--t-fast);
  box-shadow: 0 4px 14px rgba(0, 175, 240, .22);
}
.auth-submit:hover {
  background: var(--accent-2);
  transform: translateY(-1px);
}
.auth-submit:active { transform: translateY(0); }
.auth-alt {
  font-size: 14px;
  color: var(--muted);
  text-align: center;
  margin: 4px 0 0;
}
.auth-alt a {
  color: var(--accent);
  font-weight: 700;
  margin-left: 4px;
}

/* ============================================================
   Video stats row — stats on the left, like/dislike pill right
   ============================================================ */
.video-stats-row {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin: 0;
}
.video-stats-row .video-stats {
  flex: 1;
  min-width: 0;
}
/* Mobile: rearrange into a two-row layout so nothing overflows.
   Row 1 = primary stats (views + duration — the two numbers
   users glance at first). Row 2 = secondary stats (quality +
   upload date). The reaction pill breaks onto its own full-width
   row below the stats pill, preventing the layout from squishing
   both into a narrow gap where the date collides with the 100%
   badge. */
@media (max-width: 900px) {
  .video-stats-row {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  .video-stats-row .video-stats {
    flex: none;
    gap: 10px 16px;
    padding: 10px 14px;
    font-size: 12px;
    border-radius: 14px;   /* square up — full pill looks odd when wrapped */
  }
  .video-stats .vs-primary {
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
  }
  .video-stats .vs-secondary {
    font-size: 12px;
    color: var(--muted);
  }
  .video-stats-row .video-react {
    align-self: flex-start;
  }
}

/* ============================================================
   Video like / dislike pill (Spankbang-style)
   ============================================================ */
.video-react {
  display: inline-flex;
  align-items: center;
  gap: 0;
  padding: 6px 14px;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: 999px;
  flex-shrink: 0;
}
.video-react-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  padding: 6px 8px;
  border-radius: 999px;
  transition: color var(--t-fast), background var(--t-fast),
              transform var(--t-fast);
}
.video-react-btn:hover:not([disabled]) {
  background: var(--bg-2);
  transform: scale(1.08);
}
.video-react-btn[disabled] {
  cursor: not-allowed;
  opacity: .6;
}
.video-react-btn.like.active,
.video-react-btn.like:hover:not([disabled]) {
  color: var(--accent);
}
.video-react-btn.dislike.active,
.video-react-btn.dislike:hover:not([disabled]) {
  color: #e53935;
}
.video-react-ratio {
  min-width: 44px;
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  padding: 0 4px;
  user-select: none;
}
.video-react-btn svg { display: block; }

/* ============================================================
   Comments section (TikTok-style nested comments)
   ============================================================ */
.comments-section {
  margin-top: 30px;
  padding-top: 24px;
  border-top: 2px solid var(--line);
}
.comments-head {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  margin: 0 0 18px;
}

/* ----- new comment form ----- */
.comment-form {
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 22px;
}
.comment-form-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.comment-form-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  flex-shrink: 0;
}
.comment-form-author {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
}
.comment-form textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
  resize: vertical;
  min-height: 70px;
  box-sizing: border-box;
  transition: all var(--t-fast);
}
.comment-form textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.comment-form-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}

/* ----- login prompt (plain text, no big button) ----- */
.comment-login-prompt {
  padding: 14px 16px;
  background: var(--bg-1);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  color: var(--muted);
  font-size: 14px;
  margin-bottom: 22px;
  text-align: center;
}
.auth-inline-link {
  color: var(--accent);
  font-weight: 700;
  text-decoration: underline;
}
.auth-inline-link:hover { color: var(--accent-2); }

/* ----- comment list ----- */
.comment-list {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.comment {
  display: flex;
  gap: 12px;
  padding: 0;
  background: transparent;
  border: none;
}
/* Circular avatar — first letter of the username */
.comment-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 700;
  font-size: 16px;
  flex-shrink: 0;
}
.comment-reply .comment-avatar {
  width: 32px;
  height: 32px;
  font-size: 13px;
}
.comment-main {
  flex: 1;
  min-width: 0;
}
.comment-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 4px;
}
.comment-author {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
}
.comment-time {
  font-size: 11px;
  color: var(--muted);
}
.comment-body {
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  word-wrap: break-word;
  overflow-wrap: break-word;
  padding: 2px 0;
}

/* ----- like / dislike + reply action row ----- */
.comment-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 6px;
}
.c-react-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  padding: 4px 6px;
  border-radius: 6px;
  transition: all var(--t-fast);
}
.c-react-btn:hover { background: var(--bg-2); }
.c-react-btn svg {
  width: 16px;
  height: 16px;
  transition: transform var(--t-fast);
}
.c-react-btn:hover svg { transform: scale(1.15); }
.c-react-btn.like.active {
  color: var(--accent);
}
.c-react-btn.dislike.active {
  color: #e53935;
}
.c-react-count {
  min-width: 10px;
  text-align: left;
}
.c-reply-btn {
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 6px;
  transition: all var(--t-fast);
}
.c-reply-btn:hover {
  background: var(--bg-2);
  color: var(--accent);
}

/* ----- inline reply form ----- */
/* Slide-down + fade-in when the Trả lời button toggles the
   form visible. Keeping the animation on every reveal (not just
   the first) gives the click physical feedback. */
@keyframes c-reply-in {
  from { opacity: 0; transform: translateY(-4px); max-height: 0; }
  to   { opacity: 1; transform: translateY(0);    max-height: 260px; }
}
.c-reply-form {
  margin: 10px 0 4px;
  padding: 12px;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
  animation: c-reply-in .18s ease-out;
}
.c-reply-form[hidden] { display: none; }

/* A posted comment / reply fades in when it's freshly inserted
   (the server-rendered reload path: after POST the page reloads
   and the new node carries a .comment-new class we add from JS
   via sessionStorage). Keep it subtle — a quick lift + fade. */
@keyframes c-new-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.comment.comment-new {
  animation: c-new-in .28s ease-out;
}
.c-reply-form textarea {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
  resize: vertical;
  min-height: 52px;
  box-sizing: border-box;
}
.c-reply-form textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.c-reply-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 8px;
}
.btn-ghost {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--muted);
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all var(--t-fast);
}
.btn-ghost:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* ----- nested replies (1 level deep) ----- */
.comment-replies {
  list-style: none;
  margin: 12px 0 0;
  padding: 0 0 0 18px;
  border-left: 2px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.comment-replies > li { padding: 0; }

.comment-empty {
  padding: 20px;
  text-align: center;
  color: var(--muted);
  background: var(--bg-1);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
}

/* ============================================================
   Shorts row — horizontal strip of 9:16 cards rendered at the
   bottom of every list page (home, tag, search, channel, ...).
   ============================================================ */
.shorts-row {
  margin: 36px 0 20px;
  padding: 20px 0 14px;
  border-top: 1px solid var(--line);
}
.shorts-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
  padding: 0 4px;
}
.shorts-head strong {
  font-size: 18px;
  font-weight: 800;
  color: var(--text);
  letter-spacing: -.3px;
}
.shorts-head .muted {
  font-size: 12px;
  color: var(--muted);
}
.shorts-scroll {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  padding: 4px 4px 14px;
  scrollbar-width: thin;
  scrollbar-color: var(--accent) transparent;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}
.shorts-scroll::-webkit-scrollbar { height: 6px; }
.shorts-scroll::-webkit-scrollbar-thumb {
  background: var(--accent);
  border-radius: 3px;
}

/* Shorts grid page — multi-row vertical card grid */
.shorts-grid-page {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 16px;
}
@media (min-width: 900px) {
  .shorts-grid-page {
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  }
}

/* Each card is a tall 9:16 tile that snaps to the left edge on
   swipe. First hover lazy-loads the short trailer mp4 into a
   <video> element appended by main.js — we fade the still <img>
   out + the video in to produce the same silent auto-loop xhamster
   ships on its ``video-thumb__moment`` cards. Card basis is
   240px so the thumb footprint matches a regular video card's
   260×~150 area (shorts are portrait so width is ~60% of the
   landscape card width but the perceived "weight" matches). */
.short-card {
  flex: 0 0 240px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  color: var(--text);
  scroll-snap-align: start;
  transition: transform var(--t-fast);
}
.short-card:hover { transform: translateY(-3px); }
.short-thumb {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius);
  overflow: hidden;
  background: #000;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}
.short-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity var(--t-mid);
}
.short-thumb video.short-preview-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity var(--t-mid);
  z-index: 1;
}
.short-thumb.is-previewing video.short-preview-video { opacity: 1; }
.short-thumb.is-previewing img { opacity: 0; }

.short-play-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 44px;
  color: rgba(255, 255, 255, .92);
  text-shadow: 0 4px 16px rgba(0, 0, 0, .85);
  opacity: 0;
  transition: opacity var(--t-fast);
  pointer-events: none;
  z-index: 3;
}
.short-card:hover .short-play-overlay { opacity: 1; }
.short-thumb.is-previewing .short-play-overlay { opacity: 0; }

.short-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0 2px;
}
.short-title {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.7em;
}
.short-stats {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 11px;
  color: var(--muted);
}
.short-views,
.short-likes {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.short-likes { color: var(--accent); font-weight: 600; }

@media (max-width: 900px) {
  .short-card { flex-basis: 190px; }
}
@media (max-width: 600px) {
  .short-card { flex-basis: 160px; }
  .shorts-head strong { font-size: 16px; }
}

/* ============================================================
   Shorts viewer — dual layout
   ============================================================
   Desktop (>= 900px) → xhamster shorts pattern:
     [ sv-stage (centered 9:16 video + floating action rail on
       the video's right edge) | sv-side (channel header +
       title/desc card + CTAs + "Từ <channel>" grid) ]
   Mobile (< 900px) → TikTok Reels pattern:
     full-bleed video, transparent overlays, right-side action
     rail floats over the video, bottom-left minimal creator +
     title text with drop-shadow (no black gradient), everything
     auto-hides after 3 s of idle. */

.shorts-viewer {
  position: relative;
  display: grid;
  /* Sidebar width scales with viewport: 320-360px on smaller
     desktops so the video column keeps enough room to render
     a full-height 9:16 frame, and up to 440px on wider screens
     where horizontal real estate is cheap. */
  grid-template-columns: 1fr clamp(320px, 28vw, 440px);
  gap: 20px;
  align-items: stretch;
  width: 100%;
  /* ``--sv-viewer-h`` is written by ``main.js`` on load and on
     every resize: it measures the viewer's own ``offsetTop`` and
     subtracts it from the live viewport height, so the stage
     always fits perfectly regardless of header / cat-strip /
     padding stack. The fallback (``100svh``) only applies before
     the JS has run. */
  height: var(--sv-viewer-h, 100svh);
  min-height: 480px;
  padding: 0 24px;
  background: #000;
  color: #fff;
  overflow: hidden;
}
@supports not (height: 100svh) {
  .shorts-viewer { height: var(--sv-viewer-h, 100vh); }
}
/* Hide the secondary category-strip nav on shorts pages at
   every breakpoint. The strip is a discovery chrome for the
   grid pages — a full-bleed TikTok-style viewer should never
   surface it, otherwise the stage clips the bottom of the
   video frame to leave room for the chips. Desktop header
   auto-hides (slides up, reappears on hover) — see the
   fixed-position rules in the header section above. Mobile
   still hides the header entirely via the media query below. */
body:has(.shorts-viewer) .cat-strip,
body:has(.shorts-viewer) .cat-strip-outer,
body:has(.shorts-viewer) .site-footer { display: none !important; }

/* Paint the surrounding page background black whenever the
   shorts viewer is mounted so the video column blends into a
   single dark canvas on every breakpoint. Before this rule the
   body's light cream default bled through on the left + right
   of the centred viewer on wide desktops, breaking the
   TikTok-style look. Targets ``<html>`` + ``<body>`` + the
   ``<main class="main-area">`` wrapper all at once because any
   one of them can render visible empty space depending on the
   breakpoint. */
html:has(.shorts-viewer),
body:has(.shorts-viewer),
body:has(.shorts-viewer) .main-area { background: #000 !important; }
/* Ultra-wide displays: cap the viewer so a single video doesn't
   stretch across the whole monitor — centre the two-column
   layout and let the extra width breathe. */
@media (min-width: 1600px) {
  .shorts-viewer {
    max-width: 1440px;
    margin: 0 auto;
    grid-template-columns: 1fr clamp(380px, 26vw, 460px);
  }
}
/* Break out of the page container's side padding so the black
   stage reaches the viewport edges. */
.main-area:has(.shorts-viewer) {
  padding: 0;
  max-width: none;
}

/* ----- Feed: scroll-snap stack of slides -------------------- */
.sv-feed {
  position: relative;
  grid-column: 1;
  width: 100%;
  height: 100%;
  overflow-y: scroll;
  overflow-x: hidden;
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  border-radius: var(--radius-lg);
}
.sv-feed::-webkit-scrollbar { display: none; }
.sv-slide {
  position: relative;
  width: 100%;
  height: 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  display: block;
}

/* ----- Stage (per-slide video frame) ----------------------- */
.sv-stage {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.sv-video {
  /* Fill the entire stage and let ``object-fit: contain`` scale
     the real video to be as large as possible while remaining
     fully visible. No fixed aspect-ratio on the layout box —
     that would waste stage space on landscape / square shorts.
     The browser letterboxes the source inside the stage and
     the black background fills the bars, so the effect matches
     TikTok's "fit 100% to screen" behaviour on every device. */
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  background: #000;
  border-radius: var(--radius-lg);
  box-shadow: 0 8px 40px rgba(0, 0, 0, .6);
  object-fit: contain;
  cursor: pointer;
}

/* Back arrow — top-left of the stage, mirrors xhamster's
   "‹" circle that takes the viewer back to the list. */
.sv-back {
  position: absolute;
  top: 14px;
  left: 14px;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  transition: background var(--t-fast);
  z-index: 5;
}
.sv-back:hover { background: rgba(0, 0, 0, .78); }

/* Mute toggle — top-right corner. */
/* Audio control group: mute button + volume slider */
.sv-audio-ctrl {
  position: absolute;
  top: 80px;
  right: 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  z-index: 5;
}
.sv-mute-toggle {
  width: 42px;
  height: 42px;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background var(--t-fast);
  position: relative;
}
.sv-mute-toggle:hover { background: rgba(0, 0, 0, .78); }
.sv-mute-toggle .sv-mute-off { display: none; }
.sv-mute-toggle.unmuted .sv-mute-on { display: none; }
.sv-mute-toggle.unmuted .sv-mute-off { display: block; }

/* Volume slider — vertical, appears below mute button */
.sv-volume-slider {
  writing-mode: vertical-lr;
  direction: rtl;
  width: 36px;
  height: 0;
  opacity: 0;
  overflow: hidden;
  transition: height .2s ease, opacity .2s ease;
  cursor: pointer;
  accent-color: #00aff0;
  background: rgba(0, 0, 0, .5);
  border-radius: 18px;
  padding: 8px 0;
}
.sv-audio-ctrl:hover .sv-volume-slider,
.sv-volume-slider:focus {
  height: 100px;
  opacity: 1;
}

/* Progress bar — thin bar at bottom of slide */
.sv-progress-wrap {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: rgba(255, 255, 255, .2);
  z-index: 6;
  cursor: pointer;
}
.sv-progress-wrap:hover { height: 6px; }
.sv-progress-bar {
  height: 100%;
  width: 0%;
  background: #00aff0;
  transition: width .1s linear;
}

/* Play/Pause overlay — center of slide, shown on tap */
.sv-play-toggle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 64px;
  height: 64px;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .45);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 5;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease;
}
.sv-play-toggle.visible {
  opacity: 1;
  pointer-events: auto;
}
.sv-play-toggle .sv-pause-icon { display: none; }
.sv-slide.sv-playing .sv-play-toggle .sv-play-icon { display: none; }
.sv-slide.sv-playing .sv-play-toggle .sv-pause-icon { display: block; }

/* ----- Action rail — floats on the video's right edge ------
   Vertical stack of circular icons + counts below, TikTok /
   xhamster style. Pinned inside .sv-stage so the rail moves
   with the centered video at any stage width. */
.sv-rail {
  position: absolute;
  right: 14px;
  bottom: 80px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  z-index: 5;
  transition: opacity .3s ease, transform .3s ease;
}
.sv-react { margin: 0; }
.sv-action,
.sv-action-like,
.sv-rail-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(22, 24, 35, .55);
  color: #fff;
  border: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--t-fast), transform var(--t-fast),
              color var(--t-fast);
  overflow: hidden;
}
.sv-rail-avatar {
  width: 52px;
  height: 52px;
  background: transparent;
  border: 2px solid #fff;
  position: relative;
  margin-bottom: 14px;
}
.sv-rail-avatar .sv-channel-avatar {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}
.sv-rail-avatar .sv-channel-initial {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 800;
  font-size: 18px;
}
/* (previous design had a red "+" follow badge on the avatar,
   but we don't ship a follow feature — the fake affordance was
   removed so the bottom of the avatar is clean and the avatar
   circle itself is the click target to open the channel.) */
.sv-action:hover,
.sv-action-like:hover { transform: scale(1.05); }
.sv-action-like.active {
  background: var(--accent);
  color: #fff;
}
.sv-action-count {
  font-size: 12px;
  color: #fff;
  font-weight: 700;
  text-align: center;
  margin: 0 0 8px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .8);
  min-width: 0;
}

/* Next-short chevron (inside the stage). The prev chevron
   lives in .sv-nav-wrap on the stage's left edge. */
.sv-stage-next {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 4;
}
.sv-nav-wrap {
  position: absolute;
  left: 64px;  /* sits right of the back button at top-left */
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 12px;
  z-index: 4;
}
.sv-nav {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(22, 24, 35, .55);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  transition: background var(--t-fast);
}
.sv-nav:hover { background: rgba(22, 24, 35, .8); }
.sv-nav-disabled { opacity: .25; pointer-events: none; }

/* ----- Sidebar (desktop xhamster layout) -------------------- */
.sv-side {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-self: stretch;
  padding-top: 8px;
  overflow-y: auto;
  max-height: calc(100vh - 96px);
}
.sv-side::-webkit-scrollbar { width: 6px; }
.sv-side::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .15);
  border-radius: 3px;
}

.sv-channel-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: var(--radius-lg);
  color: #fff;
  text-decoration: none;
  transition: background var(--t-fast);
}
.sv-channel-header:hover { background: rgba(255, 255, 255, .1); }
.sv-channel-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}
.sv-channel-initial {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 800;
  font-size: 18px;
  text-transform: uppercase;
}
.sv-channel-meta { flex: 1; min-width: 0; }
.sv-channel-name {
  font-size: 15px;
  font-weight: 700;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sv-channel-cta {
  font-size: 12px;
  color: var(--accent);
  font-weight: 600;
}

/* Title / description block (shared base) */
.sv-info { color: #fff; }
.sv-title {
  font-size: 16px;
  font-weight: 700;
  line-height: 1.4;
  margin: 0 0 8px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.sv-uploader {
  display: inline-block;
  color: var(--accent);
  font-weight: 700;
  font-size: 13px;
  text-decoration: none;
  margin-bottom: 6px;
}
.sv-uploader:hover { text-decoration: underline; }
.sv-desc {
  font-size: 13px;
  opacity: .75;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.sv-info-desktop {
  padding: 14px 16px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: var(--radius-lg);
}
.sv-info-mobile { display: none; }

/* CTAs — "Video gốc" + "Xem <channel>". Side-by-side pill
   buttons mirroring xhamster's secondary/primary pair. */
.sv-ctas {
  display: flex;
  gap: 10px;
}
.sv-cta {
  flex: 1;
  padding: 11px 14px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
  transition: background var(--t-fast), transform var(--t-fast);
}
.sv-cta-secondary {
  background: rgba(255, 255, 255, .1);
  color: #fff;
}
.sv-cta-secondary:hover { background: rgba(255, 255, 255, .18); }
.sv-cta-primary {
  background: var(--accent);
  color: #fff;
}
.sv-cta-primary:hover { background: var(--accent-2); transform: translateY(-1px); }

/* "Từ <channel>" tab + related-shorts grid */
.sv-tabs { margin-top: 4px; }
.sv-tab-head {
  display: flex;
  gap: 18px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(255, 255, 255, .1);
  margin-bottom: 12px;
}
.sv-tab-active {
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  position: relative;
  padding-bottom: 10px;
}
.sv-tab-active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -11px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
}
.sv-tab-count {
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  margin-left: 4px;
}
.sv-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}
.sv-grid-tile {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: 8px;
  overflow: hidden;
  background: #111;
  display: block;
  text-decoration: none;
  color: #fff;
}
.sv-grid-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-fast);
}
.sv-grid-tile:hover img { transform: scale(1.05); }
.sv-grid-views {
  position: absolute;
  left: 6px;
  bottom: 6px;
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .8);
  z-index: 2;
}

/* ----- Sidebar tab bar (Comments / Từ Channel) --------------- */
.sv-sidebar-tabs { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.sv-sidebar-tab-bar {
  display: flex;
  gap: 0;
  border-bottom: 1px solid rgba(255, 255, 255, .1);
  margin-bottom: 12px;
}
.sv-sidebar-tab {
  flex: 1;
  padding: 10px 0;
  background: none;
  border: none;
  color: rgba(255, 255, 255, .5);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  position: relative;
  transition: color var(--t-fast);
}
.sv-sidebar-tab:hover { color: rgba(255, 255, 255, .8); }
.sv-sidebar-tab.active { color: #fff; }
.sv-sidebar-tab.active::after {
  content: "";
  position: absolute;
  left: 20%; right: 20%;
  bottom: -1px;
  height: 2px;
  background: var(--accent);
  border-radius: 1px;
}
.sv-sidebar-tab-panel { flex: 1; overflow-y: auto; min-height: 0; }
.sv-sidebar-tab-panel[hidden] { display: none; }

/* ----- Inline comments inside shorts sidebar & sheet --------- */
.sv-comments-slot {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.sv-comments-loading {
  color: rgba(255, 255, 255, .4);
  font-size: 13px;
  text-align: center;
  padding: 32px 0;
}
.sv-comments-empty {
  color: rgba(255, 255, 255, .35);
  font-size: 13px;
  text-align: center;
  padding: 24px 0;
}

/* Dark-themed comment overrides for shorts sidebar + sheet */
.sv-side .comment,
.sv-sheet-body .comment {
  display: flex;
  gap: 10px;
  padding: 0;
}
.sv-side .comment-avatar,
.sv-sheet-body .comment-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 700;
  font-size: 13px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.sv-side .comment-main,
.sv-sheet-body .comment-main { flex: 1; min-width: 0; }
.sv-side .comment-head,
.sv-sheet-body .comment-head {
  display: flex;
  gap: 8px;
  align-items: baseline;
  margin-bottom: 2px;
}
.sv-side .comment-author,
.sv-sheet-body .comment-author {
  font-size: 13px;
  font-weight: 700;
  color: #fff;
}
.sv-side .comment-time,
.sv-sheet-body .comment-time {
  font-size: 11px;
  color: rgba(255, 255, 255, .4);
}
.sv-side .comment-body,
.sv-sheet-body .comment-body {
  font-size: 13px;
  line-height: 1.45;
  color: rgba(255, 255, 255, .85);
  word-wrap: break-word;
}
.sv-side .comment-actions,
.sv-sheet-body .comment-actions {
  display: flex;
  gap: 12px;
  margin-top: 4px;
}
.sv-side .c-react-btn,
.sv-sheet-body .c-react-btn {
  display: inline-flex;
  gap: 4px;
  background: transparent;
  border: 0;
  color: rgba(255, 255, 255, .4);
  font-size: 12px;
  font-weight: 600;
  padding: 2px 4px;
  border-radius: 4px;
  cursor: pointer;
}
.sv-side .c-react-btn:hover,
.sv-sheet-body .c-react-btn:hover { color: rgba(255, 255, 255, .7); }
.sv-side .c-react-btn.like.active,
.sv-sheet-body .c-react-btn.like.active { color: var(--accent); }
.sv-side .c-reply-btn,
.sv-sheet-body .c-reply-btn {
  background: transparent;
  border: 0;
  color: rgba(255, 255, 255, .4);
  font-size: 12px;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 4px;
}
.sv-side .c-reply-btn:hover,
.sv-sheet-body .c-reply-btn:hover { color: rgba(255, 255, 255, .7); }
.sv-side .comment-replies,
.sv-sheet-body .comment-replies {
  list-style: none;
  margin: 8px 0 0;
  padding: 0 0 0 14px;
  border-left: 2px solid rgba(255, 255, 255, .08);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Comment form inside shorts */
.sv-side .sv-comment-form,
.sv-sheet-body .sv-comment-form {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
  margin-bottom: 4px;
}
.sv-side .sv-comment-form textarea,
.sv-sheet-body .sv-comment-form textarea {
  flex: 1;
  padding: 8px 10px;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 8px;
  background: rgba(255, 255, 255, .06);
  color: #fff;
  font-size: 13px;
  min-height: 36px;
  max-height: 120px;
  resize: none;
  font-family: inherit;
}
.sv-side .sv-comment-form textarea::placeholder,
.sv-sheet-body .sv-comment-form textarea::placeholder {
  color: rgba(255, 255, 255, .3);
}
.sv-side .sv-comment-form textarea:focus,
.sv-sheet-body .sv-comment-form textarea:focus {
  outline: none;
  border-color: var(--accent);
}
.sv-side .sv-comment-submit,
.sv-sheet-body .sv-comment-submit {
  padding: 8px 14px;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.sv-side .sv-comment-submit:hover,
.sv-sheet-body .sv-comment-submit:hover {
  filter: brightness(1.1);
}
.sv-comment-login {
  text-align: center;
  padding: 12px 0;
  font-size: 13px;
  color: rgba(255, 255, 255, .5);
  border-bottom: 1px solid rgba(255, 255, 255, .08);
  margin-bottom: 4px;
}
.sv-comment-login a {
  color: var(--accent);
  font-weight: 600;
}
/* Reply form inside shorts */
.sv-side .c-reply-form,
.sv-sheet-body .c-reply-form {
  margin: 6px 0 4px;
  padding: 8px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 8px;
}
.sv-side .c-reply-form[hidden],
.sv-sheet-body .c-reply-form[hidden] { display: none; }
.sv-side .c-reply-form textarea,
.sv-sheet-body .c-reply-form textarea {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 6px;
  background: rgba(255, 255, 255, .06);
  color: #fff;
  font-size: 13px;
  min-height: 32px;
  resize: none;
  font-family: inherit;
  margin-bottom: 6px;
}
.sv-side .c-reply-actions,
.sv-sheet-body .c-reply-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}
.sv-side .c-reply-actions button,
.sv-sheet-body .c-reply-actions button {
  padding: 4px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  border: none;
}
.sv-side .c-reply-cancel,
.sv-sheet-body .c-reply-cancel {
  background: transparent;
  color: rgba(255, 255, 255, .5);
}
.sv-side .c-reply-actions button[type="submit"],
.sv-sheet-body .c-reply-actions button[type="submit"] {
  background: var(--accent);
  color: #fff;
}

/* ----- Mobile bottom sheet for shorts comments --------------- */
.sv-comment-sheet {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: flex-end;
}
.sv-comment-sheet[hidden] { display: none; }
.sv-sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .5);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.sv-sheet-panel {
  position: relative;
  width: 100%;
  max-height: 70vh;
  background: #1a1a1a;
  border-radius: 16px 16px 0 0;
  display: flex;
  flex-direction: column;
  animation: sv-sheet-up .3s ease;
}
@keyframes sv-sheet-up {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
.sv-sheet-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, .1);
  flex-shrink: 0;
}
.sv-sheet-title {
  color: #fff;
  font-weight: 700;
  font-size: 16px;
}
.sv-sheet-close {
  background: none;
  border: none;
  color: rgba(255, 255, 255, .6);
  font-size: 24px;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}
.sv-sheet-body {
  overflow-y: auto;
  flex: 1;
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 120px;
}
/* Hide bottom sheet on desktop — sidebar has its own comments */
@media (min-width: 901px) {
  .sv-comment-sheet { display: none !important; }
}
/* Comment button in rail — reset anchor-like styling for button */
.sv-action-comments {
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  padding: 0;
  font: inherit;
}

/* ============================================================
   Mobile (< 900px) — TikTok Reels layout
   ============================================================ */
@media (max-width: 900px) {
  /* On mobile the shorts viewer is a full-bleed TikTok-style
     experience: the sticky site header, its cat-strip, and the
     page footer all get hidden so the 9:16 video fills the
     entire viewport. Uses :has() so we don't need a body class
     from the server. Desktop keeps chrome as usual. */
  body:has(.shorts-viewer) .site-header,
  body:has(.shorts-viewer) .site-footer,
  body:has(.shorts-viewer) .cat-strip,
  body:has(.shorts-viewer) .cat-strip-outer { display: none !important; }
  body:has(.shorts-viewer) .main-area {
    padding: 0 !important;
    margin: 0 !important;
    max-width: none !important;
  }

  .shorts-viewer {
    grid-template-columns: 1fr;
    gap: 0;
    padding: 0;
    /* ``svh`` matches the visible viewport even while mobile
     * browser chrome (URL bar / nav shelf) is collapsing, so
     * the first slide isn't taller than the screen. */
    min-height: 100svh;
    height: 100svh;
    border-radius: 0;
  }
  .sv-feed {
    height: 100svh;
    border-radius: 0;
  }
  .sv-slide { height: 100svh; }
  .sv-stage {
    grid-column: 1;
    height: 100svh;
    min-height: 100svh;
  }
  .sv-video {
    max-height: 100vh;
    height: 100%;
    width: 100%;
    border-radius: 0;
    /* ``contain`` so the whole short is always visible — users
       never lose faces / subtitles to a cover-crop on phones
       with aspect ratios that differ from the source video. */
    object-fit: contain;
  }

  /* Sidebar with channel header + tabs is hidden on mobile —
     users navigate to the channel page via the floating rail
     avatar instead. */
  .sv-side { display: none; }

  /* Mobile overlay info — bottom-left, transparent, drop-shadow
     typography, auto-hides when idle via the .sv-idle class. */
  .sv-info-desktop { display: none; }
  .sv-info-mobile {
    display: block;
    position: absolute;
    left: 14px;
    right: 80px;   /* leave room for the floating rail */
    bottom: 22px;
    padding: 0;
    background: transparent;
    border: 0;
    z-index: 4;
    pointer-events: none;
    opacity: 1;
    transform: translateY(0);
    transition: opacity .3s ease, transform .3s ease;
  }
  .sv-info-mobile > * { pointer-events: auto; }
  .sv-info-mobile .sv-title,
  .sv-info-mobile .sv-uploader,
  .sv-info-mobile .sv-desc {
    text-shadow:
      0 2px 6px rgba(0, 0, 0, .9),
      0 0 2px rgba(0, 0, 0, .9);
  }
  .sv-info-mobile .sv-title {
    font-size: 15px;
    -webkit-line-clamp: 2;
    margin-bottom: 4px;
  }
  .sv-info-mobile .sv-uploader { font-size: 14px; }
  .sv-info-mobile .sv-desc {
    font-size: 12px;
    -webkit-line-clamp: 1;
    opacity: 1;
  }

  /* Rail stays on the right edge with smaller buttons so it
     doesn't crowd the video on phone screens. */
  .sv-rail {
    right: 10px;
    bottom: 96px;
    gap: 2px;
  }
  .sv-action,
  .sv-action-like { width: 46px; height: 46px; }
  .sv-rail-avatar { width: 50px; height: 50px; }
  .sv-action-count {
    font-size: 12px;
    margin-bottom: 14px;
  }

  /* Prev/next arrow buttons are hidden on mobile — vertical swipe
     on the video is the native way to advance the feed, matching
     TikTok / Reels. Keeping the arrows as well would crowd the
     rail and fight with the swipe gesture. */
  .sv-nav-wrap,
  .sv-stage-next { display: none; }

  .sv-back { top: 10px; left: 10px; }
  .sv-mute-toggle { top: 10px; right: 10px; }

  /* Auto-hide everything non-essential when the user stops
     interacting for 3s — main.js toggles .sv-idle. The video
     itself never fades. */
  .shorts-viewer.sv-idle .sv-info-mobile,
  .shorts-viewer.sv-idle .sv-rail,
  .shorts-viewer.sv-idle .sv-mute-toggle,
  .shorts-viewer.sv-idle .sv-back,
  .shorts-viewer.sv-idle .sv-nav-wrap,
  .shorts-viewer.sv-idle .sv-stage-next {
    opacity: 0;
    transform: translateY(4px);
    pointer-events: none;
  }
}
