/* Purposeful motion: a choreographed welcome, then a story revealed by scrolling. */
:root{--ease-out:cubic-bezier(.23,1,.32,1);--ease-in-out:cubic-bezier(.77,0,.175,1);--ease-drawer:cubic-bezier(.32,.72,0,1)}
.headline-line{display:block;overflow:clip;padding-bottom:.09em;margin-bottom:-.09em}
.headline-line>span{display:block}
.hero-art{isolation:isolate}
.browser-stage{min-width:0;perspective:1000px}
.reading-progress{position:fixed;z-index:50;left:0;top:0;width:100%;height:3px;background:var(--blue);transform:scaleX(0);transform-origin:left;pointer-events:none}
.footer-meta{display:flex;align-items:center;gap:25px}
.motion-toggle{display:inline-flex;align-items:center;gap:8px;background:transparent;border:0;color:var(--muted);font-size:11px;padding:10px 0;min-height:38px}
.motion-toggle span{color:var(--blue);font-size:8px}
.motion-toggle[aria-pressed="true"] span{color:var(--muted)}
.motion-toggle:disabled{cursor:default}
/* Content is visible without JS. Hidden reveal states exist only after successful setup. */
.motion-ready [data-reveal="line"] .headline-line>span{transform:translateY(110%);transition:transform 800ms var(--ease-out)}
.motion-ready [data-reveal="line"].is-visible .headline-line>span{transform:translateY(0);transition-delay:var(--line-delay,0ms)}
.motion-ready [data-reveal="service"]>div{opacity:0;transform:translateX(20px);transition:opacity 600ms var(--ease-out),transform 600ms var(--ease-out)}
.motion-ready [data-reveal="service"]>.service-icon{opacity:0;transform:translateY(15px) rotate(-12deg);transition:opacity 500ms var(--ease-out),transform 800ms var(--ease-out)}
.motion-ready [data-reveal="service"].is-visible>div,.motion-ready [data-reveal="service"].is-visible>.service-icon{opacity:1;transform:none;transition-delay:var(--reveal-delay,0ms)}
.project-image{isolation:isolate}
.project-image::after{content:'';position:absolute;inset:0;z-index:2;background:var(--blue);transform:scaleX(0);transform-origin:right;pointer-events:none}
.motion-ready [data-reveal="project"]::after{transform:scaleX(1);transition:transform 1000ms var(--ease-in-out)}
.motion-ready [data-reveal="project"].is-visible::after{transform:scaleX(0)}
.motion-ready [data-reveal="project"]>.project-image-inner{transform:translateY(7%) scale(.96);transition:transform 1000ms var(--ease-out)}
.motion-ready [data-reveal="project"].is-visible>.project-image-inner{transform:none}
.motion-ready [data-reveal="step"]>div{opacity:0;transform:translateX(20px);transition:opacity 600ms var(--ease-out),transform 600ms var(--ease-out)}
.motion-ready [data-reveal="step"]>.step-number{opacity:0;transform:scale(.9);transition:opacity 500ms var(--ease-out),transform 600ms var(--ease-out)}
.motion-ready [data-reveal="step"].is-visible>div,.motion-ready [data-reveal="step"].is-visible>.step-number{opacity:1;transform:none}
.motion-ready [data-reveal="contact"]{opacity:0;transform:translateX(20px);transition:opacity 600ms var(--ease-out),transform 600ms var(--ease-out)}
.motion-ready [data-reveal="contact"].is-visible{opacity:1;transform:none;transition-delay:var(--reveal-delay,0ms)}
/* First visit: type rises into its line, the project lands on the blue canvas. */
.intro-active .hero h1 .headline-line>span{animation:type-enter 1000ms var(--ease-out) both;animation-delay:var(--line-delay,0ms)}
.intro-active .hero .intro-line{animation:soft-enter 600ms var(--ease-out) both}
.intro-active .hero-description{animation:soft-enter 800ms var(--ease-out) 160ms both}
.intro-active .hero-actions{animation:soft-enter 800ms var(--ease-out) 240ms both}
.intro-active .hero-note{animation:soft-enter 800ms var(--ease-out) 320ms both}
.intro-active .hero-art{animation:canvas-enter 1000ms var(--ease-out) 80ms both}
.intro-active .browser-stage{animation:project-land 1200ms var(--ease-out) 160ms both;transform-origin:70% 60%}
.intro-active .canvas-top .cloud-detail{animation:cloud-enter 1200ms var(--ease-out) 240ms both}
.intro-active .brand-symbol{animation:brand-enter 800ms var(--ease-out) both;transform-origin:center}
@keyframes type-enter{from{transform:translateY(110%) rotate(2deg)}to{transform:translateY(0) rotate(0)}}
@keyframes soft-enter{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes canvas-enter{from{opacity:0;transform:translateY(30px) scale(.97)}to{opacity:1;transform:none}}
@keyframes project-land{from{opacity:0;transform:translate3d(25px,48px,0) rotateY(-14deg) rotateZ(5deg) scale(.94)}to{opacity:1;transform:none}}
@keyframes cloud-enter{from{transform:translateX(20px);opacity:0}to{transform:translateX(0);opacity:.25}}
@keyframes brand-enter{from{transform:rotate(-12deg) scale(.9);opacity:0}to{transform:none;opacity:1}}
/* Native scroll progress does not crop or zoom portfolio screenshots. */
@supports(animation-timeline:scroll()){
  .motion-ready .reading-progress{animation:reading-progress 1s linear both;animation-timeline:scroll(root)}
  @keyframes reading-progress{from{transform:scaleX(0)}to{transform:scaleX(1)}}
}
/* Pointer feedback is deliberately much faster than the marketing entrances. */
.button{transition:background 160ms ease,transform 160ms var(--ease-out)}
.button:hover{transform:none}
@media(hover:hover) and (pointer:fine){
  .button:hover{transform:translateY(-2px)}
  .button .icon,.text-link .icon,.contact-option .icon{transition:transform 160ms var(--ease-out)}
  .button:hover .icon,.text-link:hover .icon{transform:translateX(3px)}
  .contact-option:hover .icon{transform:translate(3px,calc(-50% - 3px))}
  .canvas-bottom a{transition:background 160ms ease,transform 160ms var(--ease-out)}
  .canvas-bottom a:hover{transform:rotate(5deg)}
}
html:not(.keyboard-nav) .button:active{transform:scale(.97)}
/* Keyboard users should never wait for content or a control to settle. */
.keyboard-nav *, .keyboard-nav *::before,.keyboard-nav *::after{animation:none!important;transition:none!important}
.keyboard-nav .headline-line>span,.keyboard-nav [data-reveal]>div,.keyboard-nav [data-reveal]>.service-icon,.keyboard-nav [data-reveal]>.step-number,.keyboard-nav [data-reveal="contact"]{transform:none!important;opacity:1!important}
.keyboard-nav [data-reveal="project"]::after{transform:scaleX(0)!important}
.keyboard-nav{scroll-behavior:auto}
.motion-reduced{scroll-behavior:auto}
.motion-reduced *, .motion-reduced *::before,.motion-reduced *::after{animation:none!important;transition:none!important}
.motion-reduced .headline-line>span,.motion-reduced [data-reveal]>div,.motion-reduced [data-reveal]>.service-icon,.motion-reduced [data-reveal]>.step-number,.motion-reduced [data-reveal="contact"]{transform:none!important;opacity:1!important}
.motion-reduced [data-reveal="project"]::after{transform:scaleX(0)!important}
.motion-reduced .reading-progress{display:none}
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none!important;transition:none!important}
  .headline-line>span,[data-reveal]>div,[data-reveal]>.service-icon,[data-reveal]>.step-number,[data-reveal="contact"]{transform:none!important;opacity:1!important}
  [data-reveal="project"]::after{transform:scaleX(0)!important}
  .reading-progress{display:none}
}
@media(max-width:700px){
  .footer-meta{flex-direction:column;align-items:flex-start;gap:5px}
  .motion-ready [data-reveal="service"]>div{transform:translateX(12px)}
  .motion-ready [data-reveal="service"].is-visible>div{transform:none}
  .motion-ready [data-reveal="service"].is-visible>div,.motion-ready [data-reveal="service"].is-visible>.service-icon{transition-delay:0ms}
}
@media print{[data-reveal], [data-reveal]>*, .headline-line>span{opacity:1!important;transform:none!important;animation:none!important;transition:none!important}.project-image::after,.reading-progress,.motion-toggle{display:none!important}}

/* Keep off-screen entrance offsets inside the phone page gutters. */
@media(max-width:700px){.motion-ready [data-reveal="step"]>div,.motion-ready [data-reveal="contact"]{transform:translateX(12px)}.motion-ready [data-reveal="step"].is-visible>div,.motion-ready [data-reveal="contact"].is-visible{transform:none}}
@media(max-width:700px){.intro-active .browser-stage{animation-name:project-land-mobile}}
@keyframes project-land-mobile{from{opacity:0;transform:translateY(32px) rotateY(-6deg) rotateZ(2deg) scale(.94)}to{opacity:1;transform:none}}
