/* ============================================
   PornTok - Premium Dark Theme Styles
   TikTok-style NSFW Video Viewer
   ============================================ */

/* SEO/accessibility header: real, crawlable content for search engines + screen readers, visually
   off-screen (the standard sr-only pattern — NOT display:none, so it is not treated as hidden text).
   The visual app renders on top in #app. */
.seo-intro {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- CSS Custom Properties ---------- */
:root {
  --bg-primary: #000000;
  --bg-surface: #0a0a0f;
  --bg-card: rgba(255, 255, 255, 0.05);
  --bg-glass: rgba(10, 10, 15, 0.75);
  --bg-glass-heavy: rgba(10, 10, 15, 0.92);

  --accent-pink: #ff2d55;
  --accent-purple: #7c3aed;
  --accent-gradient: linear-gradient(135deg, #ff2d55, #c025d1, #7c3aed);
  --accent-gradient-h: linear-gradient(90deg, #ff2d55, #c025d1, #7c3aed);

  --text-primary: #ffffff;
  --text-secondary: rgba(255, 255, 255, 0.7);
  --text-muted: rgba(255, 255, 255, 0.4);

  --border-subtle: rgba(255, 255, 255, 0.08);
  --border-accent: rgba(255, 45, 85, 0.3);

  --shadow-glow: 0 0 20px rgba(255, 45, 85, 0.2);
  --shadow-card: 0 8px 32px rgba(0, 0, 0, 0.4);

  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --radius-xl: 28px;
  --radius-full: 9999px;

  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --z-feed: 1;
  --z-overlay: 10;
  --z-topbar: 50;
  --z-drawer: 100;
  --z-splash: 200;
  --z-toast: 300;
  --z-install: 150;

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* ---------- Reset & Base ---------- */
*, *::before, *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  font-family: var(--font);
  background: var(--bg-primary);
  color: var(--text-primary);
  overflow: hidden;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  user-select: none;
  -webkit-user-select: none;
}

#app {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}

/* ---------- Scrollbar ---------- */
::-webkit-scrollbar { width: 0; height: 0; }
* { scrollbar-width: none; }

/* ---------- Top Bar ---------- */
#top-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--z-topbar);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(4px + var(--safe-top)) 16px 12px;
  background: transparent;
  pointer-events: none;
}

#top-bar > * { pointer-events: auto; }

/* Now an <a> back to the landing feed — strip the default link styling so it looks unchanged.
   color:inherit matters: .accent paints the "Tok" half with a clipped gradient, and a link colour
   would override it. */
.logo {
  display: flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.logo-icon {
  width: 32px;
  height: 32px;
  filter: drop-shadow(0 0 8px rgba(255, 45, 85, 0.5));
}

.logo-text {
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-shadow: 0 2px 8px rgba(0,0,0,0.5);
}

.accent {
  background: var(--accent-gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.top-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
}

/* ---------- Icon Buttons ---------- */
.icon-btn {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-full);
  border: 1px solid var(--border-subtle);
  background: var(--bg-glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-primary);
  transition: all 0.2s ease;
}

.icon-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: var(--border-accent);
  box-shadow: var(--shadow-glow);
}

.icon-btn:active {
  transform: scale(0.92);
}

.icon-btn svg {
  width: 20px;
  height: 20px;
}

.icon-btn.active {
  background: var(--accent-pink);
  border-color: var(--accent-pink);
  box-shadow: 0 0 16px rgba(255, 45, 85, 0.4);
}

/* ---------- Tags Drawer ---------- */
.drawer {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-drawer);
  pointer-events: none;
  visibility: hidden;
}

.drawer.open {
  pointer-events: auto;
  visibility: visible;
}

.drawer-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.15);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.drawer.open .drawer-backdrop {
  opacity: 1;
}

.drawer-content {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(340px, 85vw);
  background: rgba(10, 10, 15, 0.2);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-left: 1px solid var(--border-subtle);
  transform: translateX(100%);
  transition: transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

.drawer.open .drawer-content {
  transform: translateX(0);
}

.drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(16px + var(--safe-top)) 20px 16px;
  border-bottom: 1px solid var(--border-subtle);
}

.drawer-header h2 {
  font-size: 1.25rem;
  font-weight: 600;
  background: var(--accent-gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* ---------- Drawer Tabs ---------- */
.drawer-tabs {
  display: flex;
  gap: 4px;
  background: rgba(255,255,255,0.06);
  border-radius: var(--radius-full);
  padding: 3px;
}

.drawer-tab {
  padding: 8px 18px;
  border: none;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font);
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
}

.drawer-tab.active {
  background: var(--accent-gradient);
  color: #fff;
  font-weight: 600;
}

.drawer-tab:not(.active):hover {
  color: var(--text-primary);
  background: rgba(255,255,255,0.08);
}

.drawer-tab-content {
  display: none;
}

.drawer-tab-content.active {
  display: block;
}

/* ---------- Tags Grid ---------- */
.tags-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  padding: 20px;
}

/* ---------- Algorithm Picker ---------- */
.algo-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  padding: 20px;
}

.algo-pill {
  padding: 14px 16px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-subtle);
  background: var(--bg-card);
  color: var(--text-secondary);
  font-family: var(--font);
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.25s ease;
  text-align: center;
  text-transform: capitalize;
  position: relative;
  overflow: hidden;
}

.algo-pill::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--accent-gradient);
  opacity: 0;
  transition: opacity 0.25s ease;
}

.algo-pill:hover {
  border-color: var(--border-accent);
  color: var(--text-primary);
  transform: translateY(-2px);
  box-shadow: var(--shadow-glow);
}

.algo-pill:hover::before {
  opacity: 0.1;
}

.algo-pill:active {
  transform: scale(0.97);
}

.algo-pill.algo-active {
  border-color: var(--accent-pink);
  color: var(--text-primary);
  background: rgba(255, 45, 85, 0.12);
}

.algo-pill.algo-active::before {
  opacity: 0.15;
}

.tag-card {
  padding: 14px 16px;
  border-radius: var(--radius-md);
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  cursor: pointer;
  transition: all 0.25s ease;
  text-align: center;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-secondary);
  text-transform: capitalize;
  position: relative;
  overflow: hidden;
}

.tag-card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--accent-gradient);
  opacity: 0;
  transition: opacity 0.25s ease;
}

.tag-card:hover {
  border-color: var(--border-accent);
  color: var(--text-primary);
  transform: translateY(-2px);
  box-shadow: var(--shadow-glow);
}

.tag-card:hover::before {
  opacity: 0.1;
}

.tag-card.active {
  border-color: var(--accent-pink);
  color: var(--text-primary);
  background: rgba(255, 45, 85, 0.12);
}

.tag-card.active::before {
  opacity: 0.15;
}

/* ---------- Active Tag Bar ---------- */
.active-tag {
  display: none !important;
  top: calc(64px + var(--safe-top));
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-topbar);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px 8px 16px;
  background: var(--bg-glass-heavy);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--border-accent);
  border-radius: var(--radius-full);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent-pink);
  box-shadow: var(--shadow-glow);
  animation: slideDown 0.3s cubic-bezier(0.32, 0.72, 0, 1);
  text-transform: capitalize;
}

.clear-btn {
  width: 24px;
  height: 24px;
  border-radius: var(--radius-full);
  border: none;
  background: rgba(255, 255, 255, 0.1);
  color: var(--text-secondary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  transition: all 0.2s;
}

.clear-btn:hover {
  background: var(--accent-pink);
  color: white;
}

/* ---------- Feed Container ---------- */
.feed-container {
  width: 100%;
  height: 100%;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  /* NO scroll-behavior:smooth here — on a mandatory-snap container it animates the snap
     adjustment on top of the native fling, which reads as a brake/bounce between videos.
     Programmatic scrolls stay smooth: goToSlide passes behavior:'smooth' explicitly. */
  -webkit-overflow-scrolling: touch;
}

/* Ad gate: while an ad is being held, the feed can't be scrolled either way. Scrollbars are
   already zero-width, so toggling this causes no layout shift. Taps/clicks still work.
   Flipping -webkit-overflow-scrolling from touch→auto is the reliable iOS way to CANCEL an
   in-flight momentum fling (overflow:hidden alone doesn't); overscroll-behavior stops scroll
   chaining. The JS guardAdInView() re-pin is the belt-and-suspenders backstop. */
.feed-container.ad-lock {
  overflow-y: hidden;
  -webkit-overflow-scrolling: auto;
  overscroll-behavior: contain;
}

/* The ad's hold bar sits above the ad iframe / badges / action buttons. */
.ad-slide .video-progress { z-index: 14; }

/* ---------- Video Slide ---------- */
.video-slide {
  width: 100%;
  height: 100vh;
  height: 100dvh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  position: relative;
  overflow: hidden;
  background: var(--bg-primary);
}

.video-wrapper {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
}

.video-player {
  /* Absolutely fill the wrapper. As a flex item the <video> was sized to its
     intrinsic aspect (min-height:auto), so height:100% was ignored and it rendered
     at the wrong height (e.g. 906px in a 604px slide) → the "half-screen then
     stretch" flash. Absolute positioning pins it to the wrapper so object-fit:cover
     crops correctly from the first paint. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
  /* Hide until actually playing to prevent any flash */
  opacity: 0;
  transition: opacity 0.15s ease;
}

.video-player.is-playing {
  opacity: 1;
}

/* Anti-download: transparent shield over video */
.video-shield {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  background: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

/* Disable selection and callout on all media */
video, img {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  pointer-events: none;
}

/* Re-enable pointer events on video for play/pause via wrapper click.
   NOTE: do NOT set position here — the wrapper must keep its position:absolute
   + inset:0 (defined above) so it fills the whole slide. A stray position:relative
   here collapsed the wrapper to the video's intrinsic height (the half-screen bug). */
.video-wrapper {
  cursor: pointer;
}

/* Landscape/horizontal videos in the 9:16 feed. Fill the frame (object-fit:cover) with NO extra
   transform:scale — the old scale(1.15) zoomed 15% ON TOP of the crop, throwing away even more of an
   already-cropped 16:9 frame. Static framing biased slightly ABOVE centre (40%), where the subject/
   torso usually sits, instead of the old content-blind 12s pan that could sit on the ceiling while the
   action was in a corner. A per-video smart crop (ffmpeg energy analysis) can later set object-position
   from JS; until then this is the safe, non-nauseating default. */
.video-player.landscape-zoom {
  object-fit: cover;
  object-position: 50% 40%;
}

/* ---------- Video Loading ---------- */
.video-loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.3);
  z-index: 2;
  transition: opacity 0.3s;
}

.video-loading.hidden {
  opacity: 0;
  pointer-events: none;
}

.spinner {
  width: 44px;
  height: 44px;
  position: relative;
}

.spinner::before,
.spinner::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

/* Outer ring — pink/magenta */
.spinner::before {
  inset: 0;
  border: 3px solid transparent;
  border-top-color: var(--accent-pink);
  border-right-color: rgba(255, 45, 85, 0.3);
}

/* Inner ring — orange, counter-spin */
.spinner::after {
  inset: 6px;
  border: 2.5px solid transparent;
  border-bottom-color: var(--accent-orange);
  border-left-color: rgba(255, 149, 0, 0.3);
  animation: spinReverse 0.7s linear infinite;
}

/* ---------- Animations ---------- */
@keyframes spin {
  to { transform: rotate(360deg); }
}

@keyframes spinReverse {
  to { transform: rotate(-360deg); }
}

/* ---------- Rewind Indicator ---------- */
.rewind-indicator {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
  z-index: 50;
  pointer-events: none;
}
/* Bias the badge toward the half being held — left for rewind (default), right for fast-forward —
   so the on-screen feedback matches which side the finger is on. */
.rewind-indicator:not(.scrub-right) { justify-content: flex-start; padding-left: 18%; }
.rewind-indicator.scrub-right { justify-content: flex-end; padding-right: 18%; }

.rewind-indicator .rewind-icon {
  width: 60px;
  height: 60px;
  border-radius: var(--radius-full);
  background: var(--bg-glass);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The rewind icon spins BACKWARDS (counter-clockwise) while scrubbing back. */
.rewind-indicator .rewind-icon svg {
  width: 28px;
  height: 28px;
  animation: spinBack 0.8s linear infinite;
}

@keyframes spinBack {
  to { transform: rotate(-360deg); }
}

/* While rewinding, never flash the loading spinner (seeks fire 'waiting' events). */
.video-slide.rewinding .video-loading {
  opacity: 0 !important;
  pointer-events: none;
}

/* ---------- Video Poster ---------- */
.video-poster {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.3s ease;
  cursor: pointer;
}

.video-poster.hidden {
  opacity: 0;
  pointer-events: none;
}

/* ---------- Slide Overlay ---------- */
.slide-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 70px;
  z-index: var(--z-overlay);
  pointer-events: none;
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.slide-overlay.overlay-hidden {
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none !important;
}

/* Keep tags always visible — they live outside the overlay */

.slide-overlay.overlay-hidden .slide-info {
  pointer-events: none !important;
}

.slide-gradient {
  position: absolute;
  bottom: 0;
  left: 0;
  right: -70px;
  height: 280px;
  background: linear-gradient(0deg, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.4) 50%, transparent 100%);
  pointer-events: none;
}

.slide-info {
  position: relative;
  padding: 0 16px calc(80px + var(--safe-bottom));
  pointer-events: auto;
}

.slide-title {
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--text-primary);
  text-shadow: 0 1px 4px rgba(0,0,0,0.6);
  margin-bottom: 4px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.slide-views {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.75rem;
  color: var(--text-muted);
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
  margin-bottom: 6px;
}

.slide-views svg {
  opacity: 0.7;
}

.slide-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.slide-tags-fixed {
  position: absolute;
  bottom: calc(24px + var(--safe-bottom));
  left: 16px;
  right: 70px;
  z-index: var(--z-overlay);
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  pointer-events: auto;
}

.tag-pill {
  padding: 4px 10px;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.2s;
  pointer-events: auto;
  text-transform: capitalize;
}

.tag-pill:hover {
  background: rgba(255, 45, 85, 0.2);
  border-color: var(--border-accent);
  color: var(--accent-pink);
}

.tag-pill.tag-active {
  background: var(--accent-gradient);
  border-color: rgba(192, 37, 209, 0.6);
  color: #fff;
  box-shadow: 0 0 14px rgba(124, 58, 237, 0.5), 0 0 6px rgba(255, 45, 85, 0.3);
  transform: scale(1.08);
}

/* ---------- Slide Actions (Right sidebar) ---------- */
.slide-actions {
  position: absolute;
  right: 10px;
  bottom: calc(100px + var(--safe-bottom));
  z-index: var(--z-overlay);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  transition: right 0.3s ease, left 0.3s ease, opacity 0.2s ease;
}

.slide-actions.actions-left {
  right: auto;
  left: 10px;
}

.action-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-primary);
  transition: all 0.2s;
}

.action-btn svg {
  width: 28px;
  height: 28px;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.5));
  transition: transform 0.2s;
}

.action-btn span {
  font-size: 0.65rem;
  font-weight: 500;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
  color: var(--text-secondary);
}

.action-btn:hover svg {
  transform: scale(1.15);
}

.action-btn:active svg {
  transform: scale(0.9);
}

.like-btn.liked svg {
  background: var(--accent-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  fill: url(#like-gradient);
  animation: popHeart 0.35s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.like-btn.liked span {
  background: var(--accent-gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* ---------- Author Profile Button ---------- */
.author-btn {
  position: relative;
  text-decoration: none;
}

.author-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 2px solid #fff;
  object-fit: cover;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,0.5));
  transition: transform 0.2s;
}

.author-btn:hover .author-avatar {
  transform: scale(1.1);
}

.author-btn:active .author-avatar {
  transform: scale(0.95);
}

.verified-badge {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--accent-gradient);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--bg-primary);
  line-height: 1;
}

/* ---------- Drawer legal footer (2257 / DMCA compliance links) ---------- */
.drawer-legal {
  margin-top: auto;
  padding: 16px 4px 4px;
  border-top: 1px solid rgba(255,255,255,0.08);
  text-align: center;
}
.drawer-legal-links {
  display: flex;
  gap: 8px;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  font-size: 0.8rem;
}
.drawer-legal-links a { color: #9aa0a6; text-decoration: none; }
.drawer-legal-links a:hover { color: #fff; text-decoration: underline; }
.drawer-legal-links span { color: #555; }
.drawer-legal-note { margin-top: 6px; font-size: 0.7rem; color: #666; }

/* ---------- Monetized chat-head (cam smartlink) ---------- */
.chathead-ad { position: relative; }
/* Border = the video's source color (matches the repeat button) via --chc. */
.chathead-ad .author-avatar { border-color: var(--chc, #ff2d55); }
/* Fallback circle shown before live cam thumbs load (or on image error) */
.chathead-ad.avatar-fallback {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 2px solid var(--chc, #fff);
  background: var(--cg, linear-gradient(135deg, #ff2d55 0%, #c0392b 100%));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,0.5));
}
.chathead-ad.avatar-fallback::after { content: attr(data-emoji); font-size: 18px; }
/* Green "online" dot — reads as a live user, lifts CTR */
.chathead-live {
  position: absolute;
  bottom: -4px;
  left: 50%;
  transform: translateX(-50%);
  background: #22c55e;
  color: #fff;
  font-size: 6.5px;
  font-weight: 800;
  letter-spacing: 0.2px;
  line-height: 1;
  padding: 1px 3px;
  border-radius: 3px;
  border: 1px solid var(--bg-primary, #000);
  box-shadow: 0 0 5px rgba(34,197,94,0.6);
  text-transform: uppercase;
  white-space: nowrap;
  z-index: 2;
}

/* ---------- Source Watermark ---------- */
.source-watermark {
  position: absolute;
  bottom: calc(16px + var(--safe-bottom));
  right: 12px;
  z-index: 2;
  opacity: 0.5;
  transition: opacity 0.2s;
  text-decoration: none;
}

.source-watermark img {
  height: 20px;
  width: auto;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.7));
}

.source-watermark:hover {
  opacity: 1;
}

/* ---------- Heart Animation (double-tap) ---------- */
.heart-animation {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 20;
  pointer-events: none;
}

.heart-animation svg {
  width: 100px;
  height: 100px;
  fill: url(#like-gradient);
  opacity: 0;
  transform: scale(0);
}

.heart-animation.pop svg {
  animation: heartPop 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
}

/* ---------- Pause Indicator ---------- */
.pause-indicator {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 15;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
}

.pause-indicator.show {
  opacity: 1;
}

.pause-icon {
  width: 60px;
  height: 60px;
  border-radius: var(--radius-full);
  background: var(--bg-glass);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.pause-icon svg {
  width: 28px;
  height: 28px;
}

/* ---------- No Video Fallback ---------- */
.no-video-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  background: var(--bg-surface);
  z-index: 5;
}

.no-video-fallback .fallback-icon {
  width: 64px;
  height: 64px;
  border-radius: var(--radius-full);
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  display: flex;
  align-items: center;
  justify-content: center;
}

.no-video-fallback .fallback-icon svg {
  width: 28px;
  height: 28px;
  color: var(--text-muted);
}

.no-video-fallback p {
  font-size: 0.9rem;
  color: var(--text-muted);
}

.btn-primary {
  padding: 10px 24px;
  border-radius: var(--radius-full);
  border: none;
  background: var(--accent-gradient);
  color: white;
  font-family: var(--font);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.25s;
  box-shadow: 0 4px 16px rgba(255, 45, 85, 0.3);
}

.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 24px rgba(255, 45, 85, 0.4);
}

.btn-primary:active {
  transform: scale(0.96);
}

.btn-ghost {
  padding: 10px 24px;
  border-radius: var(--radius-full);
  border: 1px solid var(--border-subtle);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font);
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
}

.btn-ghost:hover {
  border-color: var(--text-muted);
  color: var(--text-primary);
}

/* ---------- Loading More ---------- */
.loading-more {
  position: fixed;
  bottom: calc(20px + var(--safe-bottom));
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-overlay);
  padding: 12px 24px;
  background: var(--bg-glass);
  backdrop-filter: blur(12px);
  border-radius: var(--radius-full);
  border: 1px solid var(--border-subtle);
}

.loading-more .spinner {
  width: 24px;
  height: 24px;
  border-width: 2px;
}

/* ---------- Splash Screen ---------- */
.splash {
  position: fixed;
  inset: 0;
  z-index: var(--z-splash);
  background: var(--bg-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.5s ease, visibility 0.5s ease;
}

.splash.hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* ===================== Age + Audience Gate ===================== */
.ptgate {
  position: fixed;
  inset: 0;
  z-index: 250;                 /* above the splash (200), below toasts (300) */
  background: rgba(8, 8, 12, .5); /* translucent so the feed shows through — the visitor sees the page */
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.ptgate[hidden] { display: none; }
.ptgate-card {
  max-width: 360px;
  width: 100%;
  background: rgba(16, 16, 24, .94);
  border: 1px solid #2a2a36;
  border-radius: 18px;
  padding: 22px 20px;
  text-align: center;
  box-shadow: 0 20px 60px rgba(0, 0, 0, .6);
}
.ptgate-logo { font-weight: 800; font-size: 1.4rem; color: #fff; margin-bottom: 6px; }
.ptgate-logo .accent {
  background: linear-gradient(135deg, #ff2d55, #c025d1, #7c3aed);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.ptgate-warn { color: #e7405f; font-weight: 600; font-size: .85rem; margin: .2em 0 1em; }
.ptgate-q { color: #fff; font-weight: 600; margin: 0 0 .7em; }
.ptgate-opts { display: flex; flex-direction: row; gap: 8px; }
.ptgate-btn {
  flex: 1; padding: 14px 6px; border-radius: 12px;
  border: 1px solid #333; background: #1c1c26; color: #fff;
  font-size: 1rem; font-weight: 600;
  cursor: pointer; transition: border-color .15s, background .15s; text-align: center;
}
.ptgate-btn:hover, .ptgate-btn:focus { border-color: #ff2d55; background: #241820; outline: none; }

/* Audience selector inside the Categories drawer */
.aud-row { display: flex; gap: 8px; margin: 0 0 14px; }
.aud-opt {
  flex: 1; padding: 9px 6px; border-radius: 10px;
  border: 1px solid var(--border, #2a2a36); background: var(--bg-elevated, #1c1c26);
  color: var(--text-secondary, #cfcfda); font-size: .8rem; font-weight: 600; cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.aud-opt.active { border-color: #ff2d55; background: #241820; color: #fff; }

/* SEO -> app handoff cover. Holds the exact thumbnail the visitor tapped (already in their cache,
   so it paints on the first frame) while the feed builds underneath, replacing the logo + "Loading
   the feed" splash that taps from the SEO home were dying on. Sits just under --z-splash so the
   real splash still wins if a cold start ever runs alongside it. */
#handoff-poster {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-splash) - 1);
  background-color: var(--bg-primary);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  transition: opacity 0.4s ease;
}

#handoff-poster.gone {
  opacity: 0;
  pointer-events: none;
}

.splash-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

.splash-logo svg {
  animation: pulseLogo 2s ease-in-out infinite;
  filter: drop-shadow(0 0 20px rgba(255, 45, 85, 0.4));
}

.splash-title {
  font-size: 2.5rem;
  font-weight: 700;
  letter-spacing: -0.03em;
}

.splash-sub {
  font-size: 0.9rem;
  color: var(--text-muted);
}

.splash-bar {
  width: 180px;
  height: 3px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}

.splash-bar-fill {
  width: 30%;
  height: 100%;
  border-radius: 2px;
  background: var(--accent-gradient-h);
  animation: loadingBar 1.5s ease-in-out infinite;
}

/* ---------- Install Banner ---------- */
.install-banner {
  position: fixed;
  bottom: calc(20px + var(--safe-bottom));
  left: 16px;
  right: 16px;
  z-index: var(--z-install);
  background: var(--bg-glass-heavy);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  box-shadow: var(--shadow-card);
  animation: slideUp 0.4s cubic-bezier(0.32, 0.72, 0, 1);
}

.install-banner p {
  font-size: 0.9rem;
  font-weight: 500;
}

.install-actions {
  display: flex;
  gap: 10px;
}

.install-actions .btn-primary,
.install-actions .btn-ghost {
  flex: 1;
  padding: 10px 16px;
  font-size: 0.85rem;
}

/* ---------- Toast ---------- */
.toast {
  position: fixed;
  bottom: calc(80px + var(--safe-bottom));
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-toast);
  background: var(--bg-glass-heavy);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  padding: 10px 20px;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-primary);
  box-shadow: var(--shadow-card);
  animation: slideUp 0.3s ease, fadeOut 0.3s ease 2s forwards;
  white-space: nowrap;
}

/* ---------- Empty State ---------- */
.empty-state {
  width: 100%;
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 40px;
  text-align: center;
}

.empty-state svg {
  width: 64px;
  height: 64px;
  color: var(--text-muted);
  margin-bottom: 8px;
}

.empty-state h3 {
  font-size: 1.2rem;
  font-weight: 600;
}

.empty-state p {
  font-size: 0.9rem;
  color: var(--text-muted);
  max-width: 280px;
}

/* ---------- Muted Indicator ---------- */
.muted-indicator {
  position: absolute;
  top: calc(72px + var(--safe-top));
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-overlay);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: var(--bg-glass);
  backdrop-filter: blur(12px);
  border-radius: var(--radius-full);
  font-size: 0.8rem;
  color: var(--text-secondary);
  opacity: 0;
  transition: opacity 0.3s;
  pointer-events: none;
}

.muted-indicator.show {
  opacity: 1;
  pointer-events: auto;
  cursor: pointer;
}

.muted-indicator svg {
  width: 16px;
  height: 16px;
}

/* ---------- Animations ---------- */

@keyframes popHeart {
  0% { transform: scale(0.5); }
  50% { transform: scale(1.3); }
  100% { transform: scale(1); }
}

@keyframes heartPop {
  0% { opacity: 0; transform: scale(0); }
  15% { opacity: 1; transform: scale(1.2); }
  30% { transform: scale(0.95); }
  45% { transform: scale(1.05); }
  60% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1); }
}

@keyframes slideDown {
  from { opacity: 0; transform: translateX(-50%) translateY(-10px); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

@keyframes slideUp {
  from { opacity: 0; transform: translateX(-50%) translateY(20px); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

@keyframes fadeOut {
  to { opacity: 0; visibility: hidden; }
}

@keyframes loadingBar {
  0% { transform: translateX(-100%); }
  50% { transform: translateX(200%); }
  100% { transform: translateX(400%); }
}

@keyframes pulseLogo {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.05); opacity: 0.8; }
}

@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

/* ---------- Skeleton Loading ---------- */
.skeleton {
  background: linear-gradient(90deg,
    rgba(255,255,255,0.04) 25%,
    rgba(255,255,255,0.08) 50%,
    rgba(255,255,255,0.04) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: var(--radius-sm);
}

/* ---------- Responsive ---------- */
@media (min-width: 768px) {
  .feed-container {
    max-width: 480px;
    margin: 0 auto;
    border-left: 1px solid var(--border-subtle);
    border-right: 1px solid var(--border-subtle);
  }

  .video-slide {
    max-width: 480px;
  }

  #top-bar {
    max-width: 480px;
    left: 50%;
    transform: translateX(-50%);
  }

  .active-tag {
    max-width: 300px;
  }

  .slide-actions {
    right: calc(50% - 240px + 10px);
  }

  .slide-overlay {
    max-width: 410px;
    left: calc(50% - 240px);
  }

  .install-banner {
    max-width: 420px;
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }

  .drawer-content {
    width: 360px;
  }
}

@media (max-width: 360px) {
  .slide-title {
    font-size: 0.85rem;
  }

  .tag-pill {
    font-size: 0.68rem;
    padding: 3px 8px;
  }

  .action-btn svg {
    width: 24px;
    height: 24px;
  }
}

/* ---------- Progress Bar (video) ---------- */
.video-progress {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: rgba(255, 255, 255, 0.1);
  z-index: var(--z-overlay);
  /* Draggable scrubber. touch-action:none is load-bearing — the feed scrolls by native scroll-snap,
     so without it a drag here would scroll the feed instead of seeking. The bar is only 3px, far too
     thin to grab, so ::before pads the hit area up to ~22px without changing the visible height. */
  touch-action: none;
  cursor: pointer;
}
.video-progress::before {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 22px;
}
.video-progress-fill {
  height: 100%;
  background: var(--accent-gradient-h);
  width: 0%;
  transition: width 0.1s linear;
  border-radius: 0 2px 2px 0;
  position: relative;
}
/* Grab knob — hidden until the user touches the bar, so idle playback still looks clean. */
.video-progress-knob {
  position: absolute;
  right: 0;
  top: 50%;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
  transform: translate(50%, -50%) scale(0);
  transition: transform 0.12s ease;
  pointer-events: none;
}
/* While scrubbing: fatten the bar, drop the fill's smoothing so it tracks the finger 1:1, show knob. */
.video-slide.scrubbing .video-progress { height: 6px; }
.video-slide.scrubbing .video-progress-fill { transition: none; }
.video-slide.scrubbing .video-progress-knob { transform: translate(50%, -50%) scale(1); }

/* ---------- Autoplay Badge ---------- */
.autoplay-badge {
  position: fixed;
  top: calc(66px + var(--safe-top));
  right: 16px;
  z-index: var(--z-topbar);
  padding: 4px 10px;
  background: var(--bg-glass);
  backdrop-filter: blur(12px);
  border-radius: var(--radius-full);
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--text-muted);
  border: 1px solid var(--border-subtle);
  opacity: 0;
  transition: opacity 0.3s;
  pointer-events: none;
}

.autoplay-badge.show {
  opacity: 1;
}

/* ---------- Repeat Mode Button ---------- */
.mode-btn {
  position: relative;
  min-width: 52px;
  padding: 4px 10px !important;
  border-radius: var(--radius-full) !important;
  font-size: 0.7rem;
  font-weight: 700;
  transition: all 0.3s ease;
}

.mode-btn .mode-label {
  font-size: 0.65rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.mode-btn.active {
  background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
  color: white;
}

.mode-btn.active .mode-label {
  color: white;
}

/* ---------- Slide Number ---------- */
.slide-number {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 5;
  padding: 4px 10px;
  border-radius: var(--radius-full);
  background: rgba(0, 0, 0, 0.5);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--text-muted);
  pointer-events: none;
}

/* ---------- Source Badge ---------- */
.source-badge {
  position: absolute;
  top: 12px;
  right: 6px;
  z-index: 5;
  padding: 6px 14px;
  border-radius: var(--radius-full);
  font-size: 0.85rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  pointer-events: none;
  text-transform: uppercase;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.15);
}

.source-rm {
  background: rgba(255, 71, 87, 0.7);
  color: #ffe0e4;
}

.source-tp {
  background: rgba(254, 44, 85, 0.7);
  color: #ffe0e8;
}

.source-og {
  background: rgba(255, 107, 53, 0.7);
  color: #fff3e0;
}

.source-pn {
  background: rgba(16, 185, 129, 0.5);
  color: #fff;
}

.source-ph {
  background: rgba(255, 144, 0, 0.7);
  color: #fff;
}

.source-er {
  background: rgba(233, 30, 140, 0.7);
  color: #ffe0f0;
}

.source-ff {
  background: rgba(168, 85, 247, 0.7);
  color: #f0e0ff;
}

.source-rg {
  background: rgba(204, 0, 0, 0.7);
  color: #ffe0e0;
}

/* ---------- Feed scroll override for PC ---------- */
.feed-container {
  scroll-snap-type: y mandatory;
  -webkit-overflow-scrolling: touch;
}

.video-slide {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

@media (min-width: 768px) {
  .autoplay-badge {
    right: calc(50% - 240px + 16px);
  }
}

/* Mobile: raise action buttons */
@media (max-width: 767px) {
  .slide-actions {
    bottom: calc(200px + var(--safe-bottom));
  }
}

/* ==============================
   AD SLIDES
   ============================== */
.ad-slide {
  position: relative;
  cursor: pointer;
}

/* Live Chaturbate cam ad — dual iframe: top pane cropped to the video, bottom pane
   cropped to the chat (both from the same room embed). Crop = tunable CSS vars.
   Defaults are rough guesses; tune live via porntok.webcam/?lctune . */
:root {
  /* NATIVE render. We used to hand the embed a 1000x1400 box purely to force CB's desktop
     layout, then translate+scale to crop the video region out of it — a workaround for the
     mobile redirect. With mobileRedirect=never pinned on the embed src (camEmbedSrc in app.js,
     per CB affiliate support), the embed can just lay itself out at the real slide size, so the
     crop is dead weight: it upscaled the stream and cost sharpness for nothing.
     Identity transform = no crop. The ?lctune sliders still drive these if it needs a nudge. */
  --lcv-x: 0px; --lcv-y: 0px; --lcv-s: 1;
}
.ad-livecam { background: #000; overflow: hidden; }
/* Model photo shows INSTANTLY as a poster; the live video fades in over it once loaded. */
/* The CB snapshot maxes out at 480x270; blown up to fill a 9:16 slide it looks pixelated. A soft blur
   turns it into a clean placeholder (reads as intentional) for the ~1.5s before the sharp HD live cam
   fades in over it. scale(1.1) hides the blur's translucent edges. */
.lc-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 20%; z-index: 1; filter: blur(4px); transform: scale(1.1); }
.lc-pane { position: absolute; inset: 0; overflow: hidden; z-index: 2; background: transparent; }
.livecam-frame {
  position: absolute; top: 0; left: 0;
  width: 100%; height: 100%;          /* real slide size → CB renders to fit, no crop needed */
  border: 0;
  transform-origin: top left;
  opacity: 0;
  transition: opacity 0.35s ease;
}
.livecam-frame.lc-on { opacity: 1; }
.lc-vframe {
  /* embed_video_only streams a 16:9 camera. Force a TRUE 16:9 iframe sized to the slide HEIGHT and
     center it, so the live cam COVERS the portrait slide (full height, left/right cropped by .lc-pane)
     and fills the screen like the fullscreen mobile view — not a small letterboxed band. Device-correct
     (keys off the real slide height, not a 9:16 assumption). Fine-tune per device via ?lctune. */
  width: auto; height: 100%; left: 50%; aspect-ratio: 16 / 9;
  transform: translateX(-50%) translate(var(--lcv-x), var(--lcv-y)) scale(var(--lcv-s));
}
/* Tap anywhere → CB signup (our referral). Shows a LIVE badge + "Chatea gratis" button. */
.lc-cta { position: absolute; inset: 0; z-index: 3; display: block; text-decoration: none; }
.lc-badge {
  position: absolute; top: 14px; right: 14px;   /* right side → doesn't cover the PornTok logo */
  background: rgba(255, 45, 85, 0.92); color: #fff;
  font-weight: 800; font-size: 13px; letter-spacing: 0.3px;
  padding: 5px 11px; border-radius: 999px;
}
.lc-cta-btn {
  position: absolute; left: 50%; bottom: 13%; transform: translateX(-50%);
  white-space: nowrap; background: #ff2d55; color: #fff;
  font-weight: 800; font-size: 16px; padding: 12px 26px; border-radius: 999px;
  box-shadow: 0 6px 24px rgba(255, 45, 85, 0.5);
}
/* "Ad" disclosure sits just BELOW the PornTok logo (top-left) on the cam ad. */
.ad-livecam .ad-label { z-index: 5; position: absolute; top: calc(42px + var(--safe-top)); left: 16px; bottom: auto; right: auto; pointer-events: none; }

/* Ad action buttons (like / volume / hide) must sit ABOVE the CTA overlay + cam iframe. */
.ad-slide .ad-actions { z-index: 12; pointer-events: none; }
.ad-slide .ad-actions .action-btn { pointer-events: auto; }
/* Hide the top-right chrome (categories + repeat) on ads — set the instant an ad appears
   (body.on-ad), so it never flashes in and out. */
body.on-ad #tags-toggle,
body.on-ad #autoplay-toggle { opacity: 0 !important; pointer-events: none !important; transition: opacity 0.12s ease; }

/* Crop tuner (only shown via ?lctune) */
.lc-tuner {
  position: fixed; left: 8px; right: 8px; bottom: 8px; z-index: 99999;
  background: rgba(10,10,16,0.94); border: 1px solid #333; border-radius: 10px;
  padding: 8px 10px; display: flex; flex-direction: column; gap: 4px;
  font-size: 11px; color: #eee; max-height: 46vh; overflow: auto;
}
.lc-tuner.lc-tuner-min > label, .lc-tuner.lc-tuner-min > .lc-tuner-out { display: none; }
.lc-tuner label { display: flex; align-items: center; gap: 8px; }
.lc-tuner label input { flex: 1; }
.lc-tuner-out { font-family: monospace; font-size: 10px; color: #6fd; word-break: break-all; }
.lc-tuner-hide { align-self: flex-end; background: #ff2d55; color: #fff; border: 0; border-radius: 6px; padding: 3px 8px; }

/* ExoClick outstream video ad slide */
.ad-video {
  background: #000;
  overflow: hidden;
}
/* CrakRevenue fallback fills the slide until ExoClick fills the <ins> */
.ad-video .ad-video-fallback {
  position: absolute;
  inset: 0;
  z-index: 1;
}
.ad-video .ad-video-fallback .ad-link { width: 100%; height: 100%; }
/* The ExoClick ad layer sits on top; transparent + click-through until it fills */
.ad-video ins.eas6a97888e37 {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  pointer-events: none;
}
.ad-video ins.eas6a97888e37 iframe,
.ad-video ins.eas6a97888e37 video,
.ad-video ins.eas6a97888e37 > * {
  max-width: 100% !important;
  max-height: 100vh !important;
}
/* Once ExoClick renders a real ad, hide the fallback and let the ad take clicks */
.ad-video.exo-filled .ad-video-fallback { display: none; }
.ad-video.exo-filled ins.eas6a97888e37 { pointer-events: auto; background: #000; }

/* ExoClick VAST video ad slide — our own player. Nothing sits under the ad: no house creative, so
   the slide stays plain black until the real ad is wired, then reveals the <video> + click overlay.
   The tag is prefetched ~1.5 screens ahead (serveVastAds) so that black is never actually seen. */
.ad-vast { background: #000; overflow: hidden; }
.ad-vast .vast-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; background: #000; z-index: 2; display: none;
}
.ad-vast .vast-click { position: absolute; inset: 0; z-index: 3; display: none; }
.ad-vast.vast-filled .vast-video { display: block; }
.ad-vast.vast-filled .vast-click { display: block; }
.ad-vast .ad-label { z-index: 10; }
/* ?vastdebug log panel — fixed to the viewport, NOT to a slide, so it survives the no-fill
   removal we need to observe. Only rendered when the flag is on (VAST_DEBUG in app.js). */
.vast-log {
  position: fixed; left: 6px; right: 6px; bottom: 6px;
  z-index: 9999; pointer-events: none;
  max-height: 42vh; overflow: hidden;
  background: rgba(0, 0, 0, 0.88); color: #0f0;
  font: 600 11px/1.45 ui-monospace, Menlo, Consolas, monospace;
  padding: 6px 8px; border-radius: 8px; word-break: break-word;
}
.vast-log b { color: #ff0; }

.ad-link {
  display: block;
  width: 100%;
  height: 100%;
  text-decoration: none;
  color: #fff;
  position: relative;
  overflow: hidden;
}

.ad-bg {
  position: absolute;
  inset: 0;
  animation: adBgShift 8s ease-in-out infinite alternate;
}

@keyframes adBgShift {
  0%   { filter: brightness(1) saturate(1); }
  100% { filter: brightness(1.15) saturate(1.3); }
}

/* Floating particles */
.ad-particles {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.ad-particles::before,
.ad-particles::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  animation: adFloat 6s ease-in-out infinite;
}

.ad-particles::before {
  width: 300px; height: 300px;
  top: -80px; left: -80px;
  animation-delay: 0s;
}

.ad-particles::after {
  width: 200px; height: 200px;
  bottom: -40px; right: -40px;
  animation-delay: 3s;
}

@keyframes adFloat {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%       { transform: translate(20px, -20px) scale(1.1); }
}

/* Ad content layout */
.ad-content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 40px 32px;
  text-align: center;
}

.ad-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 999px;
  padding: 6px 16px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  animation: adPulse 2s ease-in-out infinite;
}

@keyframes adPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,255,255,0.3); }
  50%       { box-shadow: 0 0 0 8px rgba(255,255,255,0); }
}

.ad-emoji {
  font-size: 72px;
  filter: drop-shadow(0 4px 16px rgba(0,0,0,0.3));
  animation: adEmojiBounce 3s ease-in-out infinite;
}

@keyframes adEmojiBounce {
  0%, 100% { transform: translateY(0) scale(1); }
  50%       { transform: translateY(-10px) scale(1.05); }
}

.ad-headline {
  font-size: clamp(24px, 6vw, 36px);
  font-weight: 800;
  line-height: 1.2;
  margin: 0;
  text-shadow: 0 2px 20px rgba(0,0,0,0.4);
  max-width: 340px;
}

.ad-sub {
  font-size: 16px;
  opacity: 0.85;
  margin: 0;
  max-width: 300px;
  line-height: 1.5;
}

.ad-cta-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 8px;
  padding: 14px 32px;
  border-radius: 999px;
  font-size: 16px;
  font-weight: 700;
  color: #fff;
  box-shadow: 0 4px 24px rgba(0,0,0,0.35);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  text-shadow: none;
  letter-spacing: 0.02em;
}

.ad-link:active .ad-cta-btn {
  transform: scale(0.96);
}

/* "Publicidad" label */
.ad-label {
  position: absolute;
  top: 12px;
  right: 12px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255,255,255,0.5);
  background: rgba(0,0,0,0.25);
  padding: 3px 8px;
  border-radius: 4px;
  pointer-events: none;
}

/* Countdown pill next to the "Ad" label while the hold runs. Emptied when the gate opens,
   and :empty hides it — no leftover chip once the user is free to scroll. */
.ad-count {
  display: inline-block;
  min-width: 14px;
  margin-left: 6px;
  padding: 0 4px;
  border-radius: 999px;
  background: rgba(255,255,255,0.22);
  color: #fff;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.ad-count:empty { display: none; }

/* ── Bottom banner (CPM) — fixed bar, only on video slides ─────────────────── */
:root { --bottom-ad-h: 52px; }
#bottom-ad {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  height: calc(var(--bottom-ad-h) + var(--safe-bottom));
  padding-bottom: var(--safe-bottom);
  z-index: 40;                 /* above slide overlays (10), below top bar (50) + drawers (100) */
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(10, 10, 15, 0.92);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
body.show-bottom-ad #bottom-ad { display: flex; }
.bottom-ad-tag {
  position: absolute; left: 10px; top: 5px;
  font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.4);
}
.bottom-ad-slot {
  width: 320px; max-width: 100%; height: var(--bottom-ad-h);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
#bottom-ad-iframe { width: 320px; height: 50px; border: 0; display: block; }
/* Reserve mode: shrink the video area so the bar sits BELOW it (nothing hidden behind the bar).
   object-fit:cover still fills the reduced area edge-to-edge → no side/top bands, just ~52px shorter. */
body.show-bottom-ad .video-wrapper { bottom: calc(var(--bottom-ad-h) + var(--safe-bottom)); }

/* Lift ALL the bottom chrome by the bar height so nothing sits behind the banner: progress bar,
   action buttons (like/hide/profile/mute), tags, the title/source line, and the source watermark. */
body.show-bottom-ad .video-progress   { bottom: calc(var(--bottom-ad-h) + var(--safe-bottom)); }
body.show-bottom-ad .slide-actions    { bottom: calc(100px + var(--bottom-ad-h) + var(--safe-bottom)); }
body.show-bottom-ad .slide-tags-fixed { bottom: calc(24px + var(--bottom-ad-h) + var(--safe-bottom)); }
body.show-bottom-ad .slide-info       { padding-bottom: calc(80px + var(--bottom-ad-h) + var(--safe-bottom)); }
body.show-bottom-ad .source-watermark { bottom: calc(16px + var(--bottom-ad-h) + var(--safe-bottom)); }

/* Mobile raises the action column to 200px so it clears the title. That lift must survive the
   ad bar too — otherwise the .show-bottom-ad rule above drops the buttons back down to 152px,
   right on top of the video name. Keep the 200px AND add the bar offset. */
@media (max-width: 767px) {
  body.show-bottom-ad .slide-actions { bottom: calc(200px + var(--bottom-ad-h) + var(--safe-bottom)); }
}

/* ── Live cam ad thumbnail ─────────────────────────── */
.ad-cam-thumb,
.ad-cr-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}
/* Small badge chip for CrakRevenue creative-image ads */
.ad-badge-sm {
  align-self: flex-start;
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(6px);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
}

.ad-cam-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  pointer-events: none;
  /* Dark vignette top & bottom */
  background:
    linear-gradient(to bottom, rgba(0,0,0,0.55) 0%, transparent 30%),
    linear-gradient(to top,    rgba(0,0,0,0.75) 0%, transparent 45%);
}

.ad-cam-top {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 16px 0;
}

.ad-live-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: #e53e3e;
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.06em;
  padding: 4px 10px;
  border-radius: 4px;
  animation: livePulse 1.8s ease-in-out infinite;
}

@keyframes livePulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.75; }
}

.ad-viewers {
  font-size: 13px;
  font-weight: 600;
  color: rgba(255,255,255,0.9);
  text-shadow: 0 1px 4px rgba(0,0,0,0.6);
}

.ad-cam-bottom {
  padding: 0 16px 28px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.ad-cam-name {
  font-size: 20px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 2px 8px rgba(0,0,0,0.7);
}

.tag-card.liked-card { background: linear-gradient(135deg, rgba(255,45,85,0.25), rgba(124,58,237,0.25)); }
