Add device animation functionality to platform row and enhance CSS for visual effects

This commit is contained in:
Matt Batchelder
2026-02-21 01:33:52 -05:00
parent 3100a93d9a
commit 618ba6ded4
4 changed files with 420 additions and 1 deletions

View File

@@ -1984,6 +1984,348 @@ p:last-child { margin-bottom: 0; }
.platform-row.reverse .platform-visual { order: unset; }
}
/* ── 10b. Device Animator ───────────────────────────────────── */
.platform-visual.has-anim {
padding: 0;
overflow: hidden;
position: relative;
font-size: inherit;
}
.da-stage {
position: absolute;
inset: 0;
}
/* Each device panel hidden by default, centred in stage */
.da-device {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0.88);
opacity: 0;
display: flex;
flex-direction: column;
align-items: center;
transition: opacity 0.55s cubic-bezier(0.4,0,0.2,1),
transform 0.55s cubic-bezier(0.4,0,0.2,1);
will-change: opacity, transform;
}
.da-device.is-active {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
.da-device.is-leaving {
opacity: 0;
transform: translate(-50%, -50%) scale(1.07);
}
/* Screen surface */
.da-screen {
width: 100%;
height: 100%;
border-radius: 2px;
position: relative;
overflow: hidden;
background:
repeating-linear-gradient(
180deg,
transparent,
transparent 3px,
rgba(0,0,0,0.10) 3px,
rgba(0,0,0,0.10) 4px
),
linear-gradient(135deg, #0c1016 0%, #151c28 60%, #0c1016 100%);
}
.da-screen::before {
content: '';
position: absolute;
top: -20%;
left: -10%;
width: 60%;
height: 60%;
background: radial-gradient(ellipse, rgba(74,222,128,0.12) 0%, transparent 70%);
pointer-events: none;
}
@keyframes da-scan {
0% { top: -6%; opacity: 0; }
5% { opacity: 1; }
95% { opacity: 1; }
100% { top: 106%; opacity: 0; }
}
.da-screen::after {
content: '';
position: absolute;
left: 0;
width: 100%;
height: 3px;
background: linear-gradient(90deg, transparent, rgba(74,222,128,0.28), transparent);
animation: da-scan 3s linear infinite;
pointer-events: none;
}
/* Device label */
.da-label {
display: block;
margin-top: 11px;
font-size: 0.68rem;
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--color-text-muted);
text-align: center;
}
/* ── Tablet ────────────────────────────────────── */
.da-tablet .da-body {
width: 128px;
height: 194px;
background: var(--color-bg-alt);
border: 2px solid var(--color-border);
border-radius: 14px;
padding: 10px 8px 14px;
display: flex;
align-items: stretch;
position: relative;
box-shadow: 0 16px 48px rgba(0,0,0,0.50);
}
.da-tablet .da-body::before {
content: '';
position: absolute;
top: 5px;
left: 50%;
transform: translateX(-50%);
width: 6px;
height: 6px;
background: var(--color-border);
border-radius: 50%;
}
.da-tablet .da-body::after {
content: '';
position: absolute;
bottom: 5px;
left: 50%;
transform: translateX(-50%);
width: 36px;
height: 3px;
background: var(--color-border);
border-radius: 2px;
}
/* ── Small Monitor ─────────────────────────────── */
.da-monitor-sm .da-body {
width: 236px;
height: 146px;
background: var(--color-bg-alt);
border: 5px solid var(--color-bg-alt);
border-radius: 6px;
outline: 1px solid var(--color-border);
padding: 3px;
display: flex;
align-items: stretch;
position: relative;
box-shadow: 0 10px 36px rgba(0,0,0,0.50);
}
.da-monitor-sm .da-body::after {
content: '';
position: absolute;
bottom: -9px;
right: 8px;
width: 5px;
height: 5px;
background: var(--color-primary);
border-radius: 50%;
box-shadow: 0 0 5px var(--color-primary);
}
.da-monitor-sm .da-stand,
.da-monitor-lg .da-stand { display: flex; flex-direction: column; align-items: center; }
.da-monitor-sm .da-stem {
width: 14px;
height: 20px;
background: var(--color-bg-alt);
border-left: 1px solid var(--color-border);
border-right: 1px solid var(--color-border);
}
.da-monitor-sm .da-base {
width: 68px;
height: 5px;
background: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: 3px;
}
/* ── Large Monitor ─────────────────────────────── */
.da-monitor-lg .da-body {
width: 298px;
height: 177px;
background: var(--color-bg-alt);
border: 4px solid var(--color-bg-alt);
border-radius: 6px;
outline: 1px solid var(--color-border);
padding: 3px;
display: flex;
align-items: stretch;
position: relative;
box-shadow: 0 12px 40px rgba(0,0,0,0.50);
}
.da-monitor-lg .da-stem {
width: 16px;
height: 26px;
background: var(--color-bg-alt);
border-left: 1px solid var(--color-border);
border-right: 1px solid var(--color-border);
}
.da-monitor-lg .da-base {
width: 88px;
height: 5px;
background: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: 3px;
}
/* ── TV ────────────────────────────────────────── */
.da-tv .da-body {
width: 320px;
height: 188px;
background: var(--color-bg-alt);
border: 4px solid var(--color-bg-alt);
border-radius: 6px 6px 4px 4px;
outline: 1px solid var(--color-border);
padding: 3px;
display: flex;
align-items: stretch;
position: relative;
box-shadow: 0 14px 48px rgba(0,0,0,0.55);
}
.da-tv .da-body::after {
content: '\25B6';
position: absolute;
bottom: -13px;
left: 50%;
transform: translateX(-50%);
font-size: 8px;
color: rgba(74,222,128,0.7);
}
.da-tv .da-feet { display: flex; justify-content: space-between; width: 180px; }
.da-tv .da-foot {
width: 12px;
height: 8px;
background: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: 0 0 4px 4px;
}
/* ── Projector ─────────────────────────────────── */
.da-projector .da-proj-layout { display: flex; flex-direction: column; align-items: center; }
.da-projector .da-proj-body {
width: 156px;
height: 62px;
background: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: 10px 10px 8px 8px;
display: flex;
align-items: center;
padding: 0 14px;
gap: 10px;
box-shadow: 0 6px 20px rgba(0,0,0,0.45);
position: relative;
}
.da-projector .da-proj-body::after {
content: '';
position: absolute;
top: 8px;
right: 10px;
width: 7px;
height: 7px;
background: var(--color-primary);
border-radius: 50%;
box-shadow: 0 0 6px var(--color-primary);
}
.da-projector .da-proj-body::before {
content: '';
position: absolute;
right: 10px;
bottom: 8px;
width: 28px;
height: 8px;
background: repeating-linear-gradient(
90deg,
var(--color-border) 0px,
var(--color-border) 2px,
transparent 2px,
transparent 5px
);
border-radius: 1px;
}
.da-projector .da-lens {
width: 38px;
height: 38px;
background: #080c12;
border: 2px solid var(--color-border);
border-radius: 50%;
flex-shrink: 0;
position: relative;
box-shadow: inset 0 0 8px rgba(0,0,0,0.8);
}
.da-projector .da-lens::after {
content: '';
position: absolute;
inset: 5px;
background: radial-gradient(circle at 35% 35%, rgba(74,222,128,0.30) 0%, #080c12 65%);
border-radius: 50%;
}
.da-projector .da-beam {
width: 240px;
height: 50px;
clip-path: polygon(31% 0%, 69% 0%, 100% 100%, 0% 100%);
background: linear-gradient(
180deg,
rgba(74,222,128,0.07) 0%,
rgba(74,222,128,0.02) 100%
);
}
.da-projector .da-proj-screen {
width: 240px;
height: 72px;
background: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: 3px;
overflow: hidden;
padding: 3px;
box-shadow: 0 4px 14px rgba(0,0,0,0.40);
}
/* ── Video Wall (2×2) ──────────────────────────── */
.da-vwall .da-vwall-grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 5px;
background: #0a0d12;
padding: 5px;
border: 1px solid var(--color-border);
border-radius: 4px;
box-shadow: 0 14px 48px rgba(0,0,0,0.60);
}
.da-vwall .da-panel {
width: 148px;
height: 90px;
background: var(--color-bg-alt);
border: 2px solid var(--color-bg-alt);
padding: 2px;
display: flex;
align-items: stretch;
overflow: hidden;
}
.da-vwall .da-panel:nth-child(2) .da-screen::after { animation-delay: -0.75s; }
.da-vwall .da-panel:nth-child(3) .da-screen::after { animation-delay: -1.5s; }
.da-vwall .da-panel:nth-child(4) .da-screen::after { animation-delay: -2.25s; }
/* ── Responsive scale-down ─────────────────────── */
@media (max-width: 900px) {
.da-device { transform: translate(-50%,-50%) scale(0.76); }
.da-device.is-active { transform: translate(-50%,-50%) scale(0.84); }
.da-device.is-leaving { transform: translate(-50%,-50%) scale(0.91); }
}
@media (max-width: 640px) {
.da-device { transform: translate(-50%,-50%) scale(0.56); }
.da-device.is-active { transform: translate(-50%,-50%) scale(0.64); }
.da-device.is-leaving { transform: translate(-50%,-50%) scale(0.70); }
}
@media (prefers-reduced-motion: reduce) {
.da-device { transition: none; }
.da-screen::after { animation: none; }
}
/* ── 11. Page Hero (inner pages) ───────────────────────────── */
.page-hero {
background: #111111;