164 lines
5.3 KiB
HTML
164 lines
5.3 KiB
HTML
<!--
|
||||
|
|
Layout: overlay — video full-bleed, glass card floats on bottom
|
|||
|
|
─────────────────────────────────────────────────────────────────────
|
|||
|
|
Implementation: card.zone = "video-overlay" + leave #video-wrap at
|
|||
|
|
full-bleed (no tween needed if it starts full-bleed). The "card" is
|
|||
|
|
positioned by CSS inside the video-overlay zone's full-canvas wrapper.
|
|||
|
|
|
|||
|
|
Recommended storyboard.json card entry (strict v3):
|
|||
|
|
{
|
|||
|
|
"id": "card-XX",
|
|||
|
|
"intent": "cinematic / dramatic moment with glass overlay",
|
|||
|
|
"startSec": 8, "endSec": 14,
|
|||
|
|
"accentIndex": 0,
|
|||
|
|
"zone": "video-overlay",
|
|||
|
|
"contentHints": { "kicker": "...", "title": "...", "detail": "..." }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
GSAP target for #video-wrap (full-bleed — usually unchanged):
|
|||
|
|
tl.to('#video-wrap',
|
|||
|
|
{ left: 0, top: 0, width: COMPOSITION_W, height: COMPOSITION_H,
|
|||
|
|
duration: 0.6, ease: 'power2.inOut' }, START_SEC);
|
|||
|
|
// Use defaults: landscape 1920×1080 / portrait 1080×1920 / 4:5 1080×1350
|
|||
|
|
|
|||
|
|
Recommended card-host inline style (since zone="video-overlay" gives
|
|||
|
|
full-canvas bounds, you typically inset the actual card visual via CSS):
|
|||
|
|
|
|||
|
|
landscape glass card, mid-left:
|
|||
|
|
.card[data-card-id="X"] .root {
|
|||
|
|
position: absolute; left: 48px; top: 460px;
|
|||
|
|
width: 660px; height: 540px;
|
|||
|
|
background: rgba(15,16,22,.78);
|
|||
|
|
backdrop-filter: blur(22px) saturate(140%);
|
|||
|
|
-webkit-backdrop-filter: blur(22px) saturate(140%);
|
|||
|
|
border-radius: 18px;
|
|||
|
|
box-shadow: 0 30px 80px -20px rgba(0,0,0,.45);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
portrait glass card, bottom band:
|
|||
|
|
.card[data-card-id="X"] .root {
|
|||
|
|
position: absolute; left: 24px; top: 1280px;
|
|||
|
|
width: 1032px; height: 564px;
|
|||
|
|
/* same glass treatment */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
4:5 glass card (y/h × 0.703):
|
|||
|
|
.card[data-card-id="X"] .root {
|
|||
|
|
position: absolute; left: 24px; top: 900px;
|
|||
|
|
width: 1032px; height: 397px;
|
|||
|
|
/* same glass treatment */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Legibility gradient (insert as a third absolute layer between video
|
|||
|
|
and card-host, in the composition's <div id="stage">):
|
|||
|
|
|
|||
|
|
<div class="legibility"></div>
|
|||
|
|
|
|||
|
|
.legibility {
|
|||
|
|
position: absolute; inset: 0; pointer-events: none; z-index: 2;
|
|||
|
|
background:
|
|||
|
|
linear-gradient(180deg, rgba(0,0,0,.55) 0%, transparent 22%,
|
|||
|
|
transparent 50%, rgba(0,0,0,.72) 100%);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Notes
|
|||
|
|
- Card root MUST be transparent or use rgba/glass background — see
|
|||
|
|
Pattern A in SKILL.md "Transparent card backgrounds".
|
|||
|
|
- Glass without legibility gradient = white-on-white catastrophe over
|
|||
|
|
bright video. Always pair them.
|
|||
|
|
- Glass on a light video also benefits from a darker base color (use
|
|||
|
|
rgba(15,16,22,.78) over rgba(255,255,255,.10) when source has bright
|
|||
|
|
daylight / interior shots).
|
|||
|
|
-->
|
|||
|
|
<!doctype html>
|
|||
|
|
<html lang="zh-CN">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="utf-8" />
|
|||
|
|
<title>layout · overlay (video full-bleed, glass card)</title>
|
|||
|
|
<style>
|
|||
|
|
html,
|
|||
|
|
body {
|
|||
|
|
margin: 0;
|
|||
|
|
padding: 0;
|
|||
|
|
background: #0a0c12;
|
|||
|
|
color: #fff;
|
|||
|
|
font-family: ui-sans-serif, system-ui, sans-serif;
|
|||
|
|
}
|
|||
|
|
.stage {
|
|||
|
|
position: relative;
|
|||
|
|
width: 1920px;
|
|||
|
|
height: 1080px;
|
|||
|
|
transform-origin: top left;
|
|||
|
|
transform: scale(0.5);
|
|||
|
|
background: #0a0c12;
|
|||
|
|
overflow: hidden;
|
|||
|
|
}
|
|||
|
|
.video-region {
|
|||
|
|
position: absolute;
|
|||
|
|
left: 0;
|
|||
|
|
top: 0;
|
|||
|
|
width: 1920px;
|
|||
|
|
height: 1080px;
|
|||
|
|
background: #1a1f2e;
|
|||
|
|
background-image: repeating-linear-gradient(
|
|||
|
|
45deg,
|
|||
|
|
transparent 0 12px,
|
|||
|
|
rgba(255, 255, 255, 0.05) 12px 13px
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
.gradient {
|
|||
|
|
position: absolute;
|
|||
|
|
inset: 0;
|
|||
|
|
pointer-events: none;
|
|||
|
|
background:
|
|||
|
|
linear-gradient(135deg, rgba(0, 0, 0, 0.55) 0%, transparent 35%),
|
|||
|
|
linear-gradient(180deg, transparent 50%, rgba(0, 0, 0, 0.55) 100%);
|
|||
|
|
}
|
|||
|
|
.card-region {
|
|||
|
|
position: absolute;
|
|||
|
|
left: 48px;
|
|||
|
|
top: 460px;
|
|||
|
|
width: 660px;
|
|||
|
|
height: 540px;
|
|||
|
|
background: rgba(255, 255, 255, 0.1);
|
|||
|
|
backdrop-filter: blur(18px) saturate(140%);
|
|||
|
|
-webkit-backdrop-filter: blur(18px) saturate(140%);
|
|||
|
|
border-radius: 18px;
|
|||
|
|
box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.45);
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
color: #fff;
|
|||
|
|
font:
|
|||
|
|
600 24px/1.3 ui-monospace,
|
|||
|
|
monospace;
|
|||
|
|
letter-spacing: 0.12em;
|
|||
|
|
}
|
|||
|
|
.label {
|
|||
|
|
padding: 12px 18px;
|
|||
|
|
border: 1.5px solid rgba(255, 255, 255, 0.7);
|
|||
|
|
border-radius: 4px;
|
|||
|
|
}
|
|||
|
|
.v-label {
|
|||
|
|
position: absolute;
|
|||
|
|
left: 28px;
|
|||
|
|
top: 28px;
|
|||
|
|
color: rgba(255, 255, 255, 0.55);
|
|||
|
|
padding: 8px 14px;
|
|||
|
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|||
|
|
border-radius: 3px;
|
|||
|
|
font:
|
|||
|
|
600 16px/1 ui-monospace,
|
|||
|
|
monospace;
|
|||
|
|
letter-spacing: 0.14em;
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div class="stage">
|
|||
|
|
<div class="video-region"><span class="v-label">VIDEO · 1920×1080 (full-bleed)</span></div>
|
|||
|
|
<div class="gradient"></div>
|
|||
|
|
<div class="card-region"><span class="label">CARD · 660×540 glass</span></div>
|
|||
|
|
</div>
|
|||
|
|
</body>
|
|||
|
|
</html>
|