/* stripcams.me / striprec.com — one stylesheet, two palettes.
   Every colour comes from a custom property Config::cssVariables() sets per host
   in <head>, so this file never names a brand colour.

   TOKEN ROLES, and getting these wrong is what made the first build unreadable:
     --bg          page background (dark on both hosts)
     --on-bg       text ON the page background      <- NOT --text
     --on-bg-muted secondary text on the page background
     --surface     card / panel background
     --text        text ON a surface                <- dark on stripcams.me
     --accent      fills (buttons, live banner, current page, back-to-top)
     --on-accent   text ON an accent fill
   stripcams.me's --text is #362119 brown, meant for the #a9baab sage card
   surface. Using it for body text put brown on a near-black page. */

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--on-bg);
  font: 16px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

a { color: inherit; text-decoration: none; }
a:focus-visible, button:focus-visible, input:focus-visible {
  outline: 2px solid var(--accent-warm); outline-offset: 2px;
}

.wrap { max-width: 1600px; margin: 0 auto; padding: 0 20px 96px; }

/* ── Header ─────────────────────────────────────────────────────────────── */
.site-header {
  display: flex; align-items: center; gap: 24px; flex-wrap: wrap;
  padding: 14px 20px;
  background: var(--accent-dk);
  border-bottom: 1px solid var(--border);
}
.brand { font-size: 1.3rem; font-weight: 700; color: var(--on-accent); }
.search { position: relative; flex: 1 1 280px; max-width: 480px; }
.search input {
  width: 100%; padding: 9px 12px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--text); font-size: 1rem;
}
.suggest {
  position: absolute; z-index: 200; inset-inline: 0; top: calc(100% + 4px);
  margin: 0; padding: 4px; list-style: none;
  background: var(--surface); border: 1px solid var(--border); border-radius: 6px;
  max-height: 60vh; overflow-y: auto;
}
.suggest a {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 7px 9px; border-radius: 4px; color: var(--text);
}
.suggest a:hover { background: var(--accent); color: var(--on-accent); }
.suggest-count { opacity: .7; font-variant-numeric: tabular-nums; }

/* ── Category nav: platform buttons + section hover-dropdowns ────────────
   Same markup contract as newsites/fastimages so a fix travels. */
.cat-nav { background: var(--surface); border-bottom: 1px solid var(--border); }
.cat-nav-list {
  list-style: none; margin: 0 auto; padding: 0 20px;
  max-width: 1600px; display: flex; flex-wrap: wrap; gap: .25rem;
}
.cat-item { position: relative; }
.cat-link {
  display: block; padding: .65rem 1rem;
  color: var(--text); font-weight: 600; font-size: .95rem;
  border-bottom: 2px solid transparent;
}
.cat-item:hover > .cat-link { color: var(--accent); border-bottom-color: var(--accent); }
.cat-dropdown {
  list-style: none; margin: 0; padding: .25rem 0;
  position: absolute; top: 100%; left: 0; min-width: 180px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 6px;
  box-shadow: 0 6px 18px rgba(0,0,0,.45);
  opacity: 0; visibility: hidden; transform: translateY(4px);
  transition: opacity .15s ease, transform .15s ease, visibility .15s;
  z-index: 150;
}
.cat-item:hover > .cat-dropdown,
.cat-item:focus-within > .cat-dropdown { opacity: 1; visibility: visible; transform: translateY(0); }
.cat-dropdown a { display: block; padding: .5rem 1rem; color: var(--text); font-size: .92rem; }
.cat-dropdown a:hover { background: var(--border); color: var(--accent); }

/* ── Headings ───────────────────────────────────────────────────────────── */
h1 { font-size: 1.6rem; margin: 26px 0 6px; color: var(--on-bg); text-wrap: balance; }
h2 { color: var(--on-bg); }
.listing-heading { font-size: 1rem; font-weight: 400; color: var(--on-bg-muted); margin: 0 0 22px; }
.empty { color: var(--on-bg-muted); padding: 40px 0; }

/* ── Card grid ──────────────────────────────────────────────────────────
   Sized off ultron: 4 across on desktop (its grid-3 = 25%), 16/10 thumbs.
   The first build used minmax(180px,1fr), which gave ~8 per row and made
   every card a thumbnail. */
.grid {
  display: grid; gap: 18px;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 8px; overflow: hidden; color: var(--text);
}
.card-link { display: block; color: inherit; }
.card-thumb {
  display: block; width: 100%;
  aspect-ratio: 16 / 10;          /* ultron's box for both img and hover video */
  object-fit: cover; background: var(--accent-dk);
}
.card-thumb--empty { display: block; }
.card-name {
  display: block; padding: 10px 12px 0; font-weight: 600; font-size: 1rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text);
}
.card-meta {
  display: block; padding: 3px 12px 12px; font-size: .875rem;
  color: var(--muted); font-variant-numeric: tabular-nums;
}
.card:hover { border-color: var(--accent); }

/* ── Buttons ────────────────────────────────────────────────────────────── */
.btn {
  display: inline-block; padding: 11px 20px; border-radius: 6px;
  background: var(--accent); color: var(--on-accent); font-weight: 600;
  border: 1px solid var(--accent); cursor: pointer;
}
.btn:hover { filter: brightness(1.12); }
.btn--ghost {
  background: transparent; color: var(--on-bg);
  border-color: var(--border);
}
.btn--ghost:hover { background: var(--surface); color: var(--text); border-color: var(--accent); }

/* ── Performer page ─────────────────────────────────────────────────────── */
.performer-meta {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  color: var(--on-bg-muted); margin-bottom: 18px;
}
.tag { padding: 3px 10px; border: 1px solid var(--border); border-radius: 999px; font-size: .85rem; }
.cb-subject {
  background: var(--surface); color: var(--text);
  border-left: 3px solid var(--accent); padding: 10px 14px; border-radius: 4px;
}
.cb-last-seen { color: var(--on-bg-muted); font-size: .9rem; }
.alias-toggle { margin: 18px 0; }

.live-banner {
  display: inline-flex; align-items: center; gap: 9px;
  margin-top: 22px; padding: 12px 20px; border-radius: 6px;
  background: var(--accent); color: var(--on-accent); font-weight: 700; font-size: 1.05rem;
}
.live-banner:hover { filter: brightness(1.12); }
.live-dot { width: 10px; height: 10px; border-radius: 50%; background: #fff; animation: pulse 1.6s infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .live-dot { animation: none; } }

/* ── Detail page ────────────────────────────────────────────────────────
   Follows fastimages: the detail surface gets its OWN width, wider than the
   listing container, so the media can show near native size on a big monitor.
   The player is shaped by the recording's real aspect ratio (inline, from the
   row) rather than a fixed box -- a lot of this catalogue is portrait and a
   16/10 box letterboxed all of it. */
/* THE DETAIL PAGE GETS A WIDER CONTAINER, which is the actual fix for the meta
   row wrapping. fastimages does this with `main:has(.image-page)`. The listing
   .wrap caps at 1600px, leaving 1520px of usable width against a meta row that
   needs ~1731px -- so forcing one line inside 1520px would have meant shrinking
   the type to ~13px. Widening the surface keeps it readable AND lets the media
   show closer to native size, which is why fastimages does it too. */
.wrap:has(.detail) { max-width: 2150px; }

.detail {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
  margin-inline: auto;
}
.detail-media {
  display: block;
  /* SIZED BY WHICHEVER AXIS BINDS FIRST, not width:100%.
     fastimages uses width:100% because its content is landscape collages
     (2132x1274). A lot of THIS catalogue is portrait -- 720x960 on the first
     row sampled -- and width:100% on a portrait clip produces a 1560px-wide
     letterbox with a small video floating in the middle of it. Letting the
     intrinsic size be clamped by max-width/max-height means portrait is bounded
     by height and landscape by width, and neither gets bars. */
  max-width: 100%;
  max-height: 80vh;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 8px;
  background: #000;
  margin-inline: auto;
}
/* A still collage keeps its own proportions and is never upscaled past its
   natural size. */
.detail-media--still { height: auto; max-width: 100%; }

.detail-dl { margin: 0; }
.detail-performer { color: var(--on-bg-muted); }
.detail-performer a { color: var(--accent-warm); text-decoration: underline; }

/* ADAPTIVE, not a fixed two-column grid. A wrapping flex row of dt:dd pairs
   takes the container's width and reflows -- same shape as fastimages'
   .meta-list -- so it matches the player above it at every viewport instead of
   being pinned to one width. */
.spec {
  display: flex;
  flex-wrap: wrap;
  /* COLUMN-GAP 0, DELIBERATELY. A flex gap applies between EVERY child, and the
     children here are 20 alternating dt/dd elements -- so `gap: 32px` put 32px
     between each label and its own value as well as between pairs: 19 gaps,
     608px of it, which pushed 10 fields onto two lines by 149px. Spacing comes
     from the margins below instead, so it separates PAIRS and not label from
     value. The row-gap stays for the narrow viewports where it does wrap. */
  gap: 7px 0;
  align-items: baseline;
  justify-content: space-between;   /* distribute the slack evenly, not all at the end */
  margin: 0;
  width: 100%;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 13px 18px;
  /* SIZED TO FIT TEN FIELDS ON ONE LINE at a normal desktop width. The ten
     values run to ~1420px of text; at .95rem plus generous margins that needed
     ~1731px and wrapped at anything under ~1800. Trimmed the type a step and
     the inter-pair margin to 16px, which brings it inside a 1520px container
     with room. It still wraps gracefully below ~1200px, which is correct --
     forcing one line there would mean unreadable type. */
  font-size: .85rem;
  line-height: 1.45;
}
.spec dt {
  color: var(--muted);
  font-weight: 600;
  margin-right: 4px;          /* label -> its own value */
  white-space: nowrap;
}
.spec dt::after { content: ':'; }
.spec dd {
  margin: 0 16px 0 0;         /* value -> the NEXT label */
  font-variant-numeric: tabular-nums;
  white-space: nowrap;        /* never split "aac / 44,100 Hz / stereo" */
}
.spec dd:last-of-type { margin-right: 0; }

/* ── Pagination ─────────────────────────────────────────────────────────── */
.pagination {
  display: flex; flex-wrap: wrap; gap: 7px; align-items: center;
  justify-content: center; margin: 40px 0 8px;
}
.pagination a, .pag-current, .pag-step {
  min-width: 44px; padding: 9px 11px; text-align: center;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--text);
  font-variant-numeric: tabular-nums;
}
.pagination a:hover { border-color: var(--accent); color: var(--accent); }
.pag-current { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 700; }
.pag-step--off { opacity: .35; }
.dots { padding: 0 4px; color: var(--on-bg-muted); }
.pag-total { color: var(--on-bg-muted); font-variant-numeric: tabular-nums; padding: 0 4px; }
.pag-goto { display: inline-flex; gap: 6px; align-items: center; }
.pag-input {
  width: 92px; padding: 9px 10px; text-align: center;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--text); font-size: 1rem;
}
.pag-go {
  padding: 9px 16px; border-radius: 6px; cursor: pointer;
  background: var(--accent); color: var(--on-accent);
  border: 1px solid var(--accent); font-weight: 600; font-size: 1rem;
}
.pag-go:hover { filter: brightness(1.12); }

/* ── Back to top ────────────────────────────────────────────────────────
   THE ESTATE PATTERN, copied from newsites/fastimages rather than invented for
   a third time. A full-width bar that slides down from behind the top edge once
   you have scrolled past 48px.

   I got this wrong twice. First as a bar pinned to the bottom of the VIEWPORT,
   which is a permanent overlay sitting on the content at every scroll position.
   Then, reading "bottom of the page", as a static block at the end of the
   content -- which is the one place a back-to-top control is useless, because
   you only reach it by already having scrolled to the bottom.

   Threshold is 48px, matching ultron: the bar should already be there by the
   time you want it. The transform keeps it out of the layout entirely when
   inactive, so it never covers anything on a fresh load. */
.backtotop {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  padding: 0.85rem 0;
  text-align: center;
  background: var(--accent);
  color: var(--on-accent, #fff);
  border: 0;
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-decoration: none;
  cursor: pointer;
  z-index: 200;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
  transform: translateY(-100%);
  transition: transform 0.3s ease;
}
.backtotop:hover { filter: brightness(1.12); color: var(--on-accent, #fff); }
.backtotop:focus-visible { outline: 2px solid var(--on-accent, #fff); outline-offset: -4px; }
.backtotop.active { transform: translateY(0); }
@media (prefers-reduced-motion: reduce) { .backtotop { transition: none; } }

/* ── Footer ─────────────────────────────────────────────────────────────── */
.site-footer {
  padding: 26px 20px; border-top: 1px solid var(--border);
  color: var(--on-bg-muted);
}

@media (max-width: 900px) {
  .grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
}
@media (max-width: 640px) {
  .grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; }
  h1 { font-size: 1.3rem; }
  .cat-nav-list { overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }
  .cat-dropdown {
    position: static; opacity: 1; visibility: visible; transform: none;
    box-shadow: none; border: 0; min-width: 0; display: none;
  }
  .cat-item:focus-within > .cat-dropdown { display: block; }
}
