Adds web-overrides/popup-designs/ with the 4-up preview (preview.html) and three standalone candidate designs (a-strip.html / b-terminal.html / c-minimal.html) so we can revisit the alternates later without re-running the design generator. Owner picked A. Design A is wired into Jellyfin's stock .upNextDialog by overriding its CSS to a full-bleed bottom 26 % strip with white 'Start Now' CTA and a custom SVG countdown ring that mirrors .upNextDialog-countdownText. The DOM stays intact so Jellyfin's own countdown timer and click handlers on .btnStartNow / .btnHide keep working untouched. Shim is bracketed by NEXT-EP-POPUP-BEGIN / NEXT-EP-POPUP-END markers inside the existing ARRFLIX-SHIM block in web-overrides/index-dev.html. Only deployed to dev (dev.arrflix.s8n.ru) for spot-check; promote to prod once verified by editing prod's index.html the same way and redeploying via the nsenter trick. Adds bin/revert-next-ep-popup.sh — sed-deletes between markers, defaults to dev with --prod flag for prod target. Saves a timestamped backup and prints the redeploy command.
760 lines
22 KiB
HTML
760 lines
22 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>ARRFLIX — Next-Episode popup designs</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&family=Bebas+Neue&family=Anton&display=swap" rel="stylesheet">
|
||
<style>
|
||
:root {
|
||
--arrflix-red: #E50914;
|
||
--arrflix-red-dark: #B00710;
|
||
--arrflix-bg: #0a0a0a;
|
||
--ink: #fff;
|
||
--ink-dim: rgba(255,255,255,0.55);
|
||
--ink-faint: rgba(255,255,255,0.3);
|
||
}
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
html, body {
|
||
background: #050505;
|
||
color: var(--ink);
|
||
font-family: 'Geist', system-ui, sans-serif;
|
||
font-feature-settings: "ss01", "ss02";
|
||
overflow-x: hidden;
|
||
}
|
||
.header {
|
||
position: sticky; top: 0; z-index: 100;
|
||
background: rgba(5,5,5,0.85);
|
||
backdrop-filter: blur(12px);
|
||
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||
padding: 18px 28px;
|
||
display: flex; align-items: center; justify-content: space-between;
|
||
}
|
||
.header h1 {
|
||
font-family: 'Bebas Neue', sans-serif;
|
||
letter-spacing: 0.1em;
|
||
font-size: 20px;
|
||
color: var(--arrflix-red);
|
||
}
|
||
.header .meta {
|
||
font-size: 11px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
color: var(--ink-dim);
|
||
}
|
||
.picker {
|
||
display: flex; gap: 10px;
|
||
}
|
||
.picker button {
|
||
background: transparent;
|
||
border: 1px solid rgba(255,255,255,0.15);
|
||
color: var(--ink-dim);
|
||
padding: 8px 14px;
|
||
font-family: inherit;
|
||
font-size: 11px;
|
||
letter-spacing: 0.15em;
|
||
text-transform: uppercase;
|
||
cursor: pointer;
|
||
transition: all 0.15s ease;
|
||
}
|
||
.picker button:hover {
|
||
border-color: var(--arrflix-red);
|
||
color: var(--ink);
|
||
}
|
||
.picker button.active {
|
||
background: var(--arrflix-red);
|
||
border-color: var(--arrflix-red);
|
||
color: white;
|
||
}
|
||
|
||
.stage {
|
||
position: relative;
|
||
width: 100%;
|
||
aspect-ratio: 16/9;
|
||
max-height: calc(100vh - 80px);
|
||
background: black;
|
||
overflow: hidden;
|
||
}
|
||
.stage::before {
|
||
/* Star Wars credits backdrop */
|
||
content: '';
|
||
position: absolute; inset: 0;
|
||
background:
|
||
radial-gradient(ellipse 60% 40% at 50% 50%, rgba(20,20,40,0.4) 0%, transparent 70%),
|
||
black;
|
||
}
|
||
.stars {
|
||
position: absolute; inset: 0;
|
||
background-image:
|
||
radial-gradient(1px 1px at 20% 30%, white, transparent),
|
||
radial-gradient(1px 1px at 65% 50%, white, transparent),
|
||
radial-gradient(1px 1px at 80% 20%, rgba(255,255,255,0.7), transparent),
|
||
radial-gradient(2px 2px at 10% 70%, white, transparent),
|
||
radial-gradient(1px 1px at 85% 80%, rgba(255,255,255,0.8), transparent),
|
||
radial-gradient(1px 1px at 45% 90%, white, transparent),
|
||
radial-gradient(1px 1px at 30% 15%, rgba(255,255,255,0.5), transparent),
|
||
radial-gradient(1.5px 1.5px at 70% 75%, white, transparent),
|
||
radial-gradient(1px 1px at 5% 45%, white, transparent),
|
||
radial-gradient(1px 1px at 95% 60%, rgba(255,255,255,0.6), transparent),
|
||
radial-gradient(1px 1px at 25% 85%, white, transparent),
|
||
radial-gradient(1px 1px at 55% 25%, white, transparent),
|
||
radial-gradient(2px 2px at 50% 50%, rgba(255,255,255,0.4), transparent),
|
||
radial-gradient(1px 1px at 15% 92%, white, transparent),
|
||
radial-gradient(1px 1px at 88% 35%, white, transparent);
|
||
background-size: 100% 100%;
|
||
}
|
||
.credits {
|
||
position: absolute;
|
||
top: 18%;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
color: #4488dd;
|
||
font-family: 'Geist', sans-serif;
|
||
font-weight: 500;
|
||
font-size: 14px;
|
||
letter-spacing: 0.04em;
|
||
text-align: center;
|
||
line-height: 1.7;
|
||
opacity: 0.55;
|
||
text-shadow: 0 0 4px rgba(68,136,221,0.2);
|
||
}
|
||
.credits .row {
|
||
display: grid; grid-template-columns: 1fr 1fr; gap: 32px;
|
||
text-align: left;
|
||
margin-bottom: 18px;
|
||
}
|
||
.credits .row .role { text-align: right; opacity: 0.85; }
|
||
.credits .row .name { text-transform: uppercase; }
|
||
.credits .title-block { text-align: center; margin-bottom: 18px; }
|
||
|
||
/* Stop the star backdrop from comUSER-Eing */
|
||
.stage .popup-host {
|
||
position: absolute; inset: 0; z-index: 50;
|
||
pointer-events: none;
|
||
}
|
||
.stage .popup-host > * { pointer-events: auto; }
|
||
|
||
/* === DESIGN A — CINEMATIC STRIP === */
|
||
.design-a {
|
||
position: absolute;
|
||
bottom: 0; left: 0; right: 0;
|
||
height: 26%;
|
||
background: linear-gradient(to top, rgba(0,0,0,0.95) 50%, rgba(0,0,0,0.7) 80%, transparent);
|
||
padding: 28px 56px 32px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 36px;
|
||
transform: translateY(0);
|
||
animation: slideUp 0.5s cubic-bezier(0.16, 1, 0.3, 1);
|
||
}
|
||
@keyframes slideUp {
|
||
from { transform: translateY(100%); opacity: 0; }
|
||
to { transform: translateY(0); opacity: 1; }
|
||
}
|
||
.design-a .ring {
|
||
position: relative;
|
||
width: 88px; height: 88px;
|
||
flex-shrink: 0;
|
||
}
|
||
.design-a .ring svg { transform: rotate(-90deg); }
|
||
.design-a .ring circle {
|
||
fill: none;
|
||
stroke-width: 3;
|
||
}
|
||
.design-a .ring .track { stroke: rgba(255,255,255,0.1); }
|
||
.design-a .ring .progress {
|
||
stroke: var(--arrflix-red);
|
||
stroke-dasharray: 264;
|
||
stroke-dashoffset: 67;
|
||
stroke-linecap: round;
|
||
transition: stroke-dashoffset 1s linear;
|
||
filter: drop-shadow(0 0 8px rgba(229, 9, 20, 0.5));
|
||
}
|
||
.design-a .ring .num {
|
||
position: absolute; inset: 0;
|
||
display: flex; align-items: center; justify-content: center;
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-size: 28px;
|
||
font-weight: 500;
|
||
letter-spacing: -0.02em;
|
||
}
|
||
.design-a .info { flex: 1; min-width: 0; }
|
||
.design-a .label {
|
||
font-size: 10px;
|
||
letter-spacing: 0.32em;
|
||
text-transform: uppercase;
|
||
color: var(--arrflix-red);
|
||
margin-bottom: 8px;
|
||
font-weight: 600;
|
||
}
|
||
.design-a .title {
|
||
font-size: 28px;
|
||
font-weight: 600;
|
||
letter-spacing: -0.02em;
|
||
margin-bottom: 6px;
|
||
line-height: 1.1;
|
||
}
|
||
.design-a .episode-title {
|
||
font-size: 16px;
|
||
color: var(--ink-dim);
|
||
margin-bottom: 4px;
|
||
}
|
||
.design-a .meta {
|
||
font-size: 12px;
|
||
color: var(--ink-faint);
|
||
letter-spacing: 0.04em;
|
||
}
|
||
.design-a .actions {
|
||
display: flex; gap: 10px;
|
||
flex-shrink: 0;
|
||
}
|
||
.design-a .btn {
|
||
border: none;
|
||
background: white;
|
||
color: black;
|
||
padding: 14px 28px;
|
||
font-family: inherit;
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
letter-spacing: 0.02em;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
transition: all 0.15s ease;
|
||
}
|
||
.design-a .btn:hover { background: rgba(255,255,255,0.85); }
|
||
.design-a .btn-secondary {
|
||
background: rgba(255,255,255,0.08);
|
||
color: white;
|
||
backdrop-filter: blur(10px);
|
||
}
|
||
.design-a .btn-secondary:hover { background: rgba(255,255,255,0.16); }
|
||
|
||
/* === DESIGN B — TERMINAL CARD === */
|
||
.design-b {
|
||
position: absolute;
|
||
bottom: 32px; right: 32px;
|
||
width: 380px;
|
||
background: rgba(5,5,5,0.92);
|
||
backdrop-filter: blur(14px);
|
||
border: 1px solid rgba(255,255,255,0.12);
|
||
border-left: 2px solid var(--arrflix-red);
|
||
padding: 20px 22px;
|
||
font-family: 'JetBrains Mono', monospace;
|
||
animation: slideRight 0.4s cubic-bezier(0.16, 1, 0.3, 1);
|
||
}
|
||
@keyframes slideRight {
|
||
from { transform: translateX(20px); opacity: 0; }
|
||
to { transform: translateX(0); opacity: 1; }
|
||
}
|
||
.design-b .top-row {
|
||
display: flex; justify-content: space-between; align-items: center;
|
||
margin-bottom: 14px;
|
||
font-size: 10px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
}
|
||
.design-b .tag {
|
||
color: var(--arrflix-red);
|
||
font-weight: 700;
|
||
}
|
||
.design-b .countdown {
|
||
color: var(--ink-dim);
|
||
}
|
||
.design-b .countdown strong {
|
||
color: var(--ink);
|
||
font-weight: 700;
|
||
}
|
||
.design-b hr {
|
||
border: none;
|
||
border-top: 1px dashed rgba(255,255,255,0.1);
|
||
margin: 12px 0;
|
||
}
|
||
.design-b .ep {
|
||
font-family: 'Geist', sans-serif;
|
||
font-size: 15px;
|
||
font-weight: 500;
|
||
margin-bottom: 4px;
|
||
color: var(--ink);
|
||
letter-spacing: -0.01em;
|
||
}
|
||
.design-b .ep-meta {
|
||
font-size: 11px;
|
||
color: var(--ink-faint);
|
||
letter-spacing: 0.06em;
|
||
margin-bottom: 16px;
|
||
}
|
||
.design-b .progress-bar {
|
||
height: 2px;
|
||
background: rgba(255,255,255,0.08);
|
||
margin-bottom: 18px;
|
||
position: relative;
|
||
}
|
||
.design-b .progress-bar::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0; left: 0;
|
||
height: 100%;
|
||
width: 75%;
|
||
background: var(--arrflix-red);
|
||
box-shadow: 0 0 8px rgba(229,9,20,0.6);
|
||
animation: fillBar 17s linear forwards;
|
||
}
|
||
@keyframes fillBar {
|
||
to { width: 100%; }
|
||
}
|
||
.design-b .actions {
|
||
display: flex; gap: 8px;
|
||
}
|
||
.design-b .btn {
|
||
flex: 1;
|
||
background: transparent;
|
||
border: 1px solid rgba(255,255,255,0.18);
|
||
color: white;
|
||
padding: 9px 14px;
|
||
font-family: inherit;
|
||
font-size: 11px;
|
||
letter-spacing: 0.18em;
|
||
text-transform: uppercase;
|
||
cursor: pointer;
|
||
transition: all 0.15s ease;
|
||
}
|
||
.design-b .btn-primary {
|
||
background: var(--arrflix-red);
|
||
border-color: var(--arrflix-red);
|
||
}
|
||
.design-b .btn-primary:hover { background: var(--arrflix-red-dark); }
|
||
.design-b .btn-secondary:hover {
|
||
background: rgba(255,255,255,0.06);
|
||
border-color: rgba(255,255,255,0.3);
|
||
}
|
||
|
||
/* === DESIGN C — MINIMAL BAR === */
|
||
.design-c {
|
||
position: absolute;
|
||
bottom: 0; left: 0; right: 0;
|
||
pointer-events: auto;
|
||
animation: fadeUp 0.4s ease;
|
||
}
|
||
@keyframes fadeUp {
|
||
from { transform: translateY(20px); opacity: 0; }
|
||
to { transform: translateY(0); opacity: 1; }
|
||
}
|
||
.design-c .progress-line {
|
||
height: 3px;
|
||
background: rgba(255,255,255,0.1);
|
||
position: relative;
|
||
}
|
||
.design-c .progress-line::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0; left: 0;
|
||
height: 100%;
|
||
width: 75%;
|
||
background: var(--arrflix-red);
|
||
animation: fillBar 17s linear forwards;
|
||
}
|
||
.design-c .row {
|
||
background: linear-gradient(to bottom, transparent, rgba(0,0,0,0.85) 30%);
|
||
padding: 24px 56px 22px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 24px;
|
||
}
|
||
.design-c .label {
|
||
font-family: 'Bebas Neue', sans-serif;
|
||
font-size: 13px;
|
||
letter-spacing: 0.32em;
|
||
color: var(--arrflix-red);
|
||
flex-shrink: 0;
|
||
}
|
||
.design-c .text {
|
||
flex: 1;
|
||
font-size: 14px;
|
||
color: var(--ink-dim);
|
||
letter-spacing: 0.02em;
|
||
}
|
||
.design-c .text strong {
|
||
color: var(--ink);
|
||
font-weight: 500;
|
||
margin-right: 8px;
|
||
}
|
||
.design-c .text .countdown {
|
||
color: var(--arrflix-red);
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-weight: 500;
|
||
margin-left: 8px;
|
||
}
|
||
.design-c .actions {
|
||
display: flex; gap: 16px;
|
||
}
|
||
.design-c .btn {
|
||
background: transparent;
|
||
border: none;
|
||
color: white;
|
||
font-family: inherit;
|
||
font-size: 12px;
|
||
letter-spacing: 0.2em;
|
||
text-transform: uppercase;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
padding: 8px 0;
|
||
position: relative;
|
||
transition: color 0.15s ease;
|
||
}
|
||
.design-c .btn::after {
|
||
content: '';
|
||
position: absolute;
|
||
left: 0; bottom: 0;
|
||
height: 1px; width: 100%;
|
||
background: currentColor;
|
||
opacity: 0.3;
|
||
transition: opacity 0.15s ease;
|
||
}
|
||
.design-c .btn:hover::after { opacity: 1; }
|
||
.design-c .btn-primary { color: var(--arrflix-red); }
|
||
|
||
/* === DESIGN D — POSTER CARD === */
|
||
.design-d {
|
||
position: absolute;
|
||
bottom: 28px; right: 28px;
|
||
width: 460px;
|
||
background: linear-gradient(135deg, rgba(15,15,15,0.95), rgba(5,5,5,0.95));
|
||
backdrop-filter: blur(20px);
|
||
border: 1px solid rgba(255,255,255,0.08);
|
||
border-radius: 4px;
|
||
overflow: hidden;
|
||
display: flex;
|
||
box-shadow: 0 20px 60px rgba(0,0,0,0.6),
|
||
0 0 0 1px rgba(229,9,20,0.15);
|
||
animation: slideRight 0.4s cubic-bezier(0.16, 1, 0.3, 1);
|
||
}
|
||
.design-d .poster {
|
||
width: 160px;
|
||
flex-shrink: 0;
|
||
background:
|
||
linear-gradient(135deg, rgba(229,9,20,0.3), transparent 60%),
|
||
radial-gradient(circle at 30% 30%, #2a1a1a, #050505);
|
||
position: relative;
|
||
display: flex; align-items: flex-end;
|
||
padding: 16px;
|
||
}
|
||
.design-d .poster::before {
|
||
content: '';
|
||
position: absolute; inset: 0;
|
||
background-image:
|
||
radial-gradient(1px 1px at 20% 30%, white, transparent),
|
||
radial-gradient(1px 1px at 70% 50%, white, transparent),
|
||
radial-gradient(1px 1px at 40% 70%, white, transparent),
|
||
radial-gradient(1px 1px at 80% 80%, white, transparent),
|
||
radial-gradient(1px 1px at 50% 20%, white, transparent),
|
||
radial-gradient(1.5px 1.5px at 60% 60%, white, transparent);
|
||
opacity: 0.4;
|
||
}
|
||
.design-d .poster .ep-num {
|
||
position: relative;
|
||
font-family: 'Anton', sans-serif;
|
||
font-size: 64px;
|
||
line-height: 0.9;
|
||
color: var(--arrflix-red);
|
||
letter-spacing: -0.04em;
|
||
text-shadow: 0 4px 20px rgba(229,9,20,0.5);
|
||
}
|
||
.design-d .body {
|
||
flex: 1;
|
||
padding: 18px 20px 16px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.design-d .top {
|
||
display: flex; justify-content: space-between; align-items: center;
|
||
margin-bottom: 10px;
|
||
}
|
||
.design-d .label {
|
||
font-size: 9.5px;
|
||
letter-spacing: 0.32em;
|
||
text-transform: uppercase;
|
||
color: var(--arrflix-red);
|
||
font-weight: 700;
|
||
}
|
||
.design-d .timer {
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-size: 11px;
|
||
letter-spacing: 0.04em;
|
||
color: var(--ink-dim);
|
||
}
|
||
.design-d .timer strong {
|
||
color: var(--ink);
|
||
font-weight: 700;
|
||
}
|
||
.design-d .show {
|
||
font-size: 13px;
|
||
color: var(--ink-faint);
|
||
margin-bottom: 4px;
|
||
letter-spacing: 0.02em;
|
||
}
|
||
.design-d .ep-title {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
letter-spacing: -0.02em;
|
||
line-height: 1.2;
|
||
margin-bottom: 12px;
|
||
}
|
||
.design-d .meta {
|
||
font-size: 11px;
|
||
color: var(--ink-faint);
|
||
letter-spacing: 0.06em;
|
||
margin-bottom: 14px;
|
||
text-transform: uppercase;
|
||
}
|
||
.design-d .meta .dot { margin: 0 8px; opacity: 0.5; }
|
||
.design-d .actions {
|
||
display: flex; gap: 8px;
|
||
margin-top: auto;
|
||
}
|
||
.design-d .btn {
|
||
flex: 1;
|
||
border: none;
|
||
padding: 11px 12px;
|
||
font-family: inherit;
|
||
font-size: 11.5px;
|
||
font-weight: 600;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
cursor: pointer;
|
||
transition: all 0.15s ease;
|
||
border-radius: 2px;
|
||
}
|
||
.design-d .btn-primary {
|
||
background: var(--arrflix-red);
|
||
color: white;
|
||
box-shadow: 0 4px 14px rgba(229,9,20,0.3);
|
||
}
|
||
.design-d .btn-primary:hover { background: var(--arrflix-red-dark); }
|
||
.design-d .btn-secondary {
|
||
background: transparent;
|
||
color: var(--ink-dim);
|
||
border: 1px solid rgba(255,255,255,0.15);
|
||
}
|
||
.design-d .btn-secondary:hover {
|
||
color: var(--ink);
|
||
border-color: rgba(255,255,255,0.4);
|
||
}
|
||
|
||
/* hidden helper */
|
||
.hidden { display: none !important; }
|
||
|
||
/* design label */
|
||
.design-label {
|
||
position: absolute;
|
||
top: 24px; left: 28px;
|
||
z-index: 60;
|
||
font-family: 'Bebas Neue', sans-serif;
|
||
letter-spacing: 0.18em;
|
||
font-size: 13px;
|
||
color: rgba(255,255,255,0.5);
|
||
border-left: 2px solid var(--arrflix-red);
|
||
padding-left: 12px;
|
||
line-height: 1.4;
|
||
}
|
||
.design-label strong {
|
||
display: block;
|
||
color: white;
|
||
font-size: 18px;
|
||
letter-spacing: 0.1em;
|
||
}
|
||
.design-label .desc {
|
||
font-family: 'Geist', sans-serif;
|
||
font-size: 11px;
|
||
letter-spacing: 0.04em;
|
||
text-transform: none;
|
||
color: var(--ink-dim);
|
||
margin-top: 4px;
|
||
max-width: 300px;
|
||
}
|
||
|
||
.footer {
|
||
padding: 28px 56px 36px;
|
||
font-size: 12px;
|
||
color: var(--ink-faint);
|
||
letter-spacing: 0.04em;
|
||
line-height: 1.7;
|
||
border-top: 1px solid rgba(255,255,255,0.06);
|
||
}
|
||
.footer strong { color: var(--ink-dim); font-weight: 500; }
|
||
.footer kbd {
|
||
background: rgba(255,255,255,0.08);
|
||
border: 1px solid rgba(255,255,255,0.12);
|
||
border-radius: 3px;
|
||
padding: 2px 6px;
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-size: 11px;
|
||
color: var(--ink-dim);
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<header class="header">
|
||
<h1>ARRFLIX · NEXT-EPISODE POPUP</h1>
|
||
<div class="picker">
|
||
<button data-d="a" class="active">A · STRIP</button>
|
||
<button data-d="b">B · TERMINAL</button>
|
||
<button data-d="c">C · MINIMAL</button>
|
||
<button data-d="d">D · POSTER</button>
|
||
</div>
|
||
<div class="meta">PICK ONE · 2026-05-10</div>
|
||
</header>
|
||
|
||
<div class="stage">
|
||
<div class="stars"></div>
|
||
<div class="credits">
|
||
<div class="title-block" style="color:#4488dd; font-weight:600;">
|
||
Production Services Provided by CGCG, Inc.
|
||
</div>
|
||
<div class="row">
|
||
<div class="role">Lighting Director<br>Lighting Lead<br>Lighting Artists</div>
|
||
<div class="name">Chung-Kai Hsueh<br>Yin-Jung Huang<br>Jung-Tzu Chang · Po-Jui Chiu<br>Char Ho · Luna Jiang<br>Chuan-Sheng Lan · Po-Yu Li</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="role">Special Effects Director<br>Special Effects Artists</div>
|
||
<div class="name">Chia-Hung Chu<br>Jia-You Cai · Lin-Chi Chen<br>Cai-Jhu Li · Zhi-Hao Liu</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="role">Production Technology</div>
|
||
<div class="name">Indigo Tang · Joe Chang<br>I Chiang · Chih-Chiang Tsai</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="design-label" id="dlabel">
|
||
<strong>A · CINEMATIC STRIP</strong>
|
||
<div class="desc">Full-bleed bottom strip. Big countdown ring. White CTA = Netflix muscle memory. Grand.</div>
|
||
</div>
|
||
|
||
<div class="popup-host">
|
||
|
||
<!-- DESIGN A -->
|
||
<div class="design-a" data-design="a">
|
||
<div class="ring">
|
||
<svg width="88" height="88" viewBox="0 0 88 88">
|
||
<circle class="track" cx="44" cy="44" r="42"/>
|
||
<circle class="progress" cx="44" cy="44" r="42"/>
|
||
</svg>
|
||
<div class="num">17</div>
|
||
</div>
|
||
<div class="info">
|
||
<div class="label">Up Next</div>
|
||
<div class="title">Star Wars: Maul · Shadow Lord</div>
|
||
<div class="episode-title">S1·E3 — Chapter 3: The Crucible</div>
|
||
<div class="meta">22 min · Ends at 2:49 AM</div>
|
||
</div>
|
||
<div class="actions">
|
||
<button class="btn">▶ Start Now</button>
|
||
<button class="btn btn-secondary">Hide</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- DESIGN B -->
|
||
<div class="design-b hidden" data-design="b">
|
||
<div class="top-row">
|
||
<span class="tag">▎ Up Next</span>
|
||
<span class="countdown"><strong>17</strong>s</span>
|
||
</div>
|
||
<hr>
|
||
<div style="font-family:'Geist',sans-serif; font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 4px;">Star Wars: Maul · Shadow Lord · S1E3</div>
|
||
<div class="ep">Chapter 3: The Crucible</div>
|
||
<div class="ep-meta">22m / ends 02:49</div>
|
||
<div class="progress-bar"></div>
|
||
<div class="actions">
|
||
<button class="btn btn-primary">▶ Start now</button>
|
||
<button class="btn btn-secondary">Hide</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- DESIGN C -->
|
||
<div class="design-c hidden" data-design="c">
|
||
<div class="progress-line"></div>
|
||
<div class="row">
|
||
<div class="label">UP NEXT</div>
|
||
<div class="text">
|
||
<strong>Star Wars: Maul · Shadow Lord</strong>S1·E3 — Chapter 3: The Crucible
|
||
<span class="countdown">00:17</span>
|
||
</div>
|
||
<div class="actions">
|
||
<button class="btn btn-primary">Start now ▶</button>
|
||
<button class="btn">Hide</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- DESIGN D -->
|
||
<div class="design-d hidden" data-design="d">
|
||
<div class="poster"><div class="ep-num">E3</div></div>
|
||
<div class="body">
|
||
<div class="top">
|
||
<div class="label">Up Next</div>
|
||
<div class="timer">in <strong>17</strong>s</div>
|
||
</div>
|
||
<div class="show">Star Wars: Maul · Shadow Lord</div>
|
||
<div class="ep-title">Chapter 3: The Crucible</div>
|
||
<div class="meta">Season 1 <span class="dot">·</span> 22 min <span class="dot">·</span> Ends 02:49</div>
|
||
<div class="actions">
|
||
<button class="btn btn-primary">▶ Start now</button>
|
||
<button class="btn btn-secondary">Hide</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footer">
|
||
Pick one (<kbd>1</kbd>–<kbd>4</kbd> or click). When approved, design ships as a JS shim into <strong>web-overrides/index.html</strong> bracketed by <strong>NEXT-EP-POPUP-BEGIN/END</strong> markers, with one-shot revert via <strong>bin/revert-next-ep-popup.sh</strong> (matching the sub-label-shim pattern). The shim hides Jellyfin's stock card and renders the chosen design in its place when Jellyfin signals an upcoming episode.
|
||
</div>
|
||
|
||
<script>
|
||
const labels = {
|
||
a: ['A · CINEMATIC STRIP', 'Full-bleed bottom strip. Big countdown ring. White CTA = Netflix muscle memory. Grand.'],
|
||
b: ['B · TERMINAL CARD', 'Bottom-right card with monospace, dashed dividers, red accent line. Edgy, ARRFLIX-distinct.'],
|
||
c: ['C · MINIMAL BAR', 'Thin progress line + small text strip across bottom. Disappears into UX. Power-user.'],
|
||
d: ['D · POSTER CARD', 'Bottom-right card with episode-number tile + show + ep title + dual buttons. Polished, pragmatic.'],
|
||
};
|
||
const buttons = document.querySelectorAll('.picker button');
|
||
const designs = document.querySelectorAll('[data-design]');
|
||
const lbl = document.getElementById('dlabel');
|
||
function show(d) {
|
||
buttons.forEach(b => b.classList.toggle('active', b.dataset.d === d));
|
||
designs.forEach(el => el.classList.toggle('hidden', el.dataset.design !== d));
|
||
lbl.querySelector('strong').textContent = labels[d][0];
|
||
lbl.querySelector('.desc').textContent = labels[d][1];
|
||
// restart fillBar animations on switch (recreate elements)
|
||
designs.forEach(el => {
|
||
if (el.dataset.design === d) {
|
||
el.style.animation = 'none';
|
||
void el.offsetHeight;
|
||
el.style.animation = '';
|
||
}
|
||
});
|
||
}
|
||
buttons.forEach(b => b.addEventListener('click', () => show(b.dataset.d)));
|
||
document.addEventListener('keydown', (e) => {
|
||
const map = { '1':'a', '2':'b', '3':'c', '4':'d' };
|
||
if (map[e.key]) show(map[e.key]);
|
||
});
|
||
|
||
// animated countdown
|
||
let t = 17;
|
||
setInterval(() => {
|
||
t--;
|
||
if (t < 0) t = 17;
|
||
document.querySelector('.design-a .num').textContent = t;
|
||
document.querySelector('.design-a .ring .progress').style.strokeDashoffset = 67 + (264 - 67) * (1 - t/17);
|
||
document.querySelector('.design-b .top-row strong').textContent = t;
|
||
document.querySelector('.design-c .countdown').textContent = '00:' + String(t).padStart(2,'0');
|
||
document.querySelector('.design-d .timer strong').textContent = t;
|
||
}, 1000);
|
||
</script>
|
||
</body>
|
||
</html>
|