/* HUAIDEV motion component (convergence + logo intro). Reusable on any page: <div id="conv" data-imo="convergence"></div>, <div id="logo" data-imo="logo"></div>.
   Strict-CSP safe: no inline styles in markup, only this stylesheet and /huaidev-motion.js. */
.imo{--imo-human:#3b94ec;--imo-ai:#52e3fa;--imo-join:#b4f8ff;--imo-ink:#e4f5ff;--imo-sub:#a9c9df;--imo-btn:#1b5d89;min-width:0}
.imo *{box-sizing:border-box}
.imo-stage{position:relative;overflow:hidden;border-radius:14px;height:min(62vw,300px);min-height:220px;background:radial-gradient(ellipse at 50% 45%,#123e64,#041025);display:grid;place-items:center}
.imo-row{display:flex;gap:10px;flex-wrap:wrap;margin-top:12px;align-items:center}
.imo-btn{font:inherit;background:var(--imo-btn);color:#fff;border:1px solid #52c5dd;border-radius:10px;padding:12px 16px;min-height:44px;cursor:pointer}
.imo-btn:focus-visible{outline:3px solid #9bf9ff;outline-offset:2px}
.imo-state{color:var(--imo-sub);font-size:13px}
.imo-notice{padding:22px;text-align:center;color:#c7e5f8;font-size:14px;margin:0}
/* convergence */
.imo-conv svg{width:100%;height:100%;display:block}
.imo-conv path{fill:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1;stroke-dashoffset:1}
.imo-conv .human{stroke:var(--imo-human)}.imo-conv .ai{stroke:var(--imo-ai)}.imo-conv .out{stroke:var(--imo-join)}
.imo-conv .node{fill:#8ef0ff;filter:drop-shadow(0 0 9px #4ce5ff);transform-box:fill-box;transform-origin:center;opacity:0}
.imo-conv .pulse{fill:#fff;opacity:0;filter:drop-shadow(0 0 7px #bff)}
.imo-conv.run .human,.imo-conv.run .ai{animation:imo-feed 6.2s cubic-bezier(.45,.05,.3,1) both}
.imo-conv.run .out{animation:imo-outline 6.2s cubic-bezier(.3,.1,.2,1) both}
.imo-conv.run .node{animation:imo-node 6.2s ease-out both}
.imo-conv.run .pulse{animation:imo-pulse 6.2s ease-in-out both}
@keyframes imo-feed{0%{stroke-dashoffset:1;opacity:1}46%{stroke-dashoffset:0;opacity:1}52%{stroke-dashoffset:0;opacity:1}66%,100%{stroke-dashoffset:0;opacity:.28}}
@keyframes imo-outline{0%,62%{stroke-dashoffset:1;opacity:0}64%{stroke-dashoffset:1;opacity:1}84%,100%{stroke-dashoffset:0;opacity:1}}
@keyframes imo-node{0%,42%{opacity:0;transform:scale(.3)}50%{opacity:1;transform:scale(1.7)}60%,100%{opacity:1;transform:scale(1)}}
@keyframes imo-pulse{0%,84%{opacity:0;transform:translateX(0)}86%{opacity:1}95%{opacity:1;transform:translateX(220px)}98%,100%{opacity:0;transform:translateX(220px)}}
/* logo intro layers (owner-verified originals, only revealed, never redrawn) */
.imo-layers{position:absolute;inset:0;display:none}
.imo-logo.ready .imo-layers{display:block}
.imo-logo.ready .imo-notice{display:none}
.imo-mk{position:absolute;left:50%;top:8%;height:60%;width:auto;max-width:80%;transform:translateX(-50%);object-fit:contain;will-change:opacity,mask-image}
.imo-wd{position:absolute;left:50%;top:74%;height:14%;width:86%;transform:translateX(-50%)}
.imo-wd{display:flex;justify-content:center;align-items:center;gap:.06em;font-weight:800;font-size:clamp(26px,7vw,46px);letter-spacing:.2em;color:#0b1f4d}
.imo-ch{display:inline-block;opacity:0;will-change:opacity,transform}
.imo-sweep{position:absolute;top:8%;height:60%;width:18%;left:0;opacity:0;pointer-events:none;mix-blend-mode:screen;background:linear-gradient(90deg,transparent,rgba(160,250,255,.75),transparent)}
@media (prefers-reduced-motion:reduce){
  .imo-conv path{animation:none!important;stroke-dashoffset:0!important}
  .imo-conv .pulse{opacity:0!important}
  .imo-conv .human,.imo-conv .ai{opacity:.28!important}
  .imo-conv .out,.imo-conv .node{opacity:1!important;animation:none!important}
}

/* The approved master is a white board: the logo stage keeps that ground so the navy wordmark and the alpha edges read as in the original. */
.imo-logo{background:#fff;border:1px solid #cfe0ef}
.imo-logo .imo-notice{color:#123}
.imo-logo .imo-sweep{mix-blend-mode:normal;background:linear-gradient(90deg,transparent,rgba(120,220,255,.55),transparent)}
.imo-logo .imo-sweep{-webkit-mask-image:linear-gradient(180deg,transparent,#000 25%,#000 75%,transparent);mask-image:linear-gradient(180deg,transparent,#000 25%,#000 75%,transparent);filter:blur(6px);opacity:0}

/* hero use: the static lockup stays as the fallback and is replaced only once the layers decoded; no honesty notice flashes while loading */
.imo-replaced{display:none!important}
.imo[data-imo-replaces] .imo-notice{display:none}
.imo[data-imo-replaces] .imo-stage:not(.ready){display:none}
.signatureStage{max-width:760px;margin:0 auto}

/* Fullscreen logo intro (owner 2026-10-22): plays automatically on open, then collapses into a dot and reveals the site.
   Same choreography and original mark layer as before, on the master's white ground. */
.introSeen .imo-introOverlay{display:none}
.pending body>.imo-introOverlay{visibility:visible!important}
.imo-introOverlay .imo-notice{display:none}
.imo-introOverlay{position:fixed;inset:0;z-index:1000;background:#030b1f;display:grid;place-items:center;transition:background-color .5s ease .9s}
.imo-introOverlay.imo-classic{background:#fff}
.imo-introOverlay .imo-stage{width:min(92vw,720px);height:min(78vh,620px);min-height:0;border:0;border-radius:0;background:transparent;overflow:visible;transform-origin:50% 50%}
.imo-introOverlay .imo-mk{top:6%;height:62%}
.imo-introOverlay .imo-wd{top:74%;height:16%;font-size:clamp(30px,8vw,64px);letter-spacing:.32em;text-indent:.32em}
.imo-skip{position:fixed;right:max(16px,env(safe-area-inset-right));bottom:max(16px,env(safe-area-inset-bottom));font:600 14px system-ui,-apple-system,sans-serif;color:#0b1f4d;background:#f2f7fa;border:1px solid #c9d8e2;border-radius:999px;padding:10px 16px;min-height:44px;cursor:pointer}
.imo-skip:focus-visible{outline:3px solid #16b6dd;outline-offset:2px}
.imo-dot{position:fixed;left:50%;top:50%;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;background:#16b6dd;box-shadow:0 0 18px #16b6dd99;opacity:0;transform:scale(0);pointer-events:none}
.imo-collapse .imo-stage{animation:imo-shrink .8s cubic-bezier(.6,0,.4,1) forwards}
.imo-collapse .imo-skip{display:none}
.imo-collapse .imo-dot{animation:imo-dot 1.5s ease forwards}
.imo-collapse,.imo-fade{background-color:transparent;pointer-events:none}
.imo-fade{transition:opacity .45s ease;opacity:0}
@keyframes imo-shrink{0%{transform:scale(1);opacity:1}85%{opacity:1}100%{transform:scale(.02);opacity:0}}
@keyframes imo-dot{0%,40%{opacity:0;transform:scale(0)}55%{opacity:1;transform:scale(1.25)}70%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(0)}}

/* Header on white (owner 2026-10-22): the logo sits on white everywhere, so the whole bar is white. */
header{background:#fff;border-bottom:1px solid #dce7ee;color:#0b1f4d;-webkit-backdrop-filter:none;backdrop-filter:none}
header .brand,header .brand strong{color:#0b1f4d}
header .brandIcon{background:transparent;border-radius:0}
header nav a{color:#1d3a5c}
header nav a:hover,header nav a:focus-visible{background:#e8f3f8;color:#071641}
header nav .workspaceLink{border:1px solid #16b6dd;color:#087d9b}
header .status{color:#087d9b}
header .langSwitch button{background:#f2f7fa;color:#0b1f4d;border-color:#c9d8e2}
header .langSwitch button[aria-pressed=true]{background:#16b6dd;color:#fff;border-color:#16b6dd}

/* hero: the original mark sits directly on the lockup's white board (no second card around the image) */
.heroArt .officialBrandLockup img{background:none;box-shadow:none;padding:0;border-radius:0}

/* Language choice (owner 2026-10-23): two flags with the country code drawn on them, no text. After the intro the
   flags grow out of the intro's dot; the chosen flag dissolves and the home page appears behind it without a cut. */
.langGate .gateChoices{gap:clamp(22px,6vw,64px);align-items:center}
.langGate .choice{padding:0}
.langGate .choice svg{width:min(38vw,300px);border-radius:10px;box-shadow:0 14px 44px rgba(0,0,0,.4)}
.langGate .flagCode{font-family:system-ui,-apple-system,"Segoe UI",sans-serif}
.introRun .langGate:not(.enter) .choice{opacity:0;transform:scale(.04)}
.langGate.enter .choice{animation:imo-flagIn .9s cubic-bezier(.2,.8,.2,1) both}
.langGate.enter .choice+.choice{animation-delay:.08s}
.langGate.leaving .choice:not(.chosen){animation:imo-fadeOut .35s ease forwards}
@keyframes imo-fadeOut{to{opacity:0}}
.langGate .choice.chosen svg{animation:imo-flagOut .95s ease forwards}
@keyframes imo-flagIn{0%{opacity:0;transform:scale(.04)}60%{opacity:1}100%{opacity:1;transform:scale(1)}}
@keyframes imo-flagOut{0%{opacity:1;transform:scale(1);filter:blur(0)}100%{opacity:0;transform:scale(1.35);filter:blur(14px)}}
@media (prefers-reduced-motion:reduce){.langGate.enter .choice,.langGate .choice.chosen svg{animation:none}.introRun .langGate:not(.enter) .choice{opacity:1;transform:none}}
.introRun .langGate{background-color:transparent;transition:background-color .7s ease}
.introRun .langGate.enter{z-index:1001;background-color:rgba(6,14,28,.5)}
.langGate.leaving{background-color:rgba(6,14,28,0);-webkit-backdrop-filter:blur(0) saturate(1);backdrop-filter:blur(0) saturate(1);transition:opacity .9s ease .15s,background-color .9s ease,-webkit-backdrop-filter .9s ease,backdrop-filter .9s ease}

/* Storyboard intro (owner 2026-10-23, team storyboard "Logo Animation Storyboard" + "Konvergenz"): dark ground, particles,
   the original mark revealed stroke by stroke in WebGL (huaidev-intro-gl.js), soft glow finale, then one glowing node. */
.imo-introOverlay.imo-gl::before{content:"";position:absolute;inset:0;background:radial-gradient(ellipse at 50% 42%,#0d2b5c 0%,#061634 46%,#020818 100%);transition:opacity .6s ease .8s}
.imo-introOverlay.imo-gl.imo-collapse::before{opacity:0}
.imo-particles{position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none;transition:opacity .6s ease}
.imo-collapse .imo-particles{opacity:0}
.imo-gl-stage{position:relative;width:min(92vw,720px);height:min(78vh,620px);background:transparent;border:0;border-radius:0;overflow:visible;transform-origin:50% 42%}
.imo-glmark{position:absolute;display:block;transform-origin:50% 50%}
.imo-halo{position:absolute;left:-30%;right:-30%;top:-22%;bottom:-24%;background:radial-gradient(closest-side at 50% 47%,rgba(240,248,255,.98) 0%,rgba(214,236,255,.93) 42%,rgba(120,180,245,.45) 70%,rgba(30,90,200,0) 100%);opacity:0;pointer-events:none;will-change:opacity,transform}
.imo-gl-stage .imo-wd{color:#0b1f4d;font-weight:800;text-shadow:0 1px 0 rgba(255,255,255,.5)}
.imo-gl .imo-skip{color:#e4f5ff;background:rgba(10,30,70,.45);border-color:rgba(160,210,255,.45)}
.imo-gl .imo-dot{width:16px;height:16px;margin:-8px 0 0 -8px;background:radial-gradient(circle,#fff 0 30%,#7fe9ff 45%,#16b6dd 70%);box-shadow:0 0 0 2px rgba(127,233,255,.55),0 0 26px 6px rgba(22,182,221,.75),0 0 60px 14px rgba(22,120,221,.35)}

/* Intro "Frame -> Converge -> HUAIDEV -> Homepage" (owner concept 2026-10-24, huaidev-intro-gl.js). Layers: the window
   (.hd-ground: dark inside, flat dark margin outside), the blue sky, the light lines (canvas), disc + mark + wordmark.
   The overlay's own background only covers the moment before the first frame. */
.imo-introOverlay.hd-intro{display:block;transition:none}
.imo-introOverlay.hd-live{background:transparent}
.hd-ground{position:absolute;left:0;top:0;background:#030b1f;box-shadow:0 0 0 200vmax #030b1f}
.hd-sky{position:absolute;inset:0;opacity:0;will-change:opacity;background:radial-gradient(circle 75vmax at 50% 45%,#0d2b5c 0%,#061634 50%,#020818 100%)}
.hd-white{position:absolute;inset:0;background:#fff;visibility:hidden;will-change:opacity}
.hd-canvas{position:absolute;inset:0;display:block;pointer-events:none}
.hd-stage{position:absolute;inset:0;pointer-events:none;overflow:hidden}
.hd-markwrap{position:absolute;transform-origin:50% 50%;will-change:transform,opacity}
.hd-mark{position:absolute;inset:0;width:100%;height:100%;display:block}
.hd-halo{position:absolute;border-radius:50%;background:radial-gradient(closest-side,rgba(110,200,255,.26),rgba(40,120,255,.1) 55%,rgba(30,90,220,0));opacity:0;visibility:hidden;pointer-events:none;will-change:opacity}
.hd-wd{position:absolute;left:0;right:0;text-align:center;white-space:nowrap;font:700 1em/1.2 system-ui,-apple-system,"Segoe UI",sans-serif;letter-spacing:.32em;text-indent:.32em;color:#0b1f4d;transform-origin:50% 50%;will-change:transform,opacity}
.hd-wd span{display:inline-block;opacity:0}
.hd-intro .imo-skip{color:#e4f5ff;background:rgba(10,30,70,.45);border-color:rgba(160,210,255,.45);z-index:2}
.hd-intro.hd-out{opacity:0;transition:opacity .3s ease}
/* the frame of the intro stays round the site: a glowing rounded window, the dark ground outside it */
:root{--hd-inset:12px;--hd-r:22px}
@media (max-width:600px){:root{--hd-inset:8px;--hd-r:24px}}
.hdFramed body{padding:var(--hd-inset)}
.hdFramed header{top:var(--hd-inset)}
.hd-frame{position:fixed;inset:var(--hd-inset);border-radius:var(--hd-r);pointer-events:none;z-index:1002;opacity:0;visibility:hidden;transition:opacity .5s ease,visibility 0s linear .5s;
  box-shadow:0 0 0 1.5px rgba(185,238,255,.92),0 0 18px 3px rgba(30,170,235,.5),inset 0 0 18px rgba(30,170,235,.18),0 0 0 100vmax #030b1f}
.hd-frame.on{opacity:1;visibility:visible;transition:opacity .5s ease}
.hd-frame.now{transition:none}
/* during the intro the language choice does not blur the site that the frame reveals; the blur comes with the flags */
.introRun .langGate:not(.enter){-webkit-backdrop-filter:none;backdrop-filter:none}
.introRun .langGate.enter:not(.leaving){transition:background-color .7s ease,-webkit-backdrop-filter .9s ease,backdrop-filter .9s ease}
@media (max-width:980px){.hdFramed header{flex-wrap:wrap}}

/* header: "▶ Intro" (plays the intro again) and the language button (flag + code, opens the wheel) */
header .headTools{display:inline-flex;align-items:center;gap:8px}
header .introReplay{display:inline-flex;align-items:center;gap:6px;padding:7px 12px;border-radius:999px;border:1px solid #c9d8e2;background:#f2f7fa;color:#0b1f4d;font:750 12px/1 system-ui,-apple-system,sans-serif;letter-spacing:.06em;cursor:pointer}
header .introReplay svg{width:10px;height:10px;fill:#16b6dd}
header .introReplay:hover,header .introReplay:focus-visible{border-color:#16b6dd;color:#071641}
header .introReplay[hidden]{display:none}
header .langOpen{display:inline-flex;align-items:center;gap:7px}
header .langOpen img{display:block;width:24px;height:18px;border-radius:3px;box-shadow:0 0 0 1px #c9d8e2}
/* the wheel arrives with the hand-over of the intro and the chosen flag dissolves into the page */
.introRun .langGate:not(.enter) .gateInner{opacity:0;transform:scale(.94)}
.langGate.enter .gateInner{animation:imo-wheelIn .9s cubic-bezier(.2,.8,.2,1) both}
@keyframes imo-wheelIn{from{opacity:0;transform:scale(.94)}to{opacity:1;transform:none}}
.langGate .wheelItem.chosen img{animation:imo-flagOut .95s ease forwards}
.langGate.leaving .wheelName,.langGate.leaving .wheelGo,.langGate.leaving .wheelBand{animation:imo-fadeOut .35s ease forwards}
@media (prefers-reduced-motion:reduce){.langGate.enter .gateInner,.langGate .wheelItem.chosen img,.langGate.leaving .wheelName,.langGate.leaving .wheelGo,.langGate.leaving .wheelBand{animation:none}.introRun .langGate:not(.enter) .gateInner{opacity:1;transform:none}}
