Back to CSS Page Transitions Vertical Split Curtain CSS + JS
Share
HTML
<!-- Curtain panels -->
<div class="curtain-left" id="cLeft"></div>
<div class="curtain-right" id="cRight"></div>

<div class="pages">

  <div class="page active" id="p0">
    <div class="p0-layout">
      <div class="p0-left">
        <div class="p0-mark">Maison Lécluse · Paris</div>
        <div class="p0-main">
          <div class="p0-season">Automne–Hiver 2025</div>
          <h1 class="p0-title">Entre<br>Ombre<br>&amp; Lumière</h1>
          <div class="p0-title-fr">Between shadow and light</div>
          <p class="p0-body">A collection born from the silences between words. Forty-two looks. Each one a conversation the body has alone.</p>
          <button class="p0-cta" data-next="1">Discover the collection <span class="p0-cta-arrow"></span></button>
        </div>
      </div>
      <div class="p0-right">
        <div class="silhouette-area">
          <div class="figure">
            <div class="fig-head"></div>
            <div class="fig-arm fig-arm-l"></div>
            <div class="fig-arm fig-arm-r"></div>
            <div class="fig-body"></div>
          </div>
        </div>
        <div class="p0-right-bottom">
          <div class="p0-detail-row"><div class="det-key">Maison</div><div class="det-val">Since 1967</div></div>
          <div class="p0-detail-row"><div class="det-key">Ateliers</div><div class="det-val">Paris · Florence</div></div>
          <div class="p0-detail-row"><div class="det-key">Collection</div><div class="det-val">AH 2025 · 42 looks</div></div>
          <div class="p0-detail-row"><div class="det-key">Runway</div><div class="det-val">Palais Royal, 4 Oct</div></div>
        </div>
      </div>
    </div>
  </div>

  <div class="page" id="p1">
    <div class="p1-top">
      <h2 class="p1-title">The<br>Collection</h2>
      <div class="p1-count">42 Looks · AH 2025</div>
    </div>
    <div class="look-grid">
      <div class="look"><div class="look-img"><div class="garment g1"></div></div><div class="look-num">Look 01</div><div class="look-name">L'aube noire</div></div>
      <div class="look"><div class="look-img"><div class="garment g2"></div></div><div class="look-num">Look 07</div><div class="look-name">Le voile froid</div></div>
      <div class="look"><div class="look-img"><div class="garment g3"></div></div><div class="look-num">Look 14</div><div class="look-name">La colonne</div></div>
      <div class="look"><div class="look-img"><div class="garment g4"></div></div><div class="look-num">Look 21</div><div class="look-name">Le bruissement</div></div>
      <div class="look"><div class="look-img"><div class="garment g5"></div></div><div class="look-num">Look 38</div><div class="look-name">La chute</div></div>
    </div>
  </div>

  <div class="page" id="p2">
    <div class="p2-left">
      <div class="p2-eyebrow">L'Atelier Lécluse</div>
      <h2 class="p2-title">Made by<br>hand, in<br>silence</h2>
      <p class="p2-body">Each garment passes through twenty-four pairs of hands before it leaves the atelier. We consider this not a process, but a conversation with the material.</p>
      <div class="craft-list">
        <div class="craft-row"><div class="craft-n">I</div><div class="craft-t">Pattern cutting by master tailleur</div></div>
        <div class="craft-row"><div class="craft-n">II</div><div class="craft-t">Hand-draping on the mannequin</div></div>
        <div class="craft-row"><div class="craft-n">III</div><div class="craft-t">Three fittings per garment minimum</div></div>
        <div class="craft-row"><div class="craft-n">IV</div><div class="craft-t">Handstitched finishing throughout</div></div>
        <div class="craft-row"><div class="craft-n">V</div><div class="craft-t">Final inspection by the directrice</div></div>
      </div>
    </div>
    <div class="p2-right">
      <div class="maison-since">Maison Lécluse · Since 1967</div>
      <div class="p2-numbers">
        <div class="num-item"><div class="num-big">58</div><div class="num-label">Years of haute<br>couture</div></div>
        <div class="num-item"><div class="num-big">24</div><div class="num-label">Artisan hands per<br>garment</div></div>
        <div class="num-item"><div class="num-big">200+</div><div class="num-label">Hours in a single<br>couture piece</div></div>
      </div>
    </div>
  </div>

  <div class="page" id="p3">
    <div class="p3-bg-text">ML</div>
    <div class="p3-content">
      <span class="p3-mark">Maison Lécluse · Paris</span>
      <h2 class="p3-title">Private<br>Fitting</h2>
      <p class="p3-sub">By appointment only. Ateliers are open to clients for consultation from Tuesday through Saturday.</p>
      <div class="p3-contact-grid">
        <div class="p3-contact-row"><div class="p3-contact-key">Address</div><div class="p3-contact-val">24 Rue du Faubourg Saint-Honoré</div></div>
        <div class="p3-contact-row"><div class="p3-contact-key">Telephone</div><div class="p3-contact-val">+33 1 42 68 00 00</div></div>
        <div class="p3-contact-row"><div class="p3-contact-key">Fitting hours</div><div class="p3-contact-val">Mar–Sam · 10h–18h</div></div>
        <div class="p3-contact-row"><div class="p3-contact-key">Correspondence</div><div class="p3-contact-val">[email protected]</div></div>
      </div>
    </div>
  </div>

</div>

<!-- Nav -->
<div class="c-nav">
  <button class="c-btn" id="cPrev">‹</button>
  <div class="c-dots">
    <button class="c-dot active" data-i="0"></button>
    <button class="c-dot" data-i="1"></button>
    <button class="c-dot" data-i="2"></button>
    <button class="c-dot" data-i="3"></button>
  </div>
  <div class="c-label" id="cLabel">Maison</div>
  <button class="c-btn" id="cNext">›</button>
</div>
CSS
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
  --noir:#080808;
  --white:#f8f4f0;
  --warm:#e8e0d4;
  --dim:rgba(248,244,240,0.4);
  --accent:#c8a060;
  --mid:rgba(248,244,240,0.1);
  --dur:900ms;
  --ease:cubic-bezier(0.76,0,0.24,1);
}
html,body{height:100%;overflow:hidden;background:var(--noir);font-family:'Cormorant Garamond',serif;}

/* Pages */
.pages{position:fixed;inset:0;}
.page{position:absolute;inset:0;pointer-events:none;visibility:hidden;}
.page.active{visibility:visible;pointer-events:auto;}

/* Curtain panels */
.curtain-left,.curtain-right{
  position:fixed;top:0;bottom:0;z-index:700;
  background:var(--noir);
  will-change:transform;
}
.curtain-left{
  left:0;width:50%;
  transform:translateX(-100%);
  transform-origin:left;
}
.curtain-right{
  right:0;width:50%;
  transform:translateX(100%);
  transform-origin:right;
}
/* Centre seam line */
.curtain-left::after{
  content:'';
  position:absolute;right:0;top:0;bottom:0;
  width:1px;
  background:linear-gradient(180deg,transparent,var(--accent),transparent);
  opacity:0;
}

/* States */
.curtain-left.close{transform:translateX(0);}
.curtain-right.close{transform:translateX(0);}
.curtain-left.close::after{opacity:0.4;}

/* PAGE 0 — MAISON */
#p0{background:var(--noir);color:var(--white);}

.p0-layout{
  height:100%;
  display:grid;grid-template-columns:1fr 1fr;
}

.p0-left{
  padding:60px 80px;
  display:flex;flex-direction:column;
  justify-content:space-between;
  border-right:1px solid var(--mid);
}

.p0-mark{
  font-family:'Italiana',serif;
  font-size:11px;letter-spacing:0.4em;text-transform:uppercase;
  color:var(--dim);
}

.p0-main{
  flex:1;display:flex;flex-direction:column;justify-content:flex-end;
  padding-bottom:20px;
}

.p0-season{
  font-size:8px;letter-spacing:0.4em;text-transform:uppercase;
  color:var(--accent);margin-bottom:24px;
  display:flex;align-items:center;gap:12px;
}
.p0-season::before{
  content:'';width:20px;height:1px;background:var(--accent);
}

.p0-title{
  font-family:'Italiana',serif;
  font-size:clamp(52px,8vw,112px);
  font-weight:400;line-height:0.9;
  letter-spacing:-0.02em;
  color:var(--white);margin-bottom:24px;
}

.p0-title-fr{
  font-size:clamp(24px,3.5vw,48px);
  font-style:italic;font-weight:300;
  color:rgba(248,244,240,0.35);margin-bottom:40px;
}

.p0-body{
  font-size:13px;line-height:1.9;font-weight:300;
  color:var(--dim);max-width:380px;font-style:italic;
}

.p0-cta{
  margin-top:40px;
  display:inline-flex;align-items:center;gap:16px;
  font-size:9px;letter-spacing:0.3em;text-transform:uppercase;
  color:var(--white);cursor:pointer;background:none;border:none;
  font-family:'Didact Gothic',sans-serif;
  transition:color .2s;
}
.p0-cta:hover{color:var(--accent);}
.p0-cta-arrow{
  width:40px;height:1px;background:currentColor;
  transition:width .3s;position:relative;
}
.p0-cta-arrow::after{
  content:'';position:absolute;right:-1px;top:-3px;
  width:7px;height:7px;
  border-right:1px solid currentColor;
  border-top:1px solid currentColor;
  transform:rotate(45deg);
}
.p0-cta:hover .p0-cta-arrow{width:64px;}

.p0-right{
  display:grid;grid-template-rows:1fr 1fr;
  padding:60px;
  gap:0;
}

/* Abstract fashion illustration using CSS shapes */
.silhouette-area{
  display:flex;align-items:center;justify-content:center;
  position:relative;
}

.figure{
  position:relative;
  width:80px;height:200px;
}
.fig-body{
  position:absolute;bottom:0;left:50%;transform:translateX(-50%);
  width:48px;height:140px;
  background:linear-gradient(180deg,rgba(200,160,96,0.2),rgba(200,160,96,0.06));
  border:1px solid rgba(200,160,96,0.2);
  border-radius:2px 2px 0 0;
}
.fig-head{
  position:absolute;bottom:136px;left:50%;transform:translateX(-50%);
  width:20px;height:24px;
  border-radius:50%;
  background:rgba(200,160,96,0.15);
  border:1px solid rgba(200,160,96,0.2);
}
.fig-arm{
  position:absolute;
  height:1px;background:rgba(200,160,96,0.25);
  top:72px;
}
.fig-arm-l{width:32px;right:48px;}
.fig-arm-r{width:32px;left:48px;}

.p0-right-bottom{
  display:flex;flex-direction:column;justify-content:flex-end;
  gap:16px;
}

.p0-detail-row{
  display:flex;justify-content:space-between;align-items:baseline;
  border-bottom:1px solid var(--mid);
  padding:12px 0;
}
.det-key{
  font-size:8px;letter-spacing:0.25em;text-transform:uppercase;
  color:rgba(248,244,240,0.25);
  font-family:'Didact Gothic',sans-serif;
}
.det-val{
  font-size:12px;font-style:italic;
  color:rgba(248,244,240,0.6);
}

/* PAGE 1 — COLLECTION */
#p1{
  background:#0c0c0c;
  color:var(--white);
  padding:60px 80px;
  display:flex;flex-direction:column;
}

.p1-top{
  display:flex;align-items:flex-end;justify-content:space-between;
  margin-bottom:52px;
  padding-bottom:24px;
  border-bottom:1px solid var(--mid);
}

.p1-title{
  font-family:'Italiana',serif;
  font-size:clamp(44px,7vw,100px);
  font-weight:400;line-height:0.9;
  letter-spacing:-0.02em;
}

.p1-count{
  font-size:9px;letter-spacing:0.25em;
  color:var(--dim);font-family:'Didact Gothic',sans-serif;
  text-transform:uppercase;
}

.look-grid{
  display:grid;
  grid-template-columns:repeat(5,1fr);
  gap:12px;
  flex:1;
}

.look{
  display:flex;flex-direction:column;gap:12px;
  cursor:pointer;
}

.look-img{
  flex:1;
  border:1px solid rgba(248,244,240,0.06);
  position:relative;overflow:hidden;
  min-height:200px;
  background:linear-gradient(180deg,#111,#0a0a0a);
  transition:border-color .3s;
}
.look:hover .look-img{border-color:rgba(200,160,96,0.3);}

/* Abstract garment shape */
.garment{
  position:absolute;bottom:0;left:50%;transform:translateX(-50%);
  width:60%;
  background:rgba(200,160,96,0.08);
  border-top:1px solid rgba(200,160,96,0.15);
}
.g1{height:70%;border-radius:2px 2px 0 0;}
.g2{height:85%;clip-path:polygon(20% 0,80% 0,100% 100%,0 100%);}
.g3{height:60%;border-radius:40% 40% 0 0;}
.g4{height:75%;clip-path:polygon(0 0,100% 0,90% 100%,10% 100%);}
.g5{height:90%;clip-path:polygon(30% 0,70% 0,100% 100%,0 100%);}

.look-num{
  font-size:8px;letter-spacing:0.2em;
  color:var(--accent);font-family:'Didact Gothic',sans-serif;
}
.look-name{
  font-family:'Cormorant Garamond',serif;
  font-size:13px;font-style:italic;color:rgba(248,244,240,0.7);
}

/* PAGE 2 — ATELIER */
#p2{
  background:var(--white);
  color:var(--noir);
  display:grid;grid-template-columns:1fr 1fr;
}

.p2-left{
  padding:80px;
  display:flex;flex-direction:column;justify-content:center;
  background:#f0ece6;
}

.p2-eyebrow{
  font-size:8px;letter-spacing:0.35em;text-transform:uppercase;
  color:var(--accent);margin-bottom:28px;
  font-family:'Didact Gothic',sans-serif;
}

.p2-title{
  font-family:'Italiana',serif;
  font-size:clamp(44px,6vw,80px);
  font-weight:400;line-height:1.0;
  color:var(--noir);letter-spacing:-0.02em;
  margin-bottom:28px;
}

.p2-body{
  font-size:15px;line-height:1.85;font-weight:300;font-style:italic;
  color:rgba(8,8,8,0.5);max-width:400px;margin-bottom:48px;
}

.craft-list{
  display:flex;flex-direction:column;gap:0;
}
.craft-row{
  display:flex;gap:20px;
  padding:18px 0;
  border-bottom:1px solid rgba(8,8,8,0.08);
  align-items:baseline;
}
.craft-n{
  font-size:9px;letter-spacing:0.15em;
  color:var(--accent);
  font-family:'Didact Gothic',sans-serif;
  width:24px;flex-shrink:0;
}
.craft-t{
  font-size:14px;font-style:italic;color:rgba(8,8,8,0.6);
}

.p2-right{
  padding:80px;
  background:var(--white);
  display:flex;flex-direction:column;justify-content:center;
  border-left:1px solid rgba(8,8,8,0.06);
}

.maison-since{
  font-size:9px;letter-spacing:0.35em;text-transform:uppercase;
  color:rgba(8,8,8,0.25);margin-bottom:40px;
  font-family:'Didact Gothic',sans-serif;
}

.p2-numbers{
  display:flex;flex-direction:column;gap:28px;
}
.num-item{
  display:flex;align-items:baseline;gap:20px;
  padding-bottom:28px;
  border-bottom:1px solid rgba(8,8,8,0.06);
}
.num-big{
  font-family:'Italiana',serif;
  font-size:56px;color:var(--noir);line-height:1;
}
.num-label{
  font-size:12px;font-style:italic;color:rgba(8,8,8,0.45);
  line-height:1.4;
}

/* PAGE 3 — CONTACT */
#p3{
  background:var(--noir);color:var(--white);
  display:flex;align-items:center;justify-content:center;
  text-align:center;padding:80px;
  position:relative;overflow:hidden;
}

.p3-bg-text{
  position:absolute;
  font-family:'Italiana',serif;
  font-size:30vw;color:rgba(248,244,240,0.025);
  line-height:1;letter-spacing:-0.06em;
  pointer-events:none;
  user-select:none;
}

.p3-content{position:relative;max-width:560px;}

.p3-mark{
  font-family:'Italiana',serif;
  font-size:9px;letter-spacing:0.5em;text-transform:uppercase;
  color:var(--dim);margin-bottom:48px;display:block;
}

.p3-title{
  font-family:'Italiana',serif;
  font-size:clamp(44px,8vw,100px);
  font-weight:400;line-height:0.9;
  letter-spacing:-0.02em;
  color:var(--white);margin-bottom:16px;
}

.p3-sub{
  font-size:14px;font-style:italic;
  color:var(--dim);margin-bottom:48px;
  line-height:1.7;
}

.p3-contact-grid{
  display:flex;flex-direction:column;gap:16px;
  border-top:1px solid var(--mid);
  padding-top:36px;
}

.p3-contact-row{
  display:flex;justify-content:space-between;
  align-items:baseline;padding:8px 0;
  border-bottom:1px solid var(--mid);
}
.p3-contact-key{
  font-size:8px;letter-spacing:0.25em;text-transform:uppercase;
  color:rgba(248,244,240,0.25);
  font-family:'Didact Gothic',sans-serif;
}
.p3-contact-val{
  font-size:13px;font-style:italic;
  color:rgba(248,244,240,0.65);
}

/* Curtain nav */
.c-nav{
  position:fixed;bottom:40px;left:50%;transform:translateX(-50%);
  z-index:800;
  display:flex;align-items:center;gap:24px;
  background:rgba(8,8,8,0.7);
  border:1px solid var(--mid);
  padding:16px 32px;
  backdrop-filter:blur(20px);
}

.c-label{
  font-size:8px;letter-spacing:0.3em;text-transform:uppercase;
  color:var(--dim);
  font-family:'Didact Gothic',sans-serif;
  min-width:80px;text-align:center;
}

.c-btn{
  width:36px;height:36px;
  border:1px solid var(--mid);
  background:none;color:var(--dim);
  font-size:16px;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  transition:border-color .2s,color .2s;
  font-family:serif;
}
.c-btn:hover{border-color:var(--accent);color:var(--accent);}

.c-dots{display:flex;gap:8px;}
.c-dot{
  width:3px;height:3px;border-radius:50%;
  background:rgba(248,244,240,0.2);border:none;cursor:pointer;
  transition:background .25s,transform .3s;
}
.c-dot.active{background:var(--accent);transform:scale(1.8);}

@media(max-width:768px){
  #p0 .p0-layout{grid-template-columns:1fr;}
  .p0-right{display:none;}
  .p0-left{padding:40px 28px;}
  #p1{padding:40px 24px;}
  .look-grid{grid-template-columns:repeat(2,1fr);}
  #p2{grid-template-columns:1fr;}
  .p2-right{display:none;}
  .p2-left{padding:40px 28px;}
  #p3{padding:40px 28px;}
}
JS
const cLeft=document.getElementById('cLeft');
const cRight=document.getElementById('cRight');
const pages=document.querySelectorAll('.page');
const cdots=document.querySelectorAll('.c-dot');
const cLabel=document.getElementById('cLabel');
const labels=['Maison','Collection','Atelier','Contact'];
let cur=0,busy=false;

const dur=900;

function curtainTransition(prev,next,done){
  cLeft.style.transition=`transform ${dur*0.4}ms cubic-bezier(0.76,0,0.24,1)`;
  cRight.style.transition=`transform ${dur*0.4}ms cubic-bezier(0.76,0,0.24,1)`;
  cLeft.classList.add('close');
  cRight.classList.add('close');

  setTimeout(()=>{
    pages[prev].classList.remove('active');
    pages[next].classList.add('active');

    cLeft.style.transition=`transform ${dur*0.55}ms cubic-bezier(0.25,1,0.5,1)`;
    cRight.style.transition=`transform ${dur*0.55}ms cubic-bezier(0.25,1,0.5,1)`;
    cLeft.classList.remove('close');
    cRight.classList.remove('close');

    setTimeout(()=>{ done&&done(); },dur*0.6);
  },dur*0.42);
}

function goTo(n){
  if(busy||n===cur)return;
  busy=true;
  const prev=cur;cur=n;
  cdots.forEach((d,i)=>d.classList.toggle('active',i===cur));
  cLabel.textContent=labels[cur];
  curtainTransition(prev,cur,()=>{busy=false;});
}

document.getElementById('cNext').onclick=()=>goTo(Math.min(3,cur+1));
document.getElementById('cPrev').onclick=()=>goTo(Math.max(0,cur-1));
cdots.forEach(d=>d.addEventListener('click',()=>goTo(+d.dataset.i)));
document.querySelectorAll('[data-next]').forEach(b=>b.addEventListener('click',()=>goTo(+b.dataset.next)));

let wt=0;
window.addEventListener('wheel',e=>{
  const now=Date.now();if(now-wt<1100)return;wt=now;
  goTo(Math.max(0,Math.min(3,cur+(e.deltaY>0?1:-1))));
},{passive:true});
document.addEventListener('keydown',e=>{
  if(e.key==='ArrowRight')goTo(Math.min(3,cur+1));
  if(e.key==='ArrowLeft')goTo(Math.max(0,cur-1));
});