/* ---- 00-tokens.css ---- */
/* The design variables. Dark cinema palette, one jade accent, two type faces, the spacing
   scale. Every other stylesheet reads from here and never restates a colour. */
:root {
    --ground: #0a0a0c;
    --surface: #131317;
    --surface-2: #1b1b21;
    --line: #2a2a33;
    --accent: #5ce89a;
    --accent-dim: #2f9c63;
    --text: #f2f2f5;
    --text-dim: #b3b3bf;
    --text-faint: #7c7c8a;
    --danger: #ff8d8d;
    --ok: #5ce89a;
    --ink: #06140c;
    --r: 12px;
    --r-lg: 18px;
    --pad: 16px;
    --gap: 12px;
    --nav-h: 60px;
    --font: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Arial, system-ui, sans-serif;
    --font-display: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Arial, system-ui, sans-serif;
    --shadow: 0 18px 44px rgba(0, 0, 0, .55);
    --safe-top: env(safe-area-inset-top, 0px);
    --safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* ---- 10-base.css ---- */
/* Base and the core components: the bar, buttons, forms, cards, the gate, the auth pages,
   the footer. A feature adds its own NN-name.css; it never edits this one. */
* { margin: 0; padding: 0; box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
    background: radial-gradient(900px 480px at 50% -200px, rgba(92, 232, 154, .08), transparent 70%), var(--ground);
    color: var(--text); font-family: var(--font);
    font-size: 16px; line-height: 1.55; min-height: 100vh; overflow-x: hidden;
}
img, video, svg { max-width: 100%; display: block; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }

.wrap { max-width: 680px; margin: 0 auto; padding: 0 var(--pad) 80px; }
.wrap-wide { max-width: 1120px; margin: 0 auto; padding: 0 20px 80px; }

/* ---------- top bar ---------- */
.bar {
    position: sticky; top: 0; z-index: 40; display: flex; align-items: center; gap: 18px;
    height: var(--nav-h); padding: 0 18px; padding-top: var(--safe-top);
    background: rgba(10, 10, 12, .84); backdrop-filter: blur(12px); border-bottom: 1px solid var(--line);
}
.bar .brand { display: inline-flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 700;
    letter-spacing: .04em; font-size: 17px; color: var(--text); }
.bar .brand:hover { text-decoration: none; color: var(--accent); }
.bar .brand .mark { flex-shrink: 0; }
.bar .spacer { flex: 1; }
.bar a.navlink { display: inline-flex; align-items: center; gap: 6px; color: var(--text-dim); font-size: 13px; font-weight: 600; white-space: nowrap; }
.bar a.navlink:hover { color: var(--accent); text-decoration: none; }
.bar a.navcta { color: var(--ink); background: var(--accent); padding: 9px 16px; border-radius: 999px; }
.bar a.navcta:hover { color: var(--ink); filter: brightness(1.06); }
@media (max-width: 540px) {
  .bar { gap: 10px; padding-left: 12px; padding-right: 12px; }
  .bar .brand { font-size: 15px; }
  .bar a.navlink { font-size: 12.5px; }
  .bar a.navlink span { display: none; }
  .bar a.navcta { padding: 7px 12px; }
}
.notice { background: var(--surface-2); border-bottom: 1px solid var(--line); color: var(--text-dim); font-size: 13.5px; text-align: center; padding: 8px 16px; }

/* ---------- buttons ---------- */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    background: var(--accent); color: var(--ink); border: none; border-radius: 999px;
    padding: 13px 24px; font: inherit; font-weight: 700; cursor: pointer; text-align: center;
    box-shadow: 0 8px 22px rgba(92, 232, 154, .18);
    transition: transform .15s ease, box-shadow .15s ease, filter .15s ease;
}
.btn:hover { filter: brightness(1.05); text-decoration: none; transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn:disabled { opacity: .55; cursor: default; }
.btn .ico { flex-shrink: 0; }
.btn-ghost { background: rgba(10, 10, 12, .45); color: var(--text); border: 1px solid rgba(242, 242, 245, .3); box-shadow: none; }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn-quiet { background: var(--surface-2); border: 1px solid var(--line); color: var(--text); box-shadow: none; }
.btn-quiet:hover { border-color: var(--accent-dim); }
.btn-danger { background: transparent; border: 1px solid rgba(255, 141, 141, .5); color: var(--danger); box-shadow: none; }
.btn-block { width: 100%; }
.btn-sm { padding: 8px 16px; font-size: 14px; }
.btn-lg { padding: 15px 28px; font-size: 16px; }

/* ---------- forms ---------- */
label { display: block; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 7px; font-weight: 700; }
input[type=text], input[type=email], input[type=password], input[type=number], input[type=url],
input[type=search], input:not([type]), textarea, select {
    width: 100%; background: rgba(0, 0, 0, .35); border: 1px solid var(--line); border-radius: 10px;
    padding: 12px 14px; color: var(--text); font: inherit; transition: border-color .15s ease, box-shadow .15s ease;
}
input::placeholder, textarea::placeholder { color: var(--text-faint); opacity: .75; }
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--accent-dim); box-shadow: 0 0 0 3px rgba(92, 232, 154, .14); }
select { appearance: none; -webkit-appearance: none; padding-right: 40px;
    background-image: linear-gradient(45deg, transparent 50%, var(--text-faint) 50%), linear-gradient(135deg, var(--text-faint) 50%, transparent 50%);
    background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%; background-size: 6px 6px; background-repeat: no-repeat; }
select option { background: var(--surface-2); color: var(--text); }
textarea { min-height: 96px; resize: vertical; }
input[type=file] { width: 100%; min-width: 0; color: var(--text-dim); font-size: 13.5px; padding: 6px 0; }
input[type=file]::file-selector-button { font: inherit; font-weight: 700; font-size: 13px; color: var(--text); background: var(--surface-2);
    border: 1px solid var(--line); border-radius: 999px; padding: 7px 14px; margin-right: 10px; cursor: pointer; }
input[type=checkbox] {
    appearance: none; -webkit-appearance: none; width: 20px; height: 20px; border: 1px solid var(--accent-dim); border-radius: 6px;
    background: rgba(0, 0, 0, .4); display: inline-grid; place-content: center; cursor: pointer; vertical-align: middle; flex-shrink: 0;
}
input[type=checkbox]::before { content: ''; width: 10px; height: 5px; border-left: 2px solid var(--ink); border-bottom: 2px solid var(--ink);
    transform: rotate(-45deg) translate(1px, -1px); opacity: 0; }
input[type=checkbox]:checked { background: var(--accent); border-color: var(--accent); }
input[type=checkbox]:checked::before { opacity: 1; }
.field { margin-bottom: 18px; }
.field .hint { display: block; margin-top: 7px; }
.check { display: block; position: relative; padding-left: 32px; margin-bottom: 12px; font-size: 14.5px; color: var(--text-dim);
    text-transform: none; letter-spacing: 0; line-height: 1.5; font-weight: 400; cursor: pointer; }
.check input { position: absolute; left: 0; top: 1px; margin: 0; }
.check a { text-decoration: underline; text-underline-offset: 2px; }
.err, .ok { font-size: 14px; margin-bottom: 14px; padding: 11px 14px; border-radius: 10px; border: 1px solid; }
.err { color: var(--danger); border-color: rgba(255, 141, 141, .35); background: rgba(255, 141, 141, .06); }
.ok { color: var(--ok); border-color: rgba(92, 232, 154, .3); background: rgba(92, 232, 154, .05); }
.hint { color: var(--text-faint); font-size: 13px; }
form .btn + .hint { margin-left: 10px; }

/* ---------- cards, panels, type ---------- */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 24px; }
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 20px 22px; margin-bottom: 14px; }
.panel > .eyebrow:first-child { padding-bottom: 12px; margin-bottom: 4px; border-bottom: 1px solid var(--line); }
.eyebrow { display: flex; align-items: center; gap: 6px; font-size: 11.5px; letter-spacing: .22em; text-transform: uppercase; color: var(--accent-dim); font-weight: 700; }
h1 { font-family: var(--font-display); font-size: 32px; line-height: 1.12; font-weight: 700; letter-spacing: -.01em; }
h2 { font-family: var(--font-display); font-size: 22px; line-height: 1.25; margin-bottom: 10px; font-weight: 700; }
h3 { font-size: 17px; margin-bottom: 8px; }
.prose p, .prose li { color: var(--text-dim); margin-bottom: 12px; }
.prose h1 { margin-bottom: 8px; }
.prose h2 { color: var(--text); margin-top: 30px; }
.prose ul { margin-left: 20px; }
.ico { vertical-align: -3px; }
.empty { text-align: center; color: var(--text-faint); padding: 56px 20px; border: 1px dashed var(--line); border-radius: var(--r-lg); }
.empty-ico { color: var(--accent-dim); margin-bottom: 10px; }
.empty-ico .ico { margin: 0 auto; }
.empty-title { font-family: var(--font-display); font-size: 22px; color: var(--text-dim); }
.three { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; margin: 26px 0 22px; }
.three .panel { margin: 0; }
.lede-left { margin: 10px 0 22px; font-size: 14.5px; }

/* the maturity label chip and its descriptors */
.label { display: inline-block; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; padding: 3px 9px; border-radius: 6px; border: 1px solid var(--line); color: var(--text-dim); font-weight: 700; vertical-align: middle; }
.label-mature { color: var(--danger); border-color: rgba(255, 141, 141, .45); }
.label-teen { color: var(--accent); border-color: var(--accent-dim); }
.descriptors { display: inline-flex; flex-wrap: wrap; gap: 4px; margin-left: 6px; vertical-align: middle; }
.descriptors span { font-size: 11px; color: var(--text-faint); border: 1px solid var(--line); border-radius: 999px; padding: 2px 8px; }

/* ---------- home ---------- */
.hero { position: relative; display: flex; align-items: center; justify-content: center; text-align: center; padding: 64px 20px 40px; }
.hero-inner { max-width: 720px; }
.hero .mark { margin: 0 auto 18px; }
.hero h1 { font-size: clamp(40px, 8vw, 72px); letter-spacing: -.02em; line-height: 1; }
.hero-line { font-size: clamp(18px, 2.6vw, 24px); color: var(--accent); margin-top: 14px; font-weight: 600; }
.hero-sub { color: var(--text-dim); margin: 14px auto 0; max-width: 52ch; }
.hero-cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 26px; }
.hero-notice { color: var(--text-faint); font-size: 12.5px; margin-top: 22px; }

/* ---------- the 18+ interstitial ---------- */
.gate { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: 22px; overflow: auto; background: var(--ground); }
.gate-inner { max-width: 470px; width: 100%; text-align: center; padding: 38px 30px 28px; border: 1px solid var(--line); border-radius: 22px;
    background: var(--surface); box-shadow: var(--shadow); }
.gate .mark { margin: 0 auto 16px; }
.gate h1 { font-size: 26px; margin-bottom: 12px; }
.gate p { color: var(--text-dim); margin-bottom: 10px; font-size: 15px; }
.gate .row { display: flex; gap: 12px; margin-top: 24px; flex-wrap: wrap; }
.gate .row .btn { flex: 1; white-space: nowrap; }
.gate .fine { font-size: 12.5px; color: var(--text-faint); margin-top: 22px; }

/* ---------- auth ---------- */
.auth { max-width: 460px; margin: 0 auto; padding: 40px var(--pad) 80px; }
.auth-mark { display: flex; justify-content: center; margin-bottom: 22px; }
.auth h1 { text-align: center; font-size: 30px; }
.auth .lede { text-align: center; margin: 10px 0 22px; }
.auth .card { margin-top: 4px; }
.auth .after { text-align: center; margin-top: 20px; }
.or { display: flex; align-items: center; gap: 10px; color: var(--text-faint); font-size: 13px; margin: 14px 0; }
.or::before, .or::after { content: ''; flex: 1; border-top: 1px solid var(--line); }
.gbtn { display: flex; justify-content: center; align-items: center; gap: 10px; }
/* Google's own mark colours, required by their sign-in branding rules. */
.g-red { fill: #EA4335; } .g-blue { fill: #4285F4; } .g-yellow { fill: #FBBC05; } .g-green { fill: #34A853; }

/* ---------- tables ---------- */
table.tbl { width: 100%; border-collapse: collapse; font-size: 14px; }
table.tbl th { text-align: left; color: var(--text-faint); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; padding: 10px 12px; border-bottom: 1px solid var(--line); }
table.tbl td { padding: 11px 12px; border-bottom: 1px solid var(--line); color: var(--text-dim); vertical-align: middle; }
table.tbl tr:last-child td { border-bottom: none; }
.tag { display: inline-block; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; padding: 3px 9px; border-radius: 999px; border: 1px solid var(--line); color: var(--text-dim); }
.tag.ok { color: var(--ok); border-color: rgba(92, 232, 154, .4); }
.tag.warn { color: var(--danger); border-color: rgba(255, 141, 141, .4); }
.scroll-x { overflow-x: auto; }

/* ---------- footer ---------- */
.foot { border-top: 1px solid var(--line); margin-top: 48px; padding: 34px 16px calc(56px + var(--safe-bottom)); background: linear-gradient(180deg, transparent, rgba(19, 19, 23, .6)); }
.foot .foot-brand { display: flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 700; font-size: 15px; color: var(--text-dim); margin-bottom: 18px; }
.foot .links { display: flex; flex-wrap: wrap; gap: 10px 22px; margin-bottom: 16px; }
.foot .links a { color: var(--text-dim); font-size: 13px; }
.foot .links a:hover { color: var(--accent); text-decoration: none; }
.foot .fine { color: var(--text-faint); font-size: 12.5px; line-height: 1.8; }

/* Scrolling without a visible bar; wheel, trackpad, keyboard and touch are untouched. */
html, body, .scroll-x { scrollbar-width: none; -ms-overflow-style: none; }
html::-webkit-scrollbar, body::-webkit-scrollbar, .scroll-x::-webkit-scrollbar { display: none; width: 0; height: 0; }
[hidden] { display: none !important; }

/* ---- 15-accounts.css ---- */
/* The account page: one column, every control a thumb can reach and hit. Switches for the
   two preferences, full-width actions on a phone, the destructive one last and apart. */
.account h1 { margin-bottom: 4px; }
.account .whoami { color: var(--text-faint); font-size: 13.5px; margin-bottom: 18px; word-break: break-all; }
.account .panel { padding: 18px 18px 20px; }
.account .panel > .eyebrow:first-child .ico { vertical-align: -2px; }
.account .panel .btn { min-height: 48px; }
.account .actions { display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap; margin-top: 12px; }
.account .actions .hint { margin: 0; }
.account .field { margin-bottom: 12px; }
.account .field input { min-height: 48px; }

/* a switch row: the words on the left, the control on the right, the whole row tappable */
.switch {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    min-height: 60px; padding: 10px 0; margin: 0; border-bottom: 1px solid var(--line);
    text-transform: none; letter-spacing: 0; font-weight: 400; cursor: pointer;
}
.switch:last-of-type { border-bottom: none; }
.switch-text b { display: block; color: var(--text); font-size: 15px; font-weight: 600; line-height: 1.3; }
.switch-text small { display: block; color: var(--text-faint); font-size: 12.5px; line-height: 1.45; margin-top: 3px; }
.switch input[type=checkbox] {
    width: 52px; height: 32px; border-radius: 999px; flex-shrink: 0;
    border-color: var(--line); background: var(--surface-2); transition: background .15s ease, border-color .15s ease;
}
.switch input[type=checkbox]::before {
    width: 24px; height: 24px; border: none; border-radius: 50%; background: var(--text-faint);
    opacity: 1; transform: translateX(-10px); transition: transform .15s ease, background .15s ease;
}
.switch input[type=checkbox]:checked { background: var(--accent); border-color: var(--accent); }
.switch input[type=checkbox]:checked::before { background: var(--ink); transform: translateX(10px); }
.switch input[type=checkbox]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 540px) {
  .account .actions { flex-direction: column; align-items: stretch; }
  .account .actions .btn { width: 100%; }
  .account .actions .hint { text-align: center; }
}

/* ---- 26-upload.css ---- */
/* The upload widget (public/js/26-upload.js): the progress bar and the status line. */
.upload { display: grid; gap: 12px; }
.upload-bar { height: 8px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.upload-fill { height: 100%; width: 0; background: var(--accent); transition: width 200ms linear; }
.upload-status { margin: 0; min-height: 1.4em; }
.upload-error { color: var(--danger); }

/* ---- 27-share.css ---- */
/* The share sheet: a bottom sheet on a phone, a centred card on a desktop. */

.share-wrap { position: fixed; inset: 0; z-index: 9000; }
body.share-open { overflow: hidden; }

.share-veil {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.62);
    opacity: 0;
    transition: opacity 160ms ease;
}
.share-wrap.is-open .share-veil { opacity: 1; }

.share-sheet {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--surface, #14171a);
    border-top: 1px solid var(--line, #262a28);
    border-radius: 20px 20px 0 0;
    padding: 18px 18px calc(18px + env(safe-area-inset-bottom, 0px));
    transform: translateY(100%);
    transition: transform 200ms cubic-bezier(0.2, 0.7, 0.3, 1);
    max-height: 86vh;
    overflow-y: auto;
}
.share-wrap.is-open .share-sheet { transform: translateY(0); }

.share-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.share-head h2 { margin: 0; font-size: 1.1rem; }
.share-x {
    width: 40px; height: 40px;
    display: grid; place-items: center;
    border-radius: 999px;
    background: transparent;
    border: 1px solid var(--line, #262a28);
    color: var(--text-dim, #a8b0ac);
    cursor: pointer;
}
.share-x:hover { color: var(--text, #e8ece9); }

.share-what {
    margin: 4px 0 16px;
    color: var(--text-dim, #a8b0ac);
    font-size: 0.95rem;
    /* One line: the title is context, not the point of the sheet. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The destinations wrap onto as many rows as they need rather than scrolling
   sideways, so nothing is hidden off the edge on a narrow phone. */
.share-targets {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(74px, 1fr));
    gap: 10px;
    margin-bottom: 18px;
}
.share-target {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 12px 6px;
    border-radius: 14px;
    background: var(--surface-2, #171a19);
    border: 1px solid var(--line, #262a28);
    color: var(--text, #e8ece9) !important;
    font-size: 0.78rem;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    min-height: 74px;
    justify-content: center;
}
.share-target:hover { border-color: var(--accent-dim, #2f6b4c); text-decoration: none; }
.share-target-ico {
    width: 40px; height: 40px;
    display: grid; place-items: center;
    border-radius: 999px;
    background: rgba(92, 232, 154, 0.12);
    color: var(--accent, #5ce89a);
}

/* The link itself, because a lot of people would rather paste it somewhere we
   never thought of. */
.share-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 8px 8px 12px;
    border: 1px solid var(--line, #262a28);
    border-radius: 999px;
    background: var(--surface-2, #171a19);
}
.share-link-ico { color: var(--text-faint, #98a09b); display: grid; place-items: center; flex: 0 0 auto; }
.share-link-url {
    flex: 1 1 auto;
    min-width: 0;
    background: transparent;
    border: 0;
    color: var(--text-dim, #a8b0ac);
    font: inherit;
    font-size: 0.9rem;
    padding: 6px 0;
    text-overflow: ellipsis;
}
.share-link-url:focus { outline: none; color: var(--text, #e8ece9); }
.share-copy { flex: 0 0 auto; }

.share-toast {
    position: fixed;
    left: 50%;
    bottom: calc(24px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    z-index: 9100;
    background: var(--surface, #14171a);
    border: 1px solid var(--line, #262a28);
    color: var(--text, #e8ece9);
    padding: 10px 16px;
    border-radius: 999px;
    font-size: 0.9rem;
}

/* On a wide screen it is a card in the middle, not a sheet stuck to the floor. */
@media (min-width: 720px) {
    .share-sheet {
        left: 50%;
        right: auto;
        bottom: auto;
        top: 50%;
        width: min(480px, 92vw);
        transform: translate(-50%, -46%);
        border-radius: 18px;
        border: 1px solid var(--line, #262a28);
        opacity: 0;
        transition: opacity 160ms ease, transform 180ms ease;
    }
    .share-wrap.is-open .share-sheet { transform: translate(-50%, -50%); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .share-veil, .share-sheet { transition: none; }
}

/* ---- 30-video.css ---- */
/* The video feature: the upload page (lib/views-video.js). The widget's own bar and status
   line are styled in 26-upload.css; this is the page around it, phone first. */
.upload-page { padding-top: 28px; }
.upload-page h1 { margin-top: 8px; }
.upload-panel { padding: 22px; }
.upload-mount .field { margin-bottom: 0; }
.upload-mount .btn { width: 100%; }
.upload-mount input[type=file] { padding: 10px 0; }
.upload-steps { margin: 12px 0 14px 20px; color: var(--text-dim); font-size: 14.5px; }
.upload-steps li { margin-bottom: 8px; }
@media (min-width: 720px) {
  .upload-mount { grid-template-columns: 1fr 1fr; align-items: start; }
  .upload-mount .btn { grid-column: 1 / -1; width: auto; justify-self: start; }
  .upload-mount .upload-bar, .upload-mount .upload-status { grid-column: 1 / -1; }
}

/* ---- 35-films.css ---- */
/* The films feature: the film page (the stage, the cover, the next-episode card) and the
   series page. Phone first at 390px: a portrait film fills a 9:16 frame, a landscape film
   letterboxes inside it. From 900px the stage fills the width under a max height. */

/* ---------- the film page ---------- */
.film-page { max-width: 1120px; margin: 0 auto; padding: 0 0 80px; }
.film-stage {
    position: relative; width: 100%; aspect-ratio: 9 / 16; max-height: calc(100vh - var(--nav-h) - 24px);
    margin: 0 auto; background: var(--ink); overflow: hidden;
}
.film-stage .film-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: var(--ink); }
.film-stage.portrait .film-video { object-fit: cover; }
.film-cover { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    background: radial-gradient(420px 320px at 50% 40%, rgba(92, 232, 154, .12), transparent 70%), var(--ink); }
/* On the stage the drawn cover sits in the upper part, leaving the middle to the play control. */
.film-stage > .film-cover > .film-cover-empty { bottom: auto; height: 42%; background: none; }
.film-cover .film-poster { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; object-fit: cover; opacity: .82; }
.film-stage.landscape .film-cover .film-poster { object-fit: contain; }
.film-cover-empty { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
    color: var(--text-faint); font-size: 14px; letter-spacing: .08em; text-transform: uppercase; text-align: center; padding: 20px;
    background: radial-gradient(420px 320px at 50% 40%, rgba(92, 232, 154, .12), transparent 70%); }
.film-cover-actions { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 16px; text-align: center; }
.film-cover-note { color: var(--text-dim); font-size: 13px; max-width: 30ch; text-shadow: 0 1px 8px rgba(0, 0, 0, .8); }
.film-stage.playing .film-cover { display: none; }
.film-unmute { position: absolute; left: 14px; top: 14px; z-index: 3; }
.film-status { position: absolute; left: 0; right: 0; bottom: 0; z-index: 4; margin: 0; padding: 12px 16px calc(12px + var(--safe-bottom));
    background: rgba(10, 10, 12, .84); color: var(--text-dim); font-size: 13.5px; text-align: center; }
.film-status.is-error { color: var(--danger); }
.film-next { position: absolute; left: 14px; right: 14px; bottom: 70px; z-index: 5; padding: 14px 16px; border-radius: var(--r-lg);
    background: rgba(19, 19, 23, .94); border: 1px solid var(--line); box-shadow: var(--shadow); }
.film-next-eyebrow { font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--accent-dim); font-weight: 700; }
.film-next-title { font-family: var(--font-display); font-weight: 700; font-size: 17px; margin-top: 4px; }
.film-next-count { margin-top: 4px; }
.film-next-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }

.film-body { padding: 18px var(--pad) 0; max-width: 760px; margin: 0 auto; }
.film-series-line { flex-wrap: wrap; gap: 10px; }
.film-series-line a { display: inline-flex; align-items: center; gap: 6px; color: var(--accent); }
.film-series-line span { color: var(--text-faint); letter-spacing: .1em; }
.film-title { font-size: 26px; margin-top: 8px; }
.film-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 12px; }
.film-fact { display: inline-flex; align-items: center; gap: 5px; color: var(--text-dim); font-size: 13.5px; }
.film-rating .ico { color: var(--accent); }
.film-synopsis { color: var(--text-dim); margin-top: 16px; font-size: 15.5px; }
.film-creator { display: flex; align-items: center; gap: 6px; margin-top: 12px; font-size: 13.5px; }
.rate-mount { margin-top: 12px; }
.film-next-link { display: flex; align-items: center; gap: 14px; margin-top: 22px; padding: 12px; border: 1px solid var(--line); border-radius: var(--r-lg);
    background: var(--surface); color: var(--text); }
.film-next-link:hover { text-decoration: none; border-color: var(--accent-dim); }
.film-next-link > div:nth-child(2) { flex: 1; min-width: 0; }
.film-next-link .ico { color: var(--accent); flex-shrink: 0; }
.film-next-link-title { font-weight: 700; margin-top: 2px; }
.film-next-link-poster { position: relative; width: 56px; aspect-ratio: 9 / 16; border-radius: 8px; overflow: hidden; background: var(--ink); flex-shrink: 0; }
.film-next-link-poster.landscape { width: 96px; aspect-ratio: 16 / 9; }
.film-next-link-poster img { position: relative; z-index: 1; width: 100%; height: 100%; object-fit: cover; }
.film-next-link-poster .film-cover-empty span { display: none; }
.film-guidelines { margin-top: 22px; }
.film-guidelines .ico, .film-cover-note .ico { display: inline-block; }

@media (min-width: 900px) {
  .film-page { padding-top: 22px; }
  .film-stage { aspect-ratio: 16 / 9; max-height: 78vh; border-radius: var(--r-lg); }
  .film-stage.portrait .film-video { object-fit: contain; }
  .film-stage .film-cover .film-poster { object-fit: contain; }
  .film-stage.portrait .film-cover .film-poster { object-fit: cover; filter: blur(0); }
  .film-body { padding-top: 24px; max-width: 1120px; }
  .film-title { font-size: 36px; }
  .film-next { left: auto; right: 22px; bottom: 76px; width: 320px; }
}

/* ---------- the series page ---------- */
.series-page { padding-top: 26px; }
.series-head { max-width: 720px; }
.series-title { margin-top: 8px; }
.series-facts { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 10px; font-size: 14px; }
.series-facts span { display: inline-flex; align-items: center; gap: 5px; }
.series-synopsis { color: var(--text-dim); margin-top: 14px; font-size: 15.5px; }
.series-start { margin-top: 20px; }
.episodes { list-style: none; margin: 28px 0 0; display: grid; gap: 12px; }
.ep { display: flex; gap: 14px; align-items: stretch; padding: 12px; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); color: var(--text); }
.ep:hover { text-decoration: none; border-color: var(--accent-dim); }
.ep-poster { position: relative; width: 84px; aspect-ratio: 9 / 16; border-radius: 10px; overflow: hidden; background: var(--ink); flex-shrink: 0; }
.ep-poster.landscape { width: 132px; aspect-ratio: 16 / 9; align-self: center; }
.ep-poster img { position: relative; z-index: 1; width: 100%; height: 100%; object-fit: cover; }
.ep-poster .film-cover-empty span { display: none; }
.ep-play { position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; justify-content: center; color: var(--text); opacity: 0; transition: opacity .15s ease; background: rgba(10, 10, 12, .35); }
.ep:hover .ep-play { opacity: 1; }
.ep-info { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 4px; }
.ep-no { font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--accent-dim); font-weight: 700; }
.ep-title { font-family: var(--font-display); font-weight: 700; font-size: 17px; }
.ep-facts { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 13px; }
.ep-facts span { display: inline-flex; align-items: center; gap: 4px; }
.ep-label { margin-top: 4px; }
@media (min-width: 900px) {
  .episodes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
}

/* ---- 40-feed.css ---- */
/* The feed: a column the height of the screen under the bar, one film per screen, snapping.
   Phone first (390 wide); at 900 and up the column is centered at a fixed width with the
   arrows beside it. Colours come from the variables; the overlays are the ground colour
   at an opacity. */
.feed-wrap { position: relative; height: calc(100vh - var(--nav-h)); height: calc(100dvh - var(--nav-h)); background: var(--ground); }
.feed-wrap ~ .foot { display: none; }   /* the footer lives in the last slot instead, where it can be reached */
.feed {
    height: 100%; overflow-y: auto; overflow-x: hidden; scroll-snap-type: y mandatory;
    overscroll-behavior-y: contain; -webkit-overflow-scrolling: touch; outline: none;
}
.feed:focus-visible { outline: none; }

.slot {
    position: relative; height: 100%; scroll-snap-align: start; scroll-snap-stop: always;
    display: flex; align-items: center; justify-content: center; overflow: hidden; background: var(--ground);
    touch-action: manipulation; -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none;
}
.slot-media { position: absolute; inset: 0; background: var(--surface); }
.slot-video { width: 100%; height: 100%; object-fit: contain; background: transparent; }
.slot-tap { position: absolute; inset: 0; cursor: pointer; }
.slot-unavailable {
    position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
    color: var(--text-faint); font-size: 14px; text-align: center; padding: 20px; pointer-events: none;
}
.slot-sound {
    position: absolute; top: 14px; left: 50%; transform: translateX(-50%); padding: 7px 14px; border-radius: 999px;
    background: rgba(10, 10, 12, .7); color: var(--text); font-size: 13px; font-weight: 600; pointer-events: none;
    opacity: 0; transition: opacity .2s ease;
}
.slot.is-active.is-muted.has-src .slot-sound { opacity: 1; }
.slot-burst {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(.4); color: var(--accent);
    opacity: 0; pointer-events: none;
}
.slot-burst .ico { fill: var(--accent); }
.slot.is-burst .slot-burst { animation: feed-burst .7s ease-out forwards; }
@keyframes feed-burst { 0% { opacity: 0; transform: translate(-50%, -50%) scale(.4); } 25% { opacity: 1; transform: translate(-50%, -50%) scale(1.1); } 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.3); } }

.slot-overlay {
    position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: flex-end; gap: 12px;
    padding: 60px 14px calc(16px + var(--safe-bottom)); pointer-events: none;
    background: linear-gradient(180deg, rgba(10, 10, 12, 0) 0%, rgba(10, 10, 12, .82) 100%);
}
.slot-overlay > * { pointer-events: auto; }
.slot-info { flex: 1; min-width: 0; }
.slot-label { margin-bottom: 8px; }
.slot-title { font-size: 20px; line-height: 1.2; margin: 0 0 4px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.slot-title a { color: var(--text); }
.slot-meta { display: flex; flex-wrap: wrap; gap: 4px 12px; color: var(--text-dim); font-size: 13px; margin-bottom: 10px; }
.slot-actions { display: flex; flex-direction: column; align-items: center; gap: 10px; flex-shrink: 0; }
.slot-btn {
    display: inline-flex; flex-direction: column; align-items: center; gap: 3px; min-width: 56px; padding: 8px 6px;
    background: transparent; border: none; color: var(--text); font: inherit; font-size: 11px; font-weight: 600; cursor: pointer;
    border-radius: 12px;
}
.slot-btn:hover { color: var(--accent); text-decoration: none; }
.slot-btn .ico { filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .6)); }

/* the note above the feed when Mature titles are being held back */
.feed-note {
    position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 2; max-width: calc(100% - 28px);
    display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 999px;
    background: rgba(19, 19, 23, .92); border: 1px solid var(--line); color: var(--text-dim); font-size: 12.5px; line-height: 1.3;
}
.feed-note:hover { color: var(--accent); text-decoration: none; border-color: var(--accent-dim); }
.feed-note .ico { flex-shrink: 0; }
.wrap-wide > .feed-note { position: static; transform: none; display: flex; justify-content: center; max-width: none; margin: 0 auto; }

/* the last snap point */
.slot-end { align-items: flex-start; overflow-y: auto; }
.slot-end-inner { width: 100%; max-width: 560px; margin: 0 auto; padding: 40px 20px 20px; text-align: center; }
.slot-end-inner .mark { margin: 0 auto 14px; }
.slot-end-inner h2 { margin-bottom: 8px; }
.slot-end-cta { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin: 20px 0 10px; }
.slot-end .foot { margin-top: 24px; padding-top: 22px; text-align: left; background: none; }
.slot-end .foot .wrap-wide { padding: 0; }

/* desktop arrows, and the toast */
.feed-arrows { display: none; }
.feed-toast {
    position: fixed; left: 50%; bottom: calc(24px + var(--safe-bottom)); transform: translateX(-50%); z-index: 60;
    max-width: calc(100% - 32px); padding: 12px 16px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--line);
    color: var(--text); font-size: 14px; box-shadow: var(--shadow); display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
}
.feed-toast[hidden] { display: none; }
.feed-toast a { font-weight: 700; white-space: nowrap; }

@media (min-width: 900px) {
  .feed-wrap { display: flex; justify-content: center; }
  .feed { width: 520px; max-width: 100%; }
  .slot { border-left: 1px solid var(--line); border-right: 1px solid var(--line); }
  .slot[data-orientation="landscape"] .slot-video { object-fit: contain; }
  .slot-overlay { padding-left: 18px; padding-right: 14px; }
  .feed-arrows { display: flex; flex-direction: column; gap: 12px; position: absolute; right: calc(50% - 260px - 72px); top: 50%; transform: translateY(-50%); }
  .feed-arrow {
      width: 48px; height: 48px; border-radius: 50%; border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
      display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  }
  .feed-arrow:hover { border-color: var(--accent-dim); color: var(--accent); }
  .feed-arrow[data-go="-1"] .ico { transform: rotate(-90deg); }
  .feed-arrow[data-go="1"] .ico { transform: rotate(90deg); }
  .feed-note { top: 14px; }
}
@media (min-width: 1240px) {
  .feed { width: 560px; }
  .feed-arrows { right: calc(50% - 280px - 80px); }
}

/* ---------- out of the way ---------- */
/* Five seconds in, everything that is not the film fades off and the film takes the
   whole screen: the bar collapses upward and the feed grows into the space it leaves,
   both over the same 450ms, so it reads as one movement rather than a jump. A tap,
   a key or a scroll brings it all back. */
.bar { overflow: hidden; transition: opacity .45s ease, height .45s ease, padding-top .45s ease, border-width .45s ease; }
.slot-overlay, .slot-sound { transition: opacity .45s ease, visibility .45s ease; }
.feed-wrap { transition: height .45s ease; }

body.is-immersive .bar {
    /* The border goes too, or a one pixel line survives the collapse. */
    opacity: 0; height: 0; padding-top: 0; border-bottom-width: 0; pointer-events: none;
}
body.is-immersive .feed-wrap { height: 100vh; height: 100dvh; }
body.is-immersive .slot-overlay,
body.is-immersive .slot-sound { opacity: 0; visibility: hidden; pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
    .bar, .slot-overlay, .slot-sound, .feed-wrap { transition: none; }
}

/* Real full screen, where the browser hands over the whole element. On a phone running
   WebKit it hands over the film instead, and the system player takes it from there. */
.slot-media:fullscreen, .slot-media:-webkit-full-screen { width: 100%; height: 100%; background: #000; }
.slot-media:fullscreen .slot-video, .slot-media:-webkit-full-screen .slot-video { width: 100%; height: 100%; object-fit: contain; }

/* ---- 41-wall.css ---- */
/* The preview wall. A visitor watches, then this asks them to make an account. It
   covers the film rather than sitting beside it: the point is that the film has
   stopped, and a sheet that can be scrolled past is not a wall. */
.wall {
    position: fixed; inset: 0; z-index: 60;
    display: grid; place-items: center;
    padding: calc(20px + env(safe-area-inset-top, 0px)) 20px calc(20px + env(safe-area-inset-bottom, 0px));
    background: rgba(6, 7, 9, .86); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    animation: wall-in .22s ease-out both;
}
@keyframes wall-in { from { opacity: 0; } to { opacity: 1; } }
.wall-card {
    width: 100%; max-width: 380px; text-align: center;
    background: var(--surface, #14161a); border: 1px solid var(--line, #24272d);
    border-radius: 18px; padding: 28px 22px 22px;
}
.wall-eyebrow { margin: 0 0 6px; color: var(--accent, #5ce89a); font-size: 12px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.wall-title { margin: 0 0 10px; font-size: 26px; line-height: 1.15; }
.wall-line { margin: 0 0 20px; color: var(--text-dim, #a6adb8); font-size: 15px; line-height: 1.5; }
.wall-acts { display: grid; gap: 10px; }
.wall-foot { margin: 16px 0 0; color: var(--text-faint, #767d88); font-size: 12.5px; line-height: 1.45; }
body.wall-open { overflow: hidden; }

/* ---- 45-discover.css ---- */
/* Discover: the search field, the label chips, the poster rows. Rows scroll sideways with
   snap on a phone and wrap into a grid from 900px up. Every tap target is at least 44px. */
.discover { padding-top: 22px; }
.discover-head { display: flex; flex-direction: column; gap: 14px; margin-bottom: 8px; }
.discover-head h1 { font-size: 28px; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* ---------- search ---------- */
.discover-search { position: relative; display: flex; align-items: center; gap: 8px; }
.discover-search-ico { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--text-faint); pointer-events: none; display: inline-flex; }
.discover-search input[type=search] { min-height: 46px; padding-left: 42px; border-radius: 999px; -webkit-appearance: none; appearance: none; }
.discover-search input[type=search]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.discover-search .btn { min-height: 44px; flex-shrink: 0; }

/* ---------- chips ---------- */
.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chip { display: inline-flex; align-items: center; min-height: 44px; padding: 0 18px; border-radius: 999px; border: 1px solid var(--line);
    background: var(--surface); color: var(--text-dim); font-size: 13.5px; font-weight: 700; letter-spacing: .02em; }
.chip:hover { text-decoration: none; border-color: var(--accent-dim); color: var(--text); }
.chip-on { background: var(--accent); border-color: var(--accent); color: var(--ink); }
.chip-on:hover { color: var(--ink); }

/* The genre row is longer than the maturity row, so on a phone it scrolls sideways
   rather than wrapping into three lines and pushing the posters off the screen. The
   negative margin lets the first and last chip sit against the page gutter while the
   padding keeps them off the edge as they scroll past. */
.chips-genre {
    flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden;
    margin-inline: -20px; padding-inline: 20px; padding-bottom: 2px;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.chips-genre::-webkit-scrollbar { display: none; }
.chips-genre .chip { flex: 0 0 auto; padding: 0 15px; font-size: 13px; }

/* ---------- rows ---------- */
.drow { margin-top: 26px; }
.drow-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.drow-head h2 { margin: 0; font-size: 20px; }
.drow-scroll {
    display: flex; gap: 12px; overflow-x: auto; overflow-y: hidden; max-width: 100%; min-width: 0;
    scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain;
    padding: 4px 4px 12px; margin: -4px -4px 0; scroll-padding: 4px;
    scrollbar-width: none; -ms-overflow-style: none;
}
.drow-scroll::-webkit-scrollbar { display: none; width: 0; height: 0; }
.drow-scroll > .poster { flex: 0 0 auto; width: 44vw; max-width: 200px; scroll-snap-align: start; }
.drow-scroll > .poster-landscape { width: 70vw; max-width: 320px; }
.discover-results { margin-top: 22px; }
.poster-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }

/* ---------- a card ---------- */
.poster { position: relative; min-width: 0; }
.poster-art { position: relative; aspect-ratio: 2 / 3; border-radius: var(--r); overflow: hidden; background: var(--surface-2); border: 1px solid var(--line); }
.poster-landscape .poster-art { aspect-ratio: 16 / 9; }
.poster-link { display: block; width: 100%; height: 100%; color: var(--text); }
.poster-link:hover { text-decoration: none; }
.poster-img { width: 100%; height: 100%; object-fit: cover; }
.poster-none { width: 100%; height: 100%; display: grid; place-items: center;
    background: linear-gradient(160deg, var(--surface-2), var(--ground) 70%), var(--surface-2); }
.poster-none span { font-family: var(--font-display); font-size: 44px; font-weight: 700; color: var(--accent-dim); letter-spacing: -.02em; }
.poster:hover .poster-art, .poster-link:focus-visible { border-color: var(--accent-dim); }
.poster-meta { display: block; padding: 8px 2px 0; color: var(--text); }
.poster-meta:hover { text-decoration: none; }
.poster-title { font-weight: 700; font-size: 14px; line-height: 1.3; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.poster-line { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 5px; font-size: 12px; color: var(--text-faint); }
.poster-line .label { font-size: 10px; padding: 2px 7px; }
.poster-stars { display: inline-flex; align-items: center; gap: 3px; color: var(--text-dim); font-weight: 700; }
.poster-stars .ico { vertical-align: 0; color: var(--accent); }
.poster-sub { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The play control sits in the art's bottom right corner, a 44px round target. */
.poster-play {
    position: absolute; right: 8px; bottom: 8px; display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; border-radius: 999px; background: var(--accent); color: var(--ink);
    box-shadow: 0 8px 22px rgba(0, 0, 0, .45); border: 1px solid rgba(6, 20, 12, .2);
}
.poster-play:hover { text-decoration: none; filter: brightness(1.06); }
.poster-play .ico { margin-left: 2px; vertical-align: 0; }

/* From 900px the rows wrap into a grid. */
@media (min-width: 900px) {
  .discover { padding-top: 32px; }
  .discover-head { flex-direction: row; align-items: center; justify-content: space-between; flex-wrap: wrap; }
  /* The genre chips take the whole line under the search field and the maturity chips. */
  .chips-genre { flex-basis: 100%; flex-wrap: wrap; overflow: visible; margin-inline: 0; padding-inline: 0; }
  .discover-head h1 { font-size: 34px; }
  .discover-search { flex: 1; max-width: 520px; margin: 0 24px; }
  .drow-scroll { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 16px; overflow: visible; padding: 0; margin: 0; scroll-snap-type: none; }
  .drow-scroll > .poster, .drow-scroll > .poster-landscape { width: auto; max-width: none; }
  .drow-scroll > .poster-landscape { grid-column: span 2; }
  .poster-grid { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 16px; }
}

/* ---------- an announced title ---------- */
/* No link, no play control: art, a name, and a word about when. The flag sits on
   the art so the card reads as "not yet" before the eye reaches the title. */
.poster-soon .poster-art { cursor: default; }
.poster .poster-art > .poster-flag {
    position: absolute; left: 8px; top: 8px; z-index: 2;
    padding: 4px 10px; border-radius: 999px;
    background: rgba(10, 10, 12, .82); border: 1px solid var(--accent-dim, #2f6b4c);
    color: var(--accent, #5ce89a); font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
}
.poster-soon .poster-img, .poster-soon .poster-none { opacity: .78; }
.feature-soon-note { color: var(--text-dim); font-size: 14px; align-self: center; margin-right: 4px; }
@media (max-width: 560px) {
    .feature-soon .feature-acts { flex-direction: column; align-items: flex-start; gap: 10px; }
    .feature-soon-note { margin-right: 0; }
}
.tag-soon { border-color: var(--accent-dim, #2f6b4c); color: var(--accent, #5ce89a); }

/* ---- 46-feature.css ---- */
/* The feature slot at the top of Discover.

   One film across the full width of the page, so the site makes the first
   recommendation instead of handing a visitor a grid and asking them to choose.
   It bleeds past the page gutter on purpose, which is why it is rendered
   outside .wrap-wide rather than inside it. */

.feature {
    position: relative;
    width: 100%;
    /* Deliberately about half a screen: enough to read as cinema, short enough
       that the first row of films is visible without scrolling. A taller banner
       pushed everything else off the page. */
    min-height: 300px;
    height: clamp(300px, 38vh, 430px);
    display: flex;
    /* The copy sits just under the top bar rather than on the floor, which is
       what keeps the whole block tight to the header. */
    align-items: flex-start;
    overflow: hidden;
    isolation: isolate;
}

.feature-art {
    position: absolute;
    inset: 0;
    z-index: 0;
}
.feature-art img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* The artwork's subject sits left of centre, so hold that edge as the frame
       narrows rather than letting a phone crop to empty sky. */
    object-position: 30% center;
    display: block;
}

/* Two washes rather than one: upward from the floor so the text always has a
   ground, and inward from the left so the copy column stays legible over a
   busy picture. The page ground is the end colour of both, so the hero melts
   into the rows below with no visible seam. */
.feature-shade {
    position: absolute;
    inset: 0;
    z-index: 1;
    /* Enough to hold the text and to melt into the page at the floor, and no
       more: the artwork is the reason the feature exists, so it stays visible.
       The floor wash ends at the page ground so there is no seam under it. */
    background:
        linear-gradient(to top, var(--ground, #0b0d0c) 0%, rgba(11, 13, 12, 0.5) 18%, rgba(11, 13, 12, 0) 46%),
        linear-gradient(to right, rgba(11, 13, 12, 0.78) 0%, rgba(11, 13, 12, 0.32) 42%, rgba(11, 13, 12, 0) 68%);
}

/* The copy column lines up with the page gutter, not the middle of the screen,
   and matches the width the rows below use so the left edges agree. */
.feature-body {
    position: relative;
    z-index: 2;
    width: 100%;
    max-width: 1120px;
    margin: 0 auto;
    padding: clamp(28px, 4vh, 44px) 20px 24px;
    text-align: left;
}
.feature-body > * { max-width: min(620px, 100%); }

.feature-eyebrow {
    margin: 0 0 10px;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--accent, #5ce89a);
}

.feature-title {
    margin: 0 0 10px;
    font-size: clamp(1.9rem, 4.4vw, 3rem);
    line-height: 1.02;
    letter-spacing: -0.02em;
    font-weight: 800;
    color: #fff;
    /* Two lines is the most a title gets; a third would push the buttons off
       the bottom of a short viewport. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.feature-line {
    margin: 0 0 14px;
    font-size: 1rem;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.82);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.feature-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 16px;
    /* The label, the rating and the runtime read as one line, so the runtime
       sits beside the rating rather than drifting to the far edge. */
    justify-content: flex-start;
}
.feature-sub { color: rgba(255, 255, 255, 0.62); font-size: 0.9rem; }

.feature-acts { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.feature-acts .btn {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    height: 48px;
    padding: 0 22px;
    border-radius: 999px;
    font-weight: 650;
    font-size: 1rem;
    text-decoration: none;
}
.btn-play {
    background: var(--accent, #5ce89a);
    color: var(--ink, #06130c) !important;
    border: 1px solid var(--accent, #5ce89a);
}
.btn-play:hover { filter: brightness(1.06); text-decoration: none; }
.btn-play svg { fill: currentColor; stroke: none; }

.btn-ghost {
    background: rgba(255, 255, 255, 0.1);
    color: #fff !important;
    border: 1px solid rgba(255, 255, 255, 0.22);
    backdrop-filter: blur(6px);
}
.btn-ghost:hover { background: rgba(255, 255, 255, 0.16); text-decoration: none; }

/* With a feature above it the search bar is a toolbar rather than a page
   heading, so it sits tight under the hero instead of leaving a gap where the
   Discover title used to be. */
.discover-hasfeature { padding-top: 0; }
.discover-hasfeature .discover-head {
    margin-top: 0;
    padding-top: 18px;
}

@media (max-width: 719px) {
    .feature {
        height: clamp(300px, 46vh, 400px);
        min-height: 300px;
    }
    .feature-body {
        margin-inline-start: 0;
        max-inline-size: 100%;
        padding-inline: var(--gutter, 16px);
    }
    /* On a phone the picture is mostly behind the words, so the floor wash
       carries further up to keep every line readable. */
    .feature-shade {
        background: linear-gradient(to top, var(--ground, #0b0d0c) 0%, rgba(11, 13, 12, 0.85) 42%, rgba(11, 13, 12, 0.25) 78%, rgba(11, 13, 12, 0.45) 100%);
    }
    .feature-acts .btn { height: 46px; flex: 1 1 auto; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
    .btn-play:hover { filter: none; }
}

/* ---- 50-ratings.css ---- */
/* The one tap stars: five buttons big enough for a thumb, the viewer's own vote filled, the
   mean and the count beside them. Rendered inside the feed's overlay today; the film page
   includes the same fragment. */
.rating { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rating .stars { display: inline-flex; gap: 2px; }
.rating .star {
    width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center;
    background: transparent; border: none; padding: 0; color: var(--text-dim); cursor: pointer; border-radius: 50%;
    -webkit-tap-highlight-color: transparent; transition: transform .12s ease, color .12s ease;
}
.rating .star .ico { filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .6)); }
.rating .star:hover { transform: scale(1.12); color: var(--accent); }
.rating .star.is-on { color: var(--accent); }
.rating .star.is-on .ico { fill: var(--accent); }
.rating.is-busy .star { opacity: .6; pointer-events: none; }
.rating-meta { color: var(--text-dim); font-size: 13px; font-weight: 600; }
.rating-count { color: var(--text-faint); font-weight: 400; }

/* ---- 60-creators.css ---- */
/* The creators feature: the application form, the studio's film cards, the owner's queues.
   Colours come from 00-tokens.css; the layout is phone first and widens at 640px. */

/* ---------- /submit ---------- */
.apply textarea { min-height: 72px; }
.apply .check { margin-top: 4px; }
.apply .btn { margin-top: 8px; }

/* ---------- /studio ---------- */
.studio-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px 24px; flex-wrap: wrap; margin-bottom: 22px; }
.studio-head > div { flex: 1 1 320px; }
.studio-head .btn { flex-shrink: 0; }
.studio-list { display: grid; gap: 12px; }
.studio-film {
    display: grid; grid-template-columns: 1fr; gap: 14px 24px; padding: 18px var(--pad);
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
}
.studio-film h2 { font-size: 19px; margin: 0; overflow-wrap: anywhere; }
.studio-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-top: 8px; color: var(--text-faint); font-size: 13px; }
.studio-meta .label { vertical-align: baseline; }
.studio-stats { display: flex; flex-wrap: wrap; gap: 14px 26px; margin-top: 14px; }
.stat b { display: block; font-family: var(--font-display); font-size: 22px; line-height: 1.1; color: var(--text); }
.stat b i { font-style: normal; font-size: 14px; color: var(--text-faint); }
.stat span { display: block; margin-top: 3px; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint); font-weight: 700; }
.studio-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.studio-actions form { display: inline; }
@media (min-width: 640px) {
    .studio-film { grid-template-columns: minmax(0, 1fr) auto; padding: 20px 22px; }
    .studio-actions { flex-direction: column; align-items: stretch; justify-content: center; min-width: 150px; }
    .studio-actions .btn { width: 100%; }
}

.studio-note { margin-top: 22px; }
.studio-note .ico { display: inline; vertical-align: -2px; margin-right: 4px; }

/* the life of a film, as a tag */
.tag.status-published { color: var(--ok); border-color: rgba(92, 232, 154, .4); }
.tag.status-ready { color: var(--accent); border-color: var(--accent-dim); }
.tag.status-processing { color: var(--text-dim); }
.tag.status-draft { color: var(--text-faint); }
.tag.status-removed { color: var(--danger); border-color: rgba(255, 141, 141, .4); }
.tag .ico { vertical-align: -2px; margin-right: 3px; }

/* ---------- the owner's queues: applications and reports ---------- */
.queue-h { display: flex; align-items: baseline; gap: 10px; margin-top: 24px; }
.queue { display: grid; gap: 12px; }
.queue-item { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 18px var(--pad); }
.queue-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.queue-top h2 { font-size: 18px; margin: 0; overflow-wrap: anywhere; }
.queue-item > .hint { margin-top: 4px; }
.queue-facts { display: grid; grid-template-columns: 1fr; gap: 4px 16px; margin-top: 14px; font-size: 14px; }
.queue-facts dt { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint); font-weight: 700; margin-top: 8px; }
.queue-facts dd { color: var(--text-dim); overflow-wrap: anywhere; }
.queue-reason { margin: 10px 0 0; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }
.queue-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.queue-actions form { display: inline; }
.decide { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }
.decide .field { margin-bottom: 10px; }
@media (min-width: 640px) {
    .queue-item { padding: 20px 22px; }
    .queue-facts { grid-template-columns: 140px minmax(0, 1fr); }
    .queue-facts dt { margin-top: 0; padding-top: 3px; }
}

/* A film waiting on the owner. Not a warning and not a success: it is simply
   out of the creator's hands until someone looks at it. */
.status-review { border-color: var(--accent-dim, #2f6b4c); color: var(--accent, #5ce89a); }

/* ---- 70-admin.css ---- */
/* The admin pages (lib/views-admin.js): the overview cards, the film and series lists, the
   edit forms and the save bar. Phone first; the wider rules sit at the end. */
.adm { max-width: 1120px; margin: 0 auto; padding: 22px var(--pad) 40px; }
.adm-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.adm-head h1 { margin-top: 6px; font-size: 28px; overflow-wrap: anywhere; }
.adm-head .eyebrow a { color: var(--accent-dim); }
.adm-head .btn { white-space: nowrap; }

/* ---------- the overview ---------- */
.adm-cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.adm-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 16px 18px; min-height: 92px; }
.adm-card .n { font-family: var(--font-display); font-size: 30px; font-weight: 700; line-height: 1.1; color: var(--text); }
.adm-card .k { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint); font-weight: 700; margin-top: 6px; }
.adm-statuses { display: flex; flex-wrap: wrap; gap: 6px 16px; margin: 14px 2px 0; font-size: 13px; color: var(--text-faint); }
.adm-statuses b { color: var(--text); }
.adm-links { display: grid; grid-template-columns: 1fr; gap: 10px; margin-top: 22px; }
.adm-link { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 12px 16px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); color: var(--text); font-weight: 600; }
.adm-link:hover { border-color: var(--accent-dim); color: var(--accent); text-decoration: none; }
.adm-link .ico { color: var(--accent-dim); flex-shrink: 0; }
.adm-link .cnt { margin-left: auto; min-width: 26px; text-align: center; font-size: 12px; font-weight: 700; color: var(--ink); background: var(--accent); border-radius: 999px; padding: 2px 8px; }

/* ---------- the film and series lists ---------- */
.flist { display: grid; gap: 10px; }
.frow { display: grid; grid-template-columns: 52px 1fr; gap: 12px; padding: 12px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); color: var(--text); min-height: 76px; }
.frow:hover { border-color: var(--accent-dim); text-decoration: none; color: var(--text); }
.frow .poster { width: 52px; aspect-ratio: 2 / 3; border-radius: 8px; background: var(--surface-2); overflow: hidden; display: flex; align-items: center; justify-content: center; color: var(--text-faint); }
.frow .poster img { width: 100%; height: 100%; object-fit: cover; }
.frow .body { min-width: 0; }
.frow .ttl { font-weight: 700; overflow-wrap: anywhere; }
.frow .meta { font-size: 12.5px; color: var(--text-faint); display: flex; flex-wrap: wrap; gap: 6px 12px; margin-top: 6px; align-items: center; }
.frow .stats { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; padding-top: 10px; border-top: 1px solid var(--line); }
.stat b { display: block; font-size: 15px; color: var(--text); line-height: 1.2; }
.stat span { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-faint); }
.status-draft, .status-processing { color: var(--text-faint); }
.status-ready { color: var(--accent); border-color: var(--accent-dim); }

/* ---------- the edit pages ---------- */
.fedit { display: grid; gap: 14px; }
.fedit .panel { margin: 0 0 14px; }
.fedit-side .panel { margin-bottom: 0; }
.two { display: grid; grid-template-columns: 1fr; gap: 0 14px; }
.descs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px 12px; }
.descs .check { margin-bottom: 0; min-height: 44px; display: flex; align-items: center; }
.descs .check input { top: auto; }
.poster-box { aspect-ratio: 2 / 3; max-width: 220px; border-radius: var(--r); background: var(--surface-2); border: 1px dashed var(--line); display: flex; align-items: center; justify-content: center; color: var(--text-faint); font-size: 13px; overflow: hidden; }
.poster-box img { width: 100%; height: 100%; object-fit: cover; }
.pubpanel .pub { display: grid; gap: 12px; margin-top: 12px; }
.pub-state { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pub-moves { display: flex; flex-wrap: wrap; gap: 8px; }
.pub-moves form { display: inline; }
.pub-moves .btn { min-height: 44px; }
.pub-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.err + .err { margin-top: 0; }
.field .err { margin: 8px 0 0; }

/* The save bar sticks to the bottom of the screen and clears the phone's home bar. */
.savebar { position: sticky; bottom: 0; z-index: 30; display: flex; align-items: center; gap: 12px; margin: 6px calc(-1 * var(--pad)) 0;
    padding: 12px var(--pad) calc(12px + var(--safe-bottom)); background: var(--ground); border-top: 1px solid var(--line); }
.savebar .hint { flex: 1; min-width: 0; }
.savebar .btn { min-height: 48px; flex: 1 1 auto; }

/* ---------- wider ---------- */
@media (min-width: 620px) {
  .adm-cards { grid-template-columns: repeat(3, 1fr); }
  .adm-links { grid-template-columns: repeat(2, 1fr); }
  .two { grid-template-columns: 1fr 1fr; }
  .descs { grid-template-columns: repeat(3, 1fr); }
  .savebar .btn { flex: 0 0 auto; min-width: 180px; }
  .savebar .hint { text-align: left; }
}
@media (min-width: 860px) {
  .adm { padding-top: 30px; }
  .adm-head h1 { font-size: 32px; }
  .adm-cards { grid-template-columns: repeat(5, 1fr); }
  .adm-links { grid-template-columns: repeat(3, 1fr); }
  .frow { grid-template-columns: 52px 1fr 380px; align-items: center; }
  .frow .stats { grid-column: auto; padding-top: 0; border-top: none; }
  .srow { grid-template-columns: 52px 1fr; }
  .fedit { grid-template-columns: minmax(0, 1fr) 300px; align-items: start; }
  .pubpanel .pub { grid-template-columns: 1fr auto; align-items: center; }
  .pub-stats { max-width: 560px; }
}

/* ---- 80-design.css ---- */
/* The design pass (VMSC-18). Everything here is layout and finish over what the feature
   stylesheets set up: one poster shape so rows align, one card rhythm, a real empty and
   loading state, and the small type and contrast corrections the QA pass asked for.
   Feature files keep their own rules; this file only settles what they disagree about. */

/* ---------- posters: one shape, whatever the film's own aspect is ----------
   A row mixing portrait and landscape films used to give every card a different height
   and width, so titles sat at different heights and the grid read as broken. Every card
   art box is now the same 16:9 window and the image covers it. The film's real shape is
   still honoured where it matters: on its own page and in the feed. */
.poster { width: 100%; }
.poster .poster-art {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius, 12px);
    overflow: hidden;
    background: var(--surface-2, #171a19);
}
.poster .poster-art img,
.poster .poster-art .poster-link > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
/* A poster that never loads (a signed URL past its expiry, a vendor hiccup) must not leave
   a broken image icon in the grid: the art box keeps its own ground and the title still
   reads. img:not([src]) and a failed load both fall through to this. */
.poster .poster-art::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(60% 60% at 50% 40%, rgba(255, 255, 255, 0.05), transparent 70%),
        var(--surface-2, #171a19);
    z-index: 0;
}
.poster .poster-art > * { position: relative; z-index: 1; }

/* The title block sits at the same height on every card in a row. */
.poster { display: flex; flex-direction: column; gap: 8px; }
.poster .poster-meta { display: block; text-decoration: none; }
.poster .poster-title {
    font-weight: 650;
    line-height: 1.25;
    /* Two lines, then an ellipsis, so one long title cannot push a row out of rhythm. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.poster .poster-line { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.poster .poster-sub { color: var(--text-faint, #8a908d); }

/* The play affordance sits clear of the safe area and is a real 44px target. */
.poster .poster-play {
    position: absolute;
    right: 10px;
    bottom: 10px;
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border-radius: 999px;
    background: var(--accent, #5ce89a);
    color: var(--ink, #06130c);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
    transition: transform 120ms ease;
}
.poster .poster-play:hover { transform: scale(1.06); }
@media (prefers-reduced-motion: reduce) {
    .poster .poster-play { transition: none; }
    .poster .poster-play:hover { transform: none; }
}

/* ---------- rows ----------
   Every card in a rail is the same width, whatever the film's own shape, so with the 16:9
   art box above they are all the same height and the titles sit on one line. The rail was
   giving portrait films 200px and landscape films 320px, which is what made a row look
   like it had been assembled out of spare parts. */
.drow-scroll > .poster,
.drow-scroll > .poster-landscape { width: 78vw; max-width: 320px; }
/* On a wide screen the rail becomes a grid, and it used to give a landscape film two
   columns and a portrait film one, so a row came out in two different card sizes. Every
   card takes one track now and the grid decides the width, which is what keeps the row
   even at any window size. */
@media (min-width: 720px) {
    /* 280px is the floor that keeps a 16:9 card taller than the 160px a poster needs to
       stay a comfortable target at every window width the e2e walks cover. */
    .drow-scroll { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
    .drow-scroll > .poster,
    .drow-scroll > .poster-landscape { width: auto; max-width: none; grid-column: auto; }
}
/* The search results grid keeps one shape too. */
.poster-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 20px 16px; }

/* A rail bleeds to the screen edge on a phone, so a card is never clipped mid-gutter. */
@media (max-width: 719px) {
    .drow-scroll {
        margin-inline: calc(var(--gutter, 16px) * -1);
        padding-inline: var(--gutter, 16px);
    }
}

/* ---------- empty and loading ---------- */
.empty {
    border: 1px dashed var(--line, #262a28);
    border-radius: var(--radius, 12px);
    padding: 28px 20px;
    text-align: center;
    color: var(--text-dim, #a8b0ac);
}
.empty strong { display: block; color: var(--text, #e8ece9); margin-bottom: 6px; font-size: 1.05rem; }
.skeleton {
    background: linear-gradient(90deg, var(--surface-2, #171a19) 25%, rgba(255, 255, 255, 0.06) 37%, var(--surface-2, #171a19) 63%);
    background-size: 400% 100%;
    animation: skeleton 1.4s ease infinite;
    border-radius: var(--radius, 12px);
}
@keyframes skeleton { from { background-position: 100% 50%; } to { background-position: 0 50%; } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }

/* ---------- legibility ----------
   Nothing a viewer reads sits below 13px, and the faint tone still clears 4.5:1 on the
   page ground. */
body { -webkit-font-smoothing: antialiased; }
small, .poster-sub, .row-note, .muted { font-size: 0.85rem; }
:root { --text-faint: #98a09b; }

/* ---------- the wordmark ----------
   LokeTV reads as two halves with a jade dot between them, the same jade as the
   play triangle inside the mark. The dot is decorative, so it is an empty
   element and never reaches a screen reader, which announces the name once. */
.wordmark { display: inline-flex; align-items: baseline; gap: 0; white-space: nowrap; }
.wordmark-dot {
    display: inline-block;
    width: 0.32em;
    height: 0.32em;
    margin: 0 0.26em;
    border-radius: 999px;
    background: var(--accent, #5ce89a);
    /* Sits on the lowercase middle rather than the baseline. */
    transform: translateY(-0.22em);
    flex: 0 0 auto;
}
