/* AiSMART Lab — motion layer (micro-interactions, reveal, skeletons, hero canvas, easter egg).
   Additive to brand.css. Everything here is transform/opacity (plus one-shot View Transitions);
   prefers-reduced-motion turns it all off and leaves the static site exactly as before. */

/* ---- hero signal canvas: same box + mask as the static art underneath ---- */
.hero--circuit > .hero-pulse{position:absolute;inset:0;width:100%;height:100%;z-index:-1;pointer-events:none;opacity:0;transition:opacity .9s var(--ease);
  -webkit-mask-image:radial-gradient(ellipse 36rem 85% at var(--hero-text-x) 50%,rgb(0 0 0 / .32) 0,rgb(0 0 0 / .40) 60%,#000 100%);
          mask-image:radial-gradient(ellipse 36rem 85% at var(--hero-text-x) 50%,rgb(0 0 0 / .32) 0,rgb(0 0 0 / .40) 60%,#000 100%)}
.hero--live > .hero-pulse{opacity:1}
@media (max-width:720px){.hero--circuit > .hero-pulse{
  -webkit-mask-image:radial-gradient(ellipse 95% 85% at 30% 50%,rgb(0 0 0 / .30) 0,rgb(0 0 0 / .4) 50%,#000 100%);
          mask-image:radial-gradient(ellipse 95% 85% at 30% 50%,rgb(0 0 0 / .30) 0,rgb(0 0 0 / .4) 50%,#000 100%)}}

@media (prefers-reduced-motion:no-preference){
  /* ---- press + hover on controls ---- */
  .btn,.site-nav a,.member-nav a,.member-nav button,.subnav a,.lib-subnav a,.lang-toggle button,.theme-toggle,.site-logout,.lib-watch{
    transition:transform 90ms var(--ease),background-color var(--dur-2) var(--ease),color var(--dur-2) var(--ease),border-color var(--dur-2) var(--ease),box-shadow var(--dur-2) var(--ease)}
  html .btn:active,html .site-nav a:active,html .member-nav a:active,html .member-nav button:active,html .subnav a:active,html .lib-subnav a:active,
  html .lang-toggle button:active,html .theme-toggle:active,html .site-logout:active,html .fx-card:active .btn{transform:scale(.96)}

  /* buttons: one light sweep per hover (primary bright, secondary tinted) */
  html .btn{position:relative;overflow:hidden;isolation:isolate}
  html .btn::after{content:"";position:absolute;inset:-1px;z-index:-1;pointer-events:none;
    background:linear-gradient(105deg,transparent 25%,rgb(255 255 255 / .5) 50%,transparent 75%);transform:translateX(-130%);transition:none}
  html[data-theme="dark"] .btn-primary::after{background:linear-gradient(105deg,transparent 25%,rgb(0 32 121 / .28) 50%,transparent 75%)}
  @media (prefers-color-scheme:dark){html:not([data-theme="light"]) .btn-primary::after{background:linear-gradient(105deg,transparent 25%,rgb(0 32 121 / .28) 50%,transparent 75%)}}
  html .btn-secondary::after{background:linear-gradient(105deg,transparent 25%,color-mix(in srgb,var(--color-primary) 30%,transparent) 50%,transparent 75%)}
  html .btn:hover::after,html .fx-card:hover .btn::after{transform:translateX(130%);transition:transform 1.1s cubic-bezier(.45,.05,.35,1)}

  /* nav "trace" underline draws in on hover/focus (not on the current page) */
  .site-nav a,.member-nav a,.subnav a,.lib-subnav a{position:relative}
  .site-nav a:not([aria-current])::after,.member-nav a:not([aria-current])::after,.subnav a:not([aria-current])::after,.lib-subnav a:not([aria-current])::after{
    content:"";position:absolute;left:var(--space-3);right:var(--space-3);bottom:6px;height:2px;border-radius:2px;background:var(--color-primary);
    transform:scaleX(0);transform-origin:left;transition:transform .25s var(--ease);pointer-events:none}
  .site-nav a:not([aria-current]):hover::after,.member-nav a:not([aria-current]):hover::after,.subnav a:not([aria-current]):hover::after,.lib-subnav a:not([aria-current]):hover::after,
  .site-nav a:not([aria-current]):focus-visible::after,.subnav a:not([aria-current]):focus-visible::after{transform:scaleX(1)}

  /* ---- cards: lift + shadow, pointer-following border glow + inner spotlight, tilt (motion.js sets the vars) ---- */
  html .fx-card{position:relative;transform-style:preserve-3d;
    transform:perspective(900px) rotateX(var(--fx-rx,0deg)) rotateY(var(--fx-ry,0deg)) translateY(var(--fx-lift,0px));
    transition:transform .35s var(--ease),box-shadow .35s var(--ease),border-color .25s var(--ease)}
  html .fx-card::before{content:"";position:absolute;inset:-1px;border-radius:inherit;padding:2px;pointer-events:none;opacity:0;transition:opacity .3s var(--ease);
    background:radial-gradient(260px circle at var(--fx-x,50%) var(--fx-y,50%),var(--color-primary),color-mix(in srgb,var(--color-primary) 35%,transparent) 40%,transparent 70%);
    -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 exclude,linear-gradient(#000 0 0)}
  html .fx-card::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;opacity:0;transition:opacity .3s var(--ease);
    background:radial-gradient(320px circle at var(--fx-x,50%) var(--fx-y,50%),color-mix(in srgb,var(--color-primary) 11%,transparent),transparent 70%)}
  @media (hover:hover) and (pointer:fine){
    html .fx-card:hover{--fx-lift:-5px;box-shadow:0 18px 40px -18px color-mix(in srgb,var(--color-primary) 55%,transparent),var(--shadow-2)}
    html .fx-card:hover::before,html .fx-card:hover::after{opacity:1}
  }
  html .fx-card.fx-tilting{transition:transform .12s linear,box-shadow .35s var(--ease),border-color .25s var(--ease)}

  /* ---- scroll reveal (only below-the-fold items are ever hidden; never without JS) ---- */
  .rv{opacity:0;transform:translateY(16px)}
  .rv.rv-in{opacity:1;transform:none;transition:opacity .6s var(--ease) calc(var(--rv-i,0) * 70ms),transform .7s var(--ease) calc(var(--rv-i,0) * 70ms)}

  /* ---- theme change: circle expands from the toggle; language: cross-fade ---- */
  ::view-transition-old(root),::view-transition-new(root){animation-duration:.35s;mix-blend-mode:normal}
  html.vt-theme::view-transition-old(root){animation:none}
  html.vt-theme::view-transition-new(root){animation:fx-reveal .9s cubic-bezier(.65,0,.35,1) both}
  @keyframes fx-reveal{from{clip-path:circle(0 at var(--vt-x,50%) var(--vt-y,0))}to{clip-path:circle(var(--vt-r,150vmax) at var(--vt-x,50%) var(--vt-y,0))}}
  html.vt-lang::view-transition-old(root){animation:fx-fade-out .25s ease both}
  html.vt-lang::view-transition-new(root){animation:fx-fade-in .3s ease .05s both}
  @keyframes fx-fade-out{to{opacity:0}}
  @keyframes fx-fade-in{from{opacity:0}}
}

/* ---- skeleton loaders (static grey blocks under reduced motion; shimmer otherwise) ---- */
.sk{position:relative;overflow:hidden;border-radius:var(--radius-sm);background:color-mix(in srgb,var(--color-text) 9%,var(--color-surface));color:transparent!important;user-select:none}
.sk-line{display:block;height:.9em;margin:.45em 0}
.sk-title{display:block;height:1.3em;width:70%;margin:.3em 0 .7em}
.sk-pill{display:inline-block;width:5.5em;height:1.6em;border-radius:var(--radius-pill);vertical-align:middle}
.sk-card{display:block;padding:var(--space-6) var(--space-5);border:1px solid var(--color-border);border-radius:var(--radius-lg);background:var(--color-surface)}
@media (prefers-reduced-motion:no-preference){
  .sk::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
    background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--color-surface) 70%,transparent),transparent);animation:sk-shimmer 1.3s infinite}
  @keyframes sk-shimmer{to{transform:translateX(100%)}}
}

/* ---- counters: tabular digits so the width never changes ---- */
[data-count]{font-variant-numeric:tabular-nums}

/* ---- easter egg: confetti canvas + toast ---- */
.fx-confetti{position:fixed;inset:0;width:100vw;height:100vh;pointer-events:none;z-index:1000}
.fx-toast{position:fixed;left:50%;bottom:calc(24px + env(safe-area-inset-bottom));z-index:1001;transform:translate(-50%,0);
  display:flex;align-items:center;gap:var(--space-2);padding:var(--space-3) var(--space-5);border-radius:var(--radius-pill);
  background:var(--brand-950,#002079);color:#fff;border:1px solid rgb(172 206 233 / .5);box-shadow:0 10px 40px rgb(0 32 121 / .35);
  font-family:var(--font-display);font-size:var(--fs-sm)}
@media (prefers-reduced-motion:no-preference){
  .fx-toast{animation:fx-toast-in .4s var(--ease) both}
  .fx-toast.fx-out{animation:fx-toast-out .35s var(--ease) both}
  @keyframes fx-toast-in{from{opacity:0;transform:translate(-50%,16px)}}
  @keyframes fx-toast-out{to{opacity:0;transform:translate(-50%,16px)}}
}

/* group heading counts (projects, awards) */
.group__count{display:inline-grid;place-items:center;min-width:2.2em;height:1.7em;margin-left:var(--space-3);padding:0 .55em;border-radius:var(--radius-pill);
  background:var(--color-primary-subtle);color:var(--color-on-primary-subtle,var(--color-primary));font-size:var(--fs-sm);vertical-align:.2em}
.sk-item{list-style:none;margin:0 0 var(--space-4)}

/* ======================= round 3 ======================= */
/* hero title: letters rise in (EN also "decodes" from signal glyphs). Built by motion.js; the real text stays for AT. */
.fx-type .w{display:inline-block;white-space:nowrap}
.fx-type .c{display:inline-block}
@media (prefers-reduced-motion:no-preference){
  .fx-type .c{opacity:0;transform:translateY(.32em)}
  .fx-type.go .c{opacity:1;transform:none;transition:opacity .45s var(--ease) var(--d,0ms),transform .6s cubic-bezier(.2,.7,.2,1) var(--d,0ms)}
  .fx-type .c.scr{color:var(--brand-200,#ACCEE9)}
}

/* section headings: a short circuit trace (line + via) under the heading, drawn in on reveal */
.fx-h2{position:relative}
.fx-h2::after{content:"";position:absolute;left:0;bottom:-.55rem;width:4.5rem;height:7px;pointer-events:none;transform-origin:left center;
  background:radial-gradient(circle at calc(100% - 3.5px) 50%,var(--color-primary) 0 2.2px,transparent 2.8px),
             linear-gradient(90deg,var(--color-primary),color-mix(in srgb,var(--color-primary) 55%,#ACCEE9)) left center/calc(100% - 6px) 2px no-repeat}
.award .fx-h2::after,.hero--circuit .fx-h2::after{content:none}
@media (prefers-reduced-motion:no-preference){
  .fx-h2:not(.fx-h2-in)::after{transform:scaleX(0)}
  .fx-h2.fx-h2-in::after{transition:transform .8s cubic-bezier(.65,0,.35,1) .15s}
}

@media (prefers-reduced-motion:no-preference){
  /* images: slow zoom inside their frame on hover */
  main figure:has(> img){overflow:hidden;border-radius:var(--radius-lg)}
  main figure:has(> img) > img{transition:transform .8s cubic-bezier(.2,.7,.2,1)}
  @media (hover:hover) and (pointer:fine){ main figure:has(> img):hover > img{transform:scale(1.045)} }

  /* lists: highlight bar + nudge on hover */
  main .record,main .docs > li,main .news-item{position:relative}
  main .record::before,main .docs > li::before,main .news-item::before{content:"";position:absolute;left:calc(-1 * var(--space-4));top:var(--space-4);bottom:var(--space-4);width:3px;border-radius:3px;
    background:linear-gradient(var(--color-primary),color-mix(in srgb,var(--color-primary) 40%,#ACCEE9));transform:scaleY(0);transform-origin:top;transition:transform .35s var(--ease);pointer-events:none}
  main .record > *,main .docs > li > *{transition:transform .35s var(--ease)}
  @media (hover:hover) and (pointer:fine){
    main .record:hover::before,main .docs > li:hover::before,main .news-item:hover::before{transform:scaleY(1)}
    main .record:hover > *,main .docs > li:hover > *{transform:translateX(6px)}
  }

  /* magnetic buttons (motion.js sets --mx/--my; uses the independent `translate` property so press scale still composes) */
  html .fx-mag{translate:var(--mx,0px) var(--my,0px);transition:translate .35s cubic-bezier(.2,.7,.2,1),transform 90ms var(--ease),background-color var(--dur-2) var(--ease),color var(--dur-2) var(--ease),border-color var(--dur-2) var(--ease),box-shadow var(--dur-2) var(--ease)}
  html .fx-mag.fx-mag-on{transition-duration:.12s,90ms,var(--dur-2),var(--dur-2),var(--dur-2),var(--dur-2)}

  /* touch: ripple from the tap point */
  .fx-ripple{position:absolute;border-radius:50%;pointer-events:none;background:color-mix(in srgb,var(--color-primary) 28%,transparent);
    transform:scale(0);opacity:1;animation:fx-ripple .6s cubic-bezier(.2,.7,.2,1) forwards}
  @keyframes fx-ripple{to{transform:scale(1);opacity:0}}
  @media (pointer:coarse){html .fx-card{overflow:hidden}}

  /* page-to-page: soft cross-document transition (Chrome 126+/Safari 18.2+; others just navigate) */
  @view-transition{navigation:auto;types:fx-page}
  html:active-view-transition-type(fx-page) main{view-transition-name:fx-main}
  html:active-view-transition-type(fx-page)::view-transition-old(root){animation:fx-fade-out .2s ease both}
  html:active-view-transition-type(fx-page)::view-transition-new(root){animation:fx-fade-in .3s ease both}
  html:active-view-transition-type(fx-page)::view-transition-old(fx-main){animation:fx-page-out .2s ease both}
  html:active-view-transition-type(fx-page)::view-transition-new(fx-main){animation:fx-page-in .42s cubic-bezier(.2,.7,.2,1) .05s both}
  @keyframes fx-page-out{to{opacity:0;transform:translateY(-6px)}}
  @keyframes fx-page-in{from{opacity:0;transform:translateY(14px)}}
}
@media (prefers-reduced-motion:no-preference) and (pointer:coarse){.site-nav a,.subnav a,.lib-subnav a,.member-nav a{overflow:hidden}}
