1<!DOCTYPE html> 2<html lang="en"> 3<head> 4<meta charset="UTF-8"> 5<meta name="viewport" content="width=device-width, initial-scale=1.0"> 6<title>Monochroam â Your lifestyle deserves more spotlight</title> 7<link rel="stylesheet" href="styles.css"> 8<style> 9/* ---- hero : full-bleed monochrome spotlight ---- 10 The whole background plays in monochrome; the cursor is a camera 11 viewfinder that reveals the scene in full colour. Scrolling blooms 12 the spotlight open until colour floods the frame. */ 13.hero{position:relative;min-height:100svh;display:flex;align-items:center;padding-top:var(--nav-h);overflow:hidden;isolation:isolate; 14 --sx:72%;--sy:40%;--spot-r:300px} 15.hero-bgmedia{position:absolute;inset:0;z-index:0;background:#08080c} 16.hero-vid{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transform:scale(1.08);will-change:transform} 17.hero-mono{position:absolute;inset:0;background:rgba(7,7,10,.32); 18 -webkit-backdrop-filter:grayscale(1) brightness(.58) contrast(1.06); 19 backdrop-filter:grayscale(1) brightness(.58) contrast(1.06); 20 -webkit-mask-image:radial-gradient(circle var(--spot-r) at var(--sx) var(--sy),transparent 0 42%,#000 80%); 21 mask-image:radial-gradient(circle var(--spot-r) at var(--sx) var(--sy),transparent 0 42%,#000 80%)} 22@supports not ((backdrop-filter:grayscale(1)) or (-webkit-backdrop-filter:grayscale(1))){.hero-mono{background:rgba(7,7,10,.7)}} 23.hero-spotglow{position:absolute;inset:0;mix-blend-mode:screen;pointer-events:none;opacity:.5; 24 background:radial-gradient(circle calc(var(--spot-r)*.95) at var(--sx) var(--sy),rgba(138,114,255,.30),rgba(255,94,44,.08) 55%,transparent 74%)} 25.hero-scrim{position:absolute;inset:0; 26 background:linear-gradient(90deg,rgba(6,6,9,.92) 0%,rgba(6,6,9,.6) 30%,rgba(6,6,9,.16) 52%,transparent 68%), 27 linear-gradient(180deg,rgba(6,6,9,.55),transparent 24% 64%,rgba(6,6,9,.96))} 28.hero .wrap{position:relative;z-index:2;width:100%} 29.hero-copy{max-width:640px;will-change:transform,opacity} 30.hero h1{margin:18px 0 22px} 31.hero .cta-row{display:flex;gap:14px;flex-wrap:wrap;margin:30px 0 28px} 32.hero .store-badge{will-change:transform} 33 34/* viewfinder ring that trails the cursor */ 35.spotring{position:absolute;left:0;top:0;width:66px;height:66px;border-radius:50%;z-index:6;pointer-events:none; 36 border:1.5px solid rgba(255,255,255,.6);opacity:0;transition:opacity .45s var(--ease); 37 background: 38 linear-gradient(rgba(255,255,255,.85),rgba(255,255,255,.85)) 50% 0/1.5px 7px, 39 linear-gradient(rgba(255,255,255,.85),rgba(255,255,255,.85)) 50% 100%/1.5px 7px, 40 linear-gradient(rgba(255,255,255,.85),rgba(255,255,255,.85)) 0 50%/7px 1.5px, 41 linear-gradient(rgba(255,255,255,.85),rgba(255,255,255,.85)) 100% 50%/7px 1.5px; 42 background-repeat:no-repeat;transform:translate(-50%,-50%);will-change:transform} 43.spotring::before{content:"";position:absolute;left:50%;top:50%;width:3px;height:3px;border-radius:50%;background:#fff;transform:translate(-50%,-50%);opacity:.9} 44.spotring .sr-f{position:absolute;left:50%;top:calc(100% + 8px);transform:translateX(-50%);font-family:var(--font-display);font-size:.58rem;letter-spacing:.18em;color:rgba(255,255,255,.7);white-space:nowrap} 45.hero.spot-live .spotring{opacity:1} 46 47/* floating proof chips â drift on idle, depth-parallax with the cursor */ 48.hero-float{position:absolute;inset:0;z-index:3;pointer-events:none;will-change:transform,opacity} 49.spot-pill{position:absolute;top:calc(var(--nav-h) + 36px);right:6%;display:flex;align-items:center;gap:7px; 50 font-size:.66rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase; 51 background:rgba(8,8,10,.72);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px); 52 border:1px solid var(--border-strong);border-radius:999px;padding:7px 12px; 53 transition:transform .55s var(--ease-out); 54 transform:translate3d(calc(var(--px,0)*-14px),calc(var(--py,0)*-10px),0)} 55.spot-pill i{width:7px;height:7px;border-radius:50%;background:var(--red);box-shadow:0 0 9px var(--red);animation:cue calc(1.6s / var(--motion-scale)) ease-in-out infinite} 56.spot-chip{position:absolute;transition:transform .55s var(--ease-out); 57 transform:translate3d(calc(var(--px,0)*var(--depth,-24)*1px),calc(var(--py,0)*var(--depth,-24)*.7px),0)} 58.spot-chip>div{display:flex;align-items:center;gap:11px;padding:13px 16px;border-radius:15px; 59 background:rgba(14,14,19,.82);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px); 60 border:1px solid var(--border-strong);box-shadow:0 26px 54px -20px rgba(0,0,0,.8); 61 animation:chipfloat calc(6s / var(--motion-scale)) ease-in-out infinite} 62.spot-chip .ic{width:36px;height:36px;border-radius:11px;display:grid;place-items:center;flex:0 0 auto;font-size:1.05rem} 63.spot-chip b{font-size:.94rem;font-weight:800;line-height:1.1} 64.spot-chip small{display:block;color:var(--text-dim);font-size:.74rem} 65.spot-chip.rate{right:21%;top:29%;--depth:-30} 66.spot-chip.taps{right:7%;bottom:23%;--depth:-16} 67.spot-chip.taps>div{animation-delay:-2.6s} 68@keyframes chipfloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-12px)}} 69[data-motion="off"] .spot-chip>div,[data-motion="off"] .spot-pill i{animation:none} 70 71 72/* ---- store CTA (primary) ---- */ 73.store-cta{margin-top:36px} 74.hero .badges-label{font-size:.72rem;letter-spacing:.22em;text-transform:uppercase;color:var(--text-faint);margin-bottom:14px;font-weight:700} 75.store-badges--hero{align-items:stretch} 76.store-note{margin-top:16px;font-size:.86rem;color:var(--text-dim);display:flex;align-items:center;gap:9px} 77.store-note .rs{color:var(--gold);letter-spacing:1px} 78 79.scroll-cue{position:absolute;
79left:50%;bottom:26px;transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;gap:8px;color:var(--text-faint);font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;z-index:4} 80.scroll-cue .line{width:1px;height:34px;background:linear-gradient(var(--text-faint),transparent);animation:cue calc(2s / var(--motion-scale)) ease-in-out infinite} 81@keyframes cue{0%,100%{transform:scaleY(.4);transform-origin:top;opacity:.4}50%{transform:scaleY(1);opacity:1}} 82 83/* ---- intro ---- */ 84.intro-grid{display:grid;grid-template-columns:1fr 1.05fr;gap:64px;align-items:center} 85.intro-media{aspect-ratio:16/10;position:relative} 86.intro-media.is-3d{aspect-ratio:auto;min-height:540px} 87.stat-row{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;margin-top:42px} 88 89/* ---- 3D membership lookbook ---- */ 90.scene3d{position:relative;width:100%;height:100%;min-height:540px;perspective:1300px;perspective-origin:46% 42%} 91.scene3d-stage{position:absolute;inset:0;transform-style:preserve-3d;transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) scale(var(--fit,1));transition:transform .6s var(--ease-out)} 92.lb-el{position:absolute;top:50%;left:50%;transform-style:preserve-3d; 93 transform:translate(-50%,-50%) translate3d(var(--x,0px),var(--y,0px),var(--z,0px)) rotateZ(var(--rz,0deg)) scale(var(--s,1)); 94 transition:transform .6s var(--ease-out),box-shadow .6s var(--ease)} 95 96.lb-plate{width:380px;height:300px;border-radius:24px;--z:-80px; 97 background:radial-gradient(120% 90% at 70% 15%,rgba(108,77,246,.5),transparent 60%), 98 radial-gradient(80% 80% at 15% 95%,rgba(255,94,44,.28),transparent 60%),#0c0c12; 99 border:1px solid var(--border)} 100.lb-plate::before{content:"";position:absolute;inset:0;border-radius:inherit;opacity:.5; 101 background-image:linear-gradient(rgba(255,255,255,.07) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.07) 1px,transparent 1px); 102 background-size:34px 34px;-webkit-mask-image:radial-gradient(ellipse 80% 80% at 50% 40%,#000 30%,transparent 80%);mask-image:radial-gradient(ellipse 80% 80% at 50% 40%,#000 30%,transparent 80%)} 103 104.lb-card{border-radius:18px;overflow:hidden;border:1px solid var(--border-strong);background:var(--surface); 105 box-shadow:0 36px 80px -28px rgba(0,0,0,.85)} 106.lb-card video{width:100%;height:100%;object-fit:cover;display:block} 107.lb-card .lb-shade{position:absolute;inset:0;background:linear-gradient(180deg,transparent 46%,rgba(8,8,10,.82))} 108.lb-card .lb-meta{position:absolute;left:13px;right:13px;bottom:12px;display:flex;align-items:center;justify-content:space-between;gap:8px} 109.lb-card .lb-meta b{font-family:var(--font-display);font-size:.82rem;text-transform:uppercase;letter-spacing:.02em;line-height:1.1} 110.lb-card .lb-meta .pricepin{font-size:.7rem;font-weight:700;color:var(--violet-bright);white-space:nowrap} 111.lb-card .lb-live{position:absolute;top:12px;left:12px;display:flex;align-items:center;gap:6px;font-size:.64rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase; 112 background:rgba(8,8,10,.7);backdrop-filter:blur(6px);border:1px solid var(--border-strong);border-radius:999px;padding:5px 9px} 113.lb-card .lb-live i{width:6px;height:6px;border-radius:50%;background:var(--red);box-shadow:0 0 8px var(--red);animation:cue calc(1.6s / var(--motion-scale)) ease-in-out infinite} 114.lb-card.a{width:196px;height:256px;--x:-122px;--y:16px;--z:0px;--rz:-8deg} 115.lb-card.b{width:202px;height:264px;--x:6px;--y:-12px;--z:80px;--s:1.04;border-color:rgba(138,114,255,.55);box-shadow:0 40px 90px -28px rgba(108,77,246,.8)} 116.lb-card.c{width:186px;height:242px;--x:112px;--y:36px;--z:34px;--rz:7deg} 117 118.lb-lens{width:104px;height:104px;border-radius:50%;--x:-152px;--y:-120px;--z:120px; 119 background:radial-gradient(circle at 38% 30%,#4a4474,#15151c 64%); 120 box-shadow:0 0 0 2px rgba(255,255,255,.1),inset 0 2px 7px rgba(255,255,255,.16),inset 0 0 0 7px rgba(0,0,0,.55),0 22px 48px -14px rgba(108,77,246,.7)} 121.lb-iris{position:absolute;inset:15px;border-radius:50%;background:repeating-conic-gradient(from 10deg,#24242f 0 30deg,#16161d 30deg 60deg);box-shadow:inset 0 0 16px rgba(0,0,0,.85)} 122.lb-pupil{position:absolute;
122left:50%;top:50%;width:34px;height:34px;border-radius:50%;transform:translate(-50%,-50%); 123 background:radial-gradient(circle,#0a0a12,#1a1340);box-shadow:0 0 20px rgba(138,114,255,.9),inset 0 0 9px rgba(138,114,255,.6);transition:width .6s var(--ease-out),height .6s var(--ease-out)} 124.lb-fstop{position:absolute;left:50%;bottom:-22px;transform:translateX(-50%);font-family:var(--font-display);font-size:.6rem;letter-spacing:.14em;color:var(--text-dim);white-space:nowrap} 125 126.lb-chip{display:flex;align-items:center;gap:9px;padding:11px 14px;border-radius:14px; 127 background:rgba(15,15,19,.82);backdrop-filter:blur(10px);border:1px solid var(--border-strong);box-shadow:0 18px 44px -16px rgba(0,0,0,.75)} 128.lb-chip .ic{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;flex:0 0 auto;font-size:.9rem} 129.lb-chip b{font-size:.86rem;font-weight:700;line-height:1.1} 130.lb-chip small{display:block;color:var(--text-dim);font-size:.7rem} 131.lb-chip.rate{--x:134px;--y:-114px;--z:150px} 132.lb-chip.book{--x:108px;--y:152px;--z:108px} 133 134.scene3d:hover .lb-plate{--z:-112px} 135.scene3d:hover .lb-card.a{--x:-150px;--z:42px;--rz:-11deg} 136.scene3d:hover .lb-card.b{--z:134px;--s:1.07} 137.scene3d:hover .lb-card.c{--x:148px;--z:82px;--rz:10deg} 138.scene3d:hover .lb-lens{--x:-184px;--y:-142px;--z:206px} 139.scene3d:hover .lb-lens .lb-pupil{width:52px;height:52px} 140.scene3d:hover .lb-chip.rate{--x:166px;--y:-140px;--z:236px} 141.scene3d:hover .lb-chip.book{--x:132px;--y:188px;--z:182px} 142@media(max-width:1180px){.scene3d-stage{--fit:.9}} 143@media(max-width:560px){.scene3d-stage{--fit:.78}} 144 145/* ---- explore sessions : scroll-driven only (no hover) ---- 146 Cards fade/rise in from below, drift out above, each column parallaxes 147 at its own speed; photos parallax inside their frames; a ghost 148 "SESSIONS" wordmark drifts behind everything. */ 149.sessions{position:relative;overflow:clip} 150/* pinned mode (desktop): the section becomes a tall scroll track and the 151 inner stage sticks to the viewport while cards fly in one by one */ 152.sess-pin{position:relative} 153.sessions.pin-on{overflow:visible;padding:0;height:calc(var(--sess-n,3)*140vh);height:calc(var(--sess-n,3)*140svh)} 154.sessions.pin-on .sess-pin{position:sticky;top:0;height:100vh;height:100svh;display:flex;flex-direction:column;justify-content:center;overflow:clip;padding-top:var(--nav-h)} 155.sessions.pin-on .sess-card{position:relative;transition:background .35s var(--ease),border-color .35s var(--ease)} 156.sessions.pin-on .sess-media{will-change:transform} 157/* while a session is zooming down from its full-page image, the card frame 158 gets out of the way and the media is free to escape its bounds */ 159.sess-card.is-zoom{overflow:visible;background:transparent;border-color:transparent;z-index:6} 160/* cinematic session title over the full-page image */ 161.sess-zoom-title{position:absolute;left:clamp(24px,6vw,90px);bottom:clamp(28px,9vh,90px);z-index:7;pointer-events:none;opacity:0;will-change:transform,opacity} 162.sess-zoom-title i{font-style:normal;display:block;margin-bottom:12px;font-size:.72rem;font-weight:700;letter-spacing:.24em;text-transform:uppercase;color:var(--violet-bright)} 163.sess-zoom-title b{display:block;font-family:var(--font-display);font-weight:800;text-transform:uppercase;font-size:clamp(2.6rem,5.6vw,4.6rem);line-height:.96;letter-spacing:-.01em;text-shadow:0 6px 40px rgba(0,0,0,.55)} 164.sess-zoom-title span{display:block;margin-top:14px;color:rgba(255,255,255,.85);font-size:1rem;letter-spacing:.04em;text-shadow:0 2px 18px rgba(0,0,0,.6)} 165@media(max-height:780px){.sessions.pin-on .sess-media{height:250px}.sessions.pin-on .sess-head{margin-bottom:32px}} 166.sess-ghost{position:absolute;top:26px;left:50%;z-index:0;transform:translate3d(-50%,0,0);white-space:nowrap;pointer-events:none; 167 font-family:var(--font-display);font-weight:800;text-transform:uppercase;line-height:1;letter-spacing:.04em; 168 font-size:clamp(6rem,17vw,15rem);color:transparent;-webkit-text-stroke:1px rgba(255,255,255,.06);will-change:transform} 169.sess-head{display:flex;align-items:flex-end;justify-content:space-between;gap:28px;margin-bottom:56px;position:relative;z-index:1} 170.sess-head .btn{flex:0 0 auto;margin-bottom:8px} 171.sess-grid{display:grid;grid-template-columns:repeat(var(--sess-cols,3),1fr);gap:26px;position:relative;z-index:1} 172.sess-card{border-radius:var(--r-xl);overflow:hidden;background:var(--surface);border:1px solid var(--border);will-change:transform,opacity} 173.sess-card[data-link]{cursor:pointer} 174.sess-loc em{font-style:normal;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} 175.sess-media{position:relative;height:330px;overflow:hidden;background:#000} 176.sess-bg{position:absolute;inset:-30px;background-size:cover;background-position:center;filter:blur(22px) brightness(.5) saturate(1.15)} 177.sess-media image-slot{position:absolute;
177left:14px;right:14px;top:14px;bottom:14px;width:auto;height:auto} 178.sess-shade{position:absolute;inset:0;z-index:1;pointer-events:none;background:linear-gradient(180deg,transparent 52%,rgba(6,6,9,.74))} 179.sess-slot{position:absolute;left:14px;bottom:14px;z-index:2;display:flex;align-items:center;gap:7px; 180 font-size:.68rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase; 181 background:rgba(8,8,10,.74);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px); 182 border:1px solid var(--border-strong);border-radius:999px;padding:7px 12px;white-space:nowrap} 183.sess-slot svg{width:13px;height:13px;flex:0 0 auto;color:var(--violet-bright)} 184.sess-body{padding:20px 22px 24px} 185.sess-title{font-family:var(--font-display);font-weight:800;text-transform:uppercase;font-size:1.16rem;line-height:1.05} 186.sess-meta{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:9px} 187.sess-loc{color:var(--text-dim);font-size:.9rem;display:flex;align-items:center;gap:6px;min-width:0} 188.sess-loc svg{width:15px;height:15px;flex:0 0 auto;color:var(--violet-bright)} 189.sess-spots{flex:0 0 auto;font-size:.74rem;font-weight:700;letter-spacing:.06em;color:var(--gold);white-space:nowrap} 190@media(max-width:900px){ 191 .sess-head{flex-direction:column;align-items:flex-start;gap:22px;margin-bottom:40px} 192 .sess-grid{grid-template-columns:1fr;max-width:460px;margin-inline:auto} 193 .sess-media{height:300px} 194} 195 196/* ---- media video ---- */ 197.media-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;border:0} 198 199/* ---- testimonials ---- */ 200.tgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:22px;align-items:stretch} 201.tgrid .tphoto{position:relative;border-radius:var(--r-lg);overflow:hidden;min-height:380px} 202.tgrid .tphoto image-slot{width:100%;height:100%} 203@media(max-width:1080px){.tgrid{grid-template-columns:repeat(2,1fr)}} 204@media(max-width:600px){.tgrid{grid-template-columns:1fr}.tgrid .tphoto{min-height:300px}} 205 206/* ---- testimonials 3D / spotlight / parallax ---- */ 207.tgrid-wrap{position:relative} 208.tcell{display:flex;opacity:1} 209.tcell.reveal{opacity:0} 210.tcell.reveal.in{animation-name:revealFade} 211@keyframes revealFade{from{opacity:0}to{opacity:1}} 212.tcell{perspective:1000px} 213.tcell>.t3d{flex:1} 214.t3d{position:relative;transform-style:preserve-3d;will-change:transform; 215 transform:translate3d(0,var(--py,0px),var(--tz,0px)) rotateX(var(--trx,0deg)) rotateY(var(--try,0deg)); 216 transition:transform .35s var(--ease-out),box-shadow .4s var(--ease),filter .3s} 217.t3d.is-tilting{transition:transform .09s linear,box-shadow .4s var(--ease),filter .3s} 218.t3d:hover{--tz:30px;filter:brightness(1.05)} 219.tphoto.t3d{min-height:380px} 220.tglare{position:absolute;inset:0;border-radius:inherit;pointer-events:none;opacity:0;z-index:4; 221 transition:opacity .35s var(--ease);mix-blend-mode:screen; 222 background:radial-gradient(circle 200px at var(--gx,50%) var(--gy,50%),rgba(255,255,255,.22),rgba(255,255,255,0) 62%)} 223.t3d:hover .tglare{opacity:1} 224.quote-card.t3d{overflow:visible} 225.quote-card.t3d .qmark{transform:translateZ(54px)} 226.quote-card.t3d>p{transform:translateZ(28px)} 227.quote-card.t3d .who{transform:translateZ(40px)} 228.tspot{position:absolute;inset:-50px;pointer-events:none;z-index:6;opacity:0; 229 transition:opacity .5s var(--ease);mix-blend-mode:multiply; 230 background:radial-gradient(circle 360px at var(--mx,50%) var(--my,40%),rgba(7,7,10,0) 0,rgba(7,7,10,0) 24%,rgba(5,5,8,.6) 80%)} 231.tgrid-wrap.is-live .tspot{opacity:1} 232@media(max-width:600px){.tphoto.t3d{min-height:300px}} 233 234/* ---- trial ---- */ 235.trial-grid{display:grid;grid-template-columns:1fr 1fr;gap:54px;align-items:center} 236.trial-form{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-xl);padding:38px} 237 238/* ---- host CTA strip ---- */ 239.host-strip-link{display:inline-flex;align-items:center;color:#fff} 240.host-strip-link .arrow{display:inline-block;transition:transform .25s var(--ease-out)} 241.host-strip-link:hover .arrow{transform:translateX(6px)} 242 243@media(max-width:980px){.spot-chip{display:none}} 244@media(max-width:880px){ 245 .hero{min-height:94svh} 246 .hero-scrim{background:linear-gradient(90deg,rgba(6,6,9,.88),rgba(6,6,9,.55) 58%,rgba(6,6,9,.28)), 247 linear-gradient(180deg,rgba(6,6,9,.62),transparent 28% 58%,rgba(6,6,9,.96))} 248 .spot-pill{top:calc(var(--nav-h) + 22px);right:5%} 249 .intro-grid,.trial-grid{grid-template-columns:1fr;gap:36px} 250 .intro-media{order:-1} 251} 252</style> 253</head> 254<body data-page=""> 255<header data-site-header></header> 256 257<main> 258 <!-- ===== HERO â full-bleed monochrome spotlight ===== --> 259 <section class="hero" id="hero"> 260 <div class="hero-bgmedia" aria-hidden="true"> 261 <video class="hero-vid" src="https://vid.cdn-website.com/md/pexels/videos/adult-art-beautiful-body-7312181-v.mp4" autoplay muted loop playsinline></video> 262 <div class="hero-mono"></div> 263 <div class="hero-spotglow"></div> 264 <div class="hero-scrim"></div> 265 </div> 266 267 <div class="wrap"> 268 <div class="hero-copy"> 269 <h1 class="display h-xxl reveal">Your lifestyle<br>deserves more<br>spotlight<span class="dot">.</span></h1> 270 <p class="lede reveal" style="--d:120ms">Book curated photography sessions and studio spaces designed for creators who want to be seen â and stand out.</p> 271 <div id="get-app" class="store-cta reveal" style="--d:220ms"> 272 <p class="badges-label">Download the app</p> 273 <div class="store-badges store-badges--hero"> 274 <a class="store-badge" href="https://apps.apple.com/us/app/monochroam/id6572305481" target="_blank" rel="noopener"><svg viewBox="0 0 24 24" fill="#fff"><path d="M16.4 12.8c0-2.3 1.9-3.4 2-3.5-1.1-1.6-2.8-1.8-3.4-1.8-1.4-.1-2.8.8-3.5.8s-1.8-.8-3-.8c-1.5 0-3 .9-3.8 2.3-1.6 2.8-.4 7 1.2 9.3.8 1.1 1.7 2.4 2.9 2.3 1.2 0 1.6-.7 3-.7s1.8.7 3 .7 2-1.1 2.8-2.2c.9-1.3 1.2-2.5 1.3-2.6-.1 0-2.5-1-2.5-3.8zM14.3 6.3c.6-.8 1-1.9.9-3-.9 0-2 .6-2.7 1.4-.6.7-1.1 1.8-1 2.8 1 .1 2.1-.5 2.8-1.2z"/></svg><span><span class="sb-t">Download on the</span><span class="sb-b">App Store</span></span></a> 275 <a class="store-badge" href="https://play.google.com/store/apps/details?id=so.monochroam.app&hl=en" target="_blank" rel="noopener"><svg viewBox="0 0 24 24">
275<path d="M3.6 2.2 13 11.6 3.6 21z" fill="#34d399"/><path d="M13 11.6 3.6 2.2l11.8 6.7z" fill="#60a5fa"/><path d="M13 11.6 15.4 8.9 20.5 11.8 15.4 14.6z" fill="#fbbf24"/><path d="M13 11.6 3.6 21l11.8-6.4z" fill="#f87171"/></svg><span><span class="sb-t">Get it on</span><span class="sb-b">Google Play</span></span></a> 276 </div> 277 <p class="store-note"><span class="rs">â â â â â </span> Free to download · Book your first session in 3 taps</p> 278 </div> 279 </div> 280 </div> 281 282 <div class="hero-float" aria-hidden="true"> 283 <span class="spot-pill"><i></i>Now live in Toronto</span> 284 <div class="spot-chip rate"><div> 285 <div class="ic" style="background:var(--violet-soft);color:var(--violet-bright)">â </div> 286 <div><b>Real sessions, real studios</b><small>browse below</small></div> 287 </div></div> 288 <div class="spot-chip taps"><div> 289 <div class="ic" style="background:rgba(255,94,44,.18);color:var(--orange)">â</div> 290 <div><b>Booked in 3 taps</b><small>instant confirmation</small></div> 291 </div></div> 292 </div> 293 294 <div class="spotring" id="spotRing" aria-hidden="true"><span class="sr-f">f/1.8</span></div> 295 <div class="scroll-cue"><span class="line"></span>Scroll</div> 296 </section> 297 298 <!-- ===== MARQUEE ===== --> 299 <div class="marquee" aria-hidden="true"> 300 <div class="marquee-track"> 301 <span class="marquee-item">Portrait sessions <i class="sep"></i> Daylight lofts <i class="sep"></i> Neon sets <i class="sep"></i> Rooftops <i class="sep"></i> Cycloramas <i class="sep"></i> Content houses <i class="sep"></i></span> 302 <span class="marquee-item">Portrait sessions <i class="sep"></i> Daylight lofts <i class="sep"></i> Neon sets <i class="sep"></i> Rooftops <i class="sep"></i> Cycloramas <i class="sep"></i> Content houses <i class="sep"></i></span> 303 </div> 304 </div> 305 306 <!-- ===== INTRO ===== --> 307 <section class="section bg-soft"> 308 <div class="wrap"> 309 <div class="intro-grid"> 310 <div> 311 <span class="eyebrow reveal">The membership</span> 312 <h2 class="display h-xl reveal" style="--d:80ms;margin:18px 0 20px">A world of<br>curated creative<br>sessions<span class="dot">.</span></h2> 313 <p class="lede reveal" style="--d:160ms">One membership, thousands of vetted studios, sets and shoots. Find your next look, book it in seconds, and show up ready to create.</p> 314 </div> 315 <div class="intro-media is-3d reveal" style="--d:120ms"> 316 <div class="scene3d" id="membership3d" aria-hidden="true"> 317 <div class="scene3d-stage"> 318 <div class="lb-el lb-plate"></div> 319 <div class="lb-el lb-card a"> 320 <video src="https://www.pexels.com/download/video/6258806/" autoplay muted loop playsinline></video> 321 <div class="lb-shade"></div> 322 <div class="lb-meta"><b>Daylight loft</b><span class="pricepin">2 cr</span></div> 323 </div> 324 <div class="lb-el lb-card c"> 325 <video src="https://www.pexels.com/download/video/7205783/" autoplay muted loop playsinline></video> 326 <div class="lb-shade"></div> 327 <div class="lb-meta"><b>Rooftop</b><span class="pricepin">3 cr</span></div> 328 </div> 329 <div class="lb-el lb-card b"> 330 <video src="https://www.pexels.com/download/video/32152186/" autoplay muted loop playsinline></video> 331 <div class="lb-shade"></div> 332 <span class="lb-live"><i></i>Now booking</span> 333 <div class="lb-meta"><b>Neon set</b><span class="pricepin">1 cr</span></div> 334 </div> 335 <div class="lb-el lb-lens"> 336 <div class="lb-iris"></div> 337 <div class="lb-pupil"></div> 338 <div class="lb-fstop">f / 1.8</div> 339 </div> 340 <div class="lb-el lb-chip rate"> 341 <div class="ic" style="background:var(--violet-soft);color:var(--violet-bright)">â </div> 342 <div><b>Now live in Toronto</b><small>real studios & sessions</small></div> 343 </div> 344 <div class="lb-el lb-chip book"> 345 <div class="ic" style="background:rgba(255,94,44,.18);color:var(--orange)">â</div> 346 <div><b>Booked in 3 taps</b><small>instant confirmation</small></div> 347 </div> 348 </div> 349 </div> 350 </div> 351 </div> 352 </div> 353 </section> 354 355 <!-- ===== EXPLORE SESSIONS ===== --> 356 <section class="section sessions" id="sessions"> 357 <div class="sess-pin"> 358 <div class="sess-ghost" aria-hidden="true">
358Sessions</div> 359 <div class="sess-zoom-title" aria-hidden="true"><i></i><b></b><span></span></div> 360 <div class="wrap"> 361 <div class="sess-head"> 362 <div> 363 <span class="eyebrow reveal">Explore sessions</span> 364 <h2 class="display h-xl reveal" style="--d:80ms;margin-top:16px">Step into<br>the next shoot<span class="dot">.</span></h2> 365 </div> 366 <a class="btn sess-btn" href="meet-the-hosts.html">Explore all sessions <span class="arrow">â</span></a> 367 </div> 368 369 <div class="sess-grid" id="sessGrid"> 370 <!-- Static snapshot of real Toronto inventory so the strongest proof asset 371 paints instantly (no "Loading sessionsâ¦" flash). feed.js overwrites this 372 with live data on load; if the network fails, this snapshot stays visible. 373 Regenerated from the publicHomeFeed endpoint â keep in sync on major changes. --> 374 <article class="sess-card" data-sspeed=".55" data-link="https://monochroam.app.link/6GkqYmSWRXb"> 375 <div class="sess-media"><div class="sess-bg" style="background-image:url("https://firebasestorage.googleapis.com/v0/b/shutterpass-32152.appspot.com/o/users%2FURG4CpqxKQf0AD7YTAMSXwwNwap1%2Fuploads%2F1778192364673000_3.jpg?alt=media&token=2cabc54c-f47d-41bf-888d-0f952426d4df")"></div><image-slot id="sess-1NVLJxZ6uWagQsjDDUAX" shape="rect" fit="contain" placeholder="" src="https://firebasestorage.googleapis.com/v0/b/shutterpass-32152.appspot.com/o/users%2FURG4CpqxKQf0AD7YTAMSXwwNwap1%2Fuploads%2F1778192364673000_3.jpg?alt=media&token=2cabc54c-f47d-41bf-888d-0f952426d4df"></image-slot></div> 376 <div class="sess-body"><h3 class="sess-title">Portraits: Cassette Culture</h3><div class="sess-meta"><div class="sess-loc"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M12 22s8-4 8-10a8 8 0 1 0-16 0c0 6 8 10 8 10Z"/><circle cx="12" cy="12" r="2.5"/></svg><em>260 Adelaide Street West Studio 300 Toronto ON M5H 1X6 Canada</em></div><span class="sess-spots">10 cr · 10 spots left</span></div></div> 377 </article> 378 <article class="sess-card" data-sspeed="-.35" data-link="https://share.monochroam.com/share/session/1QVE0lSwRpOfAeWuI6Mq"> 379 <div class="sess-media"><div class="sess-bg" style="background-image:url("https://firebasestorage.googleapis.com/v0/b/shutterpass-32152.appspot.com/o/users%2FURG4CpqxKQf0AD7YTAMSXwwNwap1%2Fuploads%2F1778192521276000_0.jpg?alt=media&token=ea46da7f-32c3-4961-8b3a-3b480dae7355")"></div><image-slot id="sess-1QVE0lSwRpOfAeWuI6Mq" shape="rect" fit="contain" placeholder="" src="https://firebasestorage.googleapis.com/v0/b/shutterpass-32152.appspot.com/o/users%2FURG4CpqxKQf0AD7YTAMSXwwNwap1%2Fuploads%2F1778192521276000_0.jpg?alt=media&token=ea46da7f-32c3-4961-8b3a-3b480dae7355"></image-slot></div> 380 <div class="sess-body"><h3 class="sess-title">Portraits: Cosmic Serenity</h3><div class="sess-meta"><div class="sess-loc"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M12 22s8-4 8-10a8 8 0 1 0-16 0c0 6 8 10 8 10Z"/><circle cx="12" cy="12" r="2.5"/></svg><em>98 Montcalm Ave Toronto ON M6E 4P2 Canada</em></div><span class="sess-spots">10 cr · 10 spots left</span></div></div> 381 </article> 382 <article class="sess-card" data-sspeed=".8" data-link="https://monochroam.app.link/G5K0m3JUq1b"> 383 <div class="sess-media"><div class="sess-bg" style="background-image:url("https://firebasestorage.googleapis.com/v0/b/shutterpass-32152.appspot.com/o/users%2FURG4CpqxKQf0AD7YTAMSXwwNwap1%2Fuploads%2F1778192860026000_17.jpg?alt=media&token=5d8e0693-0574-488d-87f8-0304200db1a6")"></div><image-slot id="sess-2A5539lR79EfP2l5uVXu" shape="rect" fit="contain" placeholder="" src="https://firebasestorage.googleapis.com/v0/b/shutterpass-32152.appspot.com/o/users%2FURG4CpqxKQf0AD7YTAMSXwwNwap1%2Fuploads%2F1778192860026000_17.jpg?alt=media&token=5d8e0693-0574-488d-87f8-0304200db1a6"></image-slot></div> 384 <div class="sess-body"><h3 class="sess-title">Portrait Photoshoot: Analog Fever</h3><div class="sess-meta"><div class="sess-loc"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M12 22s8-4 8-10a8 8 0 1 0-16 0c0 6 8 10 8 10Z"/><circle cx="12" cy="12" r="2.5"/></svg><em>1173 Dundas ST E Suite 226 Toronto ON M4M 3P1 Canada</em></div><span class="sess-spots">10 cr · 11 spots left</span></div></div> 385 </article> 386 </div> 387 </div> 388 </div> 389 </section> 390 391 <!-- ===== TESTIMONIALS ===== --> 392 <section class="section"> 393 <div class="wrap"> 394 <div class="center" style="max-width:680px;margin:0 auto 56px">
395 <span class="eyebrow eyebrow--center reveal">From our early community</span> 396 <h2 class="display h-xl reveal" style="--d:80ms;margin-top:16px">Don't take<br>our word for it</h2> 397 <p class="lede reveal" style="--d:160ms;margin:18px auto 0;font-size:1rem;opacity:.72">Early community voices â verified Toronto reviews land as our first sessions wrap.</p> 398 </div> 399 <div class="tgrid-wrap" data-spotlight> 400 <div class="tspot"></div> 401 <div class="tgrid" data-stagger="80"> 402 <div class="tcell reveal" data-pspeed="-0.06"> 403 <div class="quote-card t3d" data-tone="violet"> 404 <span class="tglare"></span> 405 <span class="qmark">â</span> 406 <p>Monochroam changed the game for me. I find and join photography events, meet fellow creators and capture amazing memories â social and exciting all at once. I'm hooked.</p> 407 <div class="who"><div class="av" style="color:var(--violet-bright)">K</div><div><b>Kate M.</b><span>Creator</span></div></div> 408 </div> 409 </div> 410 <div class="tcell reveal" data-pspeed="0.05"> 411 <div class="tphoto t3d"><video class="media-video" src="https://vid.cdn-website.com/md/pexels/videos/pexels-photo-3761547-v.mp4" autoplay muted loop playsinline></video><span class="tglare"></span></div> 412 </div> 413 <div class="tcell reveal" data-pspeed="-0.045"> 414 <div class="tphoto t3d"><video class="media-video" src="https://vid.cdn-website.com/md/pexels/videos/free-video-3403285-v.mp4" autoplay muted loop playsinline></video><span class="tglare"></span></div> 415 </div> 416 <div class="tcell reveal" data-pspeed="0.07"> 417 <div class="quote-card t3d" data-tone="magenta"> 418 <span class="tglare"></span> 419 <span class="qmark">â</span> 420 <p>My go-to for discovering photography adventures and meeting new friends. It lets me explore my passion while connecting with like-minded people â and it's so easy to use.</p> 421 <div class="who"><div class="av" style="color:#d645b4">J</div><div><b>Jayne J.</b><span>Photographer</span></div></div> 422 </div> 423 </div> 424 <div class="tcell reveal" data-pspeed="-0.06"> 425 <div class="tphoto t3d"><video class="media-video" src="https://vid.cdn-website.com/md/pexels/videos/art-beauty-bright-business-8113110-v.mp4" autoplay muted loop playsinline></video><span class="tglare"></span></div> 426 </div> 427 <div class="tcell reveal" data-pspeed="0.05"> 428 <div class="quote-card t3d" data-tone="orange"> 429 <span class="tglare"></span> 430 <span class="qmark">â</span> 431 <p>It seamlessly connects me with photography events and unforgettable moments. Monochroam satisfies my desire for social, thrilling experiences. I'm absolutely captivated.</p> 432 <div class="who"><div class="av" style="color:var(--orange)">J</div><div><b>Jayce H.</b><span>Stylist · Toronto</span></div></div> 433 </div> 434 </div> 435 <div class="tcell reveal" data-pspeed="-0.045"> 436 <div class="quote-card t3d" data-tone="gold"> 437 <span class="tglare"></span> 438 <span class="qmark">â</span> 439 <p>I appreciate simplicity and quality â and Monochroam ticks every box. Intuitive, friendly, and it lets me dive into personal branding without any hassle. A name I won't forget.</p> 440 <div class="who"><div class="av" style="color:var(--gold)">A</div><div><b>Aaron M.</b><span>Model</span></div></div> 441 </div> 442 </div> 443 <div class="tcell reveal" data-pspeed="0.07"> 444 <div class="tphoto t3d"><video class="media-video" src="https://vid.cdn-website.com/md/pexels/videos/achievement-adult-art-business-7546828-v.mp4" autoplay muted loop playsinline></video><span class="tglare"></span></div> 445 </div> 446 </div> 447 </div> 448 </div> 449 </section> 450 451 <!-- ===== HOST CTA STRIP ===== --> 452 <section class="section--tight bg-violet"> 453 <div class="wrap center"> 454 <a class="host-strip-link reveal" href="hosts.html">
455 <span class="display h-md">Run sessions? Become a Founding Host <span class="arrow">â</span></span> 456 </a> 457 </div> 458 </section> 459 460 <!-- ===== APP CTA ===== --> 461 <section class="section bg-soft"> 462 <div class="wrap center"> 463 <span class="eyebrow eyebrow--center reveal">Get the app</span> 464 <h2 class="display h-xl reveal" style="--d:80ms;margin:16px 0 20px">Your spotlight,<br><span class="grad-text">in your pocket</span></h2> 465 <p class="lede reveal" style="--d:160ms;margin-inline:auto">Browse, book and check in â all from the app. Download it free and be shooting by the weekend.</p> 466 <div class="store-badges store-badges--hero reveal" style="--d:220ms;justify-content:center;margin-top:32px"> 467 <a class="store-badge" href="https://apps.apple.com/us/app/monochroam/id6572305481" target="_blank" rel="noopener"><svg viewBox="0 0 24 24" fill="#fff"><path d="M16.4 12.8c0-2.3 1.9-3.4 2-3.5-1.1-1.6-2.8-1.8-3.4-1.8-1.4-.1-2.8.8-3.5.8s-1.8-.8-3-.8c-1.5 0-3 .9-3.8 2.3-1.6 2.8-.4 7 1.2 9.3.8 1.1 1.7 2.4 2.9 2.3 1.2 0 1.6-.7 3-.7s1.8.7 3 .7 2-1.1 2.8-2.2c.9-1.3 1.2-2.5 1.3-2.6-.1 0-2.5-1-2.5-3.8zM14.3 6.3c.6-.8 1-1.9.9-3-.9 0-2 .6-2.7 1.4-.6.7-1.1 1.8-1 2.8 1 .1 2.1-.5 2.8-1.2z"/></svg><span><span class="sb-t">Download on the</span><span class="sb-b">App Store</span></span></a> 468 <a class="store-badge" href="https://play.google.com/store/apps/details?id=so.monochroam.app&hl=en" target="_blank" rel="noopener"><svg viewBox="0 0 24 24"><path d="M3.6 2.2 13 11.6 3.6 21z" fill="#34d399"/><path d="M13 11.6 3.6 2.2l11.8 6.7z" fill="#60a5fa"/><path d="M13 11.6 15.4 8.9 20.5 11.8 15.4 14.6z" fill="#fbbf24"/><path d="M13 11.6 3.6 21l11.8-6.4z" fill="#f87171"/></svg><span><span class="sb-t">Get it on</span><span class="sb-b">Google Play</span></span></a> 469 </div> 470 </div> 471 </section> 472</main> 473 474<footer data-site-footer></footer> 475
476<script> 477/* Tweak defaults (host-persisted) */ 478const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ 479 "motion": "maximal", 480 "accent": "violet" 481}/*EDITMODE-END*/; 482</script>
vendor: 1 bytes, line 482
482
483<script src="image-slot.js"></script>
vendor: 1 bytes, line 483
483
484<script src="feed.js"></script>
vendor: 1 bytes, line 484
484
485<script> 486/* Hero â monochrome spotlight: cursor reveal, scroll colour-bloom, magnetic badges */ 487(function(){ 488 var hero=document.getElementById('hero'); 489 if(!hero) return; 490 var ring=document.getElementById('spotRing'); 491 var mono=hero.querySelector('.hero-mono'); 492 var vid=hero.querySelector('.hero-vid'); 493 var copy=hero.querySelector('.hero-copy'); 494 var floatWrap=hero.querySelector('.hero-float'); 495 var cue=hero.querySelector('.scroll-cue'); 496 var reduce=matchMedia('(prefers-reduced-motion:reduce)').matches; 497 var touch=matchMedia('(hover:none)').matches; 498 function motionOff(){return document.documentElement.dataset.motion==='off';} 499 500 var W=hero.clientWidth,H=hero.clientHeight; 501 window.addEventListener('resize',function(){W=hero.clientWidth;H=hero.clientHeight;}); 502 503 /* --- spotlight position: eased follow (spot leads, viewfinder ring trails) --- */ 504 var tx=W*.72,ty=H*.4, sx=tx,sy=ty, rx2=tx,ry2=ty, overUI=false, raf=null; 505 function frame(){ 506 sx+=(tx-sx)*.16; sy+=(ty-sy)*.16; 507 rx2+=(tx-rx2)*.09; ry2+=(ty-ry2)*.09; 508 hero.style.setProperty('--sx',sx.toFixed(1)+'px'); 509 hero.style.setProperty('--sy',sy.toFixed(1)+'px'); 510 if(ring) ring.style.transform='translate3d('+rx2.toFixed(1)+'px,'+ry2.toFixed(1)+'px,0) translate(-50%,-50%) scale('+(overUI?.5:1)+')'; 511 if(Math.abs(tx-sx)>.4||Math.abs(ty-sy)>.4||Math.abs(tx-rx2)>.4||Math.abs(ty-ry2)>.4){raf=requestAnimationFrame(frame);} 512 else raf=null; 513 } 514 function kick(){ if(!raf) raf=requestAnimationFrame(frame); } 515 516 if(!touch&&!reduce){ 517 hero.addEventListener('pointermove',function(e){ 518 if(motionOff()) return; 519 var r=hero.getBoundingClientRect(); 520 tx=e.clientX-r.left; ty=e.clientY-r.top; 521 overUI=!!(e.target.closest&&e.target.closest('a,button,input')); 522 hero.classList.add('spot-live'); 523 hero.style.setProperty('--px',(tx/r.width-.5).toFixed(3)); 524 hero.style.setProperty('--py',(ty/r.height-.5).toFixed(3)); 525 kick(); 526 }); 527 hero.addEventListener('pointerleave',function(){ 528 tx=W*.72; ty=H*.4; overUI=false; 529 hero.classList.remove('spot-live'); 530 hero.style.setProperty('--px','0'); hero.style.setProperty('--py','0'); 531 kick(); 532 }); 533 534 /* magnetic store badges */
535 [].slice.call(hero.querySelectorAll('.store-badge')).forEach(function(b){ 536 b.addEventListener('pointermove',function(e){ 537 if(motionOff()) return; 538 var r=b.getBoundingClientRect(); 539 var mx=(e.clientX-r.left-r.width/2)/r.width, my=(e.clientY-r.top-r.height/2)/r.height; 540 b.style.transform='translate('+(mx*10).toFixed(1)+'px,'+(my*8).toFixed(1)+'px)'; 541 }); 542 b.addEventListener('pointerleave',function(){b.style.transform='';}); 543 }); 544 } 545 546 /* --- touch: spotlight drifts on its own while hero is on screen --- */ 547 if(touch&&!reduce){ 548 var running=false; 549 function drift(ts){ 550 if(!running) return; 551 if(!motionOff()){ 552 tx=W*(.5+.32*Math.sin(ts*.00021)); 553 ty=H*(.4+.2*Math.sin(ts*.00033+1.3)); 554 sx+=(tx-sx)*.04; sy+=(ty-sy)*.04; 555 hero.style.setProperty('--sx',sx.toFixed(1)+'px'); 556 hero.style.setProperty('--sy',sy.toFixed(1)+'px'); 557 } 558 requestAnimationFrame(drift); 559 } 560 if('IntersectionObserver' in window){ 561 new IntersectionObserver(function(en){ 562 var on=en[0].isIntersecting; 563 if(on&&!running){running=true;requestAnimationFrame(drift);} 564 if(!on) running=false; 565 }).observe(hero); 566 }else{running=true;requestAnimationFrame(drift);} 567 } 568 569 /* --- scroll: parallax + the spotlight blooms open, colour floods in --- */ 570 if(!reduce){ 571 var ticking=false; 572 function onScroll(){ 573 if(ticking) return; ticking=true; 574 requestAnimationFrame(function(){ 575 ticking=false; 576 if(motionOff()){ 577 vid.style.transform=''; mono.style.opacity=''; copy.style.transform=''; copy.style.opacity=''; 578 if(floatWrap){floatWrap.style.transform='';floatWrap.style.opacity='';} 579 if(cue) cue.style.opacity=''; 580 hero.style.setProperty('--spot-r','300px'); 581 return; 582 } 583 var y=window.scrollY||document.documentElement.scrollTop; 584 var p=Math.min(1,Math.max(0,y/(H*.85))); 585 vid.style.transform='scale(1.08) translateY('+(y*.22).toFixed(1)+'px)'; 586 hero.style.setProperty('--spot-r',(300+p*1500).toFixed(0)+'px'); 587 mono.style.opacity=(1-p).toFixed(3); 588 copy.style.transform='translateY('+(-y*.13).toFixed(1)+'px)'; 589 copy.style.opacity=Math.max(0,1-p*1.2).toFixed(3); 590 if(floatWrap){ 591 floatWrap.style.transform='translateY('+(y*.3).toFixed(1)+'px)'; 592 floatWrap.style.opacity=Math.max(0,1-p*1.4).toFixed(3); 593 } 594 if(cue) cue.style.opacity=Math.max(0,1-p*3).toFixed(3); 595 }); 596 } 597 window.addEventListener('scroll',onScroll,{passive:true}); 598 window.addEventListener('resize',onScroll); 599 onScroll(); 600 } 601})(); 602</script>
vendor: 1 bytes, line 602
602
603<script> 604(function(){ 605 var scene=document.getElementById('membership3d'); 606 if(!scene) return; 607 var stage=scene.querySelector('.scene3d-stage'); 608 if(matchMedia('(hover:none)').matches||matchMedia('(prefers-reduced-motion:reduce)').matches) return; 609 var raf; 610 scene.addEventListener('pointermove',function(e){ 611 if(document.documentElement.dataset.motion==='off') return; 612 var r=scene.getBoundingClientRect(); 613 var px=(e.clientX-r.left)/r.width-0.5; 614 var py=(e.clientY-r.top)/r.height-0.5; 615 cancelAnimationFrame(raf); 616 raf=requestAnimationFrame(function(){ 617 stage.style.setProperty('--ry',(px*16).toFixed(2)+'deg'); 618 stage.style.setProperty('--rx',(-py*12).toFixed(2)+'deg'); 619 }); 620 }); 621 scene.addEventListener('pointerleave',function(){ 622 stage.style.setProperty('--ry','0deg'); 623 stage.style.setProperty('--rx','0deg'); 624 }); 625})(); 626 627/* Explore sessions \u2014 pinned scroll story (desktop): the section holds the 628 viewport; each session opens as a full-page image, then zooms down into 629 its card slot, one per viewport of scroll. Ends on the settled card 630 grid with the CTA fading into its place. Small screens / reduced motion 631 fall back to simple scroll parallax. Called after the live feed renders 632 the cards. */ 633window.__initSessionsPin=function(){ 634 var sec=document.getElementById('sessions'); 635 if(!sec||sec.__pinInit) return; 636 sec.__pinInit=true; 637 if(matchMedia('(prefers-reduced-motion:reduce)').matches) return; 638 var ghost=sec.querySelector('.sess-ghost'); 639 var btn=sec.querySelector('.sess-btn'); 640 var cards=[].slice.call(sec.querySelectorAll('.sess-card')); 641 if(!cards.length) return; 642 function p2(n){return ('0'+n).slice(-2);} 643 var state=cards.map(function(c){ 644 return {tx:0,ty:0,s:1,r:parseFloat(getComputedStyle(c).borderTopLeftRadius)||24}; 645 }); 646 var zt=sec.querySelector('.sess-zoom-title'); 647 var ztN=zt&&zt.querySelector('i'), ztT=zt&&zt.querySelector('b'), ztM=zt&&zt.querySelector('span'); 648 var info=cards.map(function(c){ 649 var t=c.querySelector('.sess-title'), l=c.querySelector('.sess-loc'), p=c.querySelector('.sess-slot'); 650 return {t:t?t.textContent:'', m:(l?l.textContent:'')+(p?' â '+p.textContent:'')}; 651 }); 652 var lastZ=-1; 653 function motionOff(){return document.documentElement.dataset.motion==='off';} 654 function smooth(t){t=Math.min(1,Math.max(0,t));return t*t*(3-2*t);} 655 var pinOn=false; 656 657 function resetInline(){ 658 cards.forEach(function(c,i){ 659 c.classList.remove('is-zoom'); 660 c.style.transform='';c.style.opacity=''; 661 state[i].tx=0;state[i].ty=0;state[i].s=1; 662 var m=c.querySelector('.sess-media'); 663 if(m){m.style.transform='';m.style.borderRadius='';} 664 var slot=c.querySelector('.sess-media>image-slot'); 665 if(slot) slot.style.transform=''; 666 var body=c.querySelector('.sess-body'); if(body) body.style.opacity=''; 667 var pill=c.querySelector('.sess-slot'); if(pill) pill.style.opacity=''; 668 }); 669 if(btn){btn.style.opacity='';btn.style.transform='';} 670 if(zt){zt.style.opacity='';zt.style.transform='';} 671 if(ghost) ghost.style.transform='translate3d(-50%,0,0)'; 672 } 673 function setMode(){ 674 var want=matchMedia('(min-width:900px)').matches&&window.innerHeight>=540&&!motionOff(); 675 if(want!==pinOn){pinOn=want;sec.classList.toggle('pin-on',pinOn);resetInline();} 676 } 677 678 var ticking=false; 679 function frame(){ 680 ticking=false; 681 var vh=window.innerHeight||document.documentElement.clientHeight; 682 var vw=window.innerWidth||document.documentElement.clientWidth; 683 if(motionOff()){setMode();resetInline();return;} 684 var r=sec.getBoundingClientRect(); 685 if(r.bottom<-160||r.top>vh+160) return; 686 687 if(pinOn){ 688 var track=Math.max(1,sec.offsetHeight-vh); 689 var P=Math.min(1,Math.max(0,-r.top/track)); 690 if(ghost) ghost.style.transform='translate3d(calc(-50% + '+((P-.5)*-150).toFixed(1)+'px),'+((P-.5)*90).toFixed(1)+'px,0)'; 691 var seg=.88/cards.length, zBest=0, zI=-1, zY=0; 692 var ex=Math.max(0,-r.top-track); /* px scrolled past the pin */ 693 cards.forEach(function(c,i){ 694 var st=state[i]; 695 var m=c.querySelector('.sess-media'); 696 var body=c.querySelector('.sess-body'); 697 var pill=c.querySelector('.sess-slot'); 698 var slot=c.querySelector('.sess-media>image-slot'); 699 var t=(P-i*seg)/seg; 700 if(!m){ /* card without media: simple fade, no zoom */ 701 c.style.opacity=t<=0?'0':'1'; 702 return; 703 } 704 if(t<=0||t>=.9){ /* waiting below, or settled in its slot */ 705 c.classList.remove('is-zoom'); 706 m.style.transform='';m.style.borderRadius=''; 707 if(body) body.style.opacity=''; 708 if(pill) pill.style.opacity=''; 709 st.tx=0;st.ty=0;st.s=1; 710 c.style.opacity=t<=0?'0':(.38+.62*smooth((P-.88)/.1)).toFixed(3); 711 /* settled grid keeps its parallax once the section releases: 712 per-column speeds + inner photo drift, converging to 0 at the pin */ 713 var sp=parseFloat(c.getAttribute('data-sspeed'))||0; 714 c.style.transform=ex>
7140?'translate3d(0,'+(ex*sp*-.55).toFixed(1)+'px,0)':''; 715 if(slot) slot.style.transform=''; 716 return; 717 } 718 /* zooming: from full-page image down into the card slot */ 719 c.classList.add('is-zoom'); 720 c.style.transform=''; 721 if(slot) slot.style.transform=''; 722 var mr=m.getBoundingClientRect(); 723 var nw=mr.width/st.s, nh=mr.height/st.s; /* untransformed size */ 724 var cx=(mr.left+mr.right)/2-st.tx, cy=(mr.top+mr.bottom)/2-st.ty; 725 var dx=vw/2-cx, dy=vh/2-cy; 726 var S=Math.max(vw/nw,vh/nh)*1.02; /* cover the viewport */ 727 var f=Math.min(1,t/.12); /* full-page fade-in */ 728 var b=smooth((t-.3)/.56); /* hold full-page, then zoom down */ 729 var tx=dx*(1-b), ty=dy*(1-b), s=S*(1-b)+b; 730 c.style.opacity=f.toFixed(3); 731 m.style.transform='translate3d('+tx.toFixed(1)+'px,'+ty.toFixed(1)+'px,0) scale('+s.toFixed(4)+')'; 732 m.style.borderRadius=(st.r/s).toFixed(2)+'px'; 733 st.tx=tx;st.ty=ty;st.s=s; 734 var bo=smooth((t-.78)/.16); /* card text fades in as it lands */ 735 if(body) body.style.opacity=bo.toFixed(3); 736 if(pill) pill.style.opacity=bo.toFixed(3); 737 /* cinematic title rides the full-page image, gone by mid-zoom */ 738 var tv=f*(1-smooth((t-.26)/.32)); 739 if(tv>zBest){zBest=tv;zI=i;zY=28*(1-f)-22*b;} 740 }); 741 if(zt){ 742 if(zI>=0&&zI!==lastZ){ 743 lastZ=zI; 744 if(ztN) ztN.textContent='Session '+p2(zI+1)+' / '+p2(cards.length); 745 if(ztT) ztT.textContent=info[zI].t; 746 if(ztM) ztM.textContent=info[zI].m; 747 } 748 zt.style.opacity=zBest.toFixed(3); 749 zt.style.transform='translate3d(0,'+zY.toFixed(1)+'px,0)'; 750 } 751 if(btn){ 752 var bb=smooth((P-.84)/.12); 753 btn.style.opacity=bb.toFixed(3); 754 btn.style.transform='translate3d(0,'+((1-bb)*16).toFixed(1)+'px,0)'; 755 } 756 }else{ 757 /* fallback: symmetric fade + per-column parallax */ 758 var p=Math.min(1,Math.max(0,(vh-r.top)/(vh+r.height))); 759 if(ghost) ghost.style.transform='translate3d(calc(-50% + '+((p-.5)*-150).toFixed(1)+'px),'+((p-.5)*110).toFixed(1)+'px,0)'; 760 cards.forEach(function(c){ 761 var sp=parseFloat(c.getAttribute('data-sspeed'))||0; 762 var cr=c.getBoundingClientRect(); 763 var o=(cr.top+cr.height/2-vh/2)/vh; 764 var ease=smooth(1-Math.min(1,Math.max(0,(Math.abs(o)-.2)/.42))); 765 c.style.opacity=(.08+.92*ease).toFixed(3); 766 c.style.transform='translate3d(0,'+(o*sp*240).toFixed(1)+'px,0) scale('+(.93+.07*ease).toFixed(4)+')'; 767 }); 768 } 769 } 770 function onScroll(){if(!ticking){ticking=true;requestAnimationFrame(frame);}} 771 window.addEventListener('scroll',onScroll,{passive:true}); 772 window.addEventListener('resize',function(){setMode();onScroll();}); 773 setMode();onScroll(); 774}; 775 776/* Testimonials \u2014 3D tilt + glare + cursor spotlight + scroll parallax */ 777(function(){ 778 var wrap=document.querySelector('.tgrid-wrap[data-spotlight]'); 779 if(!wrap) return; 780 var spot=wrap.querySelector('.tspot'); 781 var cards=[].slice.call(wrap.querySelectorAll('.t3d')); 782 var touch=matchMedia('(hover:none)').matches; 783 var reduce=matchMedia('(prefers-reduced-motion:reduce)').matches; 784 function motionOff(){return document.documentElement.dataset.motion==='off';} 785 786 /* cursor spotlight */ 787 if(!touch){ 788 wrap.addEventListener('pointermove',function(e){ 789 if(motionOff()){wrap.classList.remove('is-live');return;} 790 var r=wrap.getBoundingClientRect(); 791 spot.style.setProperty('--mx',((e.clientX-r.left)/r.width*100).toFixed(1)+'%'); 792 spot.style.setProperty('--my',((e.clientY-r.top)/r.height*100).toFixed(1)+'%'); 793 wrap.classList.add('is-live'); 794 }); 795 wrap.addEventListener('pointerleave',function(){wrap.classList.remove('is-live');}); 796 } 797 798 /* per-card tilt + glare */ 799 if(!touch && !reduce){ 800 cards.forEach(function(card){ 801 var raf; 802 card.addEventListener('pointermove',function(e){ 803 if(motionOff()) return; 804 var r=card.getBoundingClientRect(); 805 var px=(e.clientX-r.left)/r.width, py=(e.clientY-r.top)/r.height; 806 cancelAnimationFrame(raf); 807 raf=requestAnimationFrame(function(){ 808 card.classList.add('is-tilting'); 809 card.style.setProperty('--try',((px-0.5)*15).toFixed(2)+'deg'); 810 card.style.setProperty('--trx',((0.5-py)*13).toFixed(2)+'deg'); 811 card.style.setProperty('--gx',(px*100).toFixed(1)+'%'); 812 card.style.setProperty('--gy',(py*100).toFixed(1)+'%'); 813 }); 814 }); 815 card.addEventListener('pointerleave',function(){ 816 card.classList.remove('is-tilting'); 817 card.style.setProperty('--try','0deg'); 818 card.style.setProperty('--trx','0deg'); 819 }); 820 }); 821 } 822 823 /* scroll parallax */ 824 if(!reduce){ 825 var ticking=false; 826 function onScroll(){ 827 if(ticking) return; ticking=true; 828 requestAnimationFrame(function(){ 829 ticking=false; 830 var vh=window.innerHeight||document.documentElement.clientHeight; 831 cards.forEach(function(c){ 832 if(motionOff()){c.style.setProperty('--py','0px');return;} 833 var sp=parseFloat(c.getAttribute('data-pspeed'))||parseFloat(c.parentNode.getAttribute('data-pspeed'))||0; 834 var r=c.getBoundingClientRect(); 835 var off=(r.top+r.height/2)-vh/2; 836 var py=Math.max(-58,Math.min(58,-off*sp)); 837 c.style.setProperty('--py',py.toFixed(1)+'px'); 838 }); 839 }); 840 } 841 window.addEventListener('scroll',onScroll,{passive:true}); 842 window.addEventListener('resize',onScroll); 843 onScroll(); 844 } 845})(); 846 847/* Explore sessions â live data from the Monochroam public feed (cached 848 10 min in localStorage by feed.js). Renders only the fields the API 849 provides; the whole section is removed when no sessions come back. */ 850(function(){ 851 var sec=document.getElementById('sessions'); 852 /* Leave the static Toronto snapshot in place if the feed layer is unavailable. */ 853 if(!sec||!window.MonoFeed){return;} 854 var F=window.MonoFeed; 855 var CAL='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="3" y="5" width="18" height="16" rx="3"/><path d="M3 10h18M8 3v4M16 3v4"/></svg>'; 856 var PIN='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M12 22s8-4 8-10a8 8 0 1 0-16 0c0 6 8 10 8 10Z"/><circle cx="12" cy="12" r="2.5"/></svg>'; 857 F.sessions().then(function(list){ 858 list=(list||[]).filter(function(s){return F.has(s.sessionName);}).slice(0,3); 859 /* No live sessions (e.g. network/cache miss) â keep the static snapshot painted. */ 860 if(!list.length){if(window.__initSessionsPin) window.__initSessionsPin();return;} 861 var grid=document.getElementById('sessGrid'); 862 var speeds=['.55','-.35','.8']; 863 sec.style.setProperty('--sess-n',list.length); 864 grid.style.setProperty('--sess-cols',Math.min(3,list.length)); 865 grid.innerHTML=list.map(function(s,i){ 866 var img=F.has(s.images)?s.images[0]:null; 867 var when=F.fmtDate(s.nextSessionDate); 868 var left=F.spotsLeft(s); 869 var bits=[]; 870 if(Number(s.averageReviews)>0) bits.push('â '+Number(s.averageReviews).toFixed(1)); 871 if(Number(s.credits)>0) bits.push(s.credits+' cr'); 872 if(left) bits.push(left+' spot'+(left===1?'':'s')+' left'); 873 var h='<article class="sess-card" data-sspeed="'+speeds[i%3]+'"'+(F.has(s.sessionLink)?' data-link="'+F.esc(s.sessionLink)+'"':'')+'>'; 874 if(img){ 875 h+='<div class="sess-media">' 876 +'<div class="sess-bg" style="background-image:url("'+F.esc(img)+'")"></div>' 877 +'<image-slot id="sess-'+F.esc(s.id||i)+'" shape="rect" fit="contain" placeholder="" src="'+F.esc(img)+'"></image-slot>' 878 +(when?'<span class="sess-slot">'+CAL+'Next slot · '+F.esc(when.slot)+'</span>':'') 879 +'</div>'; 880 } 881 h+='<div class="sess-body"><h3 class="sess-title">'+F.esc(s.sessionName)+'</h3>'; 882 if(F.has(s.address)||bits.length){ 883 h+='<div class="sess-meta">' 884 +(F.has(s.address)?'<div class="sess-loc">'+PIN+'<em>'+F.esc(F.prettyAddress(s.address))+'</em></div>':'') 885 +(bits.length?'<span class="sess-spots">'+bits.join(' · ')+'</span>':'') 886 +'</div>'; 887 } 888 h+='</div></article>'; 889 return h; 890 }).join(''); 891 grid.querySelectorAll('[data-link]').forEach(function(card){ 892 card.addEventListener('click',function(){ 893 window.open(card.getAttribute('data-link'),'_blank','noopener'); 894 }); 895 }); 896 if(window.__initSessionsPin) window.__initSessionsPin(); 897 }); 898})(); 899</script>
vendor: 1 bytes, line 899
899
900<script src="components.js"></script>
900 901</body> 902</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.