/* holobiome.ai landing — icon motion.
   Three states per icon:
     idle   → always running, slow and quiet
     hover  → .card:is(:hover,:focus-within,.kb)  — a perturbation of the idle motion
     launch → .card.launch — a one-shot, ~550ms, right before navigation
   Reduced motion: idle loops stop, hover is minimal, launch is instant (handled in app.js). */

.ic { width: 100%; height: 100%; display: block; overflow: visible; }
.ic .ac  { stroke: var(--ac); }
.ic .acf { fill: var(--ac); stroke: none; }
.tb, .ic .tb { transform-box: fill-box; transform-origin: center; }   /* any node/dot that scales must scale in place — also outside .ic (background net, logos) */
.ic .vb  { transform-box: view-box; }

/* ---------- shared keyframes ---------- */
@keyframes kf-spin      { to { transform: rotate(360deg); } }
@keyframes kf-spin-rev  { to { transform: rotate(-360deg); } }
@keyframes kf-breathe   { 0%,100% { transform: scale(1); } 50% { transform: scale(1.05); } }
@keyframes kf-pulse-o   { 0%,100% { opacity: .35; } 50% { opacity: 1; } }
@keyframes kf-twinkle   { 0%,100% { opacity: .25; transform: scale(.8); } 50% { opacity: 1; transform: scale(1.25); } }
@keyframes kf-flow      { to { stroke-dashoffset: -48; } }
@keyframes kf-flow-fast { to { stroke-dashoffset: -96; } }
@keyframes kf-bob       { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
@keyframes kf-sway      { 0%,100% { transform: rotate(-5deg); } 50% { transform: rotate(5deg); } }
@keyframes kf-shake     { 0%,100% { transform: rotate(0); } 20% { transform: rotate(-7deg); } 40% { transform: rotate(6deg); } 60% { transform: rotate(-4deg); } 80% { transform: rotate(3deg); } }
@keyframes kf-expand-fade { to { transform: scale(2); opacity: 0; } }
@keyframes kf-collapse  { to { transform: scale(0); opacity: 0; } }
@keyframes kf-flash     { 0% { opacity: 0; } 35% { opacity: .95; } 100% { opacity: 0; } }
@keyframes kf-pop       { 0% { transform: scale(0); opacity: 0; } 60% { transform: scale(1.35); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes kf-fade-out  { to { opacity: 0; } }
@keyframes kf-draw      { to { stroke-dashoffset: 0; } }
@keyframes kf-rise      { 0% { transform: translateY(0); opacity: 0; } 15% { opacity: 1; } 100% { transform: translateY(-22px); opacity: 0; } }
@keyframes kf-drop      { 0% { transform: translateY(-6px); opacity: 0; } 20% { opacity: 1; } 80% { transform: translateY(18px); opacity: 1; } 100% { transform: translateY(20px); opacity: 0; } }
@keyframes kf-sweep-y   { 0%,100% { transform: translateY(0); } 50% { transform: translateY(46px); } }
@keyframes kf-sweep-y2  { 0%,100% { transform: translateY(-16px); } 50% { transform: translateY(16px); } }
@keyframes kf-fly-up    { to { transform: translateY(-26px) scale(.6); opacity: 0; } }
@keyframes kf-fly-right { to { transform: translateX(40px) rotate(6deg); opacity: 0; } }
@keyframes kf-glow      { 0%,100% { filter: drop-shadow(0 0 0 transparent); } 50% { filter: drop-shadow(0 0 6px var(--ac)); } }

/* ---------- portal ---------- */
.ic-portal .ring { animation: kf-breathe 6s ease-in-out infinite; }
.ic-portal .r2   { animation: kf-breathe 6s ease-in-out infinite 1s, kf-spin 40s linear infinite; }
.ic-portal .r3   { animation-delay: 2s; }
.ic-portal .o1   { animation: kf-spin 14s linear infinite; }
.ic-portal .o2   { animation: kf-spin-rev 9s linear infinite; }
.ic-portal .o3   { animation: kf-spin 6s linear infinite; }
.ic-portal .core { animation: kf-pulse-o 3s ease-in-out infinite; }
.card:is(:hover,:focus-within,.kb) .ic-portal .o1 { animation-duration: 3s; }
.card:is(:hover,:focus-within,.kb) .ic-portal .o2 { animation-duration: 2s; }
.card:is(:hover,:focus-within,.kb) .ic-portal .o3 { animation-duration: 1.2s; }
.card:is(:hover,:focus-within,.kb) .ic-portal .r2 { animation: kf-spin 4s linear infinite; }
.card:is(:hover,:focus-within,.kb) .ic-portal .ring { stroke-width: 3; }
.card.launch .ic-portal .ring  { animation: kf-expand-fade .55s ease-in forwards; }
.card.launch .ic-portal .orbit { animation: kf-collapse .45s ease-in forwards; }
.card.launch .ic-portal .core  { animation: kf-expand-fade .5s ease-out forwards; }
.card.launch .ic-portal .flash { animation: kf-flash .55s ease-out forwards; }

/* ---------- instructions ---------- */
@keyframes kf-chk { 0%,10% { stroke-dashoffset: 22; } 30%,80% { stroke-dashoffset: 0; } 95%,100% { stroke-dashoffset: 22; } }
.ic-instructions .chk { stroke-dasharray: 22; stroke-dashoffset: 22; animation: kf-chk 6s ease-in-out infinite; }
.ic-instructions .i2 .chk { animation-delay: .7s; }
.ic-instructions .i3 .chk { animation-delay: 1.4s; }
.ic-instructions .tube { transition: transform .5s cubic-bezier(.2,.8,.2,1); }
.ic-instructions .cap  { transition: transform .5s cubic-bezier(.2,.8,.2,1); }
.card:is(:hover,:focus-within,.kb) .ic-instructions .tube { transform: rotate(-12deg); }
.card:is(:hover,:focus-within,.kb) .ic-instructions .cap  { transform: translateY(-4px); }
.card:is(:hover,:focus-within,.kb) .ic-instructions .chk  { animation-duration: 2.4s; }
.card.launch .ic-instructions .cap { animation: kf-fly-up .5s ease-in forwards; }
.card.launch .ic-instructions .chk { animation: none; stroke-dashoffset: 0; transition: stroke-dashoffset .3s; }
.card.launch .ic-instructions .liq { animation: kf-rise .5s ease-out forwards; }

/* ---------- qr ---------- */
@keyframes kf-qr-scan { 0% { transform: translateY(0); } 50% { transform: translateY(56px); } 100% { transform: translateY(0); } }
@keyframes kf-qr-flick { 0%,100% { opacity: 1; } 50% { opacity: .15; } }
.ic-qr .scan { animation: kf-qr-scan 4s ease-in-out infinite; }
.card:is(:hover,:focus-within,.kb) .ic-qr .m { animation: kf-qr-flick .9s steps(2) infinite; animation-delay: calc(var(--i) * -.13s); }
.card:is(:hover,:focus-within,.kb) .ic-qr .scan { animation-duration: 1.2s; }
.card.launch .ic-qr .scan { animation: kf-fade-out .3s forwards; }
.card.launch .ic-qr .m, .card.launch .ic-qr .finders { animation: kf-fade-out .35s forwards; }
.card.launch .ic-qr .ok { animation: kf-pop .5s .1s cubic-bezier(.2,1.4,.4,1) forwards; }

/* ---------- h4 ---------- */
@keyframes kf-fill { 0%,8% { stroke-dashoffset: 32; } 30%,85% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: 32; } }
.ic-h4 .f { stroke-dasharray: 32; stroke-dashoffset: 32; animation: kf-fill 5s ease-in-out infinite; }
.ic-h4 .f2 { animation-delay: .5s; }
.ic-h4 .f3 { animation-delay: 1s; }
.ic-h4 .drop { animation: kf-bob 3s ease-in-out infinite; }
.ic-h4 .clip { transition: transform .3s; }
.card:is(:hover,:focus-within,.kb) .ic-h4 .clip { animation: kf-shake .6s ease-in-out; }
.card:is(:hover,:focus-within,.kb) .ic-h4 .f { animation-duration: 2s; }
.card:is(:hover,:focus-within,.kb) .ic-h4 .drop { animation-duration: 1s; }
.card.launch .ic-h4 .board { animation: kf-fly-up .55s ease-in forwards; }
.card.launch .ic-h4 .drop  { animation: kf-collapse .4s forwards; }

/* ---------- evident ---------- */
.ic-evident .env { animation: kf-bob 3.2s ease-in-out infinite; }
.ic-evident .face { animation: kf-pulse-o 4s ease-in-out infinite; }
.card:is(:hover,:focus-within,.kb) .ic-evident .env { transform: translateY(-6px) rotate(-6deg); transition: transform .4s cubic-bezier(.2,.8,.2,1); animation: none; }
.card.launch .ic-evident .env { animation: kf-fly-up .5s ease-in forwards; }
.card.launch .ic-evident .box { animation: kf-fade-out .5s forwards; }

/* ---------- demo ---------- */
@keyframes kf-dash-rot { to { stroke-dashoffset: -60; } }
.ic-demo .ring  { animation: kf-spin 30s linear infinite; }
.ic-demo .ring2 { animation: kf-spin-rev 18s linear infinite; }
.ic-demo .play  { animation: kf-breathe 3s ease-in-out infinite; }
.card:is(:hover,:focus-within,.kb) .ic-demo .ring  { animation-duration: 6s; }
.card:is(:hover,:focus-within,.kb) .ic-demo .ring2 { animation-duration: 4s; }
.card:is(:hover,:focus-within,.kb) .ic-demo .play  { animation: kf-breathe 1s ease-in-out infinite; }
.card.launch .ic-demo .play  { animation: kf-expand-fade .55s ease-in forwards; }
.card.launch .ic-demo .pulse { animation: kf-expand-fade .5s ease-out forwards; opacity: 1; }
.card.launch .ic-demo .ring, .card.launch .ic-demo .ring2 { animation: kf-fade-out .4s forwards; }

/* ---------- reports ---------- */
@keyframes kf-bar { 0%,100% { transform: scaleY(1); } 50% { transform: scaleY(var(--s, .6)); } }
.ic-reports .b { transform-box: fill-box; transform-origin: 50% 100%; animation: kf-bar 4s ease-in-out infinite; }
.ic-reports .b1 { --s: .55; }
.ic-reports .b2 { --s: .7; animation-delay: .6s; }
.ic-reports .b3 { --s: 1.6; animation-delay: 1.2s; }
.ic-reports .page { transition: transform .45s cubic-bezier(.2,.8,.2,1); }
.card:is(:hover,:focus-within,.kb) .ic-reports .p2 { transform: rotate(-6deg); }
.card:is(:hover,:focus-within,.kb) .ic-reports .p3 { transform: rotate(-13deg); }
.card:is(:hover,:focus-within,.kb) .ic-reports .b  { animation-duration: 1.4s; }
.card.launch .ic-reports .p1 { animation: kf-fly-up .5s ease-in forwards; }
.card.launch .ic-reports .p2, .card.launch .ic-reports .p3 { animation: kf-fade-out .5s forwards; }

/* ---------- s16 ---------- */
@keyframes kf-rung { 0%,100% { transform: scaleX(1); } 50% { transform: scaleX(.12); } }
.ic-s16 .strand { animation: kf-flow 3s linear infinite; }
.ic-s16 .s2 { animation-direction: reverse; }
.ic-s16 .rg { animation: kf-rung 3s ease-in-out infinite; animation-delay: calc(var(--i) * -.375s); }
.card:is(:hover,:focus-within,.kb) .ic-s16 .strand { animation-duration: .9s; }
.card:is(:hover,:focus-within,.kb) .ic-s16 .rg { animation-duration: .9s; animation-delay: calc(var(--i) * -.1125s); }
.card:is(:hover,:focus-within,.kb) .ic-s16 .lbl { fill: var(--ac); }
.card.launch .ic-s16 .s1 { transform: translateX(-16px); opacity: 0; transition: transform .5s ease-in, opacity .5s; }
.card.launch .ic-s16 .s2 { transform: translateX(16px); opacity: 0; transition: transform .5s ease-in, opacity .5s; }
.card.launch .ic-s16 .rg { animation: kf-collapse .3s forwards; }
.card.launch .ic-s16 .lbl { animation: kf-fade-out .3s forwards; }

/* ---------- bbt ---------- */
@keyframes kf-cell { 0%,100% { opacity: .22; transform: scale(1); } 50% { opacity: .95; transform: scale(1.06); } }
@keyframes kf-cell-out { to { transform: translate(calc(var(--dx) * 1.6), calc(var(--dy) * 1.6)) scale(.4); opacity: 0; } }
.ic-bbt .c { animation: kf-cell 3.6s ease-in-out infinite; animation-delay: calc(var(--i) * -.24s); }
.ic-bbt .rowhl { transition: opacity .3s; }
.card:is(:hover,:focus-within,.kb) .ic-bbt .c { animation-duration: 1.2s; animation-delay: calc(var(--i) * -.08s); }
.card:is(:hover,:focus-within,.kb) .ic-bbt .rowhl { opacity: .9; animation: kf-pulse-o 1.2s ease-in-out infinite; }
.card.launch .ic-bbt .c { animation: kf-cell-out .5s ease-in forwards; }
.card.launch .ic-bbt .frame, .card.launch .ic-bbt .rowhl { animation: kf-expand-fade .55s ease-in forwards; }

/* ---------- holopetri ---------- */
@keyframes kf-colony { 0%,100% { transform: scale(.85); opacity: .7; } 50% { transform: scale(1.2); opacity: 1; } }
@keyframes kf-scatter { to { transform: translate(calc((var(--i) - 4) * 9px), calc((var(--i) - 4) * -7px)) scale(.3); opacity: 0; } }
.ic-holopetri .col { animation: kf-colony 3.4s ease-in-out infinite; animation-delay: calc(var(--i) * -.55s); }
.ic-holopetri .bloom { opacity: 0; transform: scale(0); animation: none; transition: transform .45s cubic-bezier(.2,1.4,.4,1), opacity .3s; transition-delay: calc((var(--i) - 5) * .09s); }
.ic-holopetri .rim { animation: kf-spin 12s linear infinite; }
.card:is(:hover,:focus-within,.kb) .ic-holopetri .bloom { opacity: 1; transform: scale(1); }
.card:is(:hover,:focus-within,.kb) .ic-holopetri .col:not(.bloom) { animation-duration: 1.2s; }
.card:is(:hover,:focus-within,.kb) .ic-holopetri .rim { animation-duration: 3s; }
.card.launch .ic-holopetri .dish { animation: kf-fly-up .55s ease-in forwards; }
.card.launch .ic-holopetri .rim  { animation: kf-fade-out .3s forwards; }
.card.launch .ic-holopetri .col  { animation: kf-scatter .5s ease-in forwards; }

/* ---------- observatory ---------- */
.ic-observatory .st { animation: kf-twinkle 3s ease-in-out infinite; animation-delay: calc(var(--i) * -.43s); }
.ic-observatory .slit { animation: kf-pulse-o 4s ease-in-out infinite; }
.ic-observatory .scope { animation: kf-sway 7s ease-in-out infinite; }
.ic-observatory .target { transition: transform .4s; }
.card:is(:hover,:focus-within,.kb) .ic-observatory .scope { animation: none; transform: rotate(-14deg); transition: transform .5s cubic-bezier(.2,.8,.2,1); }
.card:is(:hover,:focus-within,.kb) .ic-observatory .target { animation: none; opacity: 1; transform: scale(2.2); }
.card:is(:hover,:focus-within,.kb) .ic-observatory .st:not(.target) { animation-duration: 1s; }
.card.launch .ic-observatory .target { animation: kf-expand-fade .55s ease-in forwards; transform: scale(2.2); }
.card.launch .ic-observatory .dome, .card.launch .ic-observatory .scope { animation: kf-fade-out .45s forwards; }

/* ---------- registry ---------- */
.ic-registry .cr1 { animation: kf-spin 24s linear infinite; }
.ic-registry .cr2 { animation: kf-spin-rev 14s linear infinite; }
.ic-registry .b1  { animation: kf-pulse-o 2.4s ease-in-out infinite; }
.ic-registry .hair, .ic-registry .lock { transition: transform .4s cubic-bezier(.2,.8,.2,1), opacity .3s; }
.card:is(:hover,:focus-within,.kb) .ic-registry .cr1 { animation-duration: 5s; }
.card:is(:hover,:focus-within,.kb) .ic-registry .cr2 { animation-duration: 3s; }
.card:is(:hover,:focus-within,.kb) .ic-registry .lock { opacity: 1; animation: kf-breathe 1s ease-in-out infinite; }
.card:is(:hover,:focus-within,.kb) .ic-registry .b2, .card:is(:hover,:focus-within,.kb) .ic-registry .b3 { opacity: .25; }
.card.launch .ic-registry .cr1, .card.launch .ic-registry .cr2 { animation: kf-collapse .5s ease-in forwards; }
.card.launch .ic-registry .lock { animation: kf-expand-fade .5s ease-out forwards; opacity: 1; }
.card.launch .ic-registry .b1 { animation: kf-flash .5s forwards; }

/* ---------- secretagent ---------- */
@keyframes kf-glint { 0%,55% { transform: translateX(-8px); opacity: 0; } 62% { opacity: .9; } 75% { transform: translateX(14px); opacity: .9; } 82%,100% { transform: translateX(16px); opacity: 0; } }
@keyframes kf-hat-tip { to { transform: translate(14px, -30px) rotate(22deg); opacity: 0; } }
.ic-secretagent .hat { animation: kf-bob 4s ease-in-out infinite; }
.ic-secretagent .glint { animation: kf-glint 5s ease-in-out infinite; }
.ic-secretagent .glasses { transition: transform .45s cubic-bezier(.2,.8,.2,1); }
.ic-secretagent .mag { transform: scale(0); opacity: 0; transition: transform .45s cubic-bezier(.2,1.4,.4,1), opacity .3s; }
.card:is(:hover,:focus-within,.kb) .ic-secretagent .glasses { transform: translateY(4px); }
.card:is(:hover,:focus-within,.kb) .ic-secretagent .hat { animation-duration: 1.4s; }
.card:is(:hover,:focus-within,.kb) .ic-secretagent .glint { animation-duration: 1.4s; }
.card:is(:hover,:focus-within,.kb) .ic-secretagent .mag { transform: scale(1); opacity: 1; }
.card.launch .ic-secretagent .hat { animation: kf-hat-tip .55s ease-in forwards; }
.card.launch .ic-secretagent .glasses, .card.launch .ic-secretagent .collar { animation: kf-fade-out .4s forwards; }
.card.launch .ic-secretagent .mag { animation: kf-expand-fade .5s ease-out forwards; transform: scale(1); opacity: 1; }

/* ---------- culture ---------- */
.ic-culture .bb { animation: kf-rise 2.6s ease-in infinite; animation-delay: calc(var(--i) * -.85s); }
.ic-culture .bb.x { animation: none; opacity: 0; }
.ic-culture .flask { transition: transform .5s cubic-bezier(.2,.8,.2,1); }
.card:is(:hover,:focus-within,.kb) .ic-culture .bb { animation-duration: 1.1s; animation-delay: calc(var(--i) * -.3s); }
.card:is(:hover,:focus-within,.kb) .ic-culture .bb.x { animation: kf-rise 1.1s ease-in infinite; animation-delay: calc(var(--i) * -.3s); }
.card.launch .ic-culture .flask { transform: rotate(24deg); }
.card.launch .ic-culture .pour  { animation: kf-draw .45s .15s ease-out forwards; }
.card.launch .ic-culture .recipe { animation: kf-fade-out .4s forwards; }

/* ---------- media ---------- */
@keyframes kf-pip-x   { 0%,22% { transform: translateX(0); } 25%,47% { transform: translateX(16px); } 50%,72% { transform: translateX(32px); } 75%,97% { transform: translateX(48px); } 100% { transform: translateX(0); } }
@keyframes kf-drop-m  { 0%,40% { transform: translateY(0); opacity: 0; } 45% { opacity: 1; } 85% { transform: translateY(20px); opacity: 1; } 90%,100% { transform: translateY(22px); opacity: 0; } }
@keyframes kf-wellfill { 0%,22% { opacity: 0; } 24%,96% { opacity: .9; } 100% { opacity: 0; } }
.ic-media .pip  { animation: kf-pip-x 8s ease-in-out infinite; }
.ic-media .drop { animation: kf-drop-m 2s ease-in infinite; }
.ic-media .wf   { opacity: 0; animation: kf-wellfill 8s linear infinite; animation-delay: calc(var(--i) * 2s - 8s); }
.ic-media .w    { transition: stroke .3s, stroke-width .3s; }
.card:is(:hover,:focus-within,.kb) .ic-media .w { stroke: var(--ac); stroke-width: 3; animation: kf-breathe 1.4s ease-in-out infinite; animation-delay: calc(var(--i) * -.35s); }
.card:is(:hover,:focus-within,.kb) .ic-media .pip { animation-duration: 3s; }
.card:is(:hover,:focus-within,.kb) .ic-media .drop { animation-duration: .75s; }
.card.launch .ic-media .pip  { animation: kf-fly-up .5s ease-in forwards; }
.card.launch .ic-media .wf   { animation: none; opacity: 1; }
.card.launch .ic-media .w    { animation: kf-expand-fade .5s ease-out forwards; }

/* ---------- evident-tools ---------- */
.ic-evident-tools .hand { animation: kf-spin 12s steps(60) infinite; }
.card:is(:hover,:focus-within,.kb) .ic-evident-tools .hand { animation: kf-spin 1s linear infinite; }
.card:is(:hover,:focus-within,.kb) .ic-evident-tools .btn { transform: translate(-2px, 2px); transition: transform .2s; }
.card.launch .ic-evident-tools .watch { animation: kf-shake .5s ease-in-out; }
.card.launch .ic-evident-tools .ring2 { animation: kf-expand-fade .55s ease-out forwards; opacity: 1; }

/* ---------- signup ---------- */
@keyframes kf-day { 0%,100% { opacity: .22; } 50% { opacity: .95; } }
.ic-signup .d { animation: kf-day 4.8s ease-in-out infinite; animation-delay: calc(var(--i) * -.4s); }
.ic-signup .pen { opacity: 0; transform: translate(10px, 10px) rotate(6deg); transition: transform .45s cubic-bezier(.2,.8,.2,1), opacity .3s; }
.card:is(:hover,:focus-within,.kb) .ic-signup .pen { opacity: 1; transform: translate(0, 0) rotate(0); }
.card:is(:hover,:focus-within,.kb) .ic-signup .d { animation-duration: 1.6s; animation-delay: calc(var(--i) * -.13s); }
.card.launch .ic-signup .d[style*="--i:5"] { fill: var(--ac); opacity: 1; animation: none; }
.card.launch .ic-signup .tick { animation: kf-draw .35s .1s ease-out forwards; }
.card.launch .ic-signup .pen  { transform: translate(-20px, -8px) rotate(-8deg); opacity: 1; transition: transform .45s cubic-bezier(.2,.8,.2,1); }

/* ---------- ont ---------- */
@keyframes kf-flip { 0%,100% { transform: scaleX(1); } 50% { transform: scaleX(-1); } }
.ic-ont .strand { animation: kf-flow 2.8s linear infinite; }
.ic-ont .pore   { animation: kf-breathe 2.8s ease-in-out infinite; }
.ic-ont .c1     { animation: kf-bob 3s ease-in-out infinite; }
.ic-ont .c2, .ic-ont .c3 { opacity: 0; transform: translateY(6px); transition: transform .4s, opacity .3s; }
.card:is(:hover,:focus-within,.kb) .ic-ont .strand { animation-duration: .8s; }
.card:is(:hover,:focus-within,.kb) .ic-ont .c1 { animation: kf-flip 1.4s ease-in-out infinite; }
.card:is(:hover,:focus-within,.kb) .ic-ont .c2, .card:is(:hover,:focus-within,.kb) .ic-ont .c3 { opacity: 1; transform: translateY(0); }
.card.launch .ic-ont .coin { animation: kf-fly-up .5s ease-in forwards; opacity: 1; }
.card.launch .ic-ont .pore { animation: kf-expand-fade .55s ease-out forwards; }

/* ---------- cohagg ---------- */
@keyframes kf-drift { 0%,100% { transform: translate(0, 0); } 33% { transform: translate(calc(var(--i) * .4px - 3px), calc(var(--i) * -.3px + 2px)); } 66% { transform: translate(calc(var(--i) * -.3px + 2px), calc(var(--i) * .35px - 3px)); } }
.ic-cohagg .dt  { animation: kf-drift 7s ease-in-out infinite; animation-delay: calc(var(--i) * -.47s); }
.ic-cohagg .dtw { transition: transform .55s cubic-bezier(.18, 1.4, .3, 1); transition-delay: calc(var(--i) * 14ms); }
.ic-cohagg .ring { opacity: 0; transform: scale(.3); transition: transform .45s cubic-bezier(.2, 1.5, .4, 1), opacity .25s; }
.card:is(:hover,:focus-within,.kb) .ic-cohagg .dtw { transform: translate(var(--tx), var(--ty)) scale(1.2); }
.card:is(:hover,:focus-within,.kb) .ic-cohagg .dt  { animation-duration: 2.4s; }
.card:is(:hover,:focus-within,.kb) .ic-cohagg .ring { opacity: .75; transform: scale(1); transition-delay: calc(.32s + var(--i) * 60ms); animation: kf-spin 14s linear infinite; }
.card.launch .ic-cohagg .dtw { transform: translate(var(--cx), var(--cy)) scale(.45); transition: transform .4s ease-in; transition-delay: 0s; }
.card.launch .ic-cohagg .dt  { animation: none; }
.card.launch .ic-cohagg .ring { animation: kf-expand-fade .45s ease-out forwards; opacity: .75; transform: scale(1); }
.card.launch .ic-cohagg .burst { animation: kf-expand-fade .5s .2s ease-out forwards; opacity: 1; }

/* ---------- fia ---------- */
@keyframes kf-peak { 0%,100% { transform: scaleY(1); } 50% { transform: scaleY(.72); } }
.ic-fia .pk { animation: kf-peak 3.2s ease-in-out infinite; animation-delay: calc(var(--i) * -.45s); }
.ic-fia .mag { transition: transform .55s cubic-bezier(.2,.8,.2,1); }
.card:is(:hover,:focus-within,.kb) .ic-fia .mag { transform: translate(-16px, -6px); }
.card:is(:hover,:focus-within,.kb) .ic-fia .pk  { animation-duration: 1.1s; }
.card.launch .ic-fia .big { animation: none; transform: scaleY(1.35); transition: transform .4s cubic-bezier(.2,1.4,.4,1); }
.card.launch .ic-fia .pk:not(.big) { animation: none; transform: scaleY(.1); transition: transform .4s ease-in; }
.card.launch .ic-fia .mag { animation: kf-fade-out .4s forwards; }

/* ---------- photo ---------- */
.ic-photo .blades { animation: kf-spin 40s linear infinite; }
.ic-photo .bl, .ic-photo .ble { transition: transform .45s cubic-bezier(.2,.8,.2,1); }
.ic-photo .iris { transition: transform .45s cubic-bezier(.2,.8,.2,1); }
.card:is(:hover,:focus-within,.kb) .ic-photo .blades { animation-duration: 8s; }
.card:is(:hover,:focus-within,.kb) .ic-photo .bl, .card:is(:hover,:focus-within,.kb) .ic-photo .ble { transform: translateY(-7px); }
.card:is(:hover,:focus-within,.kb) .ic-photo .iris { transform: scale(1.7); }
.card.launch .ic-photo .bl, .card.launch .ic-photo .ble { transform: translateY(9px); transition-duration: .25s; }
.card.launch .ic-photo .iris { transform: scale(.2); transition-duration: .25s; }
.card.launch .ic-photo .flash { animation: kf-flash .45s .2s ease-out forwards; }

/* ---------- tickets ---------- */
@keyframes kf-kanban { 0%,28% { transform: translateX(0); } 33%,61% { transform: translateX(14px); } 66%,94% { transform: translateX(28px); } 100% { transform: translateX(0); } }
.ic-tickets .kc  { animation: kf-kanban 6s cubic-bezier(.3,1.4,.4,1) infinite; }
.ic-tickets .kc2 { animation: kf-kanban 6s cubic-bezier(.3,1.4,.4,1) infinite -3s; }
.ic-tickets .half, .ic-tickets .perf { transition: transform .4s cubic-bezier(.2,.8,.2,1); }
.card:is(:hover,:focus-within,.kb) .ic-tickets .kc, .card:is(:hover,:focus-within,.kb) .ic-tickets .kc2 { animation-duration: 2s; }
.card:is(:hover,:focus-within,.kb) .ic-tickets .left, .card:is(:hover,:focus-within,.kb) .ic-tickets .right, .card:is(:hover,:focus-within,.kb) .ic-tickets .perf { transform: translateY(-3px) rotate(-3deg); }
.card.launch .ic-tickets .left  { transform: translate(-10px, 2px) rotate(-8deg); opacity: 0; transition: transform .5s ease-in, opacity .5s; }
.card.launch .ic-tickets .right { transform: translate(12px, -4px) rotate(10deg); opacity: 0; transition: transform .5s ease-in, opacity .5s; }
.card.launch .ic-tickets .perf  { animation: kf-fade-out .2s forwards; }

/* ---------- thursday ---------- */
@keyframes kf-deal { 0% { transform: translate(0, 0); opacity: 0; } 10% { opacity: 1; } 85% { transform: translate(var(--cx), 50px); opacity: 1; } 100% { transform: translate(var(--cx), 54px); opacity: 0; } }
.ic-thursday .dl { animation: kf-deal 4.5s ease-in infinite; animation-delay: calc(var(--i) * -1.5s); }
.ic-thursday .tag { animation: kf-bob 4s ease-in-out infinite; }
.card:is(:hover,:focus-within,.kb) .ic-thursday .fun { animation: kf-sway 1.2s ease-in-out infinite; transform-origin: 50% 20%; }
.card:is(:hover,:focus-within,.kb) .ic-thursday .dl  { animation-duration: 1.6s; animation-delay: calc(var(--i) * -.53s); }
.card.launch .ic-thursday .dl   { animation: kf-fade-out .3s forwards; }
.card.launch .ic-thursday .star { animation: kf-pop .5s .1s cubic-bezier(.2,1.4,.4,1) forwards; }
.card.launch .ic-thursday .fun  { animation: kf-fade-out .5s forwards; }

/* ---------- compute ---------- */
.ic-compute .traces { animation: kf-flow 3s linear infinite; }
.ic-compute .core   { animation: kf-pulse-o 2.4s ease-in-out infinite; }
.ic-compute .die    { transition: filter .3s; }
.card:is(:hover,:focus-within,.kb) .ic-compute .traces { animation-duration: .7s; }
.card:is(:hover,:focus-within,.kb) .ic-compute .die    { filter: drop-shadow(0 0 6px var(--ac)); }
.card:is(:hover,:focus-within,.kb) .ic-compute .core   { animation-duration: .8s; }
.card.launch .ic-compute .boot { animation: kf-expand-fade .55s ease-out forwards; opacity: 1; }
.card.launch .ic-compute .core { animation: kf-flash .5s forwards; }
.card.launch .ic-compute .traces { animation: kf-flow-fast .5s linear infinite; }

/* ---------- assets ---------- */
@keyframes kf-ripple { 0%,100% { transform: scaleY(1); } 50% { transform: scaleY(1.18); } }
.ic-assets .beam { animation: kf-sweep-y2 3.2s ease-in-out infinite; }
.card:is(:hover,:focus-within,.kb) .ic-assets .br   { animation: kf-ripple 1s ease-in-out infinite; animation-delay: calc(var(--i) * -.1s); }
.card:is(:hover,:focus-within,.kb) .ic-assets .beam { animation-duration: 1s; }
.card.launch .ic-assets .beam { animation: none; transform: scaleY(14); opacity: 0; transition: transform .35s, opacity .4s; transform-box: fill-box; transform-origin: center; }
.card.launch .ic-assets .bars { animation: kf-fade-out .3s forwards; }
.card.launch .ic-assets .ok   { animation: kf-pop .5s .15s cubic-bezier(.2,1.4,.4,1) forwards; }

/* ---------- kitome ---------- */
@keyframes kf-travel { 0% { offset-distance: 0%; opacity: 0; } 8% { opacity: 1; } 92% { opacity: 1; } 100% { offset-distance: 100%; opacity: 0; } }
.ic-kitome .runner { display: none; }
@supports (offset-path: path('M0 0L1 1')) {
  .ic-kitome .runner { display: block; animation: kf-travel 6s ease-in-out infinite; }
}
.ic-kitome .lid { transition: transform .4s cubic-bezier(.2,.8,.2,1), opacity .3s; }
.ic-kitome .parcel { transition: transform .4s; }
.card:is(:hover,:focus-within,.kb) .ic-kitome .lid { transform: translateY(-7px); opacity: .9; }
.card:is(:hover,:focus-within,.kb) .ic-kitome .runner { animation-duration: 2s; }
.card.launch .ic-kitome .parcel { animation: kf-fly-right .55s ease-in forwards; }
.card.launch .ic-kitome .runner { animation-duration: .6s; }

/* ---------- xmap ---------- */
@keyframes kf-link { 0%,5% { stroke-dashoffset: 60; opacity: .3; } 25%,75% { stroke-dashoffset: 0; opacity: 1; } 95%,100% { stroke-dashoffset: 60; opacity: .3; } }
.ic-xmap .ln { stroke-dasharray: 60; animation: kf-link 5s ease-in-out infinite; animation-delay: calc(var(--i) * .35s); }
.ic-xmap .crossed, .ic-xmap .straight { transition: opacity .4s; }
.ic-xmap .colR { transition: transform .4s; }
.card:is(:hover,:focus-within,.kb) .ic-xmap .crossed  { opacity: 0; }
.card:is(:hover,:focus-within,.kb) .ic-xmap .straight { opacity: 1; }
.card:is(:hover,:focus-within,.kb) .ic-xmap .colR     { transform: translateX(-3px); }
.card.launch .ic-xmap .straight { opacity: 1; animation: kf-pulse-o .3s ease-in-out 2; }
.card.launch .ic-xmap .crossed  { opacity: 0; }
.card.launch .ic-xmap .colL, .card.launch .ic-xmap .colR { animation: kf-expand-fade .55s ease-in forwards; transform-box: fill-box; transform-origin: center; }

/* ---------- scraper ---------- */
.ic-scraper .pp { animation: kf-drop 2.7s ease-in infinite; animation-delay: calc(var(--i) * -.9s); }
.ic-scraper .rw { animation: kf-pulse-o 2.7s ease-in-out infinite; animation-delay: calc(var(--i) * -.9s); }
.card:is(:hover,:focus-within,.kb) .ic-scraper .pp { animation-duration: 1s; animation-delay: calc(var(--i) * -.33s); }
.card:is(:hover,:focus-within,.kb) .ic-scraper .rw { animation-duration: 1s; animation-delay: calc(var(--i) * -.33s); }
.card:is(:hover,:focus-within,.kb) .ic-scraper .fun { animation: kf-breathe 1s ease-in-out infinite; }
.card.launch .ic-scraper .rw  { animation: none; transform: translateX(12px); opacity: 1; transition: transform .45s cubic-bezier(.2,1.4,.4,1); }
.card.launch .ic-scraper .fun, .card.launch .ic-scraper .pp { animation: kf-fade-out .4s forwards; }

/* ---------- contracts ---------- */
@keyframes kf-sign { 0%,10% { stroke-dashoffset: 44; } 45%,85% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: 44; } }
.ic-contracts .sig  { animation: kf-sign 6s ease-in-out infinite; }
.ic-contracts .seal { transform: scale(1.6); transition: transform .3s cubic-bezier(.2,1.4,.4,1), opacity .25s; }
.card:is(:hover,:focus-within,.kb) .ic-contracts .seal { opacity: 1; transform: scale(1); }
.card:is(:hover,:focus-within,.kb) .ic-contracts .sig  { animation-duration: 2s; }
.card.launch .ic-contracts .doc { transform: scaleY(.04); opacity: 0; transition: transform .5s ease-in, opacity .5s; }

/* ---------- corporate ---------- */
.ic-corporate .n { animation: kf-breathe 3s ease-in-out infinite; animation-delay: calc(var(--i) * -.6s); }
.ic-corporate .e { animation: kf-pulse-o 4s ease-in-out infinite; animation-delay: calc(var(--i) * -.5s); }
.ic-corporate .net { transition: transform .5s cubic-bezier(.2,.8,.2,1); }
.card:is(:hover,:focus-within,.kb) .ic-corporate .net { transform: rotate(-4deg) scale(1.06); }
.card:is(:hover,:focus-within,.kb) .ic-corporate .e   { animation-duration: 1.2s; }
.card.launch .ic-corporate .pill { animation: kf-expand-fade .55s ease-in forwards; }
.card.launch .ic-corporate .net  { animation: kf-expand-fade .55s ease-in forwards; }

/* ---------- attic ---------- */
@keyframes kf-cloud { 0%,100% { transform: translateX(0); } 50% { transform: translateX(5px); } }
.ic-mcloud .cloud { animation: kf-cloud 8s ease-in-out infinite; }
.card:is(:hover,:focus-within,.kb) .ic-mcloud .rain { opacity: 1; animation: kf-drop 1s linear infinite; }
.card.launch .ic-mcloud .cloud { animation: kf-expand-fade .55s ease-in forwards; }

.ic-appendix .app { animation: kf-pulse-o 3s ease-in-out infinite; }
.card:is(:hover,:focus-within,.kb) .ic-appendix .gut { animation: kf-shake .7s ease-in-out infinite; }
.card.launch .ic-appendix .pop { animation: kf-expand-fade .5s ease-out forwards; opacity: 1; }
.card.launch .ic-appendix .app { animation: kf-collapse .4s forwards; }

@keyframes kf-flicker { 0%,100% { opacity: 1; } 92% { opacity: 1; } 94% { opacity: .3; } 96% { opacity: 1; } 98% { opacity: .5; } }
.ic-assets-old .frame { animation: kf-flicker 6s linear infinite; }
.card:is(:hover,:focus-within,.kb) .ic-assets-old .frame { transform: rotate(-4deg); transition: transform .4s; }
.card.launch .ic-assets-old .frame { animation: kf-drop .5s ease-in forwards; }

.ic-tickets-rt .hand { animation: kf-spin 8s linear infinite; }
.card:is(:hover,:focus-within,.kb) .ic-tickets-rt .stub { animation: kf-shake .6s ease-in-out; }
.card.launch .ic-tickets-rt .stub { animation: kf-fade-out .5s forwards; }

.ic-dotcom .arrow { animation: kf-flow 2.4s linear infinite; }
.card:is(:hover,:focus-within,.kb) .ic-dotcom .arrow { animation-duration: .6s; }
.card:is(:hover,:focus-within,.kb) .ic-dotcom .ah { animation: kf-bob 1s ease-in-out infinite; }
.card.launch .ic-dotcom .ah, .card.launch .ic-dotcom .arrow { animation: kf-fade-out .4s forwards; }

.ic-generic .hex { animation: kf-spin 30s linear infinite; }
.card.launch .ic-generic .hex { animation: kf-expand-fade .5s ease-in forwards; }

/* ---------- the Holobiome mark (.hbmark wrapper around .hblogo-intro) ----------
   Base state (no .play/.outro): nothing drawn.
   .play  → intro, ~3.3 s × --spd, `forwards` so it holds:
            0.25s network traces outward from the centre node · 1.35s pill outline draws ·
            2.05s gradient wipes in left→right, lines turn white · 2.7s glow (+ wordmark on login)
   .outro → deactivate, ~2.2 s × --spd, `both` so each element holds the intro's end state until its turn:
            (wordmark sinks) · gradient un-wipes right→left revealing the ink network ·
            outline reappears and un-draws · network retracts inward, nodes pop out
   --spd scales every duration and delay (header uses .62). app.js swaps play → outro → play:
   every data-cycle seconds on the login page, and on hover of the header logo. */
@keyframes kf-node       { 0%,100% { transform: scale(1); } 50% { transform: scale(1.14); } }
@keyframes kf-edge       { 0%,100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes kf-edge-so    { 0%,100% { stroke-opacity: .45; } 50% { stroke-opacity: 1; } }
@keyframes kf-wipe       { to { transform: scaleX(1); } }
@keyframes kf-unwipe     { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@keyframes kf-undraw     { from { stroke-dashoffset: 0; } to { stroke-dashoffset: var(--len); } }
@keyframes kf-unpop      { from { transform: scale(1); } to { transform: scale(0); } }
@keyframes kf-outline-out{ 0% { opacity: 0; stroke-dashoffset: 0; } 30% { opacity: 1; stroke-dashoffset: 0; } 100% { opacity: 1; stroke-dashoffset: 1480; } }
@keyframes kf-sink       { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(6px); } }
@keyframes kf-mark-glow  { 0% { filter: drop-shadow(0 10px 24px color-mix(in srgb, var(--pill-b) 40%, transparent)); }
                           40% { filter: drop-shadow(0 0 34px color-mix(in srgb, var(--pill-a) 95%, transparent)); }
                           100% { filter: drop-shadow(0 10px 24px color-mix(in srgb, var(--pill-b) 40%, transparent)); } }
@keyframes kf-rise-in    { to { opacity: 1; transform: translateY(0); } }

/* base */
.hbmark { --spd: 1; }
.hblogo-intro .trace { stroke: var(--net-ink); stroke-width: 5; }
.hblogo-intro .trace .e { stroke-dasharray: var(--len); stroke-dashoffset: var(--len); }
.hblogo-intro .trace .n { fill: var(--net-ink); transform: scale(0); }
.hblogo-intro .outline { stroke: var(--net-ink); stroke-width: 5; stroke-dasharray: 1480; stroke-dashoffset: 1480; }
.hblogo-intro .wipe { transform-box: view-box; transform-origin: -20px 0; transform: scaleX(0); }
.hblogo-intro .fill .net { stroke-width: 5; }
.hblogo-intro .fill .net .n { animation: kf-node calc(4.2s) ease-in-out infinite; animation-delay: calc(var(--i) * -.7s); }
.hblogo-intro .fill .net .e { animation: kf-edge 5s ease-in-out infinite; animation-delay: calc(var(--i) * -.45s); }
.login-logo .hbword .w1, .login-logo .hbword .w2 { transform-box: fill-box; }
.login-logo .hbword .w1, .login-logo .hbword .w2, .login-logo .sub { opacity: 0; transform: translateY(6px); }

/* intro */
.hbmark.play .hblogo-intro .trace .e { animation: kf-draw calc(.5s * var(--spd)) ease-out forwards; animation-delay: calc((.25s + var(--d) * 1s) * var(--spd)); }
.hbmark.play .hblogo-intro .trace .n { animation: kf-pop calc(.5s * var(--spd)) cubic-bezier(.2,1.4,.4,1) forwards; animation-delay: calc((.25s + var(--nd) * 1s) * var(--spd)); }
.hbmark.play .hblogo-intro .outline { animation: kf-draw calc(.9s * var(--spd)) cubic-bezier(.4,0,.2,1) calc(1.35s * var(--spd)) forwards, kf-fade-out calc(.4s * var(--spd)) calc(2.55s * var(--spd)) forwards; }
.hbmark.play .hblogo-intro .wipe { animation: kf-wipe calc(.75s * var(--spd)) cubic-bezier(.45,0,.2,1) calc(2.05s * var(--spd)) forwards; }
.hbmark.play .mark, .logo .hbmark.play { animation: kf-mark-glow calc(1.1s * var(--spd)) ease-out calc(2.7s * var(--spd)) both; }
.login-logo.play .hbword .w1, .login-logo.play .hbword .w2, .login-logo.play .sub { animation: kf-rise-in .6s cubic-bezier(.2,.8,.2,1) forwards; }
.login-logo.play .hbword .w1 { animation-delay: 2.6s; }
.login-logo.play .hbword .w2 { animation-delay: 2.8s; }
.login-logo.play .sub { animation-delay: 3s; }

/* outro */
.login-logo.outro .sub { animation: kf-sink .4s ease-in 0s both; }
.login-logo.outro .hbword .w2 { animation: kf-sink .45s ease-in .08s both; }
.login-logo.outro .hbword .w1 { animation: kf-sink .45s ease-in .22s both; }
.hbmark.outro .hblogo-intro .wipe { animation: kf-unwipe calc(.65s * var(--spd)) cubic-bezier(.45,0,.2,1) calc(.35s * var(--spd)) both; }
.hbmark.outro .hblogo-intro .outline { animation: kf-outline-out calc(.9s * var(--spd)) cubic-bezier(.4,0,.2,1) calc(.5s * var(--spd)) both; }
.hbmark.outro .hblogo-intro .trace .e { animation: kf-undraw calc(.4s * var(--spd)) ease-in both; animation-delay: calc((1.05s + (.7 - var(--d)) * 1s) * var(--spd)); }
.hbmark.outro .hblogo-intro .trace .n { animation: kf-unpop calc(.35s * var(--spd)) ease-in both; animation-delay: calc((1.15s + (.7 - var(--nd)) * 1s) * var(--spd)); }
.hbmark.outro .mark, .logo .hbmark.outro { animation: kf-mark-glow calc(1s * var(--spd)) ease-out calc(1.1s * var(--spd)) both; }

/* header instance: faster, and user-unit strokes thick enough to read at 58 px */
.logo .hbmark { --spd: .62; cursor: pointer; }
.logo .hblogo-intro .trace, .logo .hblogo-intro .outline, .logo .hblogo-intro .fill .net { stroke-width: 14; }
.logo .hblogo-intro .fill .net .n { animation-duration: 4s; }

/* ---------- ambient background network ---------- */
.bg .hbnet .n { animation: kf-node 9s ease-in-out infinite; animation-delay: calc(var(--i) * -1.7s); }
.bg .hbnet .e { animation: kf-edge-so 11s ease-in-out infinite; animation-delay: calc(var(--i) * -.9s); }
