/* Soliono v09 — motion and surface polish.
   Patterns adapted from MIT-licensed 21st.dev / Magic UI / Aceternity components (Blur Fade, Magic Card spotlight,
   Border Beam, Typing Animation, Text Generate, Animated Shiny Text, Dot Pattern), rewritten as plain CSS.
   One motion idea per surface; everything yields to prefers-reduced-motion and the on-page pause control. */

/* 1. Blur-fade entrances. Hidden only when scripting is on; the reveal class is added when the block scrolls into view. */
/* The entrance uses the individual `translate` property, so it never fights the hover transforms the cards already have. */
html.js [data-reveal]{--d:calc(var(--i,0)*90ms);opacity:0;translate:0 16px;filter:blur(7px);transition:opacity .7s var(--ease),translate .7s var(--ease),filter .7s var(--ease),transform .25s var(--ease),box-shadow .25s,border-color .25s,background .25s,color .2s;transition-delay:var(--d),var(--d),var(--d),0s,0s,0s,0s,0s}
html.js [data-reveal].in{opacity:1;translate:none;filter:none}

/* 2. Staggered arrival for lists the visitor re-renders (goal outcomes, solution rows, SOL preview rows). */
@keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.goal-outcome,.solution-card{animation:rise .55s var(--ease) both;animation-delay:calc(var(--i,0)*70ms)}
.action-preview.is-arriving{animation:rise .5s var(--ease) both}
.action-preview.is-arriving .preview-row,.action-preview.is-arriving .demo-confirm,.action-preview.is-arriving .demo-success{animation:rise .45s var(--ease) both;animation-delay:calc(120ms + var(--i,0)*80ms)}

/* 3. Magic Card spotlight: a soft warm glow follows the pointer on cards that already respond to it. */
.delivery-card,.about-card,.provider-area,.office-location,.service-fact,.goal-outcome,.solution-card,.index-solution{position:relative;isolation:isolate}
.delivery-card:after,.about-card:after,.provider-area:after,.office-location:after,.service-fact:after,.goal-outcome:after,.solution-card:after,.index-solution:after{content:"";position:absolute;inset:-1px -18px;z-index:-1;border-radius:8px;pointer-events:none;opacity:0;transition:opacity .35s var(--ease);background:radial-gradient(260px circle at var(--spot-x,50%) var(--spot-y,50%),var(--spot,#e5cf3e14),transparent 68%)}
.provider-area:after,.goal-outcome:after,.service-fact:after{--spot:#e5cf3e1f}
.delivery-card.pointer-card:after,.about-card.pointer-card:after,.provider-area.pointer-card:after,.office-location.pointer-card:after,.service-fact.pointer-card:after,.goal-outcome.pointer-card:after,.solution-card.pointer-card:after,.index-solution.pointer-card:after{opacity:1}
.solution-card:after{inset:0 -8px;border-radius:6px}

/* 4. Border Beam on the SOL frame: one slow comet along a one-pixel ring. Falls back to the plain border. */
@property --beam{syntax:"<angle>";inherits:false;initial-value:0deg}
@keyframes beam-turn{to{--beam:360deg}}
.sol-demo{position:relative}
@supports (background:conic-gradient(from var(--beam),red,blue)) and (mask-composite:exclude){
 .sol-demo{border-color:transparent}
 .sol-demo:before{content:"";position:absolute;inset:0;z-index:3;border-radius:inherit;padding:1px;pointer-events:none;background:conic-gradient(from var(--beam),#dcdddc 0 68%,#e5cf3e 80%,#f3e78a 84%,#dcdddc 92%);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude;animation:beam-turn 9s linear infinite}
 .paused .sol-demo:before{animation-play-state:paused}
}

/* 5. SOL conversation: thinking indicator, typed reply with a caret, no layout jump. */
.assistant-text{min-height:1.75em}
.thinking{display:inline-flex;align-items:center;gap:5px;height:1.75em;vertical-align:middle}
.thinking i{display:block;width:6px;height:6px;border-radius:50%;background:#8e9394;animation:thinking 1.2s ease-in-out infinite}
.thinking i:nth-child(2){animation-delay:.18s}.thinking i:nth-child(3){animation-delay:.36s}
@keyframes thinking{0%,80%,100%{opacity:.35;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}
.typed:after{content:"";display:inline-block;width:2px;height:1em;margin-left:2px;vertical-align:-.15em;background:#565756;animation:caret 1s steps(1) infinite}
.typed.done:after{display:none}
@keyframes caret{50%{opacity:0}}

/* 6. Text Generate: each word of a chapter title and description blurs in on its own beat. */
.universe-copy .w{display:inline-block;opacity:0;filter:blur(8px);transform:translateY(.12em);animation:word-in .7s var(--ease) forwards;animation-delay:calc(var(--i,0)*42ms)}
@keyframes word-in{to{opacity:1;filter:blur(0);transform:none}}
.paused .universe-copy .w{animation:none;opacity:1;filter:none;transform:none}

/* 7. Animated Shiny Text on the hero eyebrow: a slow glare, once every eight seconds. */
.universe-copy .eyebrow{--shine:110px;color:#c2c8cfb3;background:linear-gradient(90deg,transparent,#fff 50%,transparent) no-repeat;background-size:var(--shine) 100%;background-position:calc(-100% - var(--shine)) 0;-webkit-background-clip:text;background-clip:text;animation:shiny 8s ease-in-out infinite}
@keyframes shiny{0%,88%,100%{background-position:calc(-100% - var(--shine)) 0}30%,58%{background-position:calc(100% + var(--shine)) 0}}
.paused .universe-copy .eyebrow{animation:none;color:#c2c8cf;background:none}

/* 8. Dot Pattern behind the enquiry section, masked so it stays a texture rather than a grid. */
.contact-section{position:relative;isolation:isolate;overflow:hidden}
.contact-section:before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;background-image:radial-gradient(#14191d24 1px,transparent 1.4px);background-size:22px 22px;-webkit-mask-image:radial-gradient(ellipse 40% 62% at 17% 42%,#000 15%,transparent 72%);mask-image:radial-gradient(ellipse 40% 62% at 17% 42%,#000 15%,transparent 72%);opacity:.8}
@media(max-width:760px){.contact-section:before{-webkit-mask-image:radial-gradient(ellipse 80% 34% at 28% 10%,#000 10%,transparent 72%);mask-image:radial-gradient(ellipse 80% 34% at 28% 10%,#000 10%,transparent 72%)}}

/* 9. Primary buttons: a brief sheen on hover for fine pointers, nothing on touch. */
@media(hover:hover) and (pointer:fine){
 .button:not(.button-outline){position:relative;overflow:hidden}
 .button:not(.button-outline):after{content:"";position:absolute;inset:0;background:linear-gradient(115deg,transparent 35%,#ffffff2e 50%,transparent 65%);transform:translateX(-120%);transition:none;pointer-events:none}
 .button:not(.button-outline):hover:after{transform:translateX(120%);transition:transform .7s var(--ease)}
}

/* 10. Counted figures never shift the layout. */
.ticker{font-variant-numeric:tabular-nums}

@media(prefers-reduced-motion:reduce){
 html.js [data-reveal]{opacity:1;transform:none;filter:none;transition:none}
 .goal-outcome,.solution-card,.action-preview.is-arriving,.action-preview.is-arriving *,.universe-copy .w,.thinking i,.typed:after{animation:none!important;opacity:1;filter:none;transform:none}
 .sol-demo:before{animation:none}
 .universe-copy .eyebrow{animation:none;color:#c2c8cf;background:none}
 .button:not(.button-outline):after{display:none}
}
@media print{html.js [data-reveal]{opacity:1;transform:none;filter:none}.sol-demo:before,.contact-section:before{display:none}}
