motionsites中文站 / Orla Fashion
Orla Fashion
aadmin2026-09-15 发布Site模板0 阅读

Orla Fashion

类型:Site模板 · 分类:未分类 · 收录:2026-09-15 23:37:22 · 源码:会员可见

[hidecontent type="vip1"]
Build ONE standalone HTML file that recreates the Orla. conceptual eco-clothing site EXACTLY. Output a single file only: all CSS in <style>, all JS in <script type="module">. No other files. Do not invent extra sections, copy, colors, fonts, or products.

DELIVERABLE
- Single HTML file, served over HTTP (file:// is not allowed).
- Title: Orla. — Conceptual eco clothing
- Before first paint: <script>document.documentElement.classList.add('js')</script>
- Load MP4Box: https://cdn.jsdelivr.net/npm/mp4box@0.5.2/dist/mp4box.all.min.js (defer)
- Needs internet. Videos are HEVC Main 10: they play only where the OS has a hardware HEVC decoder (Mac/iOS, some Windows). Elsewhere the plate stays white; text, collage, and shop still work.

FONTS (exact)
- Body/UI: Switzer from Fontshare, weights 300 / 400 / 500 only.
  https://api.fontshare.com/v2/css?f[]=switzer@300,400,500&display=swap
  Preconnect api.fontshare.com and cdn.fontshare.com
- Wordmark initial only: Playball from Google Fonts.
  https://fonts.googleapis.com/css2?family=Playball&display=swap
- Fallback @font-face named "Switzer Fallback" using local Arial with:
  ascent-override 96.67%; descent-override 24.66%; line-gap-override 8.88%; size-adjust 101.38%
- Font stack: 'Switzer','Switzer Fallback','Inter Tight',-apple-system,BlinkMacSystemFont,'Helvetica Neue',Arial,sans-serif
- No second body font. No uppercase eyebrows. No font-weight 700. “Bold” means 500.

EXACT CLOUDFRONT ASSETS (use these URLs verbatim, no substitutes)

Hero / scroll-scrub plate (two clips, last frame of clip 1 matches first frame of clip 2):
- Clip 1 (hero → craft handoff), id=v1, muted playsinline preload=auto:
  https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_155845_0dc2a196-b8a2-414c-94bb-80854ed49125.mp4
- Clip 2 (craft → shop), id=v2, muted playsinline preload=metadata:
  https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_150800_16535fd3-9669-4a4e-bc00-c844ef487bd9.mp4
- Each clip sits under a 1920×1080 canvas (ids c1, c2) in a fixed full-bleed stage behind all content. No crossorigin on <video>. The frame bank fetches the same URL itself with CORS.

Materials collage PNGs (transparent cut-outs):
- driftwood AND driftwood-2 (same file, 1344×752):
  https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_140036_fa6e43d3-e7f4-499b-9499-9e484d3f21a9.png
- cotton (1024×1024):
  https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_140404_c3be9378-3e79-42c0-ac04-6b6d4dae2cbd.png
- fern (880×1168):
  https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_140415_fc81d49a-07bd-45f2-9be8-3783cf85701c.png
- granite (1024×688):
  https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_140421_958eafa8-3bb9-42b7-bb17-e9eb77b1c2e0.png

Shop photos (1792×2240 webp, object-fit cover):
- Cutout tank: https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_154644_d8054df3-3265-45bd-bb76-a9fa8cad48b0_min.webp
- Chain cuff: https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_154644_e7457aad-7517-4d45-bc8a-fd1407a57cd1_min.webp
- Wash jeans: https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_154644_0b45a6a1-252b-4d2b-8eda-c51bde258e93_min.webp
- Clear shield: https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_154644_31f5a7f2-dcc0-472d-bfae-b649290b67c7_min.webp
- Clear tote: https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_154644_d6f495b7-66cb-407e-b9d5-a092bdfad143_min.webp
- Bucket hat: https://d8j0ntlcm91z4.cloudfront.net/user_3GJaYKPxdnQG0Q9O26lu6DPmcHu/hf_20260912_154644_edb743df-1d17-4495-919e-3f3a8c28b80d_min.webp

PALETTE + TOKENS
- --ink: #24363f
- --bg: #fff
- --ghost: #ededed
- Ink alphas via color-mix(in srgb, var(--ink) N%, transparent): 88 / 64 / 48 / 32 / 24 / 08
- --pad-x: max(16px, 2.7211vw)   /* 40px @1470 */
- --pad-y: max(16px, 2.1769vw)   /* 32px @1470 */
- --ease-expo: cubic-bezier(0.16, 1, 0.3, 1)
- --in-y:12px; --in-blur:8px; --out-y:12px; --out-blur:8px
- --hero-runway: 80svh
- --sec2-runway: 220svh
- --mat-max: 180px; --mat-travel: 520px; --mat-rot: 4deg
- --measure-lead:480px; --measure-body:420px; --measure-h1:580px
- overscroll-behavior: none; overflow-x: clip
- @property --brand-min-h { syntax:'<length>'; inherits:true; initial-value:72px }
- --brand-min-h: calc(3 * var(--fs-ui) * var(--lh-ui))
- --fs-brand: min(var(--fs-display), 26svh)
- --shrink-end: .32 (JS overwrites with measured coefficient)
- CSS layers in this order: reset, tokens, base, layout, components, motion, utilities
- Use Baseline 2026 CSS: nesting, @layer, clamp(), color-mix, svh, :focus-visible
- No width media queries except the one mobile breakpoint at max-width 767px, plus pointer:coarse, hover/fine, max-aspect-ratio 3/4, and prefers-reduced-motion

TYPE SCALE (fluid clamp, no extra widths)
Weights: display/headings/body 300; labels/card titles 400; nav+buttons 500 at 14px only.
- display: clamp(80px, 16.667vw, 240px) lh .92 ls -.055em
- h1: clamp(40px, 3.333vw, 48px) lh 1.125 ls -.04em
- h2: clamp(24px, 4.667vw, 56px) lh 1.15 ls -.025em
- figure: clamp(32px, 3.333vw, 48px) lh 1.15 ls -.06em
- lead: clamp(20px, 2.222vw, 32px) lh 1.3 ls -.025em
- body-lg: clamp(18px, 2vw, 24px) lh 1.33 ls -.03em
- body: clamp(16px, 1.667vw, 20px) lh 1.45 ls -.02em
- small: 14px lh 1.7 ls -.01em weight 400
- ui: 14px (16px on pointer:coarse) lh 1.7 ls 0 weight 500
- Hierarchy is ink alpha, never a second color or caps.
- Classes: .t-display .t-h1 .t-h2 .t-figure .t-lead .t-body-lg .t-body .t-title .t-small .t-ui
- .is-ghost = --ghost; .is-demoted = --ink-64; .is-muted = --ink-32

PAGE STRUCTURE (exact copy, no extras, no Atelier section)

1) Fixed stage #stage.aria-hidden behind everything:
   #layerA: video#v1 + canvas#c1.plate
   #layerB.stage__b: video#v2 + canvas#c2.plate
   Layer B opacity = var(--x2, 0). Whole stage opacity = calc(1 - var(--stage-out, 0)).
   Videos/canvases object-fit:cover; on max-aspect-ratio 3/4 use contain + object-position center 92%.
   canvas.plate starts opacity 0; .is-live fades to 1 in 240ms. .is-blurring applies blur(stage-out * 24px). .is-covered sets visibility:hidden.

2) Fixed chrome .chrome (pointer-events:none, re-enable on brand + burger), padding pad-y / pad-x:
   - Brand <a.brand href="#top" data-reveal="display" style="--i:0"> <span.brand__initial>O</span>rla.
     Display size, shrinks with transform:scale(var(--shrink,1)) from top-left. NEVER change font-size to shrink.
     .brand__initial is Playball, weight 400, letter-spacing 0, font-size 1.04em, line-height 0, margin-right -.06em, translate 0 -.01em (tucks under the r).
   - Burger button aria-label="Menu" aria-expanded=false data-reveal style="--i:4": two 36×1.5px ink bars, 44×44 hit, gap 8px, aligned end. Visible on all viewports; on mobile it is the only nav.

3) main z-index 1

HERO #top
- Height: calc(100svh + 80svh). Sticky .hero__stage min-height 100svh, same padding, grid:
  columns minmax(0,7fr) minmax(0,3fr); rows 38svh / 1fr / auto
- h1.sr-only: Orla. Conceptual eco clothing.
- nav.hero__nav aria-label=Primary at grid 1/2, stacked start:
  Collection → #collection --i:1
  Craft → #craft --i:2
  Atelier → #atelier --i:3
  All .t-ui, no underline. Hover (fine pointer only) color --ink-64. Never fade via opacity.
- p.hero__lede.t-body-lg --i:5 at grid 2/1, max-width 420px:
  Conceptual pieces made slowly from fibres that already exist. Dyed by hand, cut once, worn for years.
- a.hero__cta.btn.t-ui --i:6 at grid 3/1:
  See the collection → #collection
- Button: min-height 44, padding 10px 24px, bg --ink-08, radius 4px. Hover invert to ink on bg. Active scale .97.

CRAFT #craft.sec2
- Height: calc(100svh + 220svh). Sticky .sec2__stage 100svh, 2-col 3fr/2fr, rows 1fr / auto.
- h2.sec2__statement.t-h1 data-split="lines" (JS splits into .word spans, each data-reveal=scroll). Centered vertically, z-index 2, max-width 580px, padding-top = brand-min-h + pad-y. Exact text:
  Every piece starts with what already exists: deadstock, recycled denim and organic hemp, dyed by hand and finished in one atelier.
- ul.specs bottom-right, width min(100%, 480px):
  Organic hemp — Rain-fed, no pesticides
  Recycled denim — 68% post-consumer cotton
  Tencel lyocell — Closed loop, solvent reused
  Deadstock cotton — Rescued mill surplus
  Rows .specs__row.t-title data-reveal=scroll, flex space-between, 12px pad, hairline --ink-24 top (and bottom on last). Right span .is-demoted.

MATERIALS COLLAGE .mats (absolute inset 0, pointer-events none). Centre corridor ~40–60% stays empty for the video.
Desktop rest positions (longer side capped 180px):
  [data-mat=driftwood]   --x:4%  --y:74% --w:180px  front  from left
  [data-mat=cotton]      --x:27% --y:6%  --w:170px  back   from top
  [data-mat=driftwood-2] --x:84% --y:30% --w:180px  front  from right, CSS transform:scale(-1,-1)
  [data-mat=fern]        --x:66% --y:40% --w:135px  back   from bottom, CSS transform:scaleX(-1)
  [data-mat=granite]     --x:76% --y:5%  --w:160px  front  from top
JS writes translate/rotate/scale as individual properties so they compose with the CSS transform, never overwrite it.
Per-item motion (key, from, k, speed, drift, rot, tau, spin, bow, s0, tilt, blur):
  driftwood   left   0  .46 -.30  1.4  5  -18   70  1.10  -6  12
  granite     top    1  .42  .26 -1.0  6   14  -50  1.08   5  12
  driftwood-2 right  2  .60  .28  -.6  4   16   60  1.12   4  14
  cotton      top    3  .30  .24 -1.2  7  -12   40   .92   8  10
  fern        bottom 4  .18  .16   .5  8   10  -90   .90  12  10
Pinned windows: in start .22 step .05 dur .28; out start .70 step .02 dur .14
Flow (phone) windows: in .28/.06/.32; out .78/.02/.14
Landing parallax zero at p=0.62. Travel 520px, rot 4°, start 60px past viewport edge.
Fly-in: remaining u=1-e along from-axis + sin(πe)*bow sideways + after-land parallax (x = q*speed*drift*520, y = −q*speed*520) + exit lift o*(40+speed*120).
Rotation: tilt + spin*u + q*rot*4. Scale: 1+(s0-1)*u.
Items use frame-rate-independent lag: current += (target-current)*(1-exp(-dt*tau)). Text never lags.

SHOP #collection.shop
- Padding: calc(pad-y * 4) pad-x. Head same 7fr/3fr split, margin-bottom 64px.
- h2.shop__title.t-display data-reveal=scroll --i:0: Shop  (margin-left -.04em)
- p.shop__lede.t-body-lg --i:1: Six pieces from the first run. Each one cut, dyed and finished in the atelier, numbered by hand.
- 16-column grid, col-gap 24px, row-gap clamp(64px, 9vw, 136px):
  a1 cols 1–3 row1  media 2:3   Cutout tank  €140  Apparel
  a2 cols 4–6 row1  media 1:1   Chain cuff   €160  Jewellery
  a3 cols 9–16 row1 media 1:1   Wash jeans   €220  Denim
  b1 cols 1–3 row2  media 1:1   Clear shield €90   Eyewear
  b2 cols 6–8 row2  media 2:3   Clear tote   €180  Bags
  b3 cols 9–11 row2 media 1:1   Bucket hat   €110  Apparel
- Card: photo → name|price .t-title → tag .t-small.is-demoted. Sentence case. media bg --ink-08, img cover, hover scale 1.03 over 700ms expo. Card press scale .985.
- Cards data-reveal=scroll with --i 2,3,4 then 0,1,2. Card --in-y 40px --in-blur 12px. Title --in-y 24px --in-blur 14px.

REVEAL CONTRACT (do not replace with CSS transitions)
Every [data-reveal] gets --in and --out (0→1) written ON THE ELEMENT, never :root.
opacity = in * (1-out)
translate Y = (1-in)*in-y − out*out-y
.filter blur only while .is-anim (mid in or out). .is-hidden when in<=0 or out>=1.
.js [data-reveal]{ --in:0 }. JS-off rested state is in=1 out=0 (the design).
Brand: --in-y 0, --in-blur 14px (focuses in place).
Mats: translate:none from the contract; --out-blur 0.
Round writes to 3 decimals; skip unchanged; toggle classes once per crossing.
One RAF loop is the only driver. No scroll listeners. No IntersectionObserver.
Entrance (load nodes): after fonts.ready or 2500ms failsafe, class is-ready, then node i starts at i*0.09s, duration 0.9s (brand 1.4s), eased expoOut t => 1-2^(-10t).
Hero exit over pin progress p1: EXIT_START .06, STEP .07, DUR .45, expoOut. Order is DOM [data-reveal] in hero.
Pinned progress = clamp((scrollY - offsetTop) / (offsetHeight - innerHeight)).
Sec2 lines: LINE_START .03 STEP .045 DUR .15. Exit start .82 step .02 dur .12. Spec row r shares line r.
Shop + flowing nodes enter by position: fade as top crosses 0.92vh → 0.62vh, stagger i*0.11, window 0.18, cubic-out (not expo).
Line splitter: split data-split=lines into word spans, group by offsetTop after layout, remeasure on resize.

VIDEO PLATE ENGINE
Clip 1 maps scroll 0 → S1 onto currentTime 0 → duration.
Clip 2 maps S1 → S2.
S1 = sec2 pin top + LINE_START * span (or first word’s band entry on phones).
S2 = shop top − innerHeight.
Handoff: --x2 over 24px (S1-12 to S1+12). Cover the unused layer.
Whiteout: --stage-out linear from S2 over 0.5*innerHeight, blur gated by .is-blurring, cover at 1.
Video current lerps to target with tau=8, snap 0.002. Text never lerps.
If VideoDecoder + MP4Box + DataStream exist: fetch each clip as arrayBuffer, demux, decode once into WebP stills (JPEG on Safari), drawImage from an LRU window of 24 bitmaps. Prefetch AHEAD 16 / MIN_AHEAD 6 / INFLIGHT 8 toward the target. Build clip 1 then clip 2 sequentially. Reveal canvas only after first real paint (.is-live). Watchdog 60s. One software-decode retry on hardware death, then revert to <video> seeking.
prefers-reduced-motion: keep fades, drop travel/blur; plate holds first frame; whiteout is a plain fade.

BRAND SHRINK
Linear over p1 in [0, 0.85] from 1 down to menu block height / brand.offsetHeight (offsetHeight ignores transforms). If nav is display:none, use resolved --brand-min-h (~72px). Publish --shrink-end on :root.

MOBILE max-width 767px
- Hide .hero__nav (burger remains). Hero becomes 1 column, rows 30svh / 1fr / auto.
- Shop head 1 column, gap 24px, margin-bottom 40px.
- Shop grid 2 columns, gap 16/40. a1 a2 b1 b2 b3 span 1; a3 spans full row.
- Sec2 is NOT pinned: height auto, stage position relative. Rows: statement / 220px collage band / list. Collage never overlaps type.
- Phone collage positions, size * 0.66:
  driftwood -4%/58%; granite 34%/4%; fern 26%/42%; cotton 64%/50%; driftwood-2 62%/0%
- JS detects sticky vs relative and switches sec2 to band-by-position reveals.

INTERACTION / A11Y
- :focus-visible outline 2px ink offset 4px; mouse focus has no outline.
- Touch-action manipulation on links/buttons.
- sr-only for the h1.
- No rubber-band bounce.
- Burger does not need a working menu panel (original is visual chrome only) but keep the button and ARIA.

DO NOT
- Do not add footer, atelier page, cart, forms, extra products, Lorem, gradients, drop shadows, or a second typeface besides Playball on the O.
- Do not use GSAP/ScrollTrigger/Lenis/Locomotive. One RAF loop, custom properties, this choreography.
- Do not swap CloudFront URLs or re-encode videos.
- Do not open as file:// instructions in the page; just make it work on a static HTTP server.
[/hidecontent]
← 返回首页