/* =====================================================================
   MOTION LAYER · direction A "Institutional clarity" · 20-10-2026
   >>> START of block to extract to /assets/css/home-motion.css <<<
   Rules: content is visible by default; only transform / opacity / filter
   (plus the FAQ block-size and two registered custom properties) animate;
   every effect sits inside prefers-reduced-motion:no-preference and is
   progressive (@supports). No libraries, no new fonts, brand colours only.
   ===================================================================== */
:root{--ease:cubic-bezier(.2,.8,.2,1)}
h1,h2,h3{text-wrap:balance}
main :is(p,li,dd){text-wrap:pretty}
main summary{text-wrap:balance}

@media (prefers-reduced-motion:no-preference){

/* ---- keyframes: only "from" frames, so the end state is always the natural page ---- */
@keyframes m-fade{from{opacity:0}}
@keyframes m-on{from{opacity:0}to{opacity:1}}
@keyframes m-rise{from{opacity:0;translate:0 14px}}
@keyframes m-word{from{translate:0 .32em}}
@keyframes m-lift{from{translate:0 12px}}
@keyframes m-rv{from{opacity:0;translate:0 24px}}
@keyframes m-rule{from{transform:scaleY(0)}}
@keyframes m-read{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes m-settle{from{scale:1.16}}
@keyframes m-frame{from{opacity:0;translate:-14px 14px}}
@keyframes m-pop{from{opacity:0;translate:0 -6px}}
@keyframes m-sheen{from{translate:-130% 0}to{translate:130% 0}}
@keyframes m-flip{from{rotate:-90deg;scale:.8}}
@keyframes m-ping{from{opacity:.7;scale:1}to{opacity:0;scale:3.4}}
@keyframes m-turn-b{from{rotate:0 1 0 -16deg;translate:-20px 0 -150px}}
@keyframes m-turn-f{from{rotate:0 1 0 -16deg;translate:14px 0 -20px}}
@keyframes m-glare{from{translate:-28% 0}to{translate:28% 0}}
@keyframes m-floor{from{opacity:.2;scale:.7 1}}
@keyframes m-fab{from{opacity:0;translate:0 14px;visibility:hidden}to{opacity:1;translate:0 0;visibility:visible}}
@keyframes m-drawer-in{from{opacity:0;transform:translateX(32px)}}
@keyframes m-drawer-out{to{opacity:0;transform:translateX(32px)}}

/* ---- 1. Hero load choreography: header, eyebrow, H1 word by word, lead, CTAs, proof, media.
        H1 and lead only move (translate), they never start transparent: LCP and reading are never delayed. ---- */
.js .site-header{animation:m-fade .5s var(--ease) backwards}
.js .hero-head::before{transform-origin:top;animation:m-rule .7s var(--ease) .15s both}
.js .hero .eyebrow{animation:m-rise .55s var(--ease) .08s both}
.js .hero h1 .w{display:inline-block;animation:m-word .38s var(--ease) both;animation-delay:calc(80ms + var(--i,0) * 28ms)}
.js .hero .lead{animation:m-lift .6s var(--ease) .38s both}
.js .hero-actions{animation:m-rise .6s var(--ease) .48s both}
.js .hero-foot{animation:m-rise .6s var(--ease) .58s both}
.js .hero-media::before{animation:m-frame .8s var(--ease) .3s both}
.js .arch img{animation:m-settle 1.4s var(--ease) both}
.js .chip{animation:m-rise .7s var(--ease) .75s both}

/* ---- 2. Signature 3D moment, part 1: hero arch in depth layers (frame / photo / address card) ---- */
.hero-media{transform-style:preserve-3d;transform:perspective(1200px) rotateY(calc(var(--hx,0) * 6deg)) rotateX(calc(var(--hy,0) * -4deg));transition:transform .6s var(--ease)}
.hero-media::before{transform:translateZ(-36px)}
.chip{transform:translateZ(64px)}
.arch img{scale:1.06;translate:calc(var(--hx,0) * -12px) calc(var(--hy,0) * -8px);transition:translate .6s var(--ease)}
@media (max-width:900px){.chip{transform:translateZ(20px)}}

/* ---- 3. Signature 3D moment, part 2: app phones turn in 3D as you scroll ---- */
.phones{perspective:1400px}
.phone{transition:transform .6s var(--ease)}
.phone.back{translate:0 0 -40px;transform:translate3d(calc(var(--px,0) * -6px),calc(var(--py,0) * -4px),0)}
.phone.front{translate:0 0 36px;transform:translate3d(calc(var(--px,0) * 10px),calc(var(--py,0) * 7px),0)}
.phones::after{content:"";position:absolute;left:10%;right:10%;bottom:-22px;height:38px;z-index:-1;pointer-events:none;background:radial-gradient(closest-side,rgba(13,22,56,.30),rgba(13,22,56,0));filter:blur(6px)}
@supports (animation-timeline:view()){
  .phone.back{animation:m-turn-b linear both;animation-timeline:view();animation-range:cover 0% cover 42%}
  .phone.front{animation:m-turn-f linear both;animation-timeline:view();animation-range:cover 0% cover 42%}
  .phone::after{content:"";position:absolute;inset:0 -60%;pointer-events:none;background:linear-gradient(105deg,transparent 42%,rgba(255,255,255,.16) 50%,transparent 58%);animation:m-glare linear both;animation-timeline:view();animation-range:cover 0% cover 100%}
  .phones::after{animation:m-floor linear both;animation-timeline:view();animation-range:cover 0% cover 42%}
}

/* ---- 4. Scroll reveal on 7 section openings and cards (CSS only; IO fallback below) ---- */
@supports (animation-timeline:view()){
  .js :is(.head,.stat,.path,.step,.person,.testi,.principle,.map-card,.office){animation:m-rv linear both;animation-timeline:view();animation-range:entry 0% entry 38%}
  .js .path:nth-child(3n+2){animation-range:entry 4% entry 42%}
  .js .path:nth-child(3n){animation-range:entry 8% entry 46%}
  /* bronze rules draw themselves: the house signature */
  .js .head::before{transform-origin:top;animation:m-rule linear both;animation-timeline:view();animation-range:entry 0% entry 60%}
  .js .step::before{transform-origin:top;animation:m-rule linear both;animation-timeline:view();animation-range:entry 20% cover 40%}
}
@supports not (animation-timeline:view()){
  .mj [data-rv]{transition:opacity .6s var(--ease),translate .6s var(--ease)}
  .mj [data-rv]:not(.in){opacity:0;translate:0 20px}
}

/* ---- 5. Header turns into frosted glass on scroll + bronze reading progress ---- */
@supports (animation-timeline:scroll()){
  html.js:not(.lite) .site-header{background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none;border-bottom-color:transparent}
  html:not(.lite) .site-header::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:0;background:rgba(250,246,238,.94);-webkit-backdrop-filter:saturate(1.3) blur(14px);backdrop-filter:saturate(1.3) blur(14px);border-bottom:1px solid var(--line);box-shadow:0 10px 24px -18px rgba(13,22,56,.35);animation:m-on linear both;animation-timeline:scroll(root);animation-range:0px 96px}
  html::before{content:"";position:fixed;top:0;left:0;right:0;height:3px;z-index:200;pointer-events:none;background:var(--bronze);transform-origin:0 50%;transform:scaleX(0);animation:m-read linear both;animation-timeline:scroll(root)}
}

/* ---- 6. Menus and FAQ ---- */
.dd:hover .dd-panel,.dd:focus-within .dd-panel,.lang[open] ul{animation:m-pop .22s var(--ease) both}
details.q[open] summary::after{animation:m-flip .3s var(--ease)}
@supports selector(::details-content){
  :root{interpolate-size:allow-keywords}
  details.q::details-content{block-size:0;overflow:clip;transition:block-size .38s var(--ease),content-visibility .38s allow-discrete}
  details.q[open]::details-content{block-size:auto}
}

/* ---- 7. Map: the Lisbon pin pulses twice when the map enters view (never loops) ---- */
.pin.hq i::after{content:"";position:absolute;inset:-3px;border-radius:50%;border:1.5px solid var(--bronze);opacity:0}
.map-card.on .pin.hq i::after{animation:m-ping 1.6s var(--ease) .3s 2}

/* ---- 7b. Floating contact buttons appear once the hero has scrolled away (CSS scroll timeline; JS fallback adds .on) ---- */
@supports (animation-timeline:scroll()){
  .fab{animation:m-fab linear both;animation-timeline:scroll(root);animation-range:640px 800px}
}
@supports not (animation-timeline:scroll()){
  .mf .fab{transition:opacity .3s var(--ease),translate .3s var(--ease),visibility .3s}
  .mf .fab:not(.on){opacity:0;translate:0 14px;visibility:hidden}
}
.mbar,.cookie{transition:translate .25s var(--ease)}

/* ---- 8. Page and drawer view transitions ---- */
@view-transition{navigation:auto}
.drawer{view-transition-name:menu-drawer}
html.vt{scroll-behavior:auto}
.vt .drawer{transition:none}
::view-transition-old(root),::view-transition-new(root){animation-duration:.28s;animation-timing-function:var(--ease)}
::view-transition-old(menu-drawer){animation:m-drawer-out .3s var(--ease) both}
::view-transition-new(menu-drawer){animation:m-drawer-in .35s var(--ease) both}

/* ---- 9. Pointer-only effects (mouse/trackpad; never on touch) ---- */
@media (hover:hover) and (pointer:fine){
  /* path cards: 3D tilt (max 5 deg) and a bronze spotlight that is a ::before moved with translate/opacity only (alpha .12 keeps AA contrast, >= 4.5:1, under the cursor) */
  .path,.path:hover{transform:perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) translateY(var(--ty,0px));transition:transform .25s ease-out,box-shadow .3s,border-color .3s}
  .path:hover,.path:focus-within{--ty:-4px}
  .path{position:relative;overflow:hidden}
  .path>*{position:relative}
  .path::before{content:"";position:absolute;left:0;top:0;width:340px;height:340px;margin:-170px 0 0 -170px;border-radius:50%;pointer-events:none;background:radial-gradient(closest-side,rgba(226,197,161,.12),rgba(226,197,161,0));opacity:0;translate:var(--mx,170px) var(--my,0px);transition:opacity .3s}
  .path:hover::before,.path:focus-within::before{opacity:1}
  /* primary button: sheen passes once, chevron slides in */
  .btn-primary{position:relative;overflow:hidden}
  .btn-primary::before{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(105deg,transparent 35%,rgba(255,255,255,.22) 50%,transparent 65%);translate:-130% 0}
  .btn-primary:hover::before,.btn-primary:focus-visible::before{animation:m-sheen .85s var(--ease) 1 both}
  .btn-primary:not(.btn-sm){padding-inline:36px}
  .btn-primary:not(.btn-sm)::after{content:"";position:absolute;right:17px;top:50%;width:8px;height:8px;margin-top:-4px;border-top:2px solid currentColor;border-right:2px solid currentColor;rotate:45deg;opacity:0;translate:-6px 0;transition:opacity .25s,translate .35s var(--ease)}
  .btn-primary:not(.btn-sm):hover::after,.btn-primary:not(.btn-sm):focus-visible::after{opacity:1;translate:0 0}
}

/* ---- 10. Data-saver: no choreography at all, the static page ---- */
html.lite,html.lite *,html.lite *::before,html.lite *::after,html.lite::before{animation:none!important;transition-duration:.01ms!important}

}/* end prefers-reduced-motion:no-preference */
/* >>> END of block to extract to home-motion.css <<< */
