/* LINORA motion layer. Everything here is transform / opacity / scale so it stays on the compositor.
   The page is complete without it. */
:root{--drawer:cubic-bezier(.7,0,.2,1)}

/* tactile paper grain (static) */
body::before{content:'';position:fixed;inset:0;z-index:90;pointer-events:none;opacity:.032;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .2  0 0 0 0 .14  0 0 0 0 .1  0 0 0 1 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>")}

/* ---------- hero: the fronts close into the carcass, one after another ---------- */
.panel{animation:front-in 1.5s var(--ease) backwards}
.panel-title{animation-name:front-in-left;animation-duration:1.7s}
.panel-photo{animation-name:front-in-right;animation-delay:.12s;animation-duration:1.7s}
.panel-swatch{animation-name:front-in-up}
.panel-swatch:nth-child(2){animation-delay:.42s}.panel-swatch:nth-child(3){animation-delay:.54s}.panel-swatch:nth-child(4){animation-delay:.66s}
@keyframes front-in-left{from{transform:translate3d(-5%,0,0);opacity:0}}
@keyframes front-in-right{from{transform:translate3d(5%,0,0);opacity:0}}
@keyframes front-in-up{from{transform:translate3d(0,46%,0);opacity:0}}
.panel-photo .panel-media img{animation:media-settle 2.4s var(--ease) .1s backwards}
.panel-swatch .panel-media img{animation:media-settle 2s var(--ease) .5s backwards}
@keyframes media-settle{from{transform:scale(1.22)}}
.panel-title .eyebrow{animation:fade-rise 1.2s var(--ease) .5s backwards}
.hero-intro{animation:fade-rise 1.2s var(--ease) 1.05s backwards}
.hero-actions{animation:fade-rise 1.2s var(--ease) 1.2s backwards}
.photo-label{animation:label-in 1.1s var(--ease) 1.1s backwards}
.swatch-tab{animation:tab-in 1.1s var(--ease) 1.25s backwards}
@keyframes fade-rise{from{transform:translate3d(0,24px,0);opacity:0}}
@keyframes label-in{from{transform:translate3d(0,100%,0)}}
@keyframes tab-in{from{opacity:0}}
/* warm light drifting over the photograph */
.panel-photo::after{content:'';position:absolute;top:-10%;bottom:-10%;left:0;width:60%;z-index:1;pointer-events:none;background:linear-gradient(100deg,transparent 0,rgba(255,226,178,.26) 50%,transparent 100%);transform:translate3d(-120%,0,0) skewX(-14deg);animation:warm-pass 13s 2.6s ease-in-out infinite}
.hero.is-off .panel-photo::after{animation-play-state:paused}
@keyframes warm-pass{0%{transform:translate3d(-120%,0,0) skewX(-14deg)}58%,100%{transform:translate3d(190%,0,0) skewX(-14deg)}}

/* ---------- masked words, drawn underlines ---------- */
.w{display:inline-block;overflow:hidden;vertical-align:top;padding:.12em .03em .22em;margin:-.12em -.03em -.22em}
.wi{display:inline-block}
h1 em,h2 em,h3 em{background-image:linear-gradient(currentColor,currentColor);background-repeat:no-repeat;background-position:0 94%;background-size:0 1px;-webkit-box-decoration-break:clone;box-decoration-break:clone;transition:background-size 1.5s .6s var(--ease)}
.is-drawn em,.is-drawn.is-drawn em{background-size:100% 1px}

/* ---------- gallery: tiles are set into the frame as they arrive ---------- */
.project.is-pending{opacity:0;transform:translate3d(0,52px,0)}
.project.is-in{opacity:1;transform:none;transition:opacity 1s var(--ease) var(--cd,0s),transform 1.3s var(--ease) var(--cd,0s)}
.project-caption h3{background:linear-gradient(currentColor,currentColor) 0 100%/0 1px no-repeat;transition:background-size .9s var(--ease);padding-bottom:3px}
.project-image img{transition:scale 1.2s var(--ease)}

/* ---------- plan: walls are drawn when the section arrives ---------- */
.room-plan.is-prep .plan-lines path:not(.is-dash),.room-plan.is-prep .plan-doors path,.room-plan.is-prep .plan-windows path,.room-plan.is-prep .plan-furniture path{stroke-dasharray:1;stroke-dashoffset:1}
.room-plan.is-prep .plan-lines .is-dash{opacity:0}
.room-plan.is-prep .room-tab{opacity:0}
.room-plan.is-prep .plan-cone{opacity:0}
.room-plan.is-drawn .plan-lines path:not(.is-dash){stroke-dashoffset:0;transition:stroke-dashoffset 2s var(--drawer)}
.room-plan.is-drawn .plan-lines path:nth-child(2){transition-delay:.15s}.room-plan.is-drawn .plan-lines path:nth-child(3){transition-delay:.3s}
.room-plan.is-drawn .plan-lines .is-dash{opacity:1;transition:opacity 1s 1.4s}
.room-plan.is-drawn .plan-doors path{stroke-dashoffset:0;transition:stroke-dashoffset 1.2s var(--drawer) 1.1s}
.room-plan.is-drawn .plan-windows path{stroke-dashoffset:0;transition:stroke-dashoffset 1.2s var(--drawer) 1.3s}
.room-plan.is-drawn .plan-furniture path{stroke-dashoffset:0;transition:stroke-dashoffset 1.6s var(--drawer) 1.5s}
.room-plan.is-drawn .room-tab{opacity:1;transition:opacity .9s 1.7s,color .4s}
.room-plan.is-drawn .plan-cone{opacity:1;transition:opacity .9s 1.9s,transform .9s var(--ease)}

/* ---------- process: numerals fill as the dimension line passes ---------- */

/* ---------- hover (pointer devices) ---------- */
@media(hover:hover) and (pointer:fine){
  .project-image:hover img{scale:1.05}
  .project-image:hover::before{opacity:1;transform:none}
  .project:hover .project-caption h3{background-size:100% 1px}
  .image-open{transform:translate3d(100%,0,0)}
  .project-image:hover .image-open,.project-image:focus-visible .image-open{transform:none}
  .has-lin-cursor .project-image,.has-lin-cursor .image-open{cursor:none}
}
.project-image:focus-visible::before{opacity:1;transform:none}
.project-image:focus-visible{outline-offset:-6px}

/* ---------- cursor: a brass dot that becomes a lens over photographs ---------- */
.lin-cursor{position:fixed;z-index:120;left:0;top:0;width:0;height:0;pointer-events:none;opacity:0;transition:opacity .3s}
.lin-cursor.is-on{opacity:1}
.lin-cursor span{position:absolute;left:0;top:0;display:grid;place-items:center;width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;background:var(--brass);font-size:10px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink);transition:width .6s var(--ease),height .6s var(--ease),margin .6s var(--ease),background-color .35s,opacity .3s}
.lin-cursor.is-link span{width:46px;height:46px;margin:-23px 0 0 -23px;background:transparent;border:1px solid var(--brass)}
.lin-cursor.is-view span{width:104px;height:104px;margin:-52px 0 0 -52px;background:var(--paper);box-shadow:0 12px 44px rgba(30,20,12,.3)}
.lin-cursor em{font-style:normal;opacity:0;transform:scale(.8);transition:opacity .3s,transform .6s var(--ease);white-space:nowrap}
.lin-cursor.is-view em{opacity:1;transform:none}

/* ---------- material marker: a slow ping around the detail being described ---------- */
.mat-marker i::before{content:'';position:absolute;inset:-1px;border-radius:50%;border:1px solid var(--paper);animation:marker-ping 3s var(--ease) infinite}
@keyframes marker-ping{from{transform:scale(1);opacity:.7}to{transform:scale(3.4);opacity:0}}

/* ---------- lightbox: the chosen picture travels into the frame ---------- */
.flip-clone{position:fixed;left:0;top:0;z-index:300;margin:0;pointer-events:none;object-fit:cover;transform-origin:0 0;will-change:transform}
.lightbox.is-flipping .lightbox-image>img{opacity:0}

/* Embedded as a live preview (portfolio showreel): small, inert and sharing the main thread with its host. */
html.zp-embedded body::before,html.zp-embedded .lin-cursor,html.zp-embedded .panel-photo::after,html.zp-embedded .mat-marker i::before{display:none!important}
html.zp-embedded .panel,html.zp-embedded .panel-media img,html.zp-embedded .hero-intro,html.zp-embedded .hero-actions,html.zp-embedded .photo-label,html.zp-embedded .swatch-tab,html.zp-embedded .panel-title .eyebrow{animation-duration:.01s!important;animation-delay:0s!important}
