diff --git a/frontend/app/ops-redesign.css b/frontend/app/ops-redesign.css index aa244b3..5031909 100644 --- a/frontend/app/ops-redesign.css +++ b/frontend/app/ops-redesign.css @@ -4961,3 +4961,21 @@ textarea:focus { .request-release-profile-toggle input[type="checkbox"]:checked::before { transform: translateX(16px); background: #181529; } .request-release-profile-toggle input[type="checkbox"]:focus-visible { outline: 2px solid #c7bdff; outline-offset: 4px; } .request-release-profile-toggle input[type="checkbox"]:disabled { cursor: wait; opacity: 0.5; } + +/* Title artwork creates a cinematic opening while the pipeline stays readable. */ +.request-detail-page.request-cinematic { position: relative; isolation: isolate; background: transparent !important; } +.request-cinematic-art { position: absolute; z-index: -1; pointer-events: none; inset: -24px -24px auto; height: 850px; overflow: hidden; border-radius: 20px 20px 0 0; background: radial-gradient(ellipse at 75% 10%, #31334a, #121214 65%); } +.request-cinematic-art img { object-fit: cover; object-position: center top; } +.request-cinematic-art::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(10,11,16,.88), rgba(10,11,16,.18) 75%), linear-gradient(180deg, rgba(12,13,18,.1), rgba(18,18,20,.5) 38%, #121214 88%); } +.request-cinematic-title { min-height: 300px; display: flex; align-items: flex-end; padding: 28px 12px 16px; } +.request-cinematic-title .page-heading { width: 100%; border: 0; background: transparent; margin: 0; } +.request-cinematic-title .page-heading h1 { font-size: clamp(2rem, 4.5vw, 3.7rem); line-height: 1.08; max-width: 900px; text-wrap: balance; text-shadow: 0 2px 22px #0009; } +.request-cinematic-title .page-heading p { color: #e3e3ec; text-shadow: 0 1px 8px #000; } +.request-cinematic-title .request-poster { width: 100px; height: 150px; border-radius: 8px; box-shadow: 0 12px 36px #0008; } +.request-cinematic:not(.has-backdrop) .request-cinematic-title { min-height: 180px; } +@media (max-width: 640px) { + .request-cinematic-art { inset: -12px -12px auto; height: 650px; } + .request-cinematic-title { min-height: 240px; padding: 16px 0 8px; } + .request-cinematic-title .request-poster { width: 68px; height: 102px; } + .request-cinematic-title .page-heading h1 { font-size: clamp(1.8rem, 7vw, 2.5rem); } +} diff --git a/frontend/app/requests/[id]/page.tsx b/frontend/app/requests/[id]/page.tsx index 3320a44..92c83b2 100644 --- a/frontend/app/requests/[id]/page.tsx +++ b/frontend/app/requests/[id]/page.tsx @@ -552,6 +552,8 @@ export default function RequestTimelinePage() { .filter((action): action is RequestAction => Boolean(action)) const posterUrl = snapshot.artwork?.poster_url const resolvedPoster = posterUrl?.startsWith('http') ? posterUrl : posterUrl ? `${getApiBase()}${posterUrl}` : null + const backdropUrl = snapshot.artwork?.backdrop_url?.replace('https://image.tmdb.org/t/p/w780/', 'https://image.tmdb.org/t/p/w1280/') + const resolvedBackdrop = backdropUrl?.startsWith('http') ? backdropUrl : backdropUrl ? `${getApiBase()}${backdropUrl}` : null const trackedPost = async (label: string, url: string, init: RequestInit = {}) => { const operationId = typeof crypto?.randomUUID === 'function' @@ -768,7 +770,11 @@ export default function RequestTimelinePage() { } return ( -
+
+ +
} /> +
+ { setBusyAction('language') try {