diff --git a/promo/landing/src/App.tsx b/promo/landing/src/App.tsx index a235c5b..97fccd8 100644 --- a/promo/landing/src/App.tsx +++ b/promo/landing/src/App.tsx @@ -1,5 +1,6 @@ import { useMemo, useRef, useState } from "react"; import logoUrl from "./assets/logo-universal.png"; +import ShowcaseVisual from "./ShowcaseVisual"; const slides = [ { @@ -136,6 +137,9 @@ export default function App() { onPointerCancel={() => { dragStartX.current = null; }} + onPointerLeave={() => { + dragStartX.current = null; + }} >
-
- - - - -
- Upload - snapgo/2026/capture.png -
-
- Copied - https://cdn.example.com/... -
-
+
diff --git a/promo/landing/src/ShowcaseVisual.tsx b/promo/landing/src/ShowcaseVisual.tsx new file mode 100644 index 0000000..f927281 --- /dev/null +++ b/promo/landing/src/ShowcaseVisual.tsx @@ -0,0 +1,435 @@ +import { useState, type PointerEvent } from "react"; + +type ShowcaseVisualProps = { + activeIndex: number; +}; + +type CaptureTool = "rect" | "arrow" | "pen" | "mosaic"; +type OcrLanguage = "zh" | "en" | "auto"; +type UploadDestination = { + id: "obs" | "ssh" | "ftp"; + label: string; + detail: string; +}; + +const destinations: UploadDestination[] = [ + { id: "obs", label: "OBS", detail: "Bucket" }, + { id: "ssh", label: "SSH", detail: "Server" }, + { id: "ftp", label: "FTP", detail: "Remote" }, +]; + +const uploadRoutes: Record = { + obs: "M 50 30 C 59 30 61 17 71 17", + ssh: "M 50 30 C 58 30 63 30 71 30", + ftp: "M 50 30 C 59 30 61 43 71 43", +}; + +const ocrModes: Array<{ + id: OcrLanguage; + label: string; + name: string; + lines: string[]; + characters: number; + confidence: string; +}> = [ + { + id: "zh", + label: "中", + name: "中文", + lines: ["让每一次截图直接进入下一步。"], + characters: 15, + confidence: "99.5%", + }, + { + id: "en", + label: "EN", + name: "English", + lines: ["Capture, understand, share."], + characters: 27, + confidence: "99.1%", + }, + { + id: "auto", + label: "AUTO", + name: "中英混排", + lines: ["Capture, understand, share.", "让每一次截图直接进入下一步。"], + characters: 42, + confidence: "99.2%", + }, +]; + +const aiModes = [ + { + id: "vision", + label: "识图", + result: "检测到系统权限弹窗,截图权限尚未开启。", + score: "96%", + }, + { + id: "summary", + label: "总结", + result: "当前页面包含 3 个设置项,建议先开启屏幕录制权限。", + score: "93%", + }, + { + id: "question", + label: "问答", + result: "前往系统设置中的隐私与安全性即可完成授权。", + score: "98%", + }, +]; + +const captureTools: Array<{ id: CaptureTool; label: string }> = [ + { id: "rect", label: "矩形" }, + { id: "arrow", label: "箭头" }, + { id: "pen", label: "画笔" }, + { id: "mosaic", label: "马赛克" }, +]; + +function stopSceneDrag(event: PointerEvent) { + event.stopPropagation(); +} + +function UploadScene() { + const [selected, setSelected] = useState(destinations[0]); + const routePath = uploadRoutes[selected.id]; + + return ( +
+
+ +
+ SCREENSHOT-1428.PNG +
+
+ + + + + +
+ {destinations.map((destination) => ( + + ))} +
+ +
+ +
+ LINK COPIED + cdn.snapgo.dev/{selected.id}/... +
+
+
+ ); +} + +function IdentificationScene() { + const [mode, setMode] = useState(aiModes[0]); + + return ( +
+
+ +
+ +
+ + + +
+
+ ! +
+ Permission required + Screen Recording +
+
+
+
+ + + +
+
+ + SnapGo Vision + +
+

{mode.result}

+
+ + {mode.score} confidence +
+
+ +
+ {aiModes.map((item) => ( + + ))} +
+
+ ); +} + +function OcrScene() { + const [copied, setCopied] = useState(false); + const [language, setLanguage] = useState("auto"); + const activeMode = ocrModes.find((mode) => mode.id === language) ?? ocrModes[2]; + + function selectLanguage(mode: OcrLanguage) { + setLanguage(mode); + setCopied(false); + } + + return ( +
+
+
+ +
+
+
+ Release notes + + + Capture, understand, share. + + + 让每一次截图直接进入下一步。 +
+
+ +
+
+ OCR + {activeMode.name} +
+

+ {activeMode.lines.map((line) => {line})} +

+
+ {activeMode.characters} characters + {activeMode.confidence} +
+ +
+ +
+ {ocrModes.map((mode) => ( + + ))} +
+
+ ); +} + +function ToolGlyph({ tool }: { tool: CaptureTool }) { + if (tool === "rect") { + return ; + } + + if (tool === "arrow") { + return ; + } + + if (tool === "pen") { + return ; + } + + return ( + + ); +} + +function AnnotationPreview({ tool }: { tool: CaptureTool }) { + if (tool === "arrow") { + return ( + + ); + } + + if (tool === "pen") { + return ( + + ); + } + + if (tool === "mosaic") { + return ; + } + + return ; +} + +function CaptureScene() { + const [tool, setTool] = useState("rect"); + + return ( +
+
+
+ + Project overview + +
+ +
+ 1280 × 720 + + + + + +
+
+ +
+ {captureTools.map((item) => ( + + ))} + +
+
+ ); +} + +const scenes = [UploadScene, IdentificationScene, OcrScene, CaptureScene]; + +export default function ShowcaseVisual({ activeIndex }: ShowcaseVisualProps) { + const Scene = scenes[activeIndex] ?? UploadScene; + + return ( +
+ +
+ ); +} diff --git a/promo/landing/src/index.css b/promo/landing/src/index.css index c161174..e495c4a 100644 --- a/promo/landing/src/index.css +++ b/promo/landing/src/index.css @@ -341,6 +341,7 @@ h1 { inset: 74px clamp(22px, 4vw, 52px) 154px; display: grid; place-items: center; + overflow: hidden; border-radius: 34px; background: linear-gradient(rgba(16, 24, 40, 0.045) 1px, transparent 1px), @@ -349,100 +350,1277 @@ h1 { background-size: 34px 34px, 34px 34px, auto; } -.capture-frame { +.scene-parallax { position: relative; - width: min(72%, 430px); - aspect-ratio: 1.34; - border: 2px solid rgba(10, 132, 255, 0.68); - border-radius: 24px; - background: - radial-gradient(circle at 25% 28%, rgba(10, 132, 255, 0.14), transparent 27%), - linear-gradient(135deg, rgba(255, 255, 255, 0.96), rgba(235, 241, 253, 0.7)); - box-shadow: - 0 24px 70px rgba(43, 78, 130, 0.18), - inset 0 0 0 1px rgba(255, 255, 255, 0.7); + width: 100%; + height: 100%; } -.corner { +.visual-scene { position: absolute; - width: 21px; - height: 21px; - border-color: #0a84ff; -} - -.top-left { - top: -7px; - left: -7px; - border-top: 4px solid; - border-left: 4px solid; - border-radius: 8px 0 0; -} - -.top-right { - top: -7px; - right: -7px; - border-top: 4px solid; - border-right: 4px solid; - border-radius: 0 8px 0 0; -} - -.bottom-left { - bottom: -7px; - left: -7px; - border-bottom: 4px solid; - border-left: 4px solid; - border-radius: 0 0 0 8px; -} - -.bottom-right { - right: -7px; - bottom: -7px; - border-right: 4px solid; - border-bottom: 4px solid; - border-radius: 0 0 8px; -} - -.preview-card { - position: absolute; - width: min(250px, 58vw); - padding: 14px 16px; - border: 1px solid rgba(255, 255, 255, 0.78); - border-radius: 18px; - background: rgba(255, 255, 255, 0.78); - box-shadow: 0 22px 46px rgba(49, 62, 91, 0.16); - backdrop-filter: blur(18px); -} - -.preview-card span { - display: block; - margin-bottom: 5px; - color: #7a8799; - font-size: 11px; - font-weight: 700; - letter-spacing: 0.12em; - text-transform: uppercase; -} - -.preview-card strong { - display: block; + inset: 0; overflow: hidden; color: #142033; - font-size: 13px; - letter-spacing: -0.02em; + animation: scene-enter 360ms cubic-bezier(0.2, 0.8, 0.2, 1) both; +} + +.visual-scene button { + color: inherit; + cursor: pointer; +} + +.visual-scene button:focus-visible { + outline: 2px solid rgba(10, 132, 255, 0.42); + outline-offset: 2px; +} + +.scene-float-soft { + animation: scene-float 5.2s ease-in-out infinite; +} + +.scene-float-delayed { + animation: scene-float 5.6s ease-in-out 0.8s infinite; +} + +/* Upload scene */ +.upload-file-card { + position: absolute; + top: 50%; + left: 5%; + z-index: 2; + width: 45%; + padding: 12px; + border: 1px solid rgba(255, 255, 255, 0.9); + border-radius: 18px; + background: rgba(255, 255, 255, 0.84); + box-shadow: 0 18px 42px rgba(55, 76, 112, 0.16); + backdrop-filter: blur(16px); + transform: translateY(-50%); +} + +.upload-file-preview { + position: relative; + display: block; + height: auto; + aspect-ratio: 2.2; + overflow: hidden; + border: 1px solid rgba(77, 95, 122, 0.1); + border-radius: 12px; + background: #f3f6fa; +} + +.screenshot-window-bar { + display: flex; + height: 22%; + min-height: 14px; + align-items: center; + gap: 7px; + padding: 0 7px; + border-bottom: 1px solid rgba(68, 87, 116, 0.09); + background: rgba(255, 255, 255, 0.92); +} + +.screenshot-window-bar > span { + display: flex; + gap: 3px; +} + +.screenshot-window-bar i { + width: 4px; + height: 4px; + border-radius: 999px; + background: #c7cfda; +} + +.screenshot-window-bar i:first-child { + background: #ff736d; +} + +.screenshot-window-bar i:nth-child(2) { + background: #ffc557; +} + +.screenshot-window-bar i:last-child { + background: #55c979; +} + +.screenshot-address-bar { + display: block; + width: 38%; + height: 4px; + border-radius: 999px; + background: #d7dee8; +} + +.screenshot-window-body { + position: absolute; + inset: 22% 0 0; + display: grid; + grid-template-columns: 25% 1fr; +} + +.screenshot-sidebar { + display: flex; + flex-direction: column; + gap: 8px; + padding: 10px 7px; + border-right: 1px solid rgba(68, 87, 116, 0.08); + background: #e7ecf3; +} + +.screenshot-sidebar i { + display: block; + width: 100%; + height: 4px; + border-radius: 999px; + background: #bdc7d5; +} + +.screenshot-sidebar i:nth-child(2) { + background: #0a84ff; + opacity: 0.72; +} + +.screenshot-main { + position: relative; + padding: 9px 9px 7px; + background: linear-gradient(145deg, #fafbfd, #eef3f8); +} + +.screenshot-heading { + display: block; + width: 48%; + height: 5px; + margin-bottom: 8px; + border-radius: 999px; + background: #8797ab; +} + +.screenshot-row { + display: block; + height: 4px; + margin-bottom: 5px; + border-radius: 999px; + background: #ced6e2; +} + +.screenshot-row.row-long { + width: 82%; +} + +.screenshot-row.row-medium { + width: 61%; +} + +.screenshot-card-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 4px; + margin: 7px 0 6px; +} + +.screenshot-card-grid i { + height: 18px; + border: 1px solid rgba(112, 131, 160, 0.1); + border-radius: 4px; + background: rgba(255, 255, 255, 0.78); +} + +.screenshot-card-grid i:nth-child(2) { + background: rgba(10, 132, 255, 0.12); +} + +.screenshot-copy-lines { + display: grid; + gap: 3px; +} + +.screenshot-copy-lines i { + display: block; + width: 92%; + height: 3px; + border-radius: 999px; + background: #d8dfe9; +} + +.screenshot-copy-lines i:nth-child(2) { + width: 72%; +} + +.screenshot-copy-lines i:last-child { + width: 44%; +} + +.upload-capture-frame { + position: absolute; + inset: 5px; + z-index: 3; + pointer-events: none; +} + +.upload-capture-corner { + position: absolute; + width: 12px; + height: 12px; + border-color: #0a84ff; + filter: drop-shadow(0 1px 2px rgba(10, 132, 255, 0.3)); +} + +.upload-capture-corner.corner-nw { + top: 0; + left: 0; + border-top: 2px solid; + border-left: 2px solid; +} + +.upload-capture-corner.corner-ne { + top: 0; + right: 0; + border-top: 2px solid; + border-right: 2px solid; +} + +.upload-capture-corner.corner-sw { + bottom: 0; + left: 0; + border-bottom: 2px solid; + border-left: 2px solid; +} + +.upload-capture-corner.corner-se { + right: 0; + bottom: 0; + border-right: 2px solid; + border-bottom: 2px solid; +} + +.upload-file-copy { + display: flex; + align-items: center; + margin-top: 10px; +} + +.upload-file-copy span { + overflow: hidden; + color: #43516a; + font-size: 10px; + font-weight: 700; + letter-spacing: 0.08em; text-overflow: ellipsis; white-space: nowrap; } -.card-one { - top: 22%; - left: -18%; - animation: float-card 5.2s ease-in-out infinite; +.upload-route { + position: absolute; + inset: 0; + z-index: 2; + width: 100%; + height: 100%; + overflow: visible; + pointer-events: none; } -.card-two { - right: -16%; - bottom: 16%; - animation: float-card 5.2s ease-in-out 0.7s infinite; +.upload-route-line { + fill: none; + stroke: #2998ff; + stroke-width: 2.4; + stroke-linecap: round; +} + +.upload-route-shimmer { + fill: none; + stroke: #dff2ff; + stroke-width: 2; + stroke-linecap: round; + animation: upload-route-marquee 0.95s linear infinite; +} + +.upload-packet { + position: absolute; + z-index: 4; + top: 50%; + left: 50%; + display: grid; + width: 20px; + height: 20px; + place-items: center; + opacity: 0; + border-radius: 999px; + background: #0a84ff; + box-shadow: 0 7px 18px rgba(10, 132, 255, 0.34); + pointer-events: none; + transform: translate(-50%, -50%); +} + +.upload-packet svg { + width: 13px; + height: 13px; + fill: none; + stroke: #fff; + stroke-width: 2; + stroke-linecap: round; + stroke-linejoin: round; + transform-origin: center; +} + +.packet-obs { + animation: upload-packet-obs 1.65s linear infinite; +} + +.packet-ssh { + animation: upload-packet-ssh 1.65s linear infinite; +} + +.packet-ftp { + animation: upload-packet-ftp 1.65s linear infinite; +} + +.packet-obs svg { + animation: upload-arrow-obs 1.65s linear infinite; +} + +.packet-ftp svg { + animation: upload-arrow-ftp 1.65s linear infinite; +} + +.upload-destinations { + position: absolute; + top: 20%; + right: 4%; + bottom: 20%; + z-index: 3; + display: grid; + width: 25%; + gap: 13px; +} + +.upload-destinations button { + display: grid; + grid-template-columns: 7px minmax(0, 1fr); + grid-template-rows: auto auto; + column-gap: 8px; + align-items: center; + min-height: 52px; + padding: 8px 10px; + text-align: left; + border: 1px solid rgba(255, 255, 255, 0.82); + border-radius: 12px; + background: rgba(255, 255, 255, 0.64); + box-shadow: 0 9px 26px rgba(55, 76, 112, 0.08); + backdrop-filter: blur(12px); + transition: + transform 180ms ease, + border-color 180ms ease, + background 180ms ease, + box-shadow 180ms ease; +} + +.upload-destinations button:hover { + z-index: 2; + transform: translateX(-3px); +} + +.upload-destinations button.is-selected { + z-index: 2; + transform: none; + border-color: rgba(10, 132, 255, 0.32); + background: rgba(255, 255, 255, 0.92); + box-shadow: 0 12px 28px rgba(10, 132, 255, 0.13); +} + +.destination-status { + grid-row: 1 / 3; + width: 7px; + height: 7px; + border-radius: 999px; + background: #b8c1cf; + transition: background 180ms ease, box-shadow 180ms ease; +} + +.upload-destinations button.is-selected .destination-status { + background: #25be72; + box-shadow: 0 0 0 4px rgba(37, 190, 114, 0.12); +} + +.upload-destinations strong { + font-size: 12px; + letter-spacing: 0; +} + +.upload-destinations small { + color: #8590a3; + font-size: 9px; + line-height: 1.1; +} + +.upload-result { + position: absolute; + bottom: 5%; + left: 5%; + z-index: 4; + display: flex; + width: 45%; + min-width: 0; + align-items: center; + gap: 9px; + padding: 9px 11px; + border: 1px solid rgba(255, 255, 255, 0.86); + border-radius: 14px; + background: rgba(255, 255, 255, 0.88); + box-shadow: 0 16px 34px rgba(45, 70, 108, 0.16); + backdrop-filter: blur(16px); +} + +.result-check { + display: grid; + flex: 0 0 auto; + place-items: center; + width: 26px; + height: 26px; + color: #fff; + font-size: 13px; + font-weight: 800; + border-radius: 999px; + background: #25be72; + box-shadow: 0 6px 14px rgba(37, 190, 114, 0.25); +} + +.upload-result div { + min-width: 0; +} + +.upload-result small, +.upload-result strong { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.upload-result small { + color: #8590a3; + font-size: 8px; + font-weight: 800; + letter-spacing: 0.12em; +} + +.upload-result strong { + margin-top: 2px; + color: #26364c; + font-size: 10px; +} + +/* AI identification scene */ +.ai-source-card { + position: absolute; + top: 8%; + bottom: 8%; + left: 5%; + width: 49%; + overflow: hidden; + border: 1px solid rgba(255, 255, 255, 0.88); + border-radius: 17px; + background: rgba(255, 255, 255, 0.76); + box-shadow: 0 18px 45px rgba(49, 71, 105, 0.15); +} + +.mini-window-bar { + display: flex; + align-items: center; + height: 28px; + gap: 5px; + padding: 0 10px; + background: rgba(245, 247, 251, 0.9); + border-bottom: 1px solid rgba(72, 91, 122, 0.07); +} + +.mini-window-bar span { + width: 6px; + height: 6px; + border-radius: 999px; + background: #d1d7e1; +} + +.mini-window-bar span:first-child { + background: #ff746e; +} + +.mini-window-bar span:nth-child(2) { + background: #ffc65a; +} + +.mini-window-bar span:last-child { + background: #57ce7c; +} + +.ai-source-content { + position: absolute; + inset: 28px 0 0; + overflow: hidden; + background: + linear-gradient(90deg, rgba(230, 235, 244, 0.86) 25%, transparent 25%), + linear-gradient(145deg, #fbfcfe, #eef3fb); +} + +.source-sidebar { + position: absolute; + top: 17%; + left: 6%; + width: 13%; + height: 62%; + border-radius: 6px; + background: repeating-linear-gradient(180deg, #bdc7d6 0 4px, transparent 4px 13px); + opacity: 0.72; +} + +.source-settings { + position: absolute; + top: 17%; + right: 7%; + display: grid; + width: 61%; + gap: 11px; +} + +.source-settings i { + display: block; + height: 7px; + border-radius: 999px; + background: #d9e0ea; +} + +.source-settings i:nth-child(2) { + width: 78%; +} + +.source-settings i:nth-child(3) { + width: 90%; +} + +.source-dialog { + position: absolute; + right: 7%; + bottom: 14%; + left: 31%; + display: flex; + align-items: center; + gap: 8px; + padding: 9px; + border: 1px solid rgba(255, 255, 255, 0.92); + border-radius: 11px; + background: rgba(255, 255, 255, 0.92); + box-shadow: 0 12px 26px rgba(53, 68, 98, 0.12); +} + +.dialog-icon { + display: grid; + flex: 0 0 auto; + place-items: center; + width: 24px; + height: 24px; + color: #fff; + font-size: 12px; + font-weight: 800; + border-radius: 8px; + background: #ff6b64; +} + +.source-dialog strong, +.source-dialog small { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.source-dialog strong { + font-size: 9px; +} + +.source-dialog small { + margin-top: 2px; + color: #8b96a6; + font-size: 8px; +} + +.ai-scan-line { + position: absolute; + z-index: 4; + top: 22px; + right: 0; + left: 0; + height: 2px; + background: #39a0ff; + box-shadow: + 0 0 10px rgba(10, 132, 255, 0.75), + 0 8px 24px rgba(10, 132, 255, 0.22); + animation: ai-scan 3.2s ease-in-out infinite; +} + +.ai-core { + position: absolute; + z-index: 5; + top: 47%; + left: 51%; + display: grid; + place-items: center; + width: 46px; + height: 46px; + color: #fff; + font-size: 12px; + font-weight: 800; + border: 5px solid rgba(255, 255, 255, 0.9); + border-radius: 999px; + background: linear-gradient(145deg, #0879f1, #47b4ff); + box-shadow: 0 14px 30px rgba(10, 132, 255, 0.28); + transform: translate(-50%, -50%); + animation: ai-core-breathe 3s ease-in-out infinite; +} + +.ai-orbit { + position: absolute; + border: 1px solid rgba(10, 132, 255, 0.22); + border-radius: 999px; +} + +.orbit-one { + inset: -11px; + border-right-color: #0a84ff; + animation: orbit-spin 5s linear infinite; +} + +.orbit-two { + inset: -20px; + border-bottom-color: rgba(10, 132, 255, 0.62); + animation: orbit-spin 7s linear reverse infinite; +} + +.ai-result-card { + position: absolute; + top: 13%; + right: 4%; + z-index: 3; + width: 43%; + padding: 13px; + border: 1px solid rgba(255, 255, 255, 0.9); + border-radius: 16px; + background: rgba(255, 255, 255, 0.88); + box-shadow: 0 20px 42px rgba(48, 70, 107, 0.17); + backdrop-filter: blur(16px); +} + +.ai-result-heading { + display: flex; + min-width: 0; + align-items: center; + gap: 6px; +} + +.ai-spark { + display: grid; + flex: 0 0 auto; + place-items: center; + width: 23px; + height: 23px; + color: #0a84ff; + font-size: 13px; + border-radius: 8px; + background: rgba(10, 132, 255, 0.1); +} + +.ai-result-heading strong { + overflow: hidden; + font-size: 10px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ai-result-heading i { + flex: 0 0 auto; + width: 6px; + height: 6px; + margin-left: auto; + border-radius: 999px; + background: #25be72; + box-shadow: 0 0 0 4px rgba(37, 190, 114, 0.11); +} + +.ai-result-card p { + min-height: 42px; + margin: 11px 0; + color: #3f4e63; + font-size: 11px; + line-height: 1.55; +} + +.confidence-row { + display: flex; + align-items: center; + gap: 7px; +} + +.confidence-row > span { + flex: 1; + height: 4px; + overflow: hidden; + border-radius: 999px; + background: #e7edf5; +} + +.confidence-row > span i { + display: block; + width: 94%; + height: 100%; + border-radius: inherit; + background: linear-gradient(90deg, #0a84ff, #71c6ff); +} + +.confidence-row small { + flex: 0 0 auto; + color: #8792a4; + font-size: 8px; +} + +.ai-mode-switch { + position: absolute; + right: 5%; + bottom: 8%; + z-index: 5; + display: flex; + gap: 3px; + padding: 3px; + border: 1px solid rgba(255, 255, 255, 0.88); + border-radius: 11px; + background: rgba(255, 255, 255, 0.72); + box-shadow: 0 10px 24px rgba(48, 70, 107, 0.1); + backdrop-filter: blur(14px); +} + +.ai-mode-switch button { + min-width: 42px; + padding: 6px 8px; + color: #718096; + font-size: 9px; + font-weight: 700; + border-radius: 8px; + background: transparent; + transition: color 160ms ease, background 160ms ease, box-shadow 160ms ease; +} + +.ai-mode-switch button.is-selected { + color: #0a70d8; + background: #fff; + box-shadow: 0 5px 12px rgba(53, 74, 108, 0.1); +} + +/* OCR scene */ +.ocr-document { + position: absolute; + top: 7%; + bottom: 7%; + left: 6%; + width: 51%; + overflow: hidden; + border: 1px solid rgba(255, 255, 255, 0.9); + border-radius: 17px; + background: rgba(255, 255, 255, 0.88); + box-shadow: 0 18px 44px rgba(48, 69, 103, 0.14); + transform: rotate(-1.4deg); +} + +.document-header { + display: flex; + align-items: center; + justify-content: space-between; + height: 30px; + padding: 0 11px; + border-bottom: 1px solid rgba(61, 80, 111, 0.07); +} + +.document-header > span { + width: 33%; + height: 6px; + border-radius: 999px; + background: #d5dce7; +} + +.document-header div { + display: flex; + gap: 4px; +} + +.document-header i { + width: 5px; + height: 5px; + border-radius: 999px; + background: #c8d0dc; +} + +.document-copy { + display: flex; + flex-direction: column; + gap: 9px; + padding: 13px 14px; +} + +.document-copy > strong { + margin-bottom: 3px; + color: #28384f; + font-size: 12px; +} + +.text-line { + display: block; + width: 100%; + height: 5px; + border-radius: 999px; + background: #d9e0e9; +} + +.line-medium { + width: 76%; +} + +.line-short { + width: 58%; +} + +.line-highlight { + position: relative; + width: 92%; + height: 18px; + margin-block: -2px; + border: 1px solid rgba(10, 132, 255, 0.17); + border-radius: 5px; + background: rgba(10, 132, 255, 0.11); +} + +.line-highlight.secondary { + width: 86%; + background: rgba(255, 196, 83, 0.18); + border-color: rgba(230, 167, 42, 0.22); +} + +.line-highlight i { + position: absolute; + top: 50%; + left: 5px; + overflow: hidden; + max-width: calc(100% - 10px); + color: #476079; + font-size: 7px; + font-style: normal; + font-weight: 650; + text-overflow: ellipsis; + white-space: nowrap; + transform: translateY(-50%); +} + +.ocr-scan-bar { + position: absolute; + z-index: 3; + top: 28px; + right: 0; + left: 0; + height: 2px; + background: #0a84ff; + box-shadow: 0 0 16px rgba(10, 132, 255, 0.66); + animation: ocr-scan 3.4s ease-in-out infinite; +} + +.ocr-selection-card { + position: absolute; + top: 12%; + right: 5%; + z-index: 4; + width: 43%; + padding: 13px; + border: 1px solid rgba(255, 255, 255, 0.92); + border-radius: 16px; + background: rgba(255, 255, 255, 0.9); + box-shadow: 0 20px 44px rgba(47, 69, 105, 0.17); + backdrop-filter: blur(16px); +} + +.selection-heading, +.selection-meta { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; +} + +.selection-heading span { + color: #0a84ff; + font-size: 9px; + font-weight: 850; + letter-spacing: 0.12em; +} + +.selection-heading small, +.selection-meta span { + color: #8a95a6; + font-size: 8px; +} + +.ocr-selection-card p { + min-height: 31px; + margin: 10px 0; + color: #3e4d63; + font-size: 10px; + line-height: 1.55; +} + +.ocr-selection-card p span { + display: block; +} + +.selection-meta strong { + color: #25a869; + font-size: 9px; +} + +.ocr-selection-card button { + display: flex; + width: 100%; + min-height: 30px; + align-items: center; + justify-content: center; + gap: 6px; + margin-top: 10px; + color: #fff; + font-size: 9px; + font-weight: 750; + border-radius: 9px; + background: #0a84ff; + box-shadow: 0 9px 20px rgba(10, 132, 255, 0.2); + transition: transform 160ms ease, background 160ms ease; +} + +.ocr-selection-card button:hover { + transform: translateY(-1px); +} + +.ocr-selection-card button.is-copied { + background: #25ad6b; +} + +.ocr-selection-card button span { + font-size: 10px; +} + +.ocr-language-pills { + position: absolute; + right: 7%; + bottom: 8%; + display: flex; + gap: 5px; +} + +.ocr-language-pills button { + padding: 5px 7px; + color: #6d7a90; + font-size: 8px; + font-weight: 750; + border: 1px solid rgba(255, 255, 255, 0.85); + border-radius: 999px; + background: rgba(255, 255, 255, 0.7); + box-shadow: 0 5px 12px rgba(48, 69, 103, 0.06); + transition: color 160ms ease, background 160ms ease, transform 160ms ease; +} + +.ocr-language-pills button:hover { + transform: translateY(-1px); +} + +.ocr-language-pills button.is-selected { + color: #0a70d8; + background: rgba(220, 239, 255, 0.88); + border-color: rgba(10, 132, 255, 0.18); +} + +/* Capture scene */ +.capture-canvas { + position: absolute; + top: 6%; + right: 5%; + bottom: 8%; + left: 5%; + overflow: hidden; + border: 1px solid rgba(255, 255, 255, 0.9); + border-radius: 17px; + background: rgba(255, 255, 255, 0.78); + box-shadow: 0 19px 46px rgba(49, 70, 105, 0.16); +} + +.canvas-app-bar { + display: flex; + height: 29px; + align-items: center; + gap: 8px; + padding: 0 11px; + color: #45536a; + background: rgba(247, 249, 252, 0.92); + border-bottom: 1px solid rgba(61, 80, 111, 0.07); +} + +.canvas-app-bar > span { + width: 7px; + height: 7px; + border-radius: 999px; + background: #0a84ff; +} + +.canvas-app-bar strong { + font-size: 8px; +} + +.canvas-app-bar i { + width: 27px; + height: 5px; + margin-left: auto; + border-radius: 999px; + background: #d8dfe9; +} + +.canvas-layout { + position: absolute; + inset: 29px 0 0; + display: grid; + grid-template-columns: 22% 1fr; + background: linear-gradient(145deg, #f8fafc, #eaf0f8); +} + +.canvas-sidebar { + border-right: 1px solid rgba(61, 80, 111, 0.07); + background: + repeating-linear-gradient(180deg, transparent 0 13px, rgba(126, 140, 162, 0.18) 13px 18px, transparent 18px 28px), + rgba(231, 236, 244, 0.8); +} + +.canvas-content { + padding: 13px 15px; +} + +.canvas-heading, +.canvas-line { + display: block; + height: 6px; + border-radius: 999px; + background: #cbd4e1; +} + +.canvas-heading { + width: 42%; + height: 9px; + margin-bottom: 13px; + background: #93a4b9; +} + +.canvas-line { + width: 74%; + margin-bottom: 8px; +} + +.canvas-line.short { + width: 54%; +} + +.canvas-chart { + display: flex; + height: 44%; + align-items: flex-end; + gap: 7px; + margin-top: 12px; + padding: 0 8px; + border-bottom: 1px solid rgba(85, 103, 132, 0.13); +} + +.canvas-chart span { + flex: 1; + min-width: 5px; + border-radius: 4px 4px 0 0; + background: linear-gradient(180deg, rgba(10, 132, 255, 0.82), rgba(10, 132, 255, 0.24)); +} + +.canvas-chart span:nth-child(1) { height: 38%; } +.canvas-chart span:nth-child(2) { height: 68%; } +.canvas-chart span:nth-child(3) { height: 51%; } +.canvas-chart span:nth-child(4) { height: 84%; } +.canvas-chart span:nth-child(5) { height: 72%; } + +.capture-selection { + position: absolute; + z-index: 3; + top: 18%; + right: 10%; + bottom: 11%; + left: 20%; + border: 2px solid #0a84ff; + background: rgba(255, 255, 255, 0.14); + box-shadow: + 0 0 0 999px rgba(21, 31, 48, 0.1), + inset 0 0 0 1px rgba(255, 255, 255, 0.48); +} + +.selection-size { + position: absolute; + top: -21px; + left: -2px; + padding: 3px 6px; + color: #fff; + font-size: 7px; + font-weight: 750; + border-radius: 5px 5px 0 0; + background: #0a84ff; +} + +.selection-handle { + position: absolute; + width: 7px; + height: 7px; + border: 2px solid #fff; + border-radius: 2px; + background: #0a84ff; + box-shadow: 0 2px 6px rgba(10, 89, 166, 0.22); +} + +.handle-nw { top: -4px; left: -4px; } +.handle-ne { top: -4px; right: -4px; } +.handle-sw { bottom: -4px; left: -4px; } +.handle-se { right: -4px; bottom: -4px; } + +.annotation-rect { + position: absolute; + top: 21%; + right: 19%; + bottom: 20%; + left: 17%; + border: 3px solid #ff5b52; + border-radius: 6px; + animation: annotation-pop 260ms ease both; +} + +.annotation-rect span { + position: absolute; + width: 5px; + height: 5px; + border-radius: 999px; + background: #ff5b52; +} + +.annotation-rect span:first-child { top: -4px; left: -4px; } +.annotation-rect span:nth-child(2) { top: -4px; right: -4px; } +.annotation-rect span:nth-child(3) { bottom: -4px; left: -4px; } +.annotation-rect span:last-child { right: -4px; bottom: -4px; } + +.annotation-arrow, +.annotation-pen { + position: absolute; + inset: 4%; + width: 92%; + height: 92%; + overflow: visible; +} + +.annotation-arrow path, +.annotation-pen path { + fill: none; + stroke: #ff5b52; + stroke-width: 7; + stroke-linecap: round; + stroke-linejoin: round; + stroke-dasharray: 260; + animation: annotation-draw 620ms ease-out both; +} + +.annotation-mosaic { + position: absolute; + top: 22%; + right: 15%; + bottom: 24%; + left: 18%; + display: grid; + grid-template-columns: repeat(5, 1fr); + gap: 1px; + overflow: hidden; + border: 2px solid rgba(255, 91, 82, 0.78); + border-radius: 6px; + background: #d8e0eb; + animation: annotation-pop 260ms ease both; +} + +.annotation-mosaic span { + background: #94a4b8; + animation: mosaic-pulse 1.8s ease-in-out infinite alternate; +} + +.annotation-mosaic span:nth-child(3n) { background: #65778f; animation-delay: 0.15s; } +.annotation-mosaic span:nth-child(4n) { background: #bdc8d5; animation-delay: 0.3s; } + +.capture-toolbar { + position: absolute; + z-index: 6; + bottom: 3%; + left: 50%; + display: flex; + align-items: center; + gap: 4px; + padding: 4px; + border: 1px solid rgba(255, 255, 255, 0.92); + border-radius: 13px; + background: rgba(255, 255, 255, 0.9); + box-shadow: 0 12px 28px rgba(40, 60, 94, 0.18); + backdrop-filter: blur(15px); + transform: translateX(-50%); +} + +.capture-toolbar button { + display: grid; + place-items: center; + width: 31px; + height: 31px; + color: #69778c; + border-radius: 9px; + background: transparent; + transition: color 160ms ease, background 160ms ease, transform 160ms ease; +} + +.capture-toolbar button:hover { + transform: translateY(-1px); +} + +.capture-toolbar button.is-selected { + color: #fff; + background: #0a84ff; + box-shadow: 0 7px 15px rgba(10, 132, 255, 0.23); +} + +.capture-toolbar svg { + width: 17px; + height: 17px; + fill: none; + stroke: currentColor; + stroke-width: 1.8; + stroke-linecap: round; + stroke-linejoin: round; +} + +.toolbar-divider { + width: 1px; + height: 18px; + margin-inline: 2px; + background: #dce2ea; +} + +.toolbar-color { + width: 17px; + height: 17px; + margin: 0 4px 0 2px; + border: 3px solid #fff; + border-radius: 999px; + background: #ff5b52; + box-shadow: 0 0 0 1px rgba(38, 52, 73, 0.12); } .slide-panel { @@ -555,14 +1733,290 @@ h1 { background: #0a84ff; } -@keyframes float-card { +@keyframes scene-enter { + from { + opacity: 0; + transform: translateY(9px) scale(0.985); + } + + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +@keyframes scene-float { 0%, 100% { transform: translate3d(0, 0, 0); } 50% { - transform: translate3d(0, -10px, 0); + transform: translate3d(0, -6px, 0); + } +} + +@keyframes upload-route-marquee { + to { + stroke-dashoffset: -100; + } +} + +@keyframes upload-packet-obs { + 0%, + 10% { + top: 50%; + left: 50%; + opacity: 0; + } + + 12% { + top: 50%; + left: 50%; + opacity: 1; + } + + 34% { + top: 46.6%; + left: 55.7%; + opacity: 1; + } + + 56% { + top: 39.2%; + left: 60.1%; + opacity: 1; + } + + 78% { + top: 31.7%; + left: 64.8%; + opacity: 1; + } + + 96% { + top: 28.3%; + left: 71%; + opacity: 1; + } + + 100% { + top: 28.3%; + left: 71%; + opacity: 0; + } +} + +@keyframes upload-packet-ssh { + 0%, + 10% { + top: 50%; + left: 50%; + opacity: 0; + } + + 12% { + top: 50%; + left: 50%; + opacity: 1; + } + + 34% { + top: 50%; + left: 55.5%; + opacity: 1; + } + + 56% { + top: 50%; + left: 60.5%; + opacity: 1; + } + + 78% { + top: 50%; + left: 65.5%; + opacity: 1; + } + + 96% { + top: 50%; + left: 71%; + opacity: 1; + } + + 100% { + top: 50%; + left: 71%; + opacity: 0; + } +} + +@keyframes upload-packet-ftp { + 0%, + 10% { + top: 50%; + left: 50%; + opacity: 0; + } + + 12% { + top: 50%; + left: 50%; + opacity: 1; + } + + 34% { + top: 53.4%; + left: 55.7%; + opacity: 1; + } + + 56% { + top: 60.8%; + left: 60.1%; + opacity: 1; + } + + 78% { + top: 68.3%; + left: 64.8%; + opacity: 1; + } + + 96% { + top: 71.7%; + left: 71%; + opacity: 1; + } + + 100% { + top: 71.7%; + left: 71%; + opacity: 0; + } +} + +@keyframes upload-arrow-obs { + 0%, + 12% { + transform: rotate(0deg); + } + + 34% { + transform: rotate(-25deg); + } + + 56% { + transform: rotate(-42deg); + } + + 78% { + transform: rotate(-36deg); + } + + 96%, + 100% { + transform: rotate(0deg); + } +} + +@keyframes upload-arrow-ftp { + 0%, + 12% { + transform: rotate(0deg); + } + + 34% { + transform: rotate(25deg); + } + + 56% { + transform: rotate(42deg); + } + + 78% { + transform: rotate(36deg); + } + + 96%, + 100% { + transform: rotate(0deg); + } +} + +@keyframes ai-scan { + 0%, + 100% { + top: 28px; + opacity: 0.3; + } + + 50% { + top: calc(100% - 3px); + opacity: 1; + } +} + +@keyframes ai-core-breathe { + 0%, + 100% { + transform: translate(-50%, -50%) scale(1); + } + + 50% { + transform: translate(-50%, -50%) scale(1.06); + } +} + +@keyframes orbit-spin { + to { + transform: rotate(360deg); + } +} + +@keyframes ocr-scan { + 0%, + 100% { + top: 30px; + opacity: 0.25; + } + + 52% { + top: calc(100% - 3px); + opacity: 1; + } +} + +@keyframes annotation-pop { + from { + opacity: 0; + transform: scale(0.9); + } + + to { + opacity: 1; + transform: scale(1); + } +} + +@keyframes annotation-draw { + from { + stroke-dashoffset: 260; + } + + to { + stroke-dashoffset: 0; + } +} + +@keyframes mosaic-pulse { + from { + filter: brightness(0.9); + } + + to { + filter: brightness(1.12); } } @@ -658,11 +2112,6 @@ h1 { border-radius: 24px; } - .capture-frame { - width: min(58%, 270px); - height: auto; - } - .slide-panel { right: 22px; bottom: 22px; @@ -755,27 +2204,304 @@ h1 { background-size: 28px 28px, 28px 28px, auto; } - .capture-frame { - width: min(58%, 240px); - border-radius: 18px; + .upload-file-card { + top: 50%; + left: 5%; + width: 45%; + padding: 8px; + border-radius: 12px; + transform: translateY(-50%); } - .preview-card { - width: 180px; - padding: 11px 12px; - border-radius: 14px; + .upload-file-preview { + height: auto; + border-radius: 8px; } - .preview-card strong { - font-size: 11px; + .upload-file-copy { + margin-top: 6px; } - .card-one { - left: -22%; + .upload-file-copy span { + font-size: 9px; } - .card-two { - right: -22%; + .upload-destinations { + top: 18%; + right: 3%; + bottom: 18%; + width: 26%; + gap: 8px; + } + + .upload-destinations button { + grid-template-columns: 6px minmax(0, 1fr); + column-gap: 5px; + min-height: 35px; + padding: 5px 6px; + border-radius: 9px; + } + + .upload-destinations button:hover { + transform: translateX(-3px); + } + + .upload-destinations button.is-selected { + transform: none; + } + + .destination-status { + width: 6px; + height: 6px; + } + + .upload-destinations strong { + font-size: 9px; + } + + .upload-destinations small { + font-size: 7px; + } + + .upload-result { + bottom: 1%; + left: 5%; + width: 45%; + gap: 6px; + padding: 7px 8px; + border-radius: 11px; + } + + .result-check { + width: 21px; + height: 21px; + font-size: 10px; + } + + .upload-result small { + font-size: 7px; + } + + .upload-result strong { + font-size: 8px; + } + + .ai-source-card { + top: 4%; + bottom: 4%; + left: 3%; + width: 49%; + border-radius: 13px; + } + + .mini-window-bar { + height: 22px; + padding-inline: 8px; + } + + .ai-source-content { + inset: 22px 0 0; + } + + .source-settings { + gap: 8px; + } + + .source-dialog { + right: 5%; + bottom: 12%; + left: 27%; + gap: 5px; + padding: 6px; + border-radius: 8px; + } + + .dialog-icon { + width: 19px; + height: 19px; + font-size: 9px; + border-radius: 6px; + } + + .source-dialog strong { + font-size: 7px; + } + + .source-dialog small { + font-size: 6px; + } + + .ai-core { + width: 34px; + height: 34px; + font-size: 9px; + border-width: 3px; + } + + .orbit-two { + inset: -15px; + } + + .ai-result-card { + top: 8%; + right: 3%; + width: 45%; + padding: 8px; + border-radius: 12px; + } + + .ai-spark { + width: 19px; + height: 19px; + font-size: 10px; + border-radius: 6px; + } + + .ai-result-heading strong { + font-size: 8px; + } + + .ai-result-card p { + min-height: 30px; + margin: 7px 0; + font-size: 8px; + line-height: 1.45; + } + + .confidence-row small { + font-size: 6px; + } + + .ai-mode-switch { + right: 4%; + bottom: 5%; + } + + .ai-mode-switch button { + min-width: 34px; + padding: 5px 6px; + font-size: 8px; + } + + .ocr-document { + top: 4%; + bottom: 4%; + left: 4%; + width: 50%; + border-radius: 13px; + } + + .document-header { + height: 24px; + padding-inline: 8px; + } + + .document-copy { + gap: 6px; + padding: 9px 10px; + } + + .document-copy > strong { + margin-bottom: 1px; + font-size: 9px; + } + + .text-line { + height: 4px; + } + + .line-highlight { + height: 14px; + } + + .line-highlight i { + font-size: 6px; + } + + .ocr-selection-card { + top: 8%; + right: 3%; + width: 45%; + padding: 8px; + border-radius: 12px; + } + + .ocr-selection-card p { + min-height: 24px; + margin: 6px 0; + font-size: 8px; + line-height: 1.45; + } + + .ocr-selection-card button { + min-height: 26px; + margin-top: 6px; + font-size: 8px; + } + + .ocr-language-pills { + right: 4%; + bottom: 4%; + gap: 3px; + } + + .ocr-language-pills button { + padding: 4px 6px; + font-size: 7px; + } + + .capture-canvas { + top: 4%; + right: 3%; + bottom: 4%; + left: 3%; + border-radius: 13px; + } + + .canvas-app-bar { + height: 23px; + } + + .canvas-layout { + inset: 23px 0 0; + } + + .canvas-content { + padding: 9px 11px; + } + + .canvas-heading { + margin-bottom: 8px; + } + + .canvas-line { + margin-bottom: 5px; + } + + .canvas-chart { + margin-top: 7px; + } + + .capture-toolbar { + bottom: 2%; + padding: 3px; + border-radius: 11px; + } + + .capture-toolbar button { + width: 27px; + height: 27px; + border-radius: 8px; + } + + .capture-toolbar svg { + width: 14px; + height: 14px; + } + + .toolbar-color { + width: 14px; + height: 14px; } .slide-panel h2 {