Migrate live changes from facere-website and add deploy configs
Bring in the newer app.jsx/styles.css/facere.html that were edited directly on the deployed copy, rename Facere.html -> facere.html to match the nginx index, and check in the docker-compose + nginx.conf that drives the container. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
74
app.jsx
74
app.jsx
@@ -151,7 +151,7 @@ function PixelLogoStatic({ word, scale, gap, color }) {
|
|||||||
Each puff is a chunky, low-res-feeling translucent disc that drifts up + fades. */
|
Each puff is a chunky, low-res-feeling translucent disc that drifts up + fades. */
|
||||||
function SmokeLayer({ chimneys, scale = 1, intensity = 1 }) {
|
function SmokeLayer({ chimneys, scale = 1, intensity = 1 }) {
|
||||||
// Each chimney emits N puffs on staggered phases.
|
// Each chimney emits N puffs on staggered phases.
|
||||||
const PUFFS_PER = 5;
|
const PUFFS_PER = 3;
|
||||||
const puffs = [];
|
const puffs = [];
|
||||||
chimneys.forEach((ch, ci) => {
|
chimneys.forEach((ch, ci) => {
|
||||||
for (let p = 0; p < PUFFS_PER; p++) {
|
for (let p = 0; p < PUFFS_PER; p++) {
|
||||||
@@ -312,27 +312,29 @@ function HeroSection({ bgRef, contentRef }) {
|
|||||||
// Smaller stacks at 71%, 80%, 85.5%.
|
// Smaller stacks at 71%, 80%, 85.5%.
|
||||||
// Image 1: assets/exterior-factory.png
|
// Image 1: assets/exterior-factory.png
|
||||||
const chimneys = [
|
const chimneys = [
|
||||||
{ x: 77.5, y: 51.0, size: 22, dur: 7.2, drift: -0.3 },
|
{ x: 71.5, y: 51.0, size: 22, dur: 7.2, drift: -0.3 },
|
||||||
{ x: 80.5, y: 49.5, size: 32, dur: 8.0, drift: -0.4 },
|
{ x: 74.5, y: 49.5, size: 32, dur: 8.0, drift: -0.4 },
|
||||||
{ x: 84.5, y: 50.4, size: 30, dur: 7.6, drift: 0.2 },
|
{ x: 78.5, y: 50.4, size: 30, dur: 7.6, drift: 0.2 },
|
||||||
{ x: 86.5, y: 51.0, size: 22, dur: 7.0, drift: 0.3 },
|
{ x: 80.5, y: 51.0, size: 22, dur: 7.0, drift: 0.3 },
|
||||||
{ x: 89.5, y: 49.8, size: 32, dur: 8.2, drift: -0.2 },
|
{ x: 83.5, y: 49.8, size: 32, dur: 8.2, drift: -0.2 },
|
||||||
{ x: 92.0, y: 51.4, size: 22, dur: 7.4, drift: 0.4 },
|
{ x: 86.0, y: 51.4, size: 22, dur: 7.4, drift: 0.4 },
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="scene scene-hero" data-screen-label="01 Hero">
|
<section className="scene scene-hero" data-screen-label="01 Hero">
|
||||||
<div className="bg-wrap" ref={bgRef}>
|
<div className="bg-wrap" ref={bgRef}>
|
||||||
{/* Image 1 — exterior factory */}
|
<div className="image-frame">
|
||||||
<div
|
{/* Image 1 — exterior factory */}
|
||||||
className="bg-image"
|
<div
|
||||||
style={{ backgroundImage: "url(assets/exterior-factory.png)" }}
|
className="bg-image"
|
||||||
/>
|
style={{ backgroundImage: "url(assets/exterior-factory.png)" }}
|
||||||
<SmokeLayer chimneys={chimneys} />
|
/>
|
||||||
<EmberLayer
|
<SmokeLayer chimneys={chimneys} />
|
||||||
count={22}
|
<EmberLayer
|
||||||
area={{ x: 32, y: 48, w: 65, h: 8 }}
|
count={22}
|
||||||
/>
|
area={{ x: 32, y: 48, w: 65, h: 8 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="vignette" />
|
<div className="vignette" />
|
||||||
<div className="haze" />
|
<div className="haze" />
|
||||||
</div>
|
</div>
|
||||||
@@ -357,17 +359,19 @@ function ProductSection({ bgRef, contentRef }) {
|
|||||||
return (
|
return (
|
||||||
<section className="scene scene-product" data-screen-label="02 Product">
|
<section className="scene scene-product" data-screen-label="02 Product">
|
||||||
<div className="bg-wrap" ref={bgRef}>
|
<div className="bg-wrap" ref={bgRef}>
|
||||||
{/* Image 2 — factory interior / assembly line */}
|
<div className="image-frame">
|
||||||
<div
|
{/* Image 2 — factory interior / assembly line */}
|
||||||
className="bg-image"
|
<div
|
||||||
style={{ backgroundImage: "url(assets/factory-interior.png)" }}
|
className="bg-image"
|
||||||
/>
|
style={{ backgroundImage: "url(assets/factory-interior.png)" }}
|
||||||
{/* Robotic arm idle motion: anchored to where the arms sit in the image */}
|
/>
|
||||||
<div className="arm-pivot arm-left" />
|
{/* Robotic arm idle motion: anchored to where the arms sit in the image */}
|
||||||
<div className="arm-pivot arm-right" />
|
<div className="arm-pivot arm-left" />
|
||||||
<SparkLayer />
|
<div className="arm-pivot arm-right" />
|
||||||
{/* Conveyor pulse strip */}
|
<SparkLayer />
|
||||||
<div className="conveyor-pulse" />
|
{/* Conveyor pulse strip */}
|
||||||
|
<div className="conveyor-pulse" />
|
||||||
|
</div>
|
||||||
<div className="vignette product-vignette" />
|
<div className="vignette product-vignette" />
|
||||||
<div className="haze" />
|
<div className="haze" />
|
||||||
</div>
|
</div>
|
||||||
@@ -409,12 +413,14 @@ function InstallSection({ bgRef, contentRef }) {
|
|||||||
return (
|
return (
|
||||||
<section className="scene scene-install" data-screen-label="03 Install">
|
<section className="scene scene-install" data-screen-label="03 Install">
|
||||||
<div className="bg-wrap" ref={bgRef}>
|
<div className="bg-wrap" ref={bgRef}>
|
||||||
{/* Image 3 — PCB / chip */}
|
<div className="image-frame">
|
||||||
<div
|
{/* Image 3 — PCB / chip */}
|
||||||
className="bg-image"
|
<div
|
||||||
style={{ backgroundImage: "url(assets/pcb-chip.png)" }}
|
className="bg-image"
|
||||||
/>
|
style={{ backgroundImage: "url(assets/pcb-chip.png)" }}
|
||||||
<ChipPulses />
|
/>
|
||||||
|
<ChipPulses />
|
||||||
|
</div>
|
||||||
<div className="vignette" />
|
<div className="vignette" />
|
||||||
<div className="haze haze-deep" />
|
<div className="haze haze-deep" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
10
deploy/docker-compose.yml
Normal file
10
deploy/docker-compose.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
services:
|
||||||
|
facere-web:
|
||||||
|
image: nginx:1.27-alpine
|
||||||
|
container_name: facere-web
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "9527:80"
|
||||||
|
volumes:
|
||||||
|
- ../:/usr/share/nginx/html:ro
|
||||||
|
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
39
deploy/nginx.conf
Normal file
39
deploy/nginx.conf
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name web.facere.cc _;
|
||||||
|
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index facere.html index.html;
|
||||||
|
|
||||||
|
charset utf-8;
|
||||||
|
|
||||||
|
location = / {
|
||||||
|
try_files /facere.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /facere.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# CSS/JS/JSX: short cache so future deploys are picked up promptly
|
||||||
|
location ~* \.(?:css|js|jsx)$ {
|
||||||
|
expires 5m;
|
||||||
|
add_header Cache-Control "public, max-age=300, must-revalidate";
|
||||||
|
types { text/css css; application/javascript js; application/javascript jsx; }
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Static media: long cache (filenames are stable / change when content changes)
|
||||||
|
location ~* \.(?:png|jpe?g|gif|webp|svg|mp4|webm|woff2?|ttf|otf|ico)$ {
|
||||||
|
expires 7d;
|
||||||
|
add_header Cache-Control "public, max-age=604800";
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
|
||||||
|
gzip_min_length 1024;
|
||||||
|
|
||||||
|
access_log /var/log/nginx/facere.access.log;
|
||||||
|
error_log /var/log/nginx/facere.error.log;
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@300;400;500;600&family=VT323&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@300;400;500;600&family=VT323&display=swap" rel="stylesheet" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles.css" />
|
<link rel="stylesheet" href="styles.css?v=20260502b" />
|
||||||
|
|
||||||
<!-- Preload background images -->
|
<!-- Preload background images -->
|
||||||
<link rel="preload" as="image" href="assets/exterior-factory.png" />
|
<link rel="preload" as="image" href="assets/exterior-factory.png" />
|
||||||
@@ -28,6 +28,6 @@
|
|||||||
<script src="https://unpkg.com/gsap@3.12.5/dist/gsap.min.js"></script>
|
<script src="https://unpkg.com/gsap@3.12.5/dist/gsap.min.js"></script>
|
||||||
<script src="https://unpkg.com/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>
|
<script src="https://unpkg.com/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>
|
||||||
|
|
||||||
<script type="text/babel" src="app.jsx"></script>
|
<script type="text/babel" src="app.jsx?v=20260502b"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
160
styles.css
160
styles.css
@@ -41,7 +41,14 @@ a { color: inherit; text-decoration: none; }
|
|||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
}
|
}
|
||||||
.scene-stack { position: absolute; inset: 0; }
|
.scene-stack { position: absolute; inset: 0; }
|
||||||
.scene-slot { position: absolute; inset: 0; }
|
.scene-slot {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
will-change: opacity;
|
||||||
|
transform: translateZ(0);
|
||||||
|
backface-visibility: hidden;
|
||||||
|
contain: layout paint;
|
||||||
|
}
|
||||||
|
|
||||||
.scene {
|
.scene {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -58,14 +65,29 @@ a { color: inherit; text-decoration: none; }
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transform-origin: 65% 50%;
|
transform-origin: 65% 50%;
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
|
transform: translateZ(0);
|
||||||
}
|
}
|
||||||
.scene-product .bg-wrap { transform-origin: 50% 60%; }
|
.scene-product .bg-wrap { transform-origin: 50% 60%; }
|
||||||
.scene-install .bg-wrap { transform-origin: 78% 50%; }
|
.scene-install .bg-wrap { transform-origin: 78% 50%; }
|
||||||
|
|
||||||
|
/* Image-aspect frame: replicates `background-size: cover` geometry as an
|
||||||
|
actual box, so any %-positioned overlay (smoke, sparks, chip pulses…)
|
||||||
|
stays locked to the image content regardless of viewport aspect.
|
||||||
|
Uses vw/vh because the bg-wrap is always 100vw × 100vh of the stage. */
|
||||||
|
.image-frame {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) translateZ(0);
|
||||||
|
aspect-ratio: 1672 / 941;
|
||||||
|
width: max(100vw, calc(100vh * 1672 / 941));
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
|
|
||||||
.bg-image {
|
.bg-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background-size: cover;
|
background-size: 100% 100%;
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
/* Crisp pixel-art feel without softening the source */
|
/* Crisp pixel-art feel without softening the source */
|
||||||
@@ -159,63 +181,63 @@ a { color: inherit; text-decoration: none; }
|
|||||||
mix-blend-mode: screen;
|
mix-blend-mode: screen;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
.ghost-r { animation: glitch-r 3.0s steps(1) infinite; }
|
.ghost-r { animation: glitch-r 12s steps(1) infinite; }
|
||||||
.ghost-c { animation: glitch-c 3.0s steps(1) infinite; }
|
.ghost-c { animation: glitch-c 12s steps(1) infinite; }
|
||||||
|
|
||||||
/* Many-band signal breakage. Multiple bursts per cycle, each band offset
|
/* Many-band signal breakage. Multiple bursts per cycle, each band offset
|
||||||
independently from the others. Some frames near-fully corrupt. */
|
independently from the others. Some frames near-fully corrupt. */
|
||||||
@keyframes glitch-r {
|
@keyframes glitch-r {
|
||||||
0%, 6% { opacity: 0; transform: translate(0, 0); clip-path: none; }
|
0%, 6% { opacity: 0; transform: translate(0, 0); clip-path: none; }
|
||||||
8% { opacity: 0.9; transform: translate(40px, 0); clip-path: inset(5% 0 78% 0); }
|
8% { opacity: 0.9; transform: translate(8px, 0); clip-path: inset(5% 0 78% 0); }
|
||||||
9% { opacity: 0.7; transform: translate(-20px, 0); clip-path: inset(15% 0 70% 0); }
|
9% { opacity: 0.7; transform: translate(-4px, 0); clip-path: inset(15% 0 70% 0); }
|
||||||
10% { opacity: 0; }
|
10% { opacity: 0; }
|
||||||
18% { opacity: 0.85; transform: translate(55px, 0); clip-path: inset(28% 0 58% 0); }
|
18% { opacity: 0.85; transform: translate(11px, 0); clip-path: inset(28% 0 58% 0); }
|
||||||
19% { opacity: 0; }
|
19% { opacity: 0; }
|
||||||
24% { opacity: 0.7; transform: translate(-35px, 0); clip-path: inset(48% 0 38% 0); }
|
24% { opacity: 0.7; transform: translate(-7px, 0); clip-path: inset(48% 0 38% 0); }
|
||||||
25% { opacity: 0.5; transform: translate(15px, 0); clip-path: inset(52% 0 36% 0); }
|
25% { opacity: 0.5; transform: translate(3px, 0); clip-path: inset(52% 0 36% 0); }
|
||||||
26% { opacity: 0; }
|
26% { opacity: 0; }
|
||||||
/* small quiet patch */
|
/* small quiet patch */
|
||||||
36% { opacity: 0.65; transform: translate(25px, 0); clip-path: inset(62% 0 24% 0); }
|
36% { opacity: 0.65; transform: translate(5px, 0); clip-path: inset(62% 0 24% 0); }
|
||||||
37% { opacity: 0; }
|
37% { opacity: 0; }
|
||||||
44% { opacity: 0.95; transform: translate(-45px, 0); clip-path: inset(72% 0 14% 0); }
|
44% { opacity: 0.95; transform: translate(-9px, 0); clip-path: inset(72% 0 14% 0); }
|
||||||
45% { opacity: 0.6; transform: translate(20px, 0); clip-path: inset(78% 0 8% 0); }
|
45% { opacity: 0.6; transform: translate(4px, 0); clip-path: inset(78% 0 8% 0); }
|
||||||
46% { opacity: 0; }
|
46% { opacity: 0; }
|
||||||
56% { opacity: 0.55; transform: translate(10px, 0); clip-path: inset(18% 0 70% 0); }
|
56% { opacity: 0.55; transform: translate(2px, 0); clip-path: inset(18% 0 70% 0); }
|
||||||
57% { opacity: 0; }
|
57% { opacity: 0; }
|
||||||
64% { opacity: 0.9; transform: translate(-50px, 0); clip-path: inset(35% 0 50% 0); }
|
64% { opacity: 0.9; transform: translate(-10px, 0); clip-path: inset(35% 0 50% 0); }
|
||||||
65% { opacity: 0; }
|
65% { opacity: 0; }
|
||||||
72% { opacity: 0.7; transform: translate(30px, 0); clip-path: inset(58% 0 30% 0); }
|
72% { opacity: 0.7; transform: translate(6px, 0); clip-path: inset(58% 0 30% 0); }
|
||||||
73% { opacity: 0; }
|
73% { opacity: 0; }
|
||||||
/* full corruption flash */
|
/* full corruption flash */
|
||||||
82% { opacity: 0.85; transform: translate(35px, 0); clip-path: none; }
|
82% { opacity: 0.85; transform: translate(7px, 0); clip-path: none; }
|
||||||
83% { opacity: 0; }
|
83% { opacity: 0; }
|
||||||
90% { opacity: 0.6; transform: translate(-15px, 0); clip-path: inset(68% 0 22% 0); }
|
90% { opacity: 0.6; transform: translate(-3px, 0); clip-path: inset(68% 0 22% 0); }
|
||||||
91%, 100% { opacity: 0; transform: translate(0, 0); clip-path: none; }
|
91%, 100% { opacity: 0; transform: translate(0, 0); clip-path: none; }
|
||||||
}
|
}
|
||||||
@keyframes glitch-c {
|
@keyframes glitch-c {
|
||||||
0%, 6% { opacity: 0; transform: translate(0, 0); clip-path: none; }
|
0%, 6% { opacity: 0; transform: translate(0, 0); clip-path: none; }
|
||||||
8% { opacity: 0.85; transform: translate(-40px, 0); clip-path: inset(5% 0 78% 0); }
|
8% { opacity: 0.85; transform: translate(-8px, 0); clip-path: inset(5% 0 78% 0); }
|
||||||
9% { opacity: 0.65; transform: translate(20px, 0); clip-path: inset(15% 0 70% 0); }
|
9% { opacity: 0.65; transform: translate(4px, 0); clip-path: inset(15% 0 70% 0); }
|
||||||
10% { opacity: 0; }
|
10% { opacity: 0; }
|
||||||
18% { opacity: 0.8; transform: translate(-55px, 0); clip-path: inset(28% 0 58% 0); }
|
18% { opacity: 0.8; transform: translate(-11px, 0); clip-path: inset(28% 0 58% 0); }
|
||||||
19% { opacity: 0; }
|
19% { opacity: 0; }
|
||||||
24% { opacity: 0.65; transform: translate(35px, 0); clip-path: inset(48% 0 38% 0); }
|
24% { opacity: 0.65; transform: translate(7px, 0); clip-path: inset(48% 0 38% 0); }
|
||||||
25% { opacity: 0.45; transform: translate(-15px, 0); clip-path: inset(52% 0 36% 0); }
|
25% { opacity: 0.45; transform: translate(-3px, 0); clip-path: inset(52% 0 36% 0); }
|
||||||
26% { opacity: 0; }
|
26% { opacity: 0; }
|
||||||
36% { opacity: 0.6; transform: translate(-25px, 0); clip-path: inset(62% 0 24% 0); }
|
36% { opacity: 0.6; transform: translate(-5px, 0); clip-path: inset(62% 0 24% 0); }
|
||||||
37% { opacity: 0; }
|
37% { opacity: 0; }
|
||||||
44% { opacity: 0.9; transform: translate(45px, 0); clip-path: inset(72% 0 14% 0); }
|
44% { opacity: 0.9; transform: translate(9px, 0); clip-path: inset(72% 0 14% 0); }
|
||||||
45% { opacity: 0.55; transform: translate(-20px, 0); clip-path: inset(78% 0 8% 0); }
|
45% { opacity: 0.55; transform: translate(-4px, 0); clip-path: inset(78% 0 8% 0); }
|
||||||
46% { opacity: 0; }
|
46% { opacity: 0; }
|
||||||
56% { opacity: 0.5; transform: translate(-10px, 0); clip-path: inset(18% 0 70% 0); }
|
56% { opacity: 0.5; transform: translate(-2px, 0); clip-path: inset(18% 0 70% 0); }
|
||||||
57% { opacity: 0; }
|
57% { opacity: 0; }
|
||||||
64% { opacity: 0.85; transform: translate(50px, 0); clip-path: inset(35% 0 50% 0); }
|
64% { opacity: 0.85; transform: translate(10px, 0); clip-path: inset(35% 0 50% 0); }
|
||||||
65% { opacity: 0; }
|
65% { opacity: 0; }
|
||||||
72% { opacity: 0.65; transform: translate(-30px, 0); clip-path: inset(58% 0 30% 0); }
|
72% { opacity: 0.65; transform: translate(-6px, 0); clip-path: inset(58% 0 30% 0); }
|
||||||
73% { opacity: 0; }
|
73% { opacity: 0; }
|
||||||
82% { opacity: 0.8; transform: translate(-35px, 0); clip-path: none; }
|
82% { opacity: 0.8; transform: translate(-7px, 0); clip-path: none; }
|
||||||
83% { opacity: 0; }
|
83% { opacity: 0; }
|
||||||
90% { opacity: 0.55; transform: translate(15px, 0); clip-path: inset(68% 0 22% 0); }
|
90% { opacity: 0.55; transform: translate(3px, 0); clip-path: inset(68% 0 22% 0); }
|
||||||
91%, 100% { opacity: 0; transform: translate(0, 0); clip-path: none; }
|
91%, 100% { opacity: 0; transform: translate(0, 0); clip-path: none; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +252,7 @@ a { color: inherit; text-decoration: none; }
|
|||||||
}
|
}
|
||||||
.logo-wrap {
|
.logo-wrap {
|
||||||
position: relative;
|
position: relative;
|
||||||
animation: logo-jitter 3.0s steps(1) infinite, logo-flicker 2.4s ease-in-out infinite, logo-dropout 7s steps(1) infinite;
|
animation: logo-jitter 12s steps(1) infinite, logo-flicker 10s ease-in-out infinite, logo-dropout 28s steps(1) infinite;
|
||||||
}
|
}
|
||||||
/* Brightness flicker — frequent dips like signal loss */
|
/* Brightness flicker — frequent dips like signal loss */
|
||||||
@keyframes logo-flicker {
|
@keyframes logo-flicker {
|
||||||
@@ -255,28 +277,28 @@ a { color: inherit; text-decoration: none; }
|
|||||||
/* Logo body — many independent band shears, frequent bursts. */
|
/* Logo body — many independent band shears, frequent bursts. */
|
||||||
@keyframes logo-jitter {
|
@keyframes logo-jitter {
|
||||||
0%, 6%, 100% { transform: translate(0, 0); clip-path: none; }
|
0%, 6%, 100% { transform: translate(0, 0); clip-path: none; }
|
||||||
8% { transform: translate(25px, 0); clip-path: inset(5% 0 78% 0); }
|
8% { transform: translate(5px, 0); clip-path: inset(5% 0 78% 0); }
|
||||||
9% { transform: translate(-15px, 0); clip-path: inset(15% 0 70% 0); }
|
9% { transform: translate(-3px, 0); clip-path: inset(15% 0 70% 0); }
|
||||||
10% { transform: translate(0, 0); clip-path: none; }
|
10% { transform: translate(0, 0); clip-path: none; }
|
||||||
18% { transform: translate(-30px, 0); clip-path: inset(28% 0 58% 0); }
|
18% { transform: translate(-6px, 0); clip-path: inset(28% 0 58% 0); }
|
||||||
19% { transform: translate(10px, 0); clip-path: none; }
|
19% { transform: translate(2px, 0); clip-path: none; }
|
||||||
24% { transform: translate(20px, 0); clip-path: inset(48% 0 38% 0); }
|
24% { transform: translate(4px, 0); clip-path: inset(48% 0 38% 0); }
|
||||||
25% { transform: translate(-10px, 0); clip-path: inset(52% 0 36% 0); }
|
25% { transform: translate(-2px, 0); clip-path: inset(52% 0 36% 0); }
|
||||||
26% { transform: translate(0, 0); clip-path: none; }
|
26% { transform: translate(0, 0); clip-path: none; }
|
||||||
36% { transform: translate(-15px, 0); clip-path: inset(62% 0 24% 0); }
|
36% { transform: translate(-3px, 0); clip-path: inset(62% 0 24% 0); }
|
||||||
37% { transform: translate(0, 0); clip-path: none; }
|
37% { transform: translate(0, 0); clip-path: none; }
|
||||||
44% { transform: translate(35px, 0); clip-path: inset(72% 0 14% 0); }
|
44% { transform: translate(7px, 0); clip-path: inset(72% 0 14% 0); }
|
||||||
45% { transform: translate(-20px, 0); clip-path: inset(78% 0 8% 0); }
|
45% { transform: translate(-4px, 0); clip-path: inset(78% 0 8% 0); }
|
||||||
46% { transform: translate(0, 0); clip-path: none; }
|
46% { transform: translate(0, 0); clip-path: none; }
|
||||||
56% { transform: translate(-10px, 0); clip-path: inset(18% 0 70% 0); }
|
56% { transform: translate(-2px, 0); clip-path: inset(18% 0 70% 0); }
|
||||||
57% { transform: translate(0, 0); clip-path: none; }
|
57% { transform: translate(0, 0); clip-path: none; }
|
||||||
64% { transform: translate(40px, 0); clip-path: inset(35% 0 50% 0); }
|
64% { transform: translate(8px, 0); clip-path: inset(35% 0 50% 0); }
|
||||||
65% { transform: translate(-15px, 0); clip-path: none; }
|
65% { transform: translate(-3px, 0); clip-path: none; }
|
||||||
72% { transform: translate(-25px, 0); clip-path: inset(58% 0 30% 0); }
|
72% { transform: translate(-5px, 0); clip-path: inset(58% 0 30% 0); }
|
||||||
73% { transform: translate(10px, 0); clip-path: none; }
|
73% { transform: translate(2px, 0); clip-path: none; }
|
||||||
82% { transform: translate(-20px, 0) skewX(-1deg); }
|
82% { transform: translate(-4px, 0) skewX(-0.2deg); }
|
||||||
83% { transform: translate(0, 0); }
|
83% { transform: translate(0, 0); }
|
||||||
90% { transform: translate(15px, 0); clip-path: inset(68% 0 22% 0); }
|
90% { transform: translate(3px, 0); clip-path: inset(68% 0 22% 0); }
|
||||||
91% { transform: translate(0, 0); clip-path: none; }
|
91% { transform: translate(0, 0); clip-path: none; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,7 +339,7 @@ a { color: inherit; text-decoration: none; }
|
|||||||
linear-gradient(rgba(2,7,13,0.95), rgba(2,7,13,0.95)) 0 68% / 100% 3% no-repeat,
|
linear-gradient(rgba(2,7,13,0.95), rgba(2,7,13,0.95)) 0 68% / 100% 3% no-repeat,
|
||||||
linear-gradient(rgba(2,7,13,0.95), rgba(2,7,13,0.95)) 0 84% / 100% 4% no-repeat;
|
linear-gradient(rgba(2,7,13,0.95), rgba(2,7,13,0.95)) 0 84% / 100% 4% no-repeat;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation: pixel-break 3.0s steps(1) infinite;
|
animation: pixel-break 12s steps(1) infinite;
|
||||||
}
|
}
|
||||||
@keyframes pixel-break {
|
@keyframes pixel-break {
|
||||||
0%, 7% { opacity: 0; }
|
0%, 7% { opacity: 0; }
|
||||||
@@ -365,29 +387,29 @@ a { color: inherit; text-decoration: none; }
|
|||||||
rgba(33,234,255,0.10) 88%,
|
rgba(33,234,255,0.10) 88%,
|
||||||
transparent 100%);
|
transparent 100%);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation: scan-tear 3.0s steps(1) infinite;
|
animation: scan-tear 12s steps(1) infinite;
|
||||||
}
|
}
|
||||||
@keyframes scan-tear {
|
@keyframes scan-tear {
|
||||||
0%, 7% { opacity: 0; top: -8%; transform: translateX(0); }
|
0%, 7% { opacity: 0; top: -8%; transform: translateX(0); }
|
||||||
8% { opacity: 0.9; top: 8%; transform: translateX(-60px); }
|
8% { opacity: 0.9; top: 8%; transform: translateX(-12px); }
|
||||||
10% { opacity: 0; }
|
10% { opacity: 0; }
|
||||||
18% { opacity: 0.85; top: 26%; transform: translateX(70px); }
|
18% { opacity: 0.85; top: 26%; transform: translateX(14px); }
|
||||||
20% { opacity: 0; }
|
20% { opacity: 0; }
|
||||||
24% { opacity: 0.95; top: 44%; transform: translateX(-50px); }
|
24% { opacity: 0.95; top: 44%; transform: translateX(-10px); }
|
||||||
26% { opacity: 0; }
|
26% { opacity: 0; }
|
||||||
36% { opacity: 0.7; top: 60%; transform: translateX(40px); }
|
36% { opacity: 0.7; top: 60%; transform: translateX(8px); }
|
||||||
37% { opacity: 0; }
|
37% { opacity: 0; }
|
||||||
44% { opacity: 0.95; top: 74%; transform: translateX(-70px); }
|
44% { opacity: 0.95; top: 74%; transform: translateX(-14px); }
|
||||||
46% { opacity: 0; }
|
46% { opacity: 0; }
|
||||||
56% { opacity: 0.6; top: 16%; transform: translateX(50px); }
|
56% { opacity: 0.6; top: 16%; transform: translateX(10px); }
|
||||||
57% { opacity: 0; }
|
57% { opacity: 0; }
|
||||||
64% { opacity: 0.9; top: 38%; transform: translateX(-40px); }
|
64% { opacity: 0.9; top: 38%; transform: translateX(-8px); }
|
||||||
65% { opacity: 0; }
|
65% { opacity: 0; }
|
||||||
72% { opacity: 0.7; top: 56%; transform: translateX(60px); }
|
72% { opacity: 0.7; top: 56%; transform: translateX(12px); }
|
||||||
73% { opacity: 0; }
|
73% { opacity: 0; }
|
||||||
82% { opacity: 0.95; top: 70%; transform: translateX(-50px); }
|
82% { opacity: 0.95; top: 70%; transform: translateX(-10px); }
|
||||||
83% { opacity: 0; }
|
83% { opacity: 0; }
|
||||||
90% { opacity: 0.6; top: 88%; transform: translateX(30px); }
|
90% { opacity: 0.6; top: 88%; transform: translateX(6px); }
|
||||||
91%, 100% { opacity: 0; }
|
91%, 100% { opacity: 0; }
|
||||||
}
|
}
|
||||||
.logo-scanlines {
|
.logo-scanlines {
|
||||||
@@ -618,18 +640,18 @@ a { color: inherit; text-decoration: none; }
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 0 8vw;
|
padding: 0 8vw;
|
||||||
max-width: 640px;
|
max-width: 780px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag {
|
.tag {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
font-size: 11px;
|
font-size: 13px;
|
||||||
letter-spacing: 0.28em;
|
letter-spacing: 0.28em;
|
||||||
color: var(--cyan);
|
color: var(--cyan);
|
||||||
margin-bottom: 32px;
|
margin-bottom: 32px;
|
||||||
padding: 7px 14px;
|
padding: 8px 16px;
|
||||||
border: 1px solid rgba(33, 234, 255, 0.25);
|
border: 1px solid rgba(33, 234, 255, 0.25);
|
||||||
background: rgba(33, 234, 255, 0.03);
|
background: rgba(33, 234, 255, 0.03);
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
@@ -648,7 +670,7 @@ a { color: inherit; text-decoration: none; }
|
|||||||
|
|
||||||
.headline {
|
.headline {
|
||||||
font-family: "VT323", "IBM Plex Mono", monospace;
|
font-family: "VT323", "IBM Plex Mono", monospace;
|
||||||
font-size: clamp(20px, 2vw, 30px);
|
font-size: clamp(36px, 4vw, 64px);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
line-height: 1.05;
|
line-height: 1.05;
|
||||||
letter-spacing: 0.01em;
|
letter-spacing: 0.01em;
|
||||||
@@ -656,7 +678,7 @@ a { color: inherit; text-decoration: none; }
|
|||||||
text-shadow:
|
text-shadow:
|
||||||
0 0 12px rgba(33, 234, 255, 0.6),
|
0 0 12px rgba(33, 234, 255, 0.6),
|
||||||
0 0 32px rgba(33, 234, 255, 0.3);
|
0 0 32px rgba(33, 234, 255, 0.3);
|
||||||
margin: 0 0 24px;
|
margin: 0 0 28px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
.headline .bracket {
|
.headline .bracket {
|
||||||
@@ -674,7 +696,7 @@ a { color: inherit; text-decoration: none; }
|
|||||||
|
|
||||||
.body, .subheadline {
|
.body, .subheadline {
|
||||||
color: var(--ink-mid);
|
color: var(--ink-mid);
|
||||||
font-size: clamp(13px, 1.05vw, 16px);
|
font-size: clamp(17px, 1.4vw, 22px);
|
||||||
line-height: 1.55;
|
line-height: 1.55;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
max-width: none;
|
max-width: none;
|
||||||
@@ -684,7 +706,7 @@ a { color: inherit; text-decoration: none; }
|
|||||||
.subheadline {
|
.subheadline {
|
||||||
margin-bottom: 32px;
|
margin-bottom: 32px;
|
||||||
letter-spacing: 0.18em;
|
letter-spacing: 0.18em;
|
||||||
font-size: 13px;
|
font-size: 16px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -697,8 +719,8 @@ a { color: inherit; text-decoration: none; }
|
|||||||
backdrop-filter: blur(2px);
|
backdrop-filter: blur(2px);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: "IBM Plex Mono", monospace;
|
font-family: "IBM Plex Mono", monospace;
|
||||||
font-size: 14px;
|
font-size: 17px;
|
||||||
max-width: 560px;
|
max-width: 720px;
|
||||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 0 0 1px rgba(33, 234, 255, 0.05),
|
0 0 0 1px rgba(33, 234, 255, 0.05),
|
||||||
@@ -772,7 +794,7 @@ a { color: inherit; text-decoration: none; }
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
color: var(--cyan);
|
color: var(--cyan);
|
||||||
font-size: 13px;
|
font-size: 15px;
|
||||||
letter-spacing: 0.16em;
|
letter-spacing: 0.16em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
border-bottom: 1px solid rgba(33, 234, 255, 0.25);
|
border-bottom: 1px solid rgba(33, 234, 255, 0.25);
|
||||||
|
|||||||
Reference in New Issue
Block a user