-
-
-
-
-
{shownTitle}
-
{shownSubtitle}
-
-
-
-
+
+
+ Loading VoCat
);
}
diff --git a/web/src/vocat.css b/web/src/vocat.css
index 38fe4f2..c2b2151 100644
--- a/web/src/vocat.css
+++ b/web/src/vocat.css
@@ -25,6 +25,34 @@
from { transform: translateX(-100%); }
to { transform: translateX(0); }
}
+@keyframes vocat-logo-draw-main {
+ 0%, 3% { stroke-dashoffset: 10000; fill: transparent; stroke: #1296db; opacity: 1; }
+ 41%, 72% { stroke-dashoffset: 0; fill: transparent; stroke: #1296db; opacity: 1; }
+ 82%, 90% { stroke-dashoffset: 0; fill: #1296db; stroke: transparent; opacity: 1; }
+ 96% { stroke-dashoffset: 0; fill: #1296db; stroke: transparent; opacity: 0; }
+ 97%, 100% { stroke-dashoffset: 10000; fill: transparent; stroke: #1296db; opacity: 1; }
+}
+@keyframes vocat-logo-draw-left {
+ 0%, 43% { stroke-dashoffset: 10000; fill: transparent; stroke: #1296db; opacity: 1; }
+ 51%, 72% { stroke-dashoffset: 0; fill: transparent; stroke: #1296db; opacity: 1; }
+ 82%, 90% { stroke-dashoffset: 0; fill: #1296db; stroke: transparent; opacity: 1; }
+ 96% { stroke-dashoffset: 0; fill: #1296db; stroke: transparent; opacity: 0; }
+ 97%, 100% { stroke-dashoffset: 10000; fill: transparent; stroke: #1296db; opacity: 1; }
+}
+@keyframes vocat-logo-draw-middle {
+ 0%, 53% { stroke-dashoffset: 10000; fill: transparent; stroke: #1296db; opacity: 1; }
+ 62%, 72% { stroke-dashoffset: 0; fill: transparent; stroke: #1296db; opacity: 1; }
+ 82%, 90% { stroke-dashoffset: 0; fill: #1296db; stroke: transparent; opacity: 1; }
+ 96% { stroke-dashoffset: 0; fill: #1296db; stroke: transparent; opacity: 0; }
+ 97%, 100% { stroke-dashoffset: 10000; fill: transparent; stroke: #1296db; opacity: 1; }
+}
+@keyframes vocat-logo-draw-right {
+ 0%, 64% { stroke-dashoffset: 10000; fill: transparent; stroke: #1296db; opacity: 1; }
+ 72% { stroke-dashoffset: 0; fill: transparent; stroke: #1296db; opacity: 1; }
+ 82%, 90% { stroke-dashoffset: 0; fill: #1296db; stroke: transparent; opacity: 1; }
+ 96% { stroke-dashoffset: 0; fill: #1296db; stroke: transparent; opacity: 0; }
+ 97%, 100% { stroke-dashoffset: 10000; fill: transparent; stroke: #1296db; opacity: 1; }
+}
/* ---- Base ---- */
html {
font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
@@ -45,6 +73,47 @@ html.dark body {
font-feature-settings: "tnum" 1, "cv01" 1;
}
+.vocat-boot-loader {
+ position: fixed;
+ inset: 0;
+ z-index: 9999;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+ background: #f9fafb;
+}
+.dark .vocat-boot-loader { background: #101014; }
+.vocat-boot-logo {
+ display: block;
+ width: clamp(144px, 24vw, 240px);
+ height: clamp(144px, 24vw, 240px);
+}
+.vocat-boot-logo path {
+ fill: transparent;
+ stroke: #1296db;
+ stroke-width: 7;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ stroke-dasharray: 10000;
+ stroke-dashoffset: 10000;
+ animation-duration: 1.9s;
+ animation-timing-function: linear;
+ animation-iteration-count: infinite;
+}
+.vocat-boot-logo path:nth-child(1) { animation-name: vocat-logo-draw-left; }
+.vocat-boot-logo path:nth-child(2) { animation-name: vocat-logo-draw-main; }
+.vocat-boot-logo path:nth-child(3) { animation-name: vocat-logo-draw-middle; }
+.vocat-boot-logo path:nth-child(4) { animation-name: vocat-logo-draw-right; }
+@media (prefers-reduced-motion: reduce) {
+ .vocat-boot-logo path {
+ animation: none;
+ fill: #1296db;
+ stroke: transparent;
+ stroke-dashoffset: 0;
+ }
+}
+
::selection {
background: rgb(14 165 233 / 1);
color: #fff;