/* Palette inspired by "html source insight.txt" - a dark, near-black
   video-tube UI with a warm orange accent (their #FF9000) and translucent
   corner badges over thumbnails, rather than this app's old indigo/navy
   scheme. Everything below still just reads these tokens, so the whole
   site recolors from this block alone. */
:root {
  --bg: #0d0d0d;
  --panel: #181818;
  --panel-2: #212121;
  --border: #333333;
  --text: #f1f1f1;
  --text-dim: #a0a0a0;
  --accent: #ff9000;
  --accent-soft: rgba(255, 144, 0, .15);
  --good: #5fd68a;
  --sidebar-width: 220px;
  --sidebar-collapsed-width: 48px;
}

* { box-sizing: border-box; }

body {
  margin: 0 0 0 var(--sidebar-width); background: var(--bg); color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  text-align: center;
  transition: margin-left .15s ease;
}
html.sidebar-collapsed body { margin-left: var(--sidebar-collapsed-width); }

h2 { margin: .5em 0; }
p { margin: .4em 0; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---- left sidebar: subreddit list ---- */
.sidebar-nav {
  position: fixed; top: 0; left: 0; bottom: 0; z-index: 20;
  width: var(--sidebar-width); background: var(--panel); border-right: 1px solid var(--border);
  display: flex; flex-direction: column; transition: width .15s ease;
}
html.sidebar-collapsed .sidebar-nav { width: var(--sidebar-collapsed-width); }

.sidebar-header {
  display: flex; align-items: center; gap: .6em; padding: .9em .8em;
  border-bottom: 1px solid var(--border); flex: none;
}
.sidebar-toggle {
  background: none; border: none; color: var(--text-dim); cursor: pointer;
  font-size: 1.3em; line-height: 1; padding: 0; flex: none;
}
.sidebar-toggle:hover { color: var(--accent); }
.sidebar-title { font-weight: 600; font-size: .85em; color: var(--text-dim); white-space: nowrap; }
html.sidebar-collapsed .sidebar-title { display: none; }

.sub-search-wrap { padding: .6em .8em 0; flex: none; }
html.sidebar-collapsed .sub-search-wrap { display: none; }
.sub-search {
  width: 100%; box-sizing: border-box; padding: .45em .6em; border-radius: 8px;
  border: 1px solid var(--border); background: var(--panel-2); color: var(--text); font-size: .85em;
}
.sub-search:focus { outline: none; border-color: var(--accent); }
.sub-search::placeholder { color: var(--text-dim); }

.sub-list { flex: 1; overflow-y: auto; overflow-x: hidden; padding: .5em; }
html.sidebar-collapsed .sub-list { display: none; }

.sub-link {
  display: block; padding: .5em .7em; border-radius: 8px; margin-bottom: 2px;
  color: var(--text-dim); font-size: .88em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sub-link:hover { background: var(--panel-2); color: var(--text); text-decoration: none; }
.sub-link.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.sub-empty { color: var(--text-dim); font-size: .82em; padding: .5em .7em; margin: 0; }

/* "New content" pills - next to a subreddit name in the sidebar (see
   sidebar_new_flags) and reused on each u/username group header inside a
   subreddit's gallery (see render_gallery_section). Solid = nothing in it
   has been hovered/tapped yet; outlined = partly gone through but some
   files are still unseen. Neither shown once everything's been seen. Not
   scoped to .sub-link since the same classes appear inside .user-toggle
   too. */
.pill {
  font-size: .64em; font-weight: 700; letter-spacing: .03em; padding: 1px 7px;
  border-radius: 999px; margin-left: 6px; vertical-align: middle;
}
.pill-new { background: var(--accent); color: #0f1115; }
.pill-count { background: transparent; color: var(--accent); border: 1px solid var(--accent); }

/* ---- header / nav ---- */
header {
  position: sticky; top: 0; z-index: 10;
  background: rgba(13, 13, 13, .92); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
  padding: .75em 1.2em;
}
.topline { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .6em; }
.brand {
  font-weight: 600; font-size: 1.05em; letter-spacing: .2px;
  color: var(--text); text-decoration: none;
}
.brand:hover { color: var(--accent); text-decoration: none; }
.headright { display: flex; align-items: center; gap: 1em; flex-wrap: wrap; }
.toplinks { display: flex; gap: 1.1em; font-size: .9em; }
.toplinks a { color: var(--text-dim); padding-bottom: 3px; border-bottom: 2px solid transparent; }
.toplinks a:hover { color: var(--text); }
.toplinks a.active { color: var(--accent); border-bottom-color: var(--accent); }

.autoplay-toggle {
  display: flex; align-items: center; gap: .4em; font-size: .85em; color: var(--text-dim);
  cursor: pointer; user-select: none;
}
.autoplay-toggle input { accent-color: var(--accent); cursor: pointer; }
.autoplay-toggle:hover { color: var(--text); }

/* ---- logged-in-user chip + role badge in the header ---- */
.user-chip { display: inline-flex; align-items: center; gap: .4em; color: var(--text-dim); }
.role-badge {
  font-size: .75em; text-transform: uppercase; letter-spacing: .03em; font-weight: 700;
  padding: 1px 7px; border-radius: 999px; background: var(--panel-2); color: var(--text-dim);
  border: 1px solid var(--border);
}
.role-badge.role-admin { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.role-badge.role-moderator { background: rgba(95, 214, 138, .15); color: var(--good); border-color: transparent; }

/* ---- login / signup ---- */
body.auth-body {
  margin-left: 0; display: flex; align-items: center; justify-content: center;
  min-height: 100vh; padding: 1.5em; box-sizing: border-box;
}
.auth-card {
  width: 100%; max-width: 360px; background: var(--panel); border: 1px solid var(--border);
  border-radius: 16px; padding: 1.8em; text-align: left;
}
.auth-card .brand { text-align: center; margin-bottom: .3em; font-size: 1.1em; }
.auth-card h2 { text-align: center; margin: 0 0 1em; }
.auth-card form { display: flex; flex-direction: column; gap: .7em; }
.auth-card input[type="text"], .auth-card input[type="password"] {
  padding: .7em .8em; border-radius: 8px; border: 1px solid var(--border);
  background: var(--panel-2); color: var(--text); font-size: .95em; box-sizing: border-box;
}
.auth-card input:focus { outline: none; border-color: var(--accent); }
.auth-submit { width: 100%; padding: .7em 0; margin-top: .3em; }
.auth-error {
  background: rgba(255, 90, 90, .1); border: 1px solid rgba(255, 90, 90, .4); color: #ff9a9a;
  padding: .6em .8em; border-radius: 8px; font-size: .85em; margin-bottom: 1em;
}
.auth-switch { text-align: center; font-size: .85em; color: var(--text-dim); margin-top: 1em; }

/* ---- admin: manage users table ---- */
.inline-form { display: inline-block; margin: 0; }
tr.row-inactive { opacity: .5; }

/* ---- admin: pipeline status page ---- */
/* Each top-level section (System health, Download pipeline, Storage size,
   and each Maintenance sub-section) sits in one of these - a bordered card
   instead of a bare heading + hr, so the consolidated Pipeline page reads
   as distinct blocks you can scan, the way a Sonarr/qBittorrent-style
   dashboard groups a status readout with its own controls. */
.admin-card {
  max-width: 900px; margin: 0 auto 1.4em; text-align: left; background: var(--panel);
  border: 1px solid var(--border); border-radius: 14px; padding: 1.3em 1.5em;
}
.admin-card h3 { margin: 0 0 .2em; }
.admin-card h3 + .auth-switch { margin-top: 0; margin-bottom: 1em; }
.admin-card h4 {
  margin: 1.3em 0 .5em; font-size: .82em; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: .05em; font-weight: 700;
}
.admin-card .status-rows { max-width: none; margin: 0; }
.admin-card .btns { justify-content: flex-start; }

.status-overall { margin-bottom: 1.2em; font-size: 1.05em; }
.status-rows {
  display: flex; flex-direction: column; gap: 10px; max-width: 700px; margin: 0 auto; text-align: left;
}
.status-row {
  display: flex; align-items: center; gap: .6em; background: var(--panel-2); border: 1px solid var(--border);
  border-left: 3px solid var(--border); border-radius: 10px; padding: .7em 1em; flex-wrap: wrap;
}
.status-row:has(.status-pill.status-ok) { border-left-color: var(--good); }
.status-row:has(.status-pill.status-down) { border-left-color: #ff9a9a; }
.status-row:has(.status-pill.status-info) { border-left-color: var(--accent); }
.status-detail { color: var(--text-dim); font-size: .88em; }
.status-pill {
  font-size: .72em; font-weight: 700; letter-spacing: .03em; padding: 2px 9px; border-radius: 999px;
  flex: none;
}
.status-pill.status-ok { background: rgba(95, 214, 138, .15); color: var(--good); }
.status-pill.status-down { background: rgba(255, 90, 90, .15); color: #ff9a9a; }
.status-pill.status-idle { background: var(--panel-2); color: var(--text-dim); border: 1px solid var(--border); }
.status-pill.status-info { background: var(--accent-soft); color: var(--accent); }

select, select.filter {
  background: var(--panel-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: .35em .6em; font-size: .85em;
}

/* ---- admin: pipeline page live output tail ---- */
.log-tail {
  max-width: none; margin: 0; text-align: left; background: #0a0a0a;
  border: 1px solid var(--border); border-radius: 10px; padding: .8em 1em;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: .78em; line-height: 1.6; color: var(--text-dim);
  white-space: pre-wrap; word-break: break-word;
  max-height: 280px; overflow-y: auto;
}
.log-tail .log-marker { color: var(--accent); }
.log-tail .log-ok { color: var(--good); }
.log-tail .log-err { color: #ff9a9a; }

/* ---- admin: downloads page (storage locations settings form) ---- */
#downloads-settings-form { max-width: 700px; margin: 1em auto 0; text-align: left; }
.location-row {
  display: flex; gap: .6em; margin-bottom: .6em;
}
.location-path-input, .location-minfree-input {
  padding: .55em .7em; border-radius: 8px; border: 1px solid var(--border);
  background: var(--panel-2); color: var(--text); font-size: .9em; box-sizing: border-box;
}
.location-path-input { flex: 3; }
.location-minfree-input { flex: 1; min-width: 8em; }

/* ---- live "new files" banner ---- */
#live-banner { max-width: 1100px; margin: 0 auto; padding: 0 1.2em; }
#live-banner.toast {
  display: flex; align-items: center; gap: .6em; margin-top: .8em;
  background: linear-gradient(90deg, var(--accent-soft), transparent);
  border: 1px solid var(--border); border-left: 3px solid var(--accent);
  padding: .6em .9em; border-radius: 10px; font-size: .88em; color: var(--text);
}
.dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex: none;
  animation: pulse 1.6s infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(255, 144, 0, .5); }
  70% { box-shadow: 0 0 0 8px rgba(255, 144, 0, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 144, 0, 0); }
}
#live-banner.toast button {
  margin-left: auto; background: var(--accent); color: var(--bg); border: none;
  padding: .4em .9em; border-radius: 8px; font-weight: 600; cursor: pointer; font-size: .85em;
}

main { max-width: 1100px; margin: 0 auto; padding: 1.2em 1.2em 3em; }

.section-divider { border: none; border-top: 1px solid var(--border); margin: 2.4em 0 1.6em; }

/* ---- rating card ---- */
.layout { display: flex; gap: 1.4em; align-items: flex-start; flex-wrap: wrap; text-align: left; }
.stage {
  flex: 1 1 480px; background: var(--panel); border: 1px solid var(--border);
  border-radius: 16px; padding: 1em; display: flex; align-items: center; justify-content: center;
}
.stage img, .stage video { max-width: 100%; max-height: 70vh; border-radius: 8px; display: block; }

.sidebar {
  width: 300px; flex: none; background: var(--panel); border: 1px solid var(--border);
  border-radius: 16px; padding: 1em; position: sticky; top: 5.2em;
}

.profile-chip {
  display: inline-flex; align-items: center; gap: 6px; background: var(--panel-2);
  padding: 2px 10px 2px 2px; border-radius: 16px; margin-bottom: .8em;
}
.profile-chip .avatar {
  width: 26px; height: 26px; border-radius: 50%; background: var(--accent-soft); color: var(--accent);
  display: inline-flex; align-items: center; justify-content: center; font-size: .75em; font-weight: 700;
}
.profile-chip .name { font-size: .85em; color: var(--text-dim); }
.profile-chip .chip-sub { font-size: .75em; color: var(--good); }

.running-score { color: var(--good); font-size: .88em; }

.ratebar { display: flex; gap: .5em; flex-wrap: wrap; }
.ratebtn {
  flex: 1 1 40px; padding: .7em 0; text-align: center; border-radius: 10px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--border); color: var(--text); font-weight: 700; font-size: 1.1em;
  transition: transform .08s ease, background .15s ease, border-color .15s ease;
}
.ratebtn:hover { border-color: var(--accent); background: var(--accent-soft); transform: translateY(-1px); }
.skip-btn {
  margin-top: .6em; width: 100%; padding: .55em 0; border-radius: 10px; cursor: pointer;
  background: transparent; border: 1px dashed var(--border); color: var(--text-dim);
}
.skip-btn:hover { color: var(--text); border-color: var(--text-dim); }

/* ---- tables (leaderboard / admin users) ---- */
table { margin: 1em auto; border-collapse: collapse; width: 100%; max-width: 700px; }
td, th { padding: .5em 1em; border-bottom: 1px solid var(--border); }
th { color: var(--text-dim); font-weight: 600; text-align: left; }

.slideshow-btn {
  font-size: .95em; padding: .4em .9em; margin: .5em; border-radius: 8px; cursor: pointer;
  background: var(--accent-soft); color: var(--accent); border: 1px solid transparent; font-weight: 600;
}
.slideshow-btn:hover { background: var(--accent); color: var(--bg); }

/* ---- gallery grid ---- */
.gallery { display: flex; flex-wrap: wrap; gap: 14px; justify-content: flex-start; max-width: 1100px; margin: 0 auto; }

/* Each user's posts live in one of these - the <h3> inside is the
   collapse/expand toggle (see .user-toggle below), right where their
   posts actually are, not tracked in some separate list elsewhere. */
.user-group { width: 100%; }
.user-tiles { display: flex; flex-wrap: wrap; gap: 14px; }
.user-group.collapsed .user-tiles { display: none; }

.user-toggle {
  width: 100%; text-align: left; margin: 1em 0 .5em .2em; color: var(--accent);
  cursor: pointer; user-select: none; display: flex; align-items: center; gap: .4em;
}
.user-toggle:hover { color: var(--text); }
.collapse-caret { display: inline-block; font-size: .7em; transition: transform .15s ease; }
.user-group.collapsed .collapse-caret { transform: rotate(-90deg); }
.count-badge {
  font-size: .65em; font-weight: 400; color: var(--text-dim); background: var(--panel-2);
  border: 1px solid var(--border); border-radius: 999px; padding: 1px 8px; margin-left: 2px; vertical-align: middle;
}
.gallery-item {
  width: 230px; background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; padding: 8px; text-align: center;
  transition: transform .12s ease, border-color .12s ease;
}
.gallery-item:hover { transform: translateY(-3px); border-color: var(--text-dim); }
.gallery-item .thumb-wrap { position: relative; }
.gallery-item .tile-media {
  width: 100%; height: 230px; object-fit: cover; border-radius: 6px; cursor: pointer; display: block;
}

.badge {
  display: inline-block; margin-top: 6px; padding: 2px 10px; border-radius: 10px;
  background: var(--good); color: #0f1115; font-size: .85em; font-weight: 600;
}
.badge.unrated { background: var(--panel-2); color: var(--text-dim); font-weight: 400; }

.quick-rate { display: flex; flex-wrap: wrap; gap: 3px; justify-content: center; margin-top: 6px; }
.quick-rate button {
  font-size: .8em; padding: 3px 7px; border: 1px solid var(--border); border-radius: 5px;
  cursor: pointer; background: var(--panel-2); color: var(--text);
}
.quick-rate button:hover { border-color: var(--accent); }
.quick-rate button.active { background: var(--accent-soft); color: var(--accent); border-color: transparent; }

/* ---- expanded click-to-view overlay ---- */
#expanded {
  display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, .9);
  z-index: 1000; padding: 2em; overflow-y: auto; box-sizing: border-box;
  align-items: center; justify-content: center; /* only takes effect once JS sets display:flex */
}
#expanded .expand-wrap {
  display: flex; gap: 20px; max-width: 900px; margin: auto; align-items: center; text-align: left;
  position: relative;
}
#expanded .expand-media { flex: 1; display: flex; align-items: center; justify-content: center; }
#expanded .expand-media img, #expanded .expand-media video { max-width: 100%; max-height: 85vh; border-radius: 8px; }
/* When .expand-media itself is the browser fullscreen element (see the
   fsBtn handler in gallery.js - fullscreen targets this stable wrapper,
   not the ephemeral per-slide .custom-player, so slideshow auto-advance
   doesn't kick you out of fullscreen), its own display:flex + centering
   above still applies and keeps the video/image centered - this just adds
   a proper black backdrop (instead of the overlay's translucent one, which
   looks wrong once nothing but this element fills the screen) and lets
   the media use the full viewport height instead of the 85vh cap that
   exists to leave room for the surrounding overlay chrome, which isn't
   there anymore once truly fullscreen. */
#expanded .expand-media:fullscreen, #expanded .expand-media:-webkit-full-screen { background: #000; }
#expanded .expand-media:fullscreen img, #expanded .expand-media:fullscreen video,
#expanded .expand-media:-webkit-full-screen img, #expanded .expand-media:-webkit-full-screen video {
  max-height: 100vh; border-radius: 0;
}
#expanded .expand-close {
  position: absolute; top: -40px; right: 0; background: var(--panel-2); color: var(--text); border: none;
  border-radius: 50%; width: 32px; height: 32px; font-size: 1.2em; cursor: pointer;
}
#expanded .expand-close:hover { background: var(--border); }
#expanded .expand-sidebar {
  width: 280px; position: sticky; top: 20px; background: var(--panel); border: 1px solid var(--border);
  padding: 1em; border-radius: 12px;
}
#expanded .expand-sidebar input[type="text"] {
  width: 100%; padding: .5em; border-radius: 6px; border: 1px solid var(--border);
  background: var(--panel-2); color: var(--text); box-sizing: border-box;
}

.slideshow-controls {
  display: flex; align-items: center; gap: .4em; margin-bottom: .8em;
}
.ss-btn {
  padding: .4em .7em; border-radius: 8px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--border); color: var(--text);
}
.ss-btn:hover { border-color: var(--accent); background: var(--accent-soft); }
.ss-playpause { font-size: 1.1em; }
.ss-progress { margin-left: auto; color: var(--text-dim); font-size: .85em; }

/* Same buttons used both in the main rating card (.ratebtn) and here
   (.expand-rate-btn) - keep them visually consistent. */
.btns { margin-top: .5em; display: flex; flex-wrap: wrap; gap: .4em; }
.btns button, .expand-rate-btn {
  font-size: 1.1em; padding: .5em .8em; border: 1px solid var(--border); border-radius: 8px;
  cursor: pointer; background: var(--panel-2); color: var(--text); font-weight: 700;
}
.btns button:hover, .expand-rate-btn:hover { border-color: var(--accent); background: var(--accent-soft); }
.expand-rate-btn.active { background: var(--accent-soft); color: var(--accent); border-color: transparent; }

/* Clickable u/username in the gallery (grid tiles + group headers) - filters
   the current view down to just that person via ?user=... on /gallery. */
.username-link { text-decoration: none; }
.username-link:hover { text-decoration: underline; }

/* Shown on video tiles when sorted by "Longest video" (see duration_map in
   render_gallery_section) - pinned over the thumbnail's bottom-right corner
   on a translucent dark chip, same convention as a video-tube site's
   duration overlay, rather than sitting as inline text below the tile. */
.duration-badge {
  position: absolute; right: 6px; bottom: 6px; margin: 0; pointer-events: none;
  padding: 1px 6px; border-radius: 4px;
  background: rgba(0, 0, 0, .75); color: #fff; font-size: .78em; font-weight: 600;
}

/* Pinned over a gallery tile's thumbnail (top-left, opposite the duration
   badge's bottom-right corner) whenever that file has no rating yet - see
   the "new_ribbon" bit in render_gallery_section's render_tile(). Same
   pinned-chip convention as the duration badge above, just flagging "new"
   instead of length. */
.ribbon-new {
  position: absolute; top: 6px; left: 6px; margin: 0; pointer-events: none;
  padding: 2px 7px; border-radius: 5px; transition: opacity .35s ease;
  background: var(--accent); color: #0f1115; font-size: .72em; font-weight: 700; letter-spacing: .03em;
}
/* Added by gallery.js's markItemSeen() once you've hovered/tapped a tile
   for a moment - fades the ribbon out client-side immediately rather than
   waiting on the /mark-seen round trip. */
.ribbon-new.seen { opacity: 0; }

/* "(clear)" link next to the Gallery heading while a ?user= filter is active. */
.clear-filter { font-size: .75em; margin-left: 4px; }

/* ---- custom video player (replaces the browser's default <video controls>
   chrome, which doesn't respect the theme) - see buildCustomPlayer() in
   gallery.js. Used on the rating stage and the click-to-expand overlay;
   the actual sizing (max-width/max-height/border-radius) still comes from
   the existing ".stage video"/"#expanded .expand-media video" rules above,
   since this is just a positioning wrapper around that same <video>. ---- */
.stage .custom-player, #expanded .expand-media .custom-player {
  position: relative; display: inline-block; max-width: 100%;
}
.cp-controls {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; gap: .5em;
  padding: .5em .7em .6em;
  background: linear-gradient(transparent, rgba(0, 0, 0, .85) 45%);
  border-radius: 0 0 8px 8px;
}
.cp-btn {
  background: none; border: none; color: #fff; cursor: pointer;
  font-size: 1.1em; line-height: 1; padding: 0 .2em; flex: none;
}
.cp-btn:hover { color: var(--accent); }
.cp-time { color: #fff; font-size: .8em; flex: none; white-space: nowrap; }
.cp-seek { flex: 1; accent-color: var(--accent); cursor: pointer; min-width: 40px; }
.cp-volume { width: 70px; accent-color: var(--accent); cursor: pointer; flex: none; }
