/* CONTRAST (fixed 06.09 after PageSpeed a11y 95 -> contrast was the only fail).
   Every failure was the same shape: a light grey/accent used as small text, or
   white text on a mid-tone accent. Solved at the TOKEN level rather than
   per-rule, so nothing can regress by adding a component later.
     light  --ink3 #8B8194->#746A7C, --hot #FF1F5A->#E9003D,
            --live #00A855->#008744, --warn #D97200->#B45F00   (all >=4.5:1)
     dark   --ink3 #7E7389->#897F94, accents unchanged, text on them flipped
            to near-black via --on-accent
   The LOGO keeps the original #FF1F5A: it is an image, exempt from contrast
   rules, and a marginally more vivid mark beside slightly deeper UI chrome is
   normal. */
/* 3xpornfree.com — magazine grid + left category rail.
   Palette: hot pink / saffron / ultramarine on warm paper.
   Deliberately not BongaCams' orange, not absexxx's green, not osexxx's layout.

   NAMING RULE: no class may contain ad, ads, banner, promo or sponsor.
   House slots use .slot / .slot-*. */

:root{
  --paper:#FFFDF7; --paper2:#F6F0E4; --card:#FFFFFF;
  --ink:#17131C; --ink2:#5A5065; --ink3:#746A7C;
  --line:#E3D9C7; --line2:#EFE8DA;
  --hot:#E9003D; --saffron:#FFC300; --ultra:#2B1AC4;
  --live:#008744; --warn:#B45F00;
  --on-accent:#FFFFFF;
  --disp:"Bricolage Grotesque","Trebuchet MS",Verdana,sans-serif;
  --body:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --r:10px; --wrap:1500px;
}
@media (prefers-color-scheme:dark){
  :root{
    --paper:#141019; --paper2:#1E1826; --card:#1A1522;
    --ink:#F7F2EA; --ink2:#B0A5BC; --ink3:#897F94;
    --line:#302739; --line2:#261F2E;
    --hot:#FF4D77; --saffron:#FFD24A; --ultra:#8877FF;
    --live:#2ED47A; --warn:#F0A030;
    /* Dark keeps the bright accents and flips the text on them to near-black.
       White on #FF4D77 is only 3.19:1; #141019 on it is 5.89:1. Inverting the
       foreground is what lets the dark theme stay vivid and still pass. */
    --on-accent:#141019;
  }
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--body);
     font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased}
h1,h2,h3{font-family:var(--disp);margin:0;letter-spacing:-.02em;text-wrap:balance}
img{max-width:100%;display:block}
a{color:inherit}
:focus-visible{outline:2px solid var(--hot);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

.skip{position:absolute;left:-9999px}
.skip:focus{left:8px;top:8px;z-index:99;background:var(--ink);color:var(--paper);padding:8px 14px;border-radius:6px}

/* ------------------------------------------------------------------ topbar */
.topbar{display:flex;align-items:center;gap:16px;padding:11px 18px;
        border-bottom:1px solid var(--line);background:var(--paper);
        position:sticky;top:0;z-index:20;flex-wrap:wrap}
.brand{flex:0 0 auto;text-decoration:none;color:var(--ink);display:flex}
.mark{display:block;height:auto}
.srch{flex:1 1 220px;max-width:340px;display:flex;gap:6px}
.srch input{flex:1;min-width:0;border:1.5px solid var(--line);background:var(--card);
            color:var(--ink);border-radius:999px;padding:7px 14px;font:inherit;font-size:13px}
.srch button{border:0;background:var(--ink);color:var(--paper);border-radius:999px;
             padding:7px 15px;font-family:var(--disp);font-weight:700;font-size:13px;cursor:pointer}
.srch-big{max-width:520px;margin:0 0 18px}
.srch-big input{font-size:15px;padding:10px 18px}
.navtabs{display:flex;gap:3px;flex-wrap:wrap;margin-left:auto}
.navtabs a{font-family:var(--disp);font-weight:700;font-size:13px;text-decoration:none;
           padding:5px 11px;border-radius:7px;color:var(--ink2)}
.navtabs a.on{background:var(--hot);color:var(--on-accent)}
.livepill{font-family:var(--mono);font-size:11px;font-weight:700;color:var(--live);
          display:flex;align-items:center;gap:6px;white-space:nowrap;font-variant-numeric:tabular-nums}
.livepill::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--live)}

/* ------------------------------------------------------------------ layout */
.layout{display:grid;grid-template-columns:212px minmax(0,1fr);max-width:var(--wrap);margin:0 auto}
@media(max-width:900px){.layout{grid-template-columns:1fr}.rail{display:none}}

.rail{border-right:1px solid var(--line);background:var(--paper2);padding:16px 0 24px;
      align-self:start;position:sticky;top:62px;max-height:calc(100vh - 62px);overflow-y:auto}
.railgrp{padding:0 14px 16px}
.railgrp h2{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
            color:var(--ink3);margin:0 0 8px;font-weight:700}
.railgrp ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px}
.railgrp a{display:flex;justify-content:space-between;gap:8px;text-decoration:none;
           font-size:13px;color:var(--ink2);padding:4px 8px;border-radius:6px}
.railgrp a:hover{background:var(--line2);color:var(--ink)}
.railgrp a .n{font-family:var(--mono);font-size:10.5px;color:var(--ink3);font-variant-numeric:tabular-nums}
.railgrp a.on{background:var(--ultra);color:var(--on-accent);font-weight:600}
.railgrp a.on .n{color:rgba(255,255,255,.78)}
.chips{display:flex;flex-wrap:wrap;gap:5px}
.chips a{font-size:11.5px;text-decoration:none;border:1px solid var(--line);
         border-radius:999px;padding:3px 9px;color:var(--ink2)}
.chips a:hover{border-color:var(--hot);color:var(--hot)}
.chips a.on{background:var(--hot);border-color:var(--hot);color:var(--on-accent)}

.main{padding:18px 20px 40px;min-width:0}
.crumb{font-family:var(--mono);font-size:11px;color:var(--ink3);margin-bottom:10px}
.crumb a{text-decoration:none}
.crumb a:hover{color:var(--hot)}
.pagehead{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 14px}
.pagehead h1{font-size:clamp(22px,3vw,31px);font-weight:800}
.pagehead .pg{font-size:.6em;font-weight:700;color:var(--ink3)}
.pagehead .cnt{font-family:var(--mono);font-size:12px;color:var(--ink3);font-variant-numeric:tabular-nums}
.lede{color:var(--ink2);font-size:14.5px;max-width:72ch;margin:8px 0 18px}
.empty{color:var(--ink2);padding:26px 0}

/* -------------------------------------------------------------------- grid */
.grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(196px,1fr));margin-bottom:14px}
.grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.tile{text-decoration:none;display:flex;flex-direction:column;border-radius:var(--r);
      overflow:hidden;border:1px solid var(--line);background:var(--card)}
.tile:hover{border-color:var(--hot)}
.tile .shot{position:relative;display:block;aspect-ratio:4/3;background:var(--paper2)}
.tile .shot img{width:100%;height:100%;object-fit:cover}
.tile .meta{padding:7px 9px 9px;display:flex;flex-direction:column;gap:3px}
.tile .nm{font-family:var(--disp);font-weight:700;font-size:14px;line-height:1.15;
          color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tile .sub{font-family:var(--mono);font-size:10.5px;color:var(--ink3);display:flex;gap:7px;
           overflow:hidden;white-space:nowrap;font-variant-numeric:tabular-nums}

.badge{position:absolute;top:7px;left:7px;font-family:var(--mono);font-size:9.5px;font-weight:700;
       letter-spacing:.08em;text-transform:uppercase;padding:3px 7px;border-radius:5px;
       color:var(--on-accent);background:var(--live);display:flex;align-items:center;gap:5px}
.badge::before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor}
.badge.away{background:var(--warn)}
.badge.off{background:var(--ink3)}
.badge.away::before,.badge.off::before{opacity:.55}
.hd{position:absolute;top:7px;right:7px;font-family:var(--mono);font-size:9.5px;font-weight:700;
    background:rgba(0,0,0,.58);color:#fff;padding:3px 6px;border-radius:5px}
.watch{position:absolute;bottom:7px;right:7px;font-family:var(--mono);font-size:10px;font-weight:700;
       background:rgba(0,0,0,.58);color:#fff;padding:3px 7px;border-radius:5px;font-variant-numeric:tabular-nums}

/* ------------------------------------------------------------------- pager */
.pager{display:flex;flex-wrap:wrap;gap:5px;align-items:center;margin:22px 0 6px}
.pager a,.pager span{font-family:var(--mono);font-size:12.5px;font-weight:700;min-width:34px;height:34px;
                     display:flex;align-items:center;justify-content:center;border:1.5px solid var(--line);
                     border-radius:7px;text-decoration:none;color:var(--ink2);padding:0 10px}
.pager a:hover{border-color:var(--hot);color:var(--hot)}
.pager .cur{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.pager .gap{border:0;min-width:16px}

/* -------------------------------------------------------------- model page */
.mgrid{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);gap:22px}
@media(max-width:900px){.mgrid{grid-template-columns:1fr}}

.stage{position:relative;aspect-ratio:16/9;border-radius:var(--r);overflow:hidden;
       border:1px solid var(--line);background:#000}
/* The poster is ALWAYS the base layer. A blocked or failed player is transparent,
   so it degrades to a real thumbnail instead of a black rectangle, and the page
   still works with JavaScript off. */
.stage-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.stage-video,.stage-frame{position:absolute;inset:0;width:100%;height:100%;border:0;
                          object-fit:cover;background:transparent}
/* The click target sits ABOVE the player so the whole stage is clickable.
   If the player is removed, this still works — nothing to eat the clicks. */
.stage-hit{position:absolute;inset:0;z-index:3}
.stage .badge,.stage .hd,.stage .watch{z-index:4;top:10px}
.stage .badge{left:10px}
.stage .hd{right:10px}
.stage .watch{top:auto;bottom:10px;right:10px;font-size:11px}
.stagenote{font-size:12.5px;color:var(--ink3);margin:8px 0 0}
.stagenote a{color:var(--hot)}

.cta{display:inline-flex;align-items:center;gap:9px;background:var(--hot);color:var(--on-accent);
     text-decoration:none;font-family:var(--disp);font-weight:800;font-size:16px;
     padding:12px 22px;border-radius:9px;margin-top:14px}
.cta:hover{background:var(--ink);color:var(--paper)}
.cta .arrow{font-family:var(--mono)}

.prose{max-width:66ch;margin-top:20px}
.prose h2,.tagh,.alsoh{font-size:19px;font-weight:800;margin:0 0 10px}
.tagh,.alsoh{margin-top:22px}
.prose p{color:var(--ink2);font-size:14.5px;margin:0 0 11px}
.tagrow{display:flex;flex-wrap:wrap;gap:6px}
.tagrow a{font-size:12px;text-decoration:none;border:1.5px solid var(--line);
          border-radius:999px;padding:4px 11px;color:var(--ink2)}
.tagrow a:hover{border-color:var(--hot);color:var(--hot)}
.catrow{margin-top:8px}
.catrow a{border-style:dashed}

.facts{border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:var(--card)}
.facts h2{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
          padding:10px 13px;background:var(--paper2);border-bottom:1px solid var(--line);
          color:var(--ink3);font-weight:700;margin:0}
.facts dl{margin:0;padding:4px 13px 12px}
.facts .row{display:flex;justify-content:space-between;gap:12px;padding:6px 0;
            border-bottom:1px solid var(--line2);font-size:13px}
.facts .row:last-child{border-bottom:0}
.facts dt{color:var(--ink3)}
.facts dd{margin:0;font-weight:600;font-family:var(--mono);font-size:12px;text-align:right;
          font-variant-numeric:tabular-nums}
.facts dd.ok{color:var(--live)}
.gonepage{max-width:60ch}

.alsorow{margin-top:30px;border-top:1px solid var(--line);padding-top:18px}
.alsorow h2{font-size:15px;font-weight:800;text-transform:uppercase;letter-spacing:.03em;margin-bottom:10px}

/* -------------------------------------------------------------------- slot */
.slot{border:1.5px dashed var(--line);border-radius:var(--r);padding:14px 16px;background:var(--paper2)}
.slot-t{font-family:var(--disp);font-weight:800;font-size:15px}
.slot-l{margin:5px 0 10px;font-size:13px;color:var(--ink2)}
.slot-c{display:inline-block;text-decoration:none;font-family:var(--disp);font-weight:700;
        font-size:13px;color:var(--on-accent);background:var(--ultra);padding:7px 14px;border-radius:7px}
.slot-c:hover{background:var(--ink)}
.slot-grid{grid-column:1/-1;margin:6px 0 16px;display:flex;flex-wrap:wrap;gap:10px 20px;
           align-items:center;justify-content:space-between}
.slot-grid .slot-l{margin:4px 0 0;flex:1 1 260px}
.slot-rail{margin:0 14px}
.slot-side{margin-top:20px}
.slot-foot{border-style:solid;background:transparent}

/* ------------------------------------------------------------------ footer */
.foot{border-top:1px solid var(--line);background:var(--paper2);margin-top:30px}
.footwrap{max-width:var(--wrap);margin:0 auto;padding:26px 20px;display:grid;gap:24px;
          grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.fcol h3{font-size:13px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;margin-bottom:9px}
.fcol ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px}
.fcol a{font-size:13px;color:var(--ink2);text-decoration:none}
.fcol a:hover{color:var(--hot)}
.fcol p{font-size:12.5px;color:var(--ink3);margin:9px 0 0;max-width:34ch}
.footbar{border-top:1px solid var(--line);padding:12px 20px;display:flex;flex-wrap:wrap;gap:10px;
         justify-content:space-between;font-size:12px;color:var(--ink3);
         max-width:var(--wrap);margin:0 auto}
.rta{font-family:var(--mono);font-size:10px;border:1px solid var(--line);padding:2px 6px;border-radius:4px}

/* ------------------------------------------------------------------- legal */
.legal{max-width:72ch}
.legal h1{font-size:28px;font-weight:800;margin-bottom:14px}
.legal h2{font-size:17px;font-weight:800;margin:22px 0 8px}
.legal p,.legal li{color:var(--ink2);font-size:14.5px}
.legal ul{padding-left:20px}
.legalfoot{margin-top:26px;font-size:12px;color:var(--ink3)}

/* Display name shown only when it differs from the username. */
.prose .alias{font-size:13px;color:var(--ink3);margin:-4px 0 12px}
.prose .alias code{font-family:var(--mono);font-size:12px;background:var(--paper2);
                   padding:1px 6px;border-radius:4px;border:1px solid var(--line)}

/* ------------------------------------------------- slot image creatives ----
   Rule: scale DOWN, never distort, never upscale past the file's own size.
   width:100% + height:auto keeps the aspect ratio at every width, and the
   width/height attributes on the <img> reserve the box before it loads so the
   grid does not jump (layout shift is a Core Web Vitals factor).
   A wide creative is capped at its display width and centred rather than
   stretched across the full column, because upscaling a 950px file to 1200px
   just makes it soft. */
.slot-has-media{padding:0;border:0;background:transparent}
.slot-media{display:block;max-width:950px;margin:0 auto;border-radius:var(--r);
            overflow:hidden;line-height:0;border:1px solid var(--line)}
.slot-media img{width:100%;height:auto;display:block}
.slot-media:hover{border-color:var(--hot)}
/* In the grid the slot spans the full row rather than sitting in one cell. */
.slot-grid.slot-has-media{grid-column:1/-1;display:block;margin:6px 0 18px}
/* The rail is 212px wide — a 3.8:1 creative would be 56px tall and illegible,
   so a wide creative is simply not shown there. Use a text slot in the rail. */
.slot-rail.slot-has-media{display:none}

/* Rotator: one candidate visible; the rest are removed by rotate.js.
   With JS off only the first is marked .on, so the slot still works. */
.slot-cand{display:none}
.slot-cand.on{display:block}
.slot-rot-grid{grid-column:1/-1;margin:6px 0 18px}
.slot-rot-side{margin-top:20px}
.slot-rot-rail{display:none}   /* 212px rail cannot show a 3.8:1 creative legibly */

/* --------------------------------------------------- stage aspect handling --
   BongaCams streams are frequently PORTRAIT (phone broadcast). A 16:9 stage with
   object-fit:cover fills the box and crops the overflow, which on a portrait
   source cuts off the head and feet and leaves a mid-body band — the performer's
   face was not visible at all.

   `contain` shows the whole frame whatever its shape. The poster is already
   loaded and sits behind the video, so blurring and scaling it fills the empty
   sides the way BongaCams' own player does, at no extra network cost.

   The blur applies ONLY under .has-player. When no player mounts — offline,
   between shows, a bot, or a failed stream — the poster is the content itself
   and must stay sharp. rotate/entry JS removes .has-player if the video dies. */
.stage{background:#0b0810}
.stage-video,.stage-frame{object-fit:contain}
.stage.has-player .stage-poster{filter:blur(26px) saturate(1.2);transform:scale(1.15)}
@media (prefers-reduced-motion:reduce){.stage.has-player .stage-poster{transform:scale(1.15)}}
