improved a lot of things

This commit is contained in:
SinachPat
2026-04-26 16:45:57 +01:00
parent 7a4c1d3147
commit 855ca56f5a
7 changed files with 4819 additions and 10 deletions
@@ -0,0 +1,652 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Live Artboard — Originmain</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root{--bg:#FFFFFF;--bg-subtle:#FAFAFA;--bg-muted:#F4F4F5;--bg-strong:#EBEBEB;--bg-inv:#0A0A0A;--bg-inv-2:#141414;--bg-inv-3:#1C1C1C;--fg:#0A0A0A;--fg-2:#52525B;--fg-3:#A1A1AA;--fg-4:#D4D4D8;--fg-inv:rgba(255,255,255,0.92);--fg-inv-2:rgba(255,255,255,0.52);--fg-inv-3:rgba(255,255,255,0.28);--blue:#0066FF;--blue-dark:#0050CC;--blue-light:#3385FF;--blue-soft:rgba(0,102,255,0.07);--blue-mid:rgba(0,102,255,0.15);--purple:#7C3AED;--teal:#0891B2;--border:rgba(0,0,0,0.07);--border-2:rgba(0,0,0,0.12);--border-inv:rgba(255,255,255,0.08);--border-inv-2:rgba(255,255,255,0.14);--r-1:4px;--r-2:8px;--r-3:12px;--r-4:16px;--r-5:20px;--r-6:24px;--r-full:9999px;--sh-xs:0 1px 2px rgba(0,0,0,0.05);--sh-sm:0 1px 3px rgba(0,0,0,0.07),0 1px 2px rgba(0,0,0,0.05);--sh-md:0 4px 8px rgba(0,0,0,0.06),0 2px 4px rgba(0,0,0,0.04);--sh-lg:0 10px 24px rgba(0,0,0,0.08),0 4px 8px rgba(0,0,0,0.05);--sh-xl:0 20px 40px rgba(0,0,0,0.09),0 8px 16px rgba(0,0,0,0.05);--sh-2xl:0 32px 64px rgba(0,0,0,0.11),0 16px 32px rgba(0,0,0,0.06);--font:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;--mono:'JetBrains Mono','SF Mono',ui-monospace,'Cascadia Code',monospace;}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
html{font-size:16px;scroll-behavior:smooth;-webkit-font-smoothing:antialiased;}
body{font-family:var(--font);background:var(--bg);color:var(--fg);line-height:1.6;overflow-x:hidden;}
img,svg{display:block;max-width:100%;}
a{color:inherit;text-decoration:none;}
button{font-family:inherit;cursor:pointer;border:none;background:none;}
.wrap{max-width:1120px;margin:0 auto;padding:0 40px;}
.section{padding:112px 0;}
.section-muted{background:var(--bg-subtle);}
.section-dark{background:var(--bg-inv);}
.d1{font-size:clamp(2.5rem,6vw,4.5rem);font-weight:900;line-height:1.02;letter-spacing:-0.045em;color:var(--fg);}
.d2{font-size:clamp(1.875rem,3.5vw,2.75rem);font-weight:800;line-height:1.1;letter-spacing:-0.038em;color:var(--fg);}
.d3{font-size:clamp(1.25rem,2.5vw,1.625rem);font-weight:700;line-height:1.25;letter-spacing:-0.028em;color:var(--fg);}
.subtitle{font-size:clamp(1rem,1.8vw,1.125rem);font-weight:400;line-height:1.75;color:var(--fg-2);}
.label{font-family:var(--mono);font-size:0.6875rem;font-weight:500;letter-spacing:0.1em;text-transform:uppercase;color:var(--fg-3);}
.label-blue{color:var(--blue);}
.btn{display:inline-flex;align-items:center;gap:8px;font-family:var(--font);font-size:0.9375rem;font-weight:600;padding:11px 22px;border-radius:var(--r-2);transition:transform 0.12s cubic-bezier(.16,1,.3,1),opacity 0.12s,box-shadow 0.12s;white-space:nowrap;letter-spacing:-0.01em;position:relative;overflow:hidden;}
.btn::after{content:'';position:absolute;inset:0;background:rgba(255,255,255,0);transition:background 0.12s;}
.btn:hover::after{background:rgba(255,255,255,0.06);}
.btn:active{transform:scale(0.98)!important;}
.btn-primary{background:var(--fg);color:var(--bg);box-shadow:var(--sh-sm);}
.btn-primary:hover{transform:translateY(-1px);box-shadow:var(--sh-md);}
.btn-secondary{background:transparent;color:var(--fg);border:1px solid var(--border-2);}
.btn-secondary:hover{background:var(--bg-muted);transform:translateY(-1px);}
.btn-blue{background:var(--blue);color:#fff;box-shadow:0 4px 12px rgba(0,102,255,0.3);}
.btn-blue:hover{background:var(--blue-dark);transform:translateY(-1px);}
.btn-lg{font-size:1rem;padding:13px 28px;}
.btn-white{background:#fff;color:#0A0A0A;box-shadow:0 4px 12px rgba(255,255,255,0.15);}
.btn-white:hover{background:#F5F5F5;transform:translateY(-1px);}
.btn-outline-white{background:transparent;color:rgba(255,255,255,0.72);border:1px solid rgba(255,255,255,0.18);}
.btn-outline-white:hover{background:rgba(255,255,255,0.06);color:rgba(255,255,255,0.9);transform:translateY(-1px);}
.divider{height:1px;background:var(--border);}
.section-head{text-align:center;max-width:640px;margin:0 auto 72px;}
.section-head .label{display:block;margin-bottom:16px;}
.section-head .d2{margin-bottom:18px;}
/* NAV */
#nav{position:fixed;top:0;left:0;right:0;z-index:200;height:60px;display:flex;align-items:center;padding:0 40px;transition:background 0.2s,border-color 0.2s,box-shadow 0.2s;}
#nav.scrolled{background:rgba(255,255,255,0.85);backdrop-filter:blur(20px) saturate(1.6);-webkit-backdrop-filter:blur(20px) saturate(1.6);border-bottom:1px solid var(--border);box-shadow:var(--sh-xs);}
.nav-inner{max-width:1120px;margin:0 auto;width:100%;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;}
.nav-logo{justify-self:start;font-size:1rem;font-weight:800;letter-spacing:-0.04em;color:var(--fg);display:flex;align-items:center;gap:2px;}
.nav-logo span{color:var(--blue);}
.nav-links{justify-self:center;display:flex;align-items:center;gap:0;list-style:none;}
.nav-links a{font-size:0.9375rem;font-weight:500;color:var(--fg-2);padding:6px 14px;border-radius:var(--r-1);transition:color 0.12s,background 0.12s;letter-spacing:-0.01em;}
.nav-links a:hover{color:var(--fg);}
.nav-actions{justify-self:end;display:flex;align-items:center;gap:8px;}
/* Dropdown */
.nav-dropdown{position:relative;}
.nav-dropdown>a{display:flex;align-items:center;gap:4px;}
.nav-dd-caret{transition:transform 0.15s;}
/* caret rotation handled via JS .open class */
.nav-dropdown-menu{position:absolute;top:calc(100% + 10px);left:50%;transform:translateX(-50%) translateY(-4px);background:rgba(255,255,255,0.98);backdrop-filter:blur(20px);border:1px solid var(--border);border-radius:var(--r-3);box-shadow:var(--sh-xl);padding:8px;min-width:240px;opacity:0;visibility:hidden;transition:opacity 0.15s,transform 0.15s,visibility 0.15s;pointer-events:none;}
.nav-dropdown-menu.open{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0);pointer-events:all;}
.nav-dropdown.open .nav-dd-caret{transform:rotate(180deg);}
/* Mobile sub-nav */
.nav-mobile-sub{display:none;padding:2px 0 6px 14px;flex-direction:column;}
.nav-mobile-sub.open{display:flex;}
.nav-mobile-sub a{font-size:0.875rem;color:rgba(255,255,255,0.4);padding:8px 4px;border-bottom:1px solid rgba(255,255,255,0.06);letter-spacing:-0.01em;transition:color 0.1s;}
.nav-mobile-sub a:last-child{border-bottom:none;}
.nav-mobile-sub a:hover{color:rgba(255,255,255,0.8);}
/* Dark hero: white nav before scrolling */
#nav:not(.scrolled) .nav-logo{color:rgba(255,255,255,0.92);}
#nav:not(.scrolled) .nav-logo span{color:#3385FF;}
#nav:not(.scrolled) .nav-links a{color:rgba(255,255,255,0.5);}
#nav:not(.scrolled) .nav-links a:hover{color:rgba(255,255,255,0.9);}
#nav:not(.scrolled) .nav-actions .btn-secondary{color:rgba(255,255,255,0.65);border-color:rgba(255,255,255,0.2);background:transparent;}
#nav:not(.scrolled) .nav-burger span{background:rgba(255,255,255,0.8);}
.nav-dd-item{display:flex;align-items:flex-start;gap:10px;padding:9px 10px;border-radius:var(--r-2);transition:background 0.1s;cursor:pointer;}
.nav-dd-item:hover{background:var(--bg-muted);}
.nav-dd-icon{width:30px;height:30px;background:var(--blue-soft);border:1px solid var(--blue-mid);border-radius:6px;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:13px;}
.nav-dd-text{display:flex;flex-direction:column;}
.nav-dd-name{font-size:0.8125rem;font-weight:600;color:var(--fg);letter-spacing:-0.01em;}
.nav-dd-desc{font-size:0.6875rem;color:var(--fg-3);margin-top:1px;line-height:1.4;}
.nav-dd-sep{height:1px;background:var(--border);margin:4px 0;}
.nav-burger{display:none;flex-direction:column;justify-content:center;align-items:center;gap:5px;width:36px;height:36px;background:none;border:none;cursor:pointer;padding:4px;border-radius:var(--r-2);}
.nav-burger span{display:block;width:20px;height:2px;background:var(--fg);border-radius:2px;transition:transform 0.22s cubic-bezier(0.16,1,0.3,1),opacity 0.18s;transform-origin:center;}
.nav-burger.open span:nth-child(1){transform:translateY(7px) rotate(45deg);}
.nav-burger.open span:nth-child(2){opacity:0;transform:scaleX(0);}
.nav-burger.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg);}
.nav-mobile{display:none;position:absolute;top:60px;left:0;right:0;background:rgba(255,255,255,0.97);backdrop-filter:blur(20px);border-bottom:1px solid var(--border);box-shadow:0 8px 32px rgba(0,0,0,0.07);padding:12px 24px 24px;flex-direction:column;gap:2px;}
.nav-mobile.open{display:flex;}
.nav-mobile ul{list-style:none;display:flex;flex-direction:column;}
.nav-mobile ul li a{display:block;font-size:1rem;font-weight:500;color:var(--fg-2);padding:11px 4px;border-bottom:1px solid var(--border);letter-spacing:-0.01em;}
.nav-mobile ul li:last-child a{border-bottom:none;}
.nav-mobile-ctas{display:flex;gap:8px;margin-top:16px;}
.nav-mobile-ctas .btn{flex:1;justify-content:center;padding:10px 12px;font-size:.875rem;}
/* PAGE HERO */
#page-hero{padding:140px 40px 100px;background:var(--bg-inv);position:relative;overflow:hidden;text-align:center;}
#page-hero::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse 80% 60% at 50% -10%,rgba(51,133,255,0.12),transparent 60%),radial-gradient(ellipse 40% 40% at 80% 70%,rgba(124,58,237,0.07),transparent 50%);pointer-events:none;}
.page-hero-inner{position:relative;max-width:800px;margin:0 auto;}
.page-hero-inner .label{color:rgba(255,255,255,0.3);margin-bottom:20px;display:block;}
.page-hero-inner .d1{color:var(--fg-inv);margin-bottom:22px;}
.page-hero-inner .subtitle{color:var(--fg-inv-2);max-width:580px;margin:0 auto 44px;}
.page-hero-ctas{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;}
/* PRODUCT VISUAL */
.pv-shell{width:100%;max-width:960px;margin:72px auto 0;border-radius:16px 16px 0 0;overflow:hidden;box-shadow:0 48px 96px rgba(0,0,0,0.45),0 0 0 1px rgba(255,255,255,0.06);border-bottom:none;position:relative;}
.pv-chrome{background:#1C1C22;height:40px;display:flex;align-items:center;padding:0 14px;gap:7px;border-bottom:1px solid rgba(255,255,255,0.05);}
.pv-dot{width:11px;height:11px;border-radius:50%;}
.pv-dot.r{background:#FF5F57;}
.pv-dot.y{background:#FFBD2E;}
.pv-dot.g{background:#28C840;}
.pv-url{flex:1;margin:0 12px;background:rgba(255,255,255,0.06);border-radius:5px;height:25px;display:flex;align-items:center;padding:0 10px;font-family:var(--mono);font-size:0.625rem;color:rgba(255,255,255,0.3);max-width:320px;}
.pv-canvas{background:#0D0D11;height:380px;position:relative;display:flex;align-items:center;justify-content:center;}
.pv-grid{position:absolute;inset:0;background-image:radial-gradient(circle,rgba(255,255,255,0.055) 1px,transparent 1px);background-size:24px 24px;pointer-events:none;}
/* ARTBOARD VISUAL */
.pv-ab{position:absolute;background:#fff;border-radius:10px;overflow:hidden;box-shadow:0 8px 40px rgba(0,0,0,0.6);}
.pv-ab.sel{box-shadow:0 0 0 2px #3385FF,0 8px 40px rgba(0,0,0,0.6);}
.pv-ab-lbl{position:absolute;top:-22px;left:0;font-family:var(--mono);font-size:0.5rem;color:#3385FF;white-space:nowrap;}
.pv-handle{position:absolute;width:7px;height:7px;background:#fff;border:2px solid #3385FF;border-radius:1.5px;z-index:10;}
.pv-h-tl{top:-3px;left:-3px;}
.pv-h-tr{top:-3px;right:-3px;}
.pv-h-bl{bottom:-3px;left:-3px;}
.pv-h-br{bottom:-3px;right:-3px;}
/* LIVE BADGE */
.pv-live-badge{position:absolute;top:16px;right:16px;display:flex;align-items:center;gap:6px;padding:5px 10px;border-radius:6px;background:rgba(16,185,129,0.12);border:1px solid rgba(16,185,129,0.25);}
.pv-live-dot{width:6px;height:6px;border-radius:50%;background:#10B981;box-shadow:0 0 0 2px rgba(16,185,129,0.25);animation:live-pulse 2s ease-in-out infinite;}
@keyframes live-pulse{0%,100%{box-shadow:0 0 0 2px rgba(16,185,129,0.25);}50%{box-shadow:0 0 0 4px rgba(16,185,129,0.1);}}
.pv-live-txt{font-family:var(--mono);font-size:0.5625rem;color:#10B981;font-weight:600;}
/* Fiber overlay */
.pv-fiber{position:absolute;pointer-events:none;z-index:5;}
.pv-fiber-box{position:absolute;border:1px solid rgba(51,133,255,0.5);border-radius:2px;}
.pv-fiber-lbl{position:absolute;background:rgba(51,133,255,0.9);color:#fff;font-family:var(--mono);font-size:0.4rem;padding:1px 4px;border-radius:2px;white-space:nowrap;top:-14px;left:0;}
/* HOW IT WORKS SECTION */
.hiw-steps{display:grid;grid-template-columns:repeat(4,1fr);gap:0;margin-top:64px;position:relative;}
.hiw-steps::before{content:'';position:absolute;top:28px;left:12.5%;right:12.5%;height:1px;background:linear-gradient(90deg,transparent,var(--border-2) 20%,var(--border-2) 80%,transparent);}
.hiw-step{display:flex;flex-direction:column;align-items:center;text-align:center;padding:0 20px;position:relative;z-index:1;}
.hiw-num{width:56px;height:56px;border-radius:50%;background:var(--bg);border:1px solid var(--border-2);display:flex;align-items:center;justify-content:center;font-family:var(--mono);font-size:1rem;font-weight:700;color:var(--blue);margin-bottom:20px;box-shadow:var(--sh-sm);}
.hiw-step h3{font-size:0.9375rem;font-weight:700;color:var(--fg);letter-spacing:-0.02em;margin-bottom:8px;}
.hiw-step p{font-size:0.8125rem;color:var(--fg-2);line-height:1.6;}
/* FEATURE SPLIT */
.feat-split{display:grid;grid-template-columns:1fr 1fr;gap:96px;align-items:center;max-width:1120px;margin:0 auto;}
.feat-split.rev{direction:rtl;}
.feat-split.rev>*{direction:ltr;}
.feat-copy .label{display:block;margin-bottom:16px;}
.feat-copy .d3{margin-bottom:16px;}
.feat-copy .subtitle{margin-bottom:28px;}
.feat-pts{list-style:none;display:flex;flex-direction:column;gap:12px;margin-bottom:32px;}
.feat-pts li{display:flex;align-items:flex-start;gap:10px;font-size:0.9375rem;color:var(--fg-2);line-height:1.55;}
.feat-pt-icon{width:20px;height:20px;border-radius:3px;background:var(--blue-soft);border:1px solid var(--blue-mid);display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1px;font-size:0.625rem;color:var(--blue);}
/* Feature visual */
.feat-vis{border-radius:var(--r-5);overflow:hidden;box-shadow:var(--sh-2xl);border:1px solid var(--border);aspect-ratio:4/3;position:relative;}
.feat-vis-dark{background:#0D0D11;border-color:rgba(255,255,255,0.07);}
.feat-vis-light{background:var(--bg-muted);}
/* TECH SECTION */
.tech-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:56px;}
.tech-card{background:var(--bg);border:1px solid var(--border);border-radius:var(--r-4);padding:32px 28px;transition:box-shadow 0.2s;}
.tech-card:hover{box-shadow:var(--sh-lg);}
.tech-icon{width:44px;height:44px;background:var(--blue-soft);border:1px solid var(--blue-mid);border-radius:var(--r-2);display:flex;align-items:center;justify-content:center;font-size:1.25rem;margin-bottom:18px;}
.tech-card h3{font-size:1rem;font-weight:700;color:var(--fg);letter-spacing:-0.02em;margin-bottom:8px;}
.tech-card p{font-size:0.875rem;color:var(--fg-2);line-height:1.65;}
.tech-tag{display:inline-block;margin-top:14px;font-family:var(--mono);font-size:0.625rem;letter-spacing:0.08em;text-transform:uppercase;color:var(--blue);background:var(--blue-soft);border:1px solid var(--blue-mid);padding:3px 9px;border-radius:var(--r-full);}
/* CODE BLOCK */
.code-block{background:#111118;border:1px solid rgba(255,255,255,0.07);border-radius:var(--r-3);padding:24px;font-family:var(--mono);font-size:0.75rem;line-height:1.75;color:rgba(255,255,255,0.75);overflow-x:auto;}
.code-block .kw{color:#7EB8FF;}
.code-block .str{color:#7DDBA0;}
.code-block .cm{color:rgba(255,255,255,0.28);}
.code-block .fn{color:#FFBA7B;}
.code-block .nm{color:#D4A0FF;}
/* RELATED */
.related-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:48px;}
.related-card{border:1px solid var(--border);border-radius:var(--r-4);padding:24px;transition:box-shadow 0.15s,border-color 0.15s;display:flex;flex-direction:column;gap:10px;}
.related-card:hover{box-shadow:var(--sh-md);border-color:var(--border-2);}
.related-icon{font-size:1.25rem;}
.related-card h3{font-size:0.9375rem;font-weight:700;color:var(--fg);letter-spacing:-0.02em;}
.related-card p{font-size:0.8125rem;color:var(--fg-2);line-height:1.6;flex:1;}
.related-link{font-size:0.8125rem;font-weight:600;color:var(--blue);}
/* CTA */
#cta-bottom{background:var(--bg-inv);padding:120px 40px;position:relative;overflow:hidden;text-align:center;}
#cta-bottom::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse 60% 80% at 30% 50%,rgba(124,58,237,0.12),transparent 60%),radial-gradient(ellipse 60% 80% at 70% 50%,rgba(0,102,255,0.1),transparent 60%);pointer-events:none;}
.cta-inner{position:relative;max-width:680px;margin:0 auto;}
.cta-headline{font-size:clamp(2rem,4.5vw,3.5rem);font-weight:900;letter-spacing:-0.045em;color:var(--fg-inv);line-height:1.05;margin-bottom:18px;}
.cta-sub{font-size:1.0625rem;color:var(--fg-inv-2);margin-bottom:44px;line-height:1.65;}
.cta-actions{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;}
/* FOOTER */
footer{background:#08080C;border-top:1px solid rgba(255,255,255,0.06);padding:72px 40px 40px;}
.ft-inner{max-width:1120px;margin:0 auto;}
.ft-top{display:grid;grid-template-columns:260px repeat(4,1fr);gap:48px;padding-bottom:56px;border-bottom:1px solid rgba(255,255,255,0.07);margin-bottom:36px;}
.ft-brand-logo{font-size:1rem;font-weight:800;letter-spacing:-0.04em;color:rgba(255,255,255,0.92);margin-bottom:8px;}
.ft-brand-logo span{color:#3385FF;}
.ft-brand-tag{font-size:0.875rem;color:rgba(255,255,255,0.3);line-height:1.65;max-width:200px;}
.ft-col h4{font-size:0.875rem;font-weight:600;color:rgba(255,255,255,0.7);margin-bottom:16px;letter-spacing:-0.01em;}
.ft-col ul{list-style:none;display:flex;flex-direction:column;gap:10px;}
.ft-col a{font-size:0.875rem;color:rgba(255,255,255,0.32);transition:color 0.14s;letter-spacing:-0.01em;}
.ft-col a:hover{color:rgba(255,255,255,0.65);}
.ft-bottom{display:flex;justify-content:space-between;align-items:center;}
.ft-copy{font-size:0.8125rem;color:rgba(255,255,255,0.22);}
/* REVEAL */
.reveal{opacity:0;transform:translateY(22px);transition:opacity 0.7s cubic-bezier(0.16,1,0.3,1),transform 0.7s cubic-bezier(0.16,1,0.3,1);}
.reveal.in{opacity:1;transform:none;}
.stagger>*{opacity:0;transform:translateY(16px);transition:opacity 0.55s cubic-bezier(0.16,1,0.3,1),transform 0.55s cubic-bezier(0.16,1,0.3,1);}
.stagger.in>*:nth-child(1){opacity:1;transform:none;transition-delay:0s;}
.stagger.in>*:nth-child(2){opacity:1;transform:none;transition-delay:0.07s;}
.stagger.in>*:nth-child(3){opacity:1;transform:none;transition-delay:0.14s;}
.stagger.in>*:nth-child(4){opacity:1;transform:none;transition-delay:0.21s;}
@media(max-width:1024px){.feat-split{grid-template-columns:1fr;gap:56px;}.feat-split.rev{direction:ltr;}.hiw-steps{grid-template-columns:1fr 1fr;gap:40px;}.hiw-steps::before{display:none;}.tech-grid{grid-template-columns:1fr 1fr;}.related-grid{grid-template-columns:1fr 1fr;}}
@media(max-width:768px){.wrap{padding:0 24px;}#nav{padding:0 24px;}.nav-inner{display:flex;justify-content:space-between;}.nav-links,.nav-actions .btn{display:none;}.nav-burger{display:flex;}#page-hero{padding:120px 24px 80px;}.pv-shell{margin-top:48px;}.hiw-steps{grid-template-columns:1fr;}.tech-grid,.related-grid{grid-template-columns:1fr;}.ft-top{grid-template-columns:1fr 1fr;}}
@media(max-width:480px){.ft-top{grid-template-columns:1fr;}}
</style>
</head>
<body>
<!-- NAV -->
<nav id="nav">
<div class="nav-inner">
<a href="/" class="nav-logo">Origin<span>main</span></a>
<ul class="nav-links">
<li class="nav-dropdown">
<a href="/#features" style="display:flex;align-items:center;gap:4px;">
Product
<svg class="nav-dd-caret" width="10" height="6" viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</a>
<div class="nav-dropdown-menu">
<a class="nav-dd-item" href="/features/live-artboard.html">
<div class="nav-dd-icon"></div>
<div class="nav-dd-text"><span class="nav-dd-name">Live Artboard</span><span class="nav-dd-desc">Your app rendered live in the canvas</span></div>
</a>
<a class="nav-dd-item" href="/features/origin-graph.html">
<div class="nav-dd-icon"></div>
<div class="nav-dd-text"><span class="nav-dd-name">Origin Graph</span><span class="nav-dd-desc">Every component, indexed and queryable</span></div>
</a>
<a class="nav-dd-item" href="/features/intent-diff.html">
<div class="nav-dd-icon"></div>
<div class="nav-dd-text"><span class="nav-dd-name">Intent Diff</span><span class="nav-dd-desc">Ship component-level diffs, not redlines</span></div>
</a>
<div class="nav-dd-sep"></div>
<a class="nav-dd-item" href="/features/completion-zone.html">
<div class="nav-dd-icon"></div>
<div class="nav-dd-text"><span class="nav-dd-name">Completion Zone</span><span class="nav-dd-desc">AI-filled design, constrained to your system</span></div>
</a>
<a class="nav-dd-item" href="/features/agent-bridge.html">
<div class="nav-dd-icon"></div>
<div class="nav-dd-text"><span class="nav-dd-name">Agent Bridge</span><span class="nav-dd-desc">MCP channel to Cursor, Claude Code & more</span></div>
</a>
<a class="nav-dd-item" href="/features/integrations.html">
<div class="nav-dd-icon">🔗</div>
<div class="nav-dd-text"><span class="nav-dd-name">Integrations</span><span class="nav-dd-desc">Linear, Slack, GitHub, Figma & more</span></div>
</a>
</div>
</li>
<li><a href="/features/integrations.html">Integrations</a></li>
<li><a href="/#pricing">Pricing</a></li>
<li><a href="#">Docs</a></li>
</ul>
<div class="nav-actions">
<a href="#" class="btn btn-secondary" style="padding:7px 16px;font-size:.875rem">Log in</a>
<a href="#" class="btn btn-primary" style="padding:8px 18px;font-size:.875rem">Request Access</a>
<button class="nav-burger" id="nav-burger" aria-label="Menu"><span></span><span></span><span></span></button>
</div>
</div>
<div class="nav-mobile" id="nav-mobile">
<ul>
<li>
<a href="/#features" id="mob-product-toggle" style="display:flex;justify-content:space-between;align-items:center;">
Product
<svg id="mob-dd-caret" width="10" height="6" viewBox="0 0 10 6" fill="none" style="transition:transform 0.15s;"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</a>
<div class="nav-mobile-sub" id="nav-mobile-sub">
<a href="/features/live-artboard.html">Live Artboard</a>
<a href="/features/origin-graph.html">Origin Graph</a>
<a href="/features/intent-diff.html">Intent Diff</a>
<a href="/features/completion-zone.html">Completion Zone</a>
<a href="/features/agent-bridge.html">Agent Bridge</a>
<a href="/features/integrations.html">Integrations</a>
</div>
</li>
<li><a href="/features/integrations.html">Integrations</a></li>
<li><a href="/#pricing">Pricing</a></li>
<li><a href="#">Docs</a></li>
</ul>
<div class="nav-mobile-ctas">
<a href="#" class="btn btn-secondary">Log in</a>
<a href="#" class="btn btn-primary">Request Access</a>
</div>
</div>
</nav>
<!-- HERO -->
<section id="page-hero">
<div class="page-hero-inner">
<span class="label reveal">Live Artboard</span>
<h1 class="d1 reveal">Your app,<br>live on the canvas.</h1>
<p class="subtitle reveal">Not a mockup. Not a screenshot. Every artboard is a real iframe render of your actual component tree — running your real code, connected to your real data.</p>
<div class="page-hero-ctas reveal">
<a href="#" class="btn btn-white btn-lg">Request Early Access</a>
<a href="#how-it-works" class="btn btn-outline-white btn-lg">See how it works ↓</a>
</div>
</div>
<!-- Product visual -->
<div class="pv-shell reveal">
<div class="pv-chrome">
<div class="pv-dot r"></div>
<div class="pv-dot y"></div>
<div class="pv-dot g"></div>
<div class="pv-url">🔒 app.originmain.io/canvas</div>
</div>
<div class="pv-canvas">
<div class="pv-grid"></div>
<div class="pv-live-badge"><div class="pv-live-dot"></div><span class="pv-live-txt">Live render</span></div>
<!-- Selected artboard -->
<div class="pv-ab sel" style="top:48px;left:80px;width:220px;">
<div class="pv-ab-lbl">DashboardCard — live</div>
<div class="pv-handle pv-h-tl"></div><div class="pv-handle pv-h-tr"></div>
<div class="pv-handle pv-h-bl"></div><div class="pv-handle pv-h-br"></div>
<!-- Fiber overlay boxes -->
<div class="pv-fiber" style="inset:0;">
<div class="pv-fiber-box" style="top:14px;left:14px;right:14px;height:28px;">
<span class="pv-fiber-lbl">Card</span>
</div>
<div class="pv-fiber-box" style="top:56px;left:14px;width:80px;height:16px;">
<span class="pv-fiber-lbl">Title</span>
</div>
<div class="pv-fiber-box" style="top:56px;right:14px;width:40px;height:16px;"></div>
</div>
<!-- Card content -->
<div style="padding:18px;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;">
<span style="font-size:0.6875rem;font-weight:600;color:#111;letter-spacing:-0.01em;">Revenue Overview</span>
<span style="font-size:0.5625rem;background:#ECFDF5;color:#059669;padding:2px 6px;border-radius:99px;font-weight:600;">Live</span>
</div>
<div style="font-size:1.375rem;font-weight:800;color:#0A0A0A;letter-spacing:-0.045em;line-height:1;margin-bottom:4px;">$12,450</div>
<div style="font-size:0.625rem;color:#059669;font-weight:600;margin-bottom:12px;">↑ +2.4%</div>
<div style="height:2px;background:#F0F0F0;border-radius:99px;overflow:hidden;margin-bottom:12px;"><div style="height:100%;width:68%;background:#0066FF;border-radius:99px;"></div></div>
</div>
</div>
<!-- Second artboard -->
<div class="pv-ab" style="top:48px;right:80px;width:160px;">
<div class="pv-ab-lbl">UserProfile</div>
<div style="padding:16px;text-align:center;">
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#7C3AED,#0066FF);margin:0 auto 8px;"></div>
<div style="font-size:0.6875rem;font-weight:700;color:#0A0A0A;margin-bottom:2px;">Sarah Chen</div>
<div style="font-size:0.5625rem;color:#A1A1AA;">Design Engineer</div>
</div>
</div>
<!-- Inspector peek -->
<div style="position:absolute;right:16px;top:168px;width:156px;background:#111115;border:1px solid rgba(255,255,255,0.07);border-radius:8px;padding:12px;font-family:monospace;">
<div style="font-size:0.4375rem;color:rgba(255,255,255,0.25);letter-spacing:0.1em;text-transform:uppercase;margin-bottom:8px;">Props — Card</div>
<div style="display:flex;justify-content:space-between;margin-bottom:5px;"><span style="font-size:0.5625rem;color:rgba(255,255,255,0.35);">title</span><span style="font-size:0.5625rem;color:#7DDBA0;">"Revenue…"</span></div>
<div style="display:flex;justify-content:space-between;margin-bottom:5px;"><span style="font-size:0.5625rem;color:rgba(255,255,255,0.35);">value</span><span style="font-size:0.5625rem;color:#7EB8FF;">12450</span></div>
<div style="display:flex;justify-content:space-between;"><span style="font-size:0.5625rem;color:rgba(255,255,255,0.35);">live</span><span style="font-size:0.5625rem;color:#FFBA7B;">true</span></div>
</div>
</div>
</div>
</section>
<!-- HOW IT WORKS -->
<section id="how-it-works" class="section">
<div class="wrap">
<div class="section-head reveal">
<span class="label">Architecture</span>
<h2 class="d2">From URL to live canvas in four steps.</h2>
<p class="subtitle">A lightweight runtime bridge connects your running app to the Originmain canvas with no build step required.</p>
</div>
<div class="hiw-steps stagger">
<div class="hiw-step">
<div class="hiw-num">01</div>
<h3>Open any route</h3>
<p>Paste any URL from your running app. Originmain opens it as an iframe-backed artboard in the canvas.</p>
</div>
<div class="hiw-step">
<div class="hiw-num">02</div>
<h3>Fiber hook injects</h3>
<p>A lightweight script injects into the iframe and hooks into React's fiber tree — reading every component's props, state, and DOM rect.</p>
</div>
<div class="hiw-step">
<div class="hiw-num">03</div>
<h3>Canvas receives tree</h3>
<p>The fiber tree streams to the host via postMessage. The canvas renders selection overlays and prop inspectors in real time.</p>
</div>
<div class="hiw-step">
<div class="hiw-num">04</div>
<h3>Edits write back</h3>
<p>Click any component. Change a prop in the inspector. The iframe re-renders instantly — no round-trips, no rebuild.</p>
</div>
</div>
</div>
</section>
<!-- DEEP DIVE 1: Real components -->
<div class="section" style="padding:100px 40px;">
<div class="feat-split reveal">
<div class="feat-copy">
<span class="label label-blue">Real renders</span>
<h2 class="d3">Not a mockup.<br>The actual component tree.</h2>
<p class="subtitle">Every artboard runs your actual React components in a sandboxed iframe. Your real styles, your real tokens, your real data — all visible and editable from the canvas.</p>
<ul class="feat-pts">
<li><span class="feat-pt-icon"></span>Open any route from your dev server, staging URL, or production app.</li>
<li><span class="feat-pt-icon"></span>The full fiber tree is mapped — every component, hook, and context value.</li>
<li><span class="feat-pt-icon"></span>Hot module reload propagates instantly. The canvas always reflects the current build.</li>
</ul>
<a href="#" class="btn btn-primary">Request early access</a>
</div>
<div class="feat-vis feat-vis-dark reveal">
<div style="position:absolute;inset:0;padding:24px;display:flex;flex-direction:column;gap:8px;overflow:hidden;">
<div style="font-family:var(--mono);font-size:0.5rem;color:rgba(255,255,255,0.25);letter-spacing:0.1em;text-transform:uppercase;margin-bottom:4px;">Fiber tree — DashboardCard</div>
<!-- Tree nodes -->
<div style="display:flex;align-items:center;gap:6px;"><span style="color:rgba(51,133,255,0.6);font-family:monospace;font-size:0.6rem;"></span><span style="font-family:var(--mono);font-size:0.625rem;color:#7EB8FF;">DashboardCard</span><span style="font-family:var(--mono);font-size:0.5rem;color:rgba(255,255,255,0.2);margin-left:auto;">×1</span></div>
<div style="padding-left:16px;display:flex;flex-direction:column;gap:6px;">
<div style="display:flex;align-items:center;gap:6px;"><span style="color:rgba(255,255,255,0.2);font-size:0.6rem;"></span><span style="font-family:var(--mono);font-size:0.625rem;color:rgba(255,255,255,0.65);">Card</span><span style="font-family:var(--mono);font-size:0.5rem;color:rgba(255,255,255,0.2);margin-left:auto;">elevation="md"</span></div>
<div style="padding-left:14px;display:flex;flex-direction:column;gap:5px;">
<div style="display:flex;align-items:center;gap:6px;"><span style="font-family:var(--mono);font-size:0.625rem;color:rgba(255,255,255,0.5);">CardHeader</span></div>
<div style="display:flex;align-items:center;gap:6px;"><span style="font-family:var(--mono);font-size:0.625rem;color:rgba(255,255,255,0.5);">MetricDisplay</span><span style="font-family:var(--mono);font-size:0.5rem;color:#FFBA7B;margin-left:auto;">value=12450</span></div>
<div style="display:flex;align-items:center;gap:6px;"><span style="font-family:var(--mono);font-size:0.625rem;color:rgba(255,255,255,0.5);">ProgressBar</span><span style="font-family:var(--mono);font-size:0.5rem;color:#7EB8FF;margin-left:auto;">value=68</span></div>
<div style="display:flex;align-items:center;gap:6px;"><span style="font-family:var(--mono);font-size:0.625rem;color:rgba(255,255,255,0.5);">TagList</span><span style="font-family:var(--mono);font-size:0.5rem;color:rgba(255,255,255,0.2);margin-left:auto;">×3 items</span></div>
</div>
</div>
<div style="margin-top:auto;padding:12px;background:rgba(51,133,255,0.08);border:1px solid rgba(51,133,255,0.15);border-radius:6px;">
<div style="font-family:var(--mono);font-size:0.5rem;color:rgba(255,255,255,0.25);margin-bottom:6px;">SELECTED — MetricDisplay</div>
<div style="display:flex;justify-content:space-between;"><span style="font-family:var(--mono);font-size:0.5625rem;color:rgba(255,255,255,0.4);">value</span><span style="font-family:var(--mono);font-size:0.5625rem;color:#FFBA7B;">12450</span></div>
<div style="display:flex;justify-content:space-between;margin-top:4px;"><span style="font-family:var(--mono);font-size:0.5625rem;color:rgba(255,255,255,0.4);">currency</span><span style="font-family:var(--mono);font-size:0.5625rem;color:#7DDBA0;">"USD"</span></div>
<div style="display:flex;justify-content:space-between;margin-top:4px;"><span style="font-family:var(--mono);font-size:0.5625rem;color:rgba(255,255,255,0.4);">format</span><span style="font-family:var(--mono);font-size:0.5625rem;color:#7DDBA0;">"compact"</span></div>
</div>
</div>
</div>
</div>
</div>
<!-- DEEP DIVE 2: Interaction -->
<div class="section section-muted" style="padding:100px 40px;">
<div class="feat-split rev reveal">
<div class="feat-copy">
<span class="label label-blue">Interaction model</span>
<h2 class="d3">Click. Edit. See it.<br>No context switch.</h2>
<p class="subtitle">Click any component in the canvas — the inspector populates with its live props. Change a value and the iframe re-renders in under 16ms. All edits accumulate into an Intent Diff automatically.</p>
<ul class="feat-pts">
<li><span class="feat-pt-icon"></span>Selection handles show the exact DOM rect reported by the fiber hook.</li>
<li><span class="feat-pt-icon"></span>Every prop change is recorded as an entry in the artboard's undo stack.</li>
<li><span class="feat-pt-icon"></span>Cmd+Z / Cmd+Shift+Z for full undo/redo — applied live to the iframe.</li>
</ul>
</div>
<div class="feat-vis feat-vis-light reveal" style="overflow:visible;">
<div style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:32px;">
<div style="width:100%;max-width:260px;position:relative;">
<!-- Artboard frame -->
<div style="background:#fff;border-radius:10px;padding:20px;box-shadow:0 8px 32px rgba(0,0,0,0.12);border:2px solid #3385FF;position:relative;">
<!-- Selection handle -->
<div style="position:absolute;top:-4px;left:-4px;width:8px;height:8px;background:#fff;border:2px solid #3385FF;border-radius:2px;"></div>
<div style="position:absolute;top:-4px;right:-4px;width:8px;height:8px;background:#fff;border:2px solid #3385FF;border-radius:2px;"></div>
<div style="position:absolute;bottom:-4px;left:-4px;width:8px;height:8px;background:#fff;border:2px solid #3385FF;border-radius:2px;"></div>
<div style="position:absolute;bottom:-4px;right:-4px;width:8px;height:8px;background:#fff;border:2px solid #3385FF;border-radius:2px;"></div>
<!-- Content -->
<div style="font-size:0.6875rem;font-weight:700;color:#0A0A0A;margin-bottom:12px;">Revenue Overview</div>
<div style="font-size:1.25rem;font-weight:800;color:#0A0A0A;letter-spacing:-0.04em;">$12,450</div>
<div style="font-size:0.5625rem;color:#059669;margin-top:3px;margin-bottom:12px;">↑ +2.4%</div>
<div style="height:2px;background:#F0F0F0;border-radius:99px;overflow:hidden;"><div style="height:100%;width:68%;background:#0066FF;border-radius:99px;"></div></div>
</div>
<!-- Inspector popup -->
<div style="position:absolute;right:-130px;top:0;width:120px;background:#111115;border:1px solid rgba(255,255,255,0.1);border-radius:8px;padding:10px;box-shadow:0 8px 24px rgba(0,0,0,0.4);">
<div style="font-family:var(--mono);font-size:0.4375rem;color:rgba(255,255,255,0.25);letter-spacing:0.1em;text-transform:uppercase;margin-bottom:7px;">Props</div>
<div style="margin-bottom:5px;"><div style="font-family:var(--mono);font-size:0.5rem;color:rgba(255,255,255,0.35);">borderRadius</div><div style="font-family:var(--mono);font-size:0.5625rem;color:#FFBA7B;margin-top:1px;">12</div></div>
<div style="margin-bottom:5px;"><div style="font-family:var(--mono);font-size:0.5rem;color:rgba(255,255,255,0.35);">accentColor</div><div style="font-family:var(--mono);font-size:0.5625rem;color:#7DDBA0;margin-top:1px;">"#0066FF"</div></div>
<div style="margin-bottom:5px;"><div style="font-family:var(--mono);font-size:0.5rem;color:rgba(255,255,255,0.35);">elevation</div><div style="font-family:var(--mono);font-size:0.5625rem;color:#7DDBA0;margin-top:1px;">"medium"</div></div>
</div>
<!-- Component label -->
<div style="position:absolute;top:-22px;left:0;font-family:var(--mono);font-size:0.5rem;color:#3385FF;">ProgressBar</div>
</div>
</div>
</div>
</div>
</div>
<!-- TECHNICAL SECTION -->
<section class="section">
<div class="wrap">
<div class="section-head reveal">
<span class="label">Technical foundation</span>
<h2 class="d2">Built on open standards.</h2>
<p class="subtitle">No proprietary runtime. No custom compiler. Live Artboard works with any React app — any version, any bundler, any framework.</p>
</div>
<div class="tech-grid stagger">
<div class="tech-card">
<div class="tech-icon"></div>
<h3>iframe sandboxing</h3>
<p>Each artboard runs in a sandboxed iframe with <code style="font-family:var(--mono);font-size:0.8em;background:var(--bg-muted);padding:1px 4px;border-radius:3px;">allow-scripts allow-same-origin</code>. Your app runs in full isolation — Originmain never modifies your code.</p>
<span class="tech-tag">Security</span>
</div>
<div class="tech-card">
<div class="tech-icon"></div>
<h3>React Fiber hook</h3>
<p>A lightweight script hooks into React's internal fiber tree via <code style="font-family:var(--mono);font-size:0.8em;background:var(--bg-muted);padding:1px 4px;border-radius:3px;">__REACT_DEVTOOLS_GLOBAL_HOOK__</code> — the same API used by React DevTools. Works with React 16.8+.</p>
<span class="tech-tag">Compatibility</span>
</div>
<div class="tech-card">
<div class="tech-icon">📡</div>
<h3>postMessage protocol</h3>
<p>Fiber tree updates stream from the iframe to the host canvas via a typed postMessage protocol. Messages are validated with a shared artboard ID so multiple artboards never cross-contaminate.</p>
<span class="tech-tag">Protocol</span>
</div>
<div class="tech-card">
<div class="tech-icon">🎯</div>
<h3>DOM rect tracking</h3>
<p>Every component's bounding rect is captured on mount and update. This drives the selection overlay, hover highlights, and resize handles — all pixel-accurate to the live render.</p>
<span class="tech-tag">Precision</span>
</div>
<div class="tech-card">
<div class="tech-icon">♻️</div>
<h3>Zero build step</h3>
<p>No Babel plugin, no webpack loader, no custom babel config. Paste any URL — dev server, staging, or production — and the artboard renders immediately.</p>
<span class="tech-tag">Zero friction</span>
</div>
<div class="tech-card">
<div class="tech-icon">🔒</div>
<h3>Cross-origin safe</h3>
<p>When the iframe is cross-origin, the renderer can include the hook script directly via a small npm package. Same protocol, same canvas experience — no compromise on security.</p>
<span class="tech-tag">Flexibility</span>
</div>
</div>
</div>
</section>
<!-- RELATED FEATURES -->
<section class="section section-muted">
<div class="wrap">
<div class="section-head reveal">
<span class="label">What's next</span>
<h2 class="d2">Live Artboard powers everything.</h2>
<p class="subtitle">The real-time component tree is the foundation for every other Originmain feature.</p>
</div>
<div class="related-grid stagger">
<a class="related-card" href="/features/origin-graph.html">
<div class="related-icon"></div>
<h3>Origin Graph</h3>
<p>The fiber tree feeds directly into the Origin Graph — building a queryable index of every component, token, and relationship in your app.</p>
<span class="related-link">Explore Origin Graph →</span>
</a>
<a class="related-card" href="/features/intent-diff.html">
<div class="related-icon"></div>
<h3>Intent Diff</h3>
<p>Every visual edit in a live artboard generates an Intent Diff — a machine-readable, component-level description of exactly what changed.</p>
<span class="related-link">Explore Intent Diff →</span>
</a>
<a class="related-card" href="/features/completion-zone.html">
<div class="related-icon"></div>
<h3>Completion Zone</h3>
<p>Mark any region of the artboard. AI fills it using your design language constraints, then renders the result live in the same artboard.</p>
<span class="related-link">Explore Completion Zone →</span>
</a>
</div>
</div>
</section>
<!-- CTA -->
<section id="cta-bottom">
<div class="cta-inner">
<h2 class="cta-headline">See your app<br>live on the canvas.</h2>
<p class="cta-sub">Early access is free. Connect your first artboard in under two minutes.</p>
<div class="cta-actions">
<a href="#" class="btn btn-white btn-lg">Request Early Access</a>
<a href="/" class="btn btn-outline-white btn-lg">Back to overview</a>
</div>
</div>
</section>
<!-- FOOTER -->
<footer>
<div class="ft-inner">
<div class="ft-top">
<div>
<div class="ft-brand-logo">Origin<span>main</span></div>
<p class="ft-brand-tag">Where design intent becomes production code.</p>
</div>
<div class="ft-col">
<h4>Product</h4>
<ul>
<li><a href="/features/live-artboard.html">Live Artboard</a></li>
<li><a href="/features/origin-graph.html">Origin Graph</a></li>
<li><a href="/features/intent-diff.html">Intent Diff</a></li>
<li><a href="/features/completion-zone.html">Completion Zone</a></li>
<li><a href="/features/agent-bridge.html">Agent Bridge</a></li>
</ul>
</div>
<div class="ft-col">
<h4>Integrations</h4>
<ul>
<li><a href="/features/integrations.html">All integrations</a></li>
<li><a href="#">GitHub</a></li>
<li><a href="#">Linear</a></li>
<li><a href="#">Slack</a></li>
</ul>
</div>
<div class="ft-col">
<h4>Developers</h4>
<ul>
<li><a href="#">Docs</a></li>
<li><a href="#">API Reference</a></li>
<li><a href="#">MCP Protocol</a></li>
<li><a href="#">Changelog</a></li>
</ul>
</div>
<div class="ft-col">
<h4>Company</h4>
<ul>
<li><a href="#">About</a></li>
<li><a href="/#pricing">Pricing</a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>
</div>
<div class="ft-bottom">
<span class="ft-copy">© 2025 Originmain. All rights reserved.</span>
</div>
</div>
</footer>
<script>
// Nav scroll
const nav=document.getElementById('nav');
window.addEventListener('scroll',()=>{nav.classList.toggle('scrolled',window.scrollY>20);});
// Dropdown: delay-based hover (desktop) + click (mobile/touch)
document.querySelectorAll('.nav-dropdown').forEach(dd=>{const menu=dd.querySelector('.nav-dropdown-menu');let t;const open=()=>{clearTimeout(t);dd.classList.add('open');menu.classList.add('open');};const close=()=>{t=setTimeout(()=>{dd.classList.remove('open');menu.classList.remove('open');},150);};dd.addEventListener('mouseenter',open);dd.addEventListener('mouseleave',close);menu.addEventListener('mouseenter',open);menu.addEventListener('mouseleave',close);dd.querySelector('a').addEventListener('click',e=>{if(window.matchMedia('(hover:none)').matches||window.innerWidth<=1024){e.preventDefault();const o=menu.classList.toggle('open');dd.classList.toggle('open',o);}});});
// Mobile product sub-accordion
const mpt=document.getElementById('mob-product-toggle'),mns=document.getElementById('nav-mobile-sub'),mdc=document.getElementById('mob-dd-caret');if(mpt&&mns){mpt.addEventListener('click',e=>{e.preventDefault();const o=mns.classList.toggle('open');if(mdc)mdc.style.transform=o?'rotate(180deg)':'';});}
// Burger
const burger=document.getElementById('nav-burger'),mob=document.getElementById('nav-mobile');
burger.addEventListener('click',()=>{const o=mob.classList.toggle('open');burger.classList.toggle('open',o);burger.setAttribute('aria-expanded',o);});
// Reveal
const io=new IntersectionObserver(entries=>{entries.forEach(e=>{if(e.isIntersecting){e.target.classList.add('in');io.unobserve(e.target);}});},{threshold:0.12});
document.querySelectorAll('.reveal,.stagger').forEach(el=>io.observe(el));
</script>
</body>
</html>