diff --git a/product-source/hololake-native-desktop/src/main.tsx b/product-source/hololake-native-desktop/src/main.tsx index 37ca8a6f1..8996d2685 100644 --- a/product-source/hololake-native-desktop/src/main.tsx +++ b/product-source/hololake-native-desktop/src/main.tsx @@ -288,6 +288,14 @@ function HoloLakeApp() { const [gateRaw, setGateRaw] = useState('') const [gateInf, setGateInf] = useState(false) const gateNumber = formatGateNumber(gateRaw) + (gateInf ? '∞' : '') + const [gateOpen, setGateOpen] = useState(false) + const gateInputRef = useRef(null) + // 封存舱点开翻转后半程再把光标送进输入格,免得翻到一半抢焦点 + useEffect(() => { + if (!gateOpen || gateStage !== 'number') return + const timer = window.setTimeout(() => gateInputRef.current?.focus(), 640) + return () => window.clearTimeout(timer) + }, [gateOpen, gateStage]) const [gateBusy, setGateBusy] = useState(false) const [gateMessage, setGateMessage] = useState('') const [gateRising, setGateRising] = useState(false) @@ -960,13 +968,20 @@ function HoloLakeApp() {

欢迎回来 · {gateNumber}

) : gateStage === 'number' ? ( -
+
setGateOpen(true)} onKeyDown={gateOpen ? undefined : (event) => { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); setGateOpen(true) } }}> +
+ + 编号校验 + 轻点翻启 +
+
- onGateInput(event.target.value)} onKeyDown={(event) => { if (event.key === 'Enter' && gateNumber) { event.preventDefault(); void gateVerifyNumber() } }}/> + onGateInput(event.target.value)} onKeyDown={(event) => { if (event.key === 'Enter' && gateNumber) { event.preventDefault(); void gateVerifyNumber() } }}/>
{gateMessage &&

{gateMessage}

} +
) : (
diff --git a/product-source/hololake-native-desktop/src/styles.css b/product-source/hololake-native-desktop/src/styles.css index 4f1757c7f..bbf55f0f2 100644 --- a/product-source/hololake-native-desktop/src/styles.css +++ b/product-source/hololake-native-desktop/src/styles.css @@ -455,6 +455,19 @@ svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-lineca .gate-pod { position: relative; z-index: 3; width: min(400px, 88vw); padding: 26px 30px 28px; text-align: center; border: 1px solid color-mix(in srgb, var(--accent-light) 22%, transparent); border-radius: 24px; background: color-mix(in srgb, var(--panel-bg) 62%, transparent); backdrop-filter: blur(26px) saturate(1.15); box-shadow: 0 34px 90px rgba(0, 0, 0, .5), 0 0 70px color-mix(in srgb, var(--primitive-warm-glow) 9%, transparent), inset 0 1px 0 rgba(255, 255, 255, .07); animation: pod-float 6.5s ease-in-out infinite; transition: opacity .7s ease, transform .7s ease; } .gate-pod.fade-out { opacity: 0; transform: translateY(18px) scale(.985); } @keyframes pod-float { 0%, 100% { translate: 0 0; } 50% { translate: 0 -9px; } } + +/* 封存翻转舱:湖面上一枚封存徽舱,轻点一下翻转翻开表单面 */ +.gate-flip { display: grid; transform-style: preserve-3d; transition: transform .95s cubic-bezier(.32, .72, .3, 1); cursor: pointer; } +.gate-flip.open { transform: rotateY(180deg); cursor: default; } +.pod-face { grid-area: 1 / 1; backface-visibility: hidden; -webkit-backface-visibility: hidden; } +.pod-form { transform: rotateY(180deg); } +.pod-sealed { display: grid; justify-items: center; align-content: center; gap: 11px; padding: 20px 6px 14px; } +.sealed-emblem { width: 86px; height: 86px; margin-bottom: 4px; } +.sealed-emblem::before { box-shadow: 0 0 30px color-mix(in srgb, var(--primitive-warm-glow) 16%, transparent); } +.sealed-title { color: var(--content-primary); font-size: 16px; font-weight: 600; letter-spacing: .44em; text-indent: .44em; } +.sealed-sub { color: var(--content-faint); font-size: 11px; letter-spacing: .32em; text-indent: .32em; } +.gate-flip:not(.open):hover .sealed-emblem::before { border-color: color-mix(in srgb, var(--primitive-warm-glow) 46%, transparent); box-shadow: 0 0 40px color-mix(in srgb, var(--primitive-warm-glow) 32%, transparent); } +.gate-flip:not(.open):hover .sealed-sub { color: var(--content-muted); } .gate-hero { position: relative; z-index: 2; display: grid; justify-items: center; gap: 10px; text-align: center; padding: 0 24px; transition: opacity 1.1s ease, transform 1.1s ease, filter 1.1s ease; } .gate-hero.veil { opacity: 0; transform: translateY(-14px) scale(1.03); filter: blur(4px); pointer-events: none; } .gate-hero > * { animation: hero-in 1.1s ease both; }