类型:Site模板 · 收录:2026-10-08 21:01:36 · 源码:会员可见
Build ONE standalone HTML file (no frameworks, no build step) that recreates the Stridr landing page PIXEL-EXACTLY.
OUTPUT
- A complete single file: <!doctype html> … </html>
- No React/Vue. No Tailwind CDN as a substitute for the CSS below.
- html,body fill the viewport, overflow:hidden, body position:fixed; inset:0. This is ONE full-screen stage, not a scrolling site.
- Respect prefers-reduced-motion: skip entrance + cursor field; never add html.intro.
- Title: Stridr — Move ahead
- Viewport: width=device-width, initial-scale=1, viewport-fit=cover
THERE IS NO VIDEO. Do not invent a <video>, background reel, or mp4. Every collage piece is a still JPG on CloudFront. Use these URLs exactly (do not hotlink GitHub JPGs; do not generate placeholders).
CLOUDFRONT BASE (required)
https://d2ol7oe51mr4n9.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/
FONTS (required @font-face, font-display:block)
Archivo X — italic, weight 100 900, stretch 62% 125%:
https://raw.githubusercontent.com/MahumSamar/stridr/main/assets/archivo-x.woff2
Inter X — weight 400:
https://raw.githubusercontent.com/MahumSamar/stridr/main/assets/inter-x.woff2
PALETTE
--bg:#ED6535; --ink:#0B111A; --brown:#2B0400; --cream:#FEF0D5
Logo color #120508. Cursor dot #FFFFF7. Menu circle #FBF1DF.
Nav glass: background rgba(237,101,53,.52); backdrop-filter blur(8px); border-radius 4px.
Cluster drop-shadow: 0 1px 1.5px rgba(40,10,0,.28)
Film grain overlay on body::after: pointer-events none, opacity .06, mix-blend-mode multiply, SVG feTurbulence fractalNoise baseFrequency .9, 160×160 tile. The orange stage NEVER animates.
COPY (exact)
Logo: Stridr
Nav: Partner Up | More
Headline (8 absolutely positioned words, all italic Archivo X weight 800 stretch 62%, color var(--ink), skewX(-6deg)):
Move left:109px top:0px font-size:104px scaleX(0.82)
ahead left:279px top:0px font-size:102px scaleX(0.82)
and left:14px top:93px font-size:100px scaleX(0.82)
orchestrate left:128px top:88px font-size:102px scaleX(0.8)
your left:459px top:85px font-size:102px scaleX(0.84)
next left:35px top:179px font-size:102px scaleX(0.86)
era-defining left:192px top:174px font-size:102px scaleX(0.82)
project left:179px top:257px font-size:102px scaleX(0.82)
Screen-reader h1 text: Move ahead and orchestrate your next era-defining project
CTA circle 171×171 at left:332.3px top:304.8px, href="#universe", border 1.2px solid rgba(255,238,214,.92), color var(--cream)
ENTER at 61.7px,61.2px
OUR UNIVERSE at 31.7px,80.2px
16×16 SVG arrow at 78.7px,109.2px path: M2 2 L13.5 13.5 M13.5 5.5 V13.5 H5.5 stroke 1.3
Tagline: One-to-one digital engineering partners (Inter X 15px, color --brown)
ARCHITECTURE
main.stage#stage is a full-bleed absolute stage.
Every block is .it { position:absolute; left:0; top:0; transform-origin:0 0 } and is placed ONLY via JS: transform: translate(left,top) scale(s). Children of .it are position:absolute.
Photo groups are .cluster containing <img class="card"> object-fit:cover, transform-origin 50% 50%, user-select none, -webkit-user-drag none.
Custom cursor #cursor: position:fixed, border-radius:50%, z-index:2000, pointer-events:none.
Hero z-index 1000, pointer-events none except the CTA.
Logo + nav z-index 1001. Tag z-index 1000.
html.intro .it, html.intro #cursor { opacity:0 } until entrance starts.
NAV (desktop)
.nav 264×48. Glass 264×43 at left:0 top:3px.
Partner Up .nl-p left:4px top:10px. More .nl-m left:146px top:10px.
Menu button .menu 30×30 circle at left:209px top:2px. Hamburger bars hidden on desktop.
Inter X 18px, letter-spacing -0.4px, color --brown.
NAV (tablet/burger — :root[data-burger])
Glass becomes 230×122 at left:9px top:46px, radius 6px, hidden until .nav.open.
Links stack: .nl-p top:56px, .nl-m top:106px with 1px top border rgba(43,4,0,.14).
Bars 13×9 become a 2-line burger that rotates into an X when open.
Transitions: cubic-bezier(.16,1,.3,1). No transitions until .nav has class anim (prevents focus flash).
Escape / outside click / link click / focusout close the menu. Burger only works when data-burger is set.
MOBILE CTA
:root[data-mobile] .cta { transform: scale(var(--cta-k, 1.3)); }
EXACT COLLAGE — each img src is BASE + filename. Positions are inside the cluster box.
g-built 534×375
4bac43a2-2d06-46c6-93a4-8ed64eb4a72d.jpg left:148 top:0 140×36 data-cx=218.0 data-cy=18.0
0c39d981-0d2c-4c52-9bf1-f81fa287fc51.jpg left:106 top:37 218×142 data-cx=215.0 data-cy=108.0
aa4283ce-1c38-42a8-82ad-176f80eb6458.jpg left:0 top:105 221×149 data-cx=110.5 data-cy=179.5
746ce713-6b20-49c5-bd1b-a6dbcfcecbf8.jpg left:146 top:228 139×110 data-cx=215.5 data-cy=283.0
823653c0-131a-456a-b8b8-d3538408bcfe.jpg left:286 top:227 248×148 data-cx=410.0 data-cy=301.0
g-news 569×240
a31e444e-b517-4da6-83a9-4e379d7fd11c.jpg left:125 top:0 275×45 data-cx=262.5 data-cy=22.5
3c102d57-3ce2-45a8-93e3-2f86a9f8897b.jpg left:0 top:44 286×196 data-cx=143.0 data-cy=142.0
18160684-b74a-49e7-b1e3-b4ee757400bf.jpg left:287 top:32 68×166 data-cx=321.0 data-cy=115.0
7c2618f8-83f4-4d87-8c62-7a6b03ecf8b5.jpg left:356 top:37 213×202 data-cx=462.5 data-cy=138.0
g-small 355×244
70d3552a-d52e-4600-99ee-e0f8c3359cd2.jpg left:0 top:0 183×97 data-cx=91.5 data-cy=48.5
30f05319-2cf3-40b3-828c-8e815bc900bc.jpg left:136 top:88 219×156 data-cx=245.5 data-cy=166.0
ecf2980e-bfea-4f27-a4dc-65b676999da2.jpg left:13 top:84 168×141 data-cx=97.0 data-cy=154.5
g-runo 254×337
b50ede66-5a08-4155-81de-65f78ced44a7.jpg left:0 top:0 254×337 data-cx=127.0 data-cy=168.5
g-community 174×96
f25f15f1-be9c-4ade-9d35-99d9f9bea45c.jpg left:0 top:0 174×96 data-cx=87.0 data-cy=48.0
g-edge 32×65
94ac8a83-e072-4e0e-a2b8-74d71f4bacfb.jpg left:0 top:0 32×65 data-cx=16.0 data-cy=32.5
g-trail 258×272
afe829a5-f522-4daf-9108-9a1d2edc8a3d.jpg left:0 top:0 176×237 data-cx=88.0 data-cy=118.5
dc272602-2eb1-402f-b22e-3dedb61a55a9.jpg left:105 top:110 153×128 data-cx=181.5 data-cy=174.0
37e38c15-e6b4-44ed-9190-4d404c5e12d1.jpg left:46 top:187 121×85 data-cx=106.5 data-cy=229.5
g-shoe 343×199
b97a61ea-7f78-4894-baac-7ef513955498.jpg left:181 top:0 162×153 data-cx=262.0 data-cy=76.5
aeb13c61-a25c-4b00-9cc6-a3b8ab2d2fcb.jpg left:0 top:67 168×109 data-cx=84.0 data-cy=121.5
b39a4d9d-f6c5-416a-8fcf-9d28ddb7b66f.jpg left:140 top:89 139×110 data-cx=209.5 data-cy=144.0
g-field 146×122
470e7d06-7a36-468f-a644-054462bf6034.jpg left:0 top:0 146×122 data-cx=73.0 data-cy=61.0
g-long 185×151
3b2d939d-df63-4753-b497-71296e2fba7f.jpg left:0 top:0 185×151 data-cx=92.5 data-cy=75.5
g-perf 215×112
e80ebb0a-417d-47d1-91d0-f27df3cc1c34.jpg left:0 top:0 215×112 data-cx=107.5 data-cy=56.0
g-support 157×97
c6d1e903-0b9b-44a0-87ea-afcb1eb210b5.jpg left:0 top:0 157×97 data-cx=78.5 data-cy=48.5
g-funding 186×94
e7d5a006-3a8f-4492-ac3b-a190115d3cdc.jpg left:0 top:0 186×94 data-cx=93.0 data-cy=47.0
g-active 220×189
0bf39a3e-8108-4354-85ab-8a61d4c23319.jpg left:0 top:0 181×73 data-cx=90.5 data-cy=36.5
a059dab5-cd00-4da1-8997-186260eafbad.jpg left:125 top:51 95×138 data-cx=172.5 data-cy=120.0
g-better 167×80
743953db-8555-42b8-b271-1bdb928508ba.jpg left:0 top:0 167×80 data-cx=83.5 data-cy=40.0
Each card MUST have data-g="<cluster id>" plus data-cx / data-cy as above (cursor physics).
LAYOUT ENGINE (must match these numbers)
Desktop canvas L = {W:1586, H:992}
Phone canvas P = {W:600, H:1100}
Tablet portrait TP = {W:820, H:1180}
Breakpoint BP = 0.74
Mode selection:
dS = min(sqrt(vw/L.W * vh/L.H), min(vw/L.W, vh/L.H)*1.04)
if min(vw,vh)<600 AND vw<1000: aspect<1 ? "mp" : "ml"
else if min(vw,vh)<600: "desktop"
else if aspect>=0.8 AND dS>=BP: "desktop"
else aspect>=1 ? "tl" : "tp"
Set data-mode, data-burger (when not desktop/phone), data-mobile (mp or ml).
Item table — each item: id, desktop x,y,w,h, then optional arrays [x,y,k] for p / tp / mp / ml, and tl [x,y]:
[
{"id":"g-built","x":58,"y":46,"w":534,"h":375,"p":[-46,92,0.5],"tp":[16,100,0.6],"tl":null,"mp":[4,90,0.36],"ml":[370,104,0.3]},
{"id":"g-news","x":557,"y":7,"w":569,"h":240,"p":[228,74,0.62],"tp":[350,88,0.6],"tl":null,"mp":[158,66,0.4],"ml":[372,10,0.34]},
{"id":"g-small","x":1134,"y":1,"w":355,"h":244,"p":[392,232,0.46],"tp":[606,250,0.52],"tl":null,"mp":[264,170,0.36],"ml":[580,64,0.3]},
{"id":"g-runo","x":1058,"y":258,"w":254,"h":337,"p":[484,440,0.46],"tp":[640,404,0.6],"tl":[1112,257],"mp":[304,262,0.36],"ml":[700,64,0.3]},
{"id":"g-community","x":1328,"y":390,"w":174,"h":96,"p":[6,300,0.56],"tp":[356,258,0.72],"tl":[1392,392],"mp":[168,190,0.5],"ml":[580,146,0.42]},
{"id":"g-edge","x":1551,"y":354,"w":32,"h":65,"p":null,"tp":[778,104,1],"tl":null,"mp":[8,236,0.7],"ml":[792,92,0.6]},
{"id":"g-trail","x":171,"y":521,"w":258,"h":272,"p":[12,770,0.46],"tp":[20,690,0.56],"tl":null,"mp":[6,498,0.42],"ml":[540,196,0.34]},
{"id":"g-shoe","x":1221,"y":577,"w":343,"h":199,"p":[412,772,0.5],"tp":[626,716,0.52],"tl":null,"mp":[262,606,0.38],"ml":[646,190,0.32]},
{"id":"g-field","x":288,"y":807,"w":146,"h":122,"p":null,"tp":[22,872,0.68],"tl":null,"mp":[6,606,0.5],"ml":[372,232,0.42]},
{"id":"g-long","x":449,"y":816,"w":185,"h":151,"p":[150,760,0.52],"tp":[150,1046,0.68],"tl":null,"mp":[90,600,0.48],"ml":[442,226,0.4]},
{"id":"g-perf","x":646,"y":821,"w":215,"h":112,"p":[190,868,0.62],"tp":[292,930,0.68],"tl":null,"mp":[6,684,0.5],"ml":[16,322,0.42]},
{"id":"g-support","x":20,"y":851,"w":157,"h":97,"p":null,"tp":[22,1110,0.66],"tl":null,"mp":[6,790,0.5],"ml":[748,176,0.42]},
{"id":"g-funding","x":1154,"y":809,"w":186,"h":94,"p":[14,940,0.56],"tp":[652,880,0.66],"tl":null,"mp":[292,694,0.5],"ml":[560,300,0.42]},
{"id":"g-active","x":1362,"y":803,"w":220,"h":189,"p":[462,982,0.62],"tp":[686,1066,0.6],"tl":null,"mp":[288,765,0.5],"ml":[740,292,0.42]},
{"id":"g-better","x":948,"y":912,"w":167,"h":80,"p":[18,1057,0.52],"tp":[470,1122,0.72],"tl":[1072,910],"mp":[100,818,0.52],"ml":[660,300,0.44]},
{"id":"hero","x":520,"y":285,"w":590,"h":478,"p":[5,318,0.86],"tp":[85,380,1.1],"tl":null,"mp":[23,300,0.6],"ml":[16,70,0.56]},
{"id":"logo","x":38,"y":30,"w":152,"h":52,"p":[18,22,0.74],"tp":null,"tl":null,"mp":null,"ml":null},
{"id":"nav","x":1296,"y":40,"w":264,"h":48,"p":[388,20,0.74],"tp":null,"tl":null,"mp":null,"ml":null},
{"id":"tag","x":644,"y":940,"w":300,"h":30,"p":[150,1066,1.0],"tp":null,"tl":null,"mp":null,"ml":null}
]
Desktop / phone layout:
C = phone? P : L
S = min(sqrt(sx*sy), min(sx,sy)*1.04)
Place each item by free-space fraction fx=x/(C.W-cw), fy=y/(C.H-ch).
Hero extra cap: min(s, 0.94*vw/c.w, 0.6*vh/c.h). Phone hero is horizontally centered.
If port and item.p is null, hide the item (g-edge, g-field, g-support).
Tagline locks to g-perf: same scale, offset by (tag.x - perf.x)*s.
Mobile mp canvas {400,860}, ml {820,380}:
Logo/nav are specially placed to corners (logo size 26–34px, nav 34/30 scale, right-aligned).
Tag beside g-perf on ml; under g-perf on mp.
Hero cap: min(s, (vw-2m)/581, (ml?0.78:0.4)*vh/c.h) and set --cta-k = max(1.3, 12/(15*s)).
Non-hero items clamped inside the viewport.
Tablet:
Logo top-left on tp; desktop-relative on tl.
Nav burger top-right, 36/30 scale (50px touch with 7px halo).
tl hero uses textK = min(1.12, pow(BP/dS, 1.6)).
Clamp non-hero cards inside the viewport.
Relayout on resize and on document.fonts.ready.
CURSOR FIELD (pointer only; skip if reduced motion)
K=0.252, AMP=1.05, SIG=421, TAU=0.1
Rest point relative to hero: x = hero.l + (929-520)*hero.s, y = hero.t + (327-285)*hero.s
Dot radius = 5 * hero.s
Each card rest bias b = 1 / prox(distance from rest to card center, group scale)
prox(d,s) = 1 + AMP * exp(-((d/(SIG*s))**2))
Parallax: dx,dy = -K * (dot - rest)
Card transform: translate(dx/s, dy/s) scale(b * prox(distance to dot, s))
Group z-index = 1 + round(maxScale * 100)
Dot follows target with exponential smoothing a = 1 - exp(-dt/TAU), dt capped 0.05s
pointermove sets target; pointercancel / touch pointerup / mouseleave return to rest.
ENTRANCE (once on load, then CANCEL every WAAPI animation)
If not reduced motion: add class intro on <html> immediately in <head>, failsafe remove after 3000ms.
Wait for fonts.ready + image.decode() (cap 700ms), then:
Easings: EXPO cubic-bezier(.16,1,.3,1), QUART cubic-bezier(.25,1,.5,1). fill:backwards.
A masked-rise: from translate 0 T% + clip inset(-(pad)% -(side)% (T-pad)% -(side)%) to 0 + full inset. Default T=115 pad=15 side=20.
logo at 0.05s / 0.95s
nav links staggered 0.14 + i*0.06 / 0.75s (T=110 pad=20 side=10)
headline lines [[0,1],[2,3,4],[5,6],[7]] start 0.16 + line*0.09 + word*0.035 / 1.05s
CTA labels 1.05 and 1.11 / 0.75s
tagline 1.35 / 0.80s (pad=25 side=5)
B nav glass fade 120ms delay / 700ms QUART
menu scale .55→1 + opacity 260ms / 750ms
C cards clip-rise from inset(100% 0 0 0) translateY(22px) to open, delay = 0.45 + 0.6*(distToHeadline/dmax) + layer*0.045, duration 900ms
D CTA iris clip-path circle(0%→75% at 50% 50%) delay 950ms / 900ms
arrow from translate(-6px,-6px) opacity 0, delay 1250ms / 650ms QUART
cursor scale 0→1 delay 1550ms / 550ms
Remove html.intro as soon as animations are created (backwards fill holds start states).
When all finished: cancel every animation, hide/show targets in one task so nothing stays on the animation layer.
HEAD FAILSAFE SCRIPT (before CSS)
if(!matchMedia('(prefers-reduced-motion: reduce)').matches){
document.documentElement.classList.add('intro');
setTimeout(function(){document.documentElement.classList.remove('intro')},3000);
}
REQUIRED CSS (include verbatim besides @font-face):
:root{--bg:#ED6535;--ink:#0B111A;--brown:#2B0400;--cream:#FEF0D5;--s:1}
*{box-sizing:border-box;margin:0;padding:0}
html,body{width:100%;height:100%;overflow:hidden;background:var(--bg)}
body{position:fixed;inset:0;-webkit-font-smoothing:antialiased}
.stage{position:absolute;inset:0;overflow:hidden}
html.intro .it,html.intro #cursor{opacity:0}
.it{position:absolute;left:0;top:0;transform-origin:0 0;will-change:transform}
.it>*{position:absolute}
.cluster{filter:drop-shadow(0 1px 1.5px rgba(40,10,0,.28))}
.card{display:block;object-fit:cover;user-select:none;-webkit-user-drag:none;transform-origin:50% 50%;will-change:transform}
#cursor{position:fixed;left:0;top:0;border-radius:50%;background:#FFFFF7;pointer-events:none;z-index:2000;will-change:transform}
.hero{z-index:1000;pointer-events:none}.hero a{pointer-events:auto}
.w{position:absolute;font-family:"Archivo X",sans-serif;font-style:italic;font-weight:800;font-stretch:62%;line-height:1;white-space:nowrap;color:var(--ink);transform-origin:0 0}
.cta{border:1.2px solid rgba(255,238,214,.92);border-radius:50%;color:var(--cream);text-decoration:none}
.cta span{position:absolute;font:15px/1 "Inter X",sans-serif;letter-spacing:-.2px;white-space:nowrap}
.logo{font:italic 800 47px/1 "Archivo X",sans-serif;font-stretch:100%;letter-spacing:-1px;color:#120508;text-decoration:none;white-space:nowrap}
.it.nav,.it.logo{z-index:1001}
.glass{border-radius:4px;background:rgba(237,101,53,.52);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
.nl{font:18px/1 "Inter X",sans-serif;letter-spacing:-.4px;color:var(--brown);text-decoration:none;white-space:nowrap}
.menu{width:30px;height:30px;border:0;border-radius:50%;background:#FBF1DF;cursor:pointer}
.tagline{font:15px/1 "Inter X",sans-serif;color:var(--brown);white-space:nowrap}
DO NOT
- Add extra sections, footer, scroll, Lenis, GSAP-only rewrites that change timing, Unsplash, or generated images
- Use a CloudFront video URL — none exists
- Change copy, colors, cluster sizes, or img dimensions
- Load local /assets/*.jpg
Reference implementation (inlined fonts): https://github.com/MahumSamar/stridr/blob/main/stridr-standalone.html[/hidecontent]