/* ==========================================================================
   Motion layer — the drafting animations, scroll reveals and transitions
   shared by every public page. All of it stops under prefers-reduced-motion.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Blueprint drafting layer
   -------------------------------------------------------------------------- */
.bp-layer{position:absolute;inset:0;overflow:hidden;pointer-events:none;color:#d9c7a5;z-index:0}
.bp-layer svg{width:100%;height:100%;display:block}
.bp-layer .bp-t{font-family:var(--pm-sans,Inter,sans-serif);font-size:11px;letter-spacing:.22em;fill:currentColor;stroke:none;opacity:0;text-transform:uppercase}
.bp-layer .bp-t-lg{font-size:15px;letter-spacing:.1em}
.bp-hero{opacity:.5}
.bp-hero .bp-grid{opacity:0;transition:opacity 1.6s ease .1s}
.bp-page{opacity:.26}
.bp-page .bp-plan,.bp-page .bp-angle,.bp-page .bp-crane,.bp-page .bp-dims{display:none}
.bp-page .bp-building{transform:translate(-80px,40px) scale(.9);transform-origin:center}

/* Lines draw themselves in, one after another */
.bp-layer .bp-s{stroke-dasharray:var(--len,1400);stroke-dashoffset:var(--len,1400);opacity:0}
.is-drawn .bp-s{animation:bp-draw 1.5s cubic-bezier(.35,.8,.35,1) forwards;animation-delay:calc(.18s + var(--i,0)*.11s)}
.is-drawn .bp-grid{opacity:1}
.is-drawn .bp-t{animation:bp-fade .9s ease forwards;animation-delay:calc(1.1s + var(--i,0)*.06s)}
@keyframes bp-draw{from{stroke-dashoffset:var(--len,1400);opacity:0}8%{opacity:1}to{stroke-dashoffset:0;opacity:1}}
@keyframes bp-fade{to{opacity:.85}}

.is-drawn .bp-compass-spin{animation:bp-spin 46s linear 2s infinite;transform-origin:250px 300px}
.is-drawn .bp-crane-arm{animation:bp-swing 16s ease-in-out 2.4s infinite;transform-origin:1330px 300px}
.is-drawn .bp-hook{animation:bp-hoist 9s ease-in-out 2.8s infinite}
.is-drawn .bp-pulse{animation:bp-draw 1.5s cubic-bezier(.35,.8,.35,1) forwards,bp-ping 3.6s ease-out 2.4s infinite;animation-delay:calc(.18s + var(--i,0)*.11s),2.4s;transform-origin:1040px 170px}
.is-drawn .bp-scan{animation:bp-scan 11s cubic-bezier(.6,0,.4,1) 2.6s infinite}
@keyframes bp-spin{to{transform:rotate(360deg)}}
@keyframes bp-swing{0%,100%{transform:rotate(0)}50%{transform:rotate(-7deg)}}
@keyframes bp-hoist{0%,100%{transform:translateY(0)}50%{transform:translateY(46px)}}
@keyframes bp-ping{0%{transform:scale(1);opacity:1}70%,100%{transform:scale(2.6);opacity:0}}
@keyframes bp-scan{0%{transform:translateX(-5%);opacity:0}10%{opacity:.5}90%{opacity:.5}100%{transform:translateX(105%);opacity:0}}

/* --------------------------------------------------------------------------
   Scroll reveals (added by motion.js so every page gets them)
   -------------------------------------------------------------------------- */
[data-m]{--m-delay:0ms}
[data-m="up"]{opacity:0;transform:translateY(34px)}
[data-m="fade"]{opacity:0}
[data-m="right"]{opacity:0;transform:translateX(-30px)}
[data-m="scale"]{opacity:0;transform:scale(.965)}
[data-m="clip"]{clip-path:inset(0 0 100% 0)}
[data-m]{transition:opacity .95s cubic-bezier(.2,.7,.2,1) var(--m-delay),transform 1.05s cubic-bezier(.2,.7,.2,1) var(--m-delay),clip-path 1.1s cubic-bezier(.2,.7,.2,1) var(--m-delay)}
[data-m].is-in{opacity:1;transform:none;clip-path:inset(0 0 0 0)}

/* Headline lines rise out of their own mask */
/* These spans are injected into the page's own headings, so they defend
   themselves against card styles that target "span" loosely. */
span.m-lines,span.m-lines span.m-line,span.m-lines span.m-line>span{all:unset;display:block;font:inherit;color:inherit;letter-spacing:inherit;text-transform:inherit;text-align:inherit}
span.m-lines span.m-line{overflow:hidden;padding:.18em 0 .2em;margin:-.18em 0 -.2em}
span.m-lines span.m-line>span{transform:translateY(calc(100% + .26em));transition:transform 1.05s cubic-bezier(.2,.75,.2,1);transition-delay:var(--m-delay,0ms)}
span.m-lines.is-in span.m-line>span{transform:none}

/* Images: a cover panel wipes away, the photo settles from a slow zoom */
.m-media{position:relative;overflow:hidden}
.m-media>img{transform:scale(1.12);transition:transform 1.5s cubic-bezier(.2,.7,.2,1)}
.m-media.is-in>img{transform:scale(1)}
.m-media::after{content:"";position:absolute;inset:0;background:var(--pm-sand,#ece7da);transform-origin:bottom;transition:transform 1.1s cubic-bezier(.76,0,.24,1);z-index:1;pointer-events:none}
.m-media.is-in::after{transform:scaleY(0)}

/* Parallax drift, driven by motion.js */
[data-parallax]{will-change:transform}

/* Thin progress rule across the top of the page */
.m-progress{position:fixed;top:0;left:0;height:2px;width:100%;transform:scaleX(0);transform-origin:left;background:linear-gradient(90deg,var(--pm-brass,#9a7a4a),var(--pm-forest,#1f3329));z-index:60;pointer-events:none}

/* Page enters with a soft lift, leaves with a fade */
@keyframes m-page-in{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.js-motion main{animation:m-page-in .8s cubic-bezier(.2,.7,.2,1) both}
.js-motion.is-leaving main,.js-motion.is-leaving .site-footer{opacity:0;transition:opacity .32s ease}

/* Links and buttons answer the pointer */
.js-motion .hp-button,.js-motion .pf-cta-button,.js-motion .cp-whatsapp,.js-motion .unsub-button{will-change:transform}
.js-motion [data-magnet]{transition:transform .5s cubic-bezier(.2,.7,.2,1)}

/* Discipline ticker */
.m-ticker{overflow:hidden;border-block:1px solid var(--pm-line,#dcd7c9);padding:18px 0;background:var(--pm-ivory,#f6f3ec)}
.m-ticker-track{display:flex;width:max-content;gap:0;animation:m-ticker 46s linear infinite}
.m-ticker:hover .m-ticker-track{animation-play-state:paused}
.m-ticker span{display:inline-flex;align-items:center;gap:38px;padding-right:38px;font-family:var(--pm-serif,Georgia,serif);font-size:clamp(20px,2vw,30px);color:var(--pm-ink,#18201b);white-space:nowrap}
.m-ticker span::after{content:"";width:7px;height:7px;border-radius:50%;background:var(--pm-brass,#9a7a4a);flex-shrink:0}
@keyframes m-ticker{to{transform:translateX(-50%)}}

@media(prefers-reduced-motion:reduce){
 .bp-layer .bp-s,.bp-layer .bp-t{stroke-dashoffset:0;opacity:.8;animation:none!important}
 .bp-layer .bp-grid{opacity:1;transition:none}
 .bp-scan{display:none}
 [data-m],[data-m].is-in{opacity:1;transform:none;clip-path:none;transition:none}
 span.m-lines span.m-line>span{transform:none}
 .m-media>img{transform:none}
 .m-media::after{display:none}
 .m-ticker-track{animation:none}
 .js-motion main{animation:none}
 .m-progress{display:none}
}

/* The hero drawing lives in the right half so the headline stays clean */
.hp-hero .bp-layer{z-index:0;opacity:1;color:#e4d3b0;-webkit-mask-image:linear-gradient(90deg,transparent 0,transparent 32%,#000 56%,#000 100%);mask-image:linear-gradient(90deg,transparent 0,transparent 32%,#000 56%,#000 100%)}
.hp-hero .bp-layer .bp-compass,.hp-hero .bp-layer .bp-plan,.hp-hero .bp-layer .bp-angle{display:none}
/* A calm drafting field behind the drawing so every line reads against the photo */
.hp-hero .bp-layer::before{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent 0,rgba(8,18,14,.1) 38%,rgba(8,18,14,.62) 72%,rgba(8,18,14,.78) 100%)}
.hp-hero .bp-layer svg{position:relative}
.hp-hero .bp-grid{opacity:0}
.hp-hero .is-drawn .bp-grid,.hp-hero .bp-layer.is-drawn .bp-grid{opacity:1}
@media(max-width:900px){.hp-hero .bp-layer{opacity:.4;-webkit-mask-image:linear-gradient(180deg,transparent 0,transparent 42%,#000 70%);mask-image:linear-gradient(180deg,transparent 0,transparent 42%,#000 70%)}}

/* Inner page headers: the drawing sits over the photo, under the title */
.light-page [class*="hero"] .bp-layer{z-index:0;color:#e4d3b0;opacity:.42;-webkit-mask-image:linear-gradient(90deg,transparent 0,transparent 30%,#000 62%);mask-image:linear-gradient(90deg,transparent 0,transparent 30%,#000 62%)}
.light-page [class*="hero"]>*:not(.bp-layer){position:relative;z-index:1}
.light-page [class*="hero-shade"],.light-page .project-detail-shade{z-index:0!important}
@media(max-width:760px){.light-page [class*="hero"] .bp-layer{opacity:.26}}

/* Text-led page intros get a faint drafting grid instead of a photo */
.light-page .projects-heading-row,.light-page .news-heading-row,.light-page .portfolio-gallery-hero,.light-page .video-hero-copy,.light-page .search-results-header,.light-page .cp-intro,.light-page .about-opening,.light-page .legal-intro{position:relative}
.light-page .projects-heading-row::before,.light-page .news-heading-row::before,.light-page .portfolio-gallery-hero::before,.light-page .search-results-header::before,.light-page .legal-intro::before{content:"";position:absolute;left:0;right:0;top:-60px;bottom:-30px;background-image:linear-gradient(var(--pm-line,#dcd7c9) 1px,transparent 1px),linear-gradient(90deg,var(--pm-line,#dcd7c9) 1px,transparent 1px);background-size:60px 60px;opacity:.5;-webkit-mask-image:radial-gradient(ellipse at 18% 40%,#000,transparent 68%);mask-image:radial-gradient(ellipse at 18% 40%,#000,transparent 68%);pointer-events:none;z-index:-1}
