inkvec / studio /index.html
Incorporo-user's picture
Inkvec 0.2: the presentation page, and Inkvec Studio Lite under studio/
a867b07 verified
Raw History Blame Contribute Delete
11.7 kB
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8" />
<!-- A web page: its own origin, plus the denoiser's runtime and weights. -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' 'wasm-unsafe-eval' 'sha256-+dTfo4HcxEndAo5tPy8N4VZ1j7HyojWz4m6mwWx2wGw=' https://cdn.jsdelivr.net; worker-src 'self' blob:; img-src 'self' blob: data:; style-src 'self' 'unsafe-inline'; font-src 'self'; connect-src 'self' https://huggingface.co https://*.huggingface.co https://*.hf.co https://cdn.jsdelivr.net"
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Turn a raster logo into an exact SVG, in your browser. Nothing is uploaded." />
<link rel="icon" href="./favicon.svg" type="image/svg+xml" />
<title>Inkvec Studio Lite</title>
<script type="module" crossorigin src="./assets/main-v2TpNvwt.js"></script>
<link rel="stylesheet" crossorigin href="./assets/main-BwYpaGSz.css">
<link rel="preload" href="./fonts/playfair-latin.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="./fonts/inter-latin.woff2" as="font" type="font/woff2" crossorigin />
<style>
/* Inkvec Studio Lite's loading screen: the whole page, not the desktop's splash card.
Inlined into the browser build's index.html (vite.config.ts), so it paints with the first
frame, before the app's bundle has been read. Always the dark charcoal, whatever the theme:
it is a brand moment of a second or three. One animation on the bar and one only: its
scale follows real progress (bytes of the engine, then its start), through a single
transition. The mark draws itself once, beside it, and that is all that moves. */
.boot {
position: fixed;
inset: 0;
z-index: 50;
display: grid;
grid-template-rows: 1fr auto;
overflow: hidden;
background: #1a1816;
color: #faf8f5;
font-family: "Inter Studio", Inter, system-ui, sans-serif;
-webkit-font-smoothing: antialiased;
user-select: none;
cursor: progress;
transition: opacity 0.22s ease;
}
.boot.leaving {
opacity: 0;
pointer-events: none;
}
/* Inside Hugging Face's frame: the same gap and copper hairline the app has there, so the
hand-over does not move anything. */
html.framed:not(.fullscreen) .boot {
top: 6px;
border-top: 1px solid rgba(201, 117, 74, 0.35);
}
/* The raster the product reads, fading out from the middle; the copper light above it. */
.boot-grid {
position: absolute;
inset: 0;
background-image:
linear-gradient(to right, rgba(250, 248, 245, 0.04) 1px, transparent 1px),
linear-gradient(to bottom, rgba(250, 248, 245, 0.04) 1px, transparent 1px);
background-size: 16px 16px;
-webkit-mask-image: radial-gradient(ellipse 55% 60% at 50% 42%, #000 0%, transparent 75%);
mask-image: radial-gradient(ellipse 55% 60% at 50% 42%, #000 0%, transparent 75%);
}
.boot-glow {
position: absolute;
inset: 0;
background: radial-gradient(ellipse 50% 45% at 50% 30%, rgba(201, 117, 74, 0.16), transparent 70%);
}
.boot-stage {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 24px 16px 8px;
min-height: 0;
text-align: center;
}
.boot-mark {
display: block;
height: clamp(64px, 13vh, 124px);
width: auto;
overflow: visible;
filter: drop-shadow(0 12px 28px rgba(201, 117, 74, 0.25));
}
.boot-mark path {
fill-rule: evenodd;
}
.boot-mark .o {
fill: none;
stroke: #c9754a;
stroke-width: 6;
stroke-linejoin: round;
stroke-dasharray: 1;
stroke-dashoffset: 1;
}
.boot-mark .b {
fill: #c9754a;
opacity: 0;
}
.boot-by {
margin: clamp(16px, 3.2vh, 28px) 0 0;
font-size: 10.5px;
font-weight: 500;
letter-spacing: 0.24em;
text-transform: uppercase;
color: rgba(250, 248, 245, 0.5);
}
.boot-word {
margin: 6px 0 0;
font-family: "Playfair Studio", Georgia, serif;
font-size: clamp(40px, 7.5vh, 66px);
font-weight: 500;
line-height: 1;
letter-spacing: -0.025em;
}
.boot-edition {
margin: 10px 0 0;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.3em;
text-transform: uppercase;
color: #c9754a;
}
.boot-progress {
width: min(440px, 100%);
margin-top: clamp(24px, 5vh, 44px);
text-align: left;
}
.boot-bar {
height: 3px;
border-radius: 2px;
background: rgba(250, 248, 245, 0.1);
overflow: hidden;
}
.boot-bar i {
display: block;
height: 100%;
background: #c9754a;
transform: scaleX(0);
transform-origin: left center;
transition: transform 0.3s cubic-bezier(0.25, 0.7, 0.25, 1);
will-change: transform;
}
.boot-row {
display: flex;
justify-content: space-between;
gap: 16px;
margin-top: 10px;
font-size: 12.5px;
color: rgba(250, 248, 245, 0.78);
}
.boot-detail {
min-height: 1.4em;
margin-top: 2px;
font-size: 11.5px;
color: rgba(250, 248, 245, 0.45);
}
.boot-num {
font-variant-numeric: tabular-nums;
}
.boot-progress .boot-row span:first-child {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.boot-foot {
position: relative;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 4px 16px;
padding: 14px 20px 16px;
font-size: 11px;
color: rgba(250, 248, 245, 0.36);
}
/* The entrance plays once the faces are in (boot.js), so it never starts on a fallback font. */
.boot-by,
.boot-word,
.boot-edition,
.boot-progress {
opacity: 0;
transform: translateY(6px);
}
html.boot-go .boot-mark .o {
animation:
boot-draw 1.1s cubic-bezier(0.6, 0, 0.2, 1) forwards,
boot-fade 0.4s ease 1.05s forwards;
}
html.boot-go .boot-mark .b {
animation: boot-show 0.5s ease 0.85s forwards;
}
html.boot-go .boot-by,
html.boot-go .boot-word,
html.boot-go .boot-edition,
html.boot-go .boot-progress {
animation: boot-rise 0.55s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
}
html.boot-go .boot-word {
animation-delay: 0.08s;
}
html.boot-go .boot-edition {
animation-delay: 0.16s;
}
html.boot-go .boot-progress {
animation-delay: 0.22s;
}
/* A start-up that could not finish says so, in place of the progress. */
.boot-failed .boot-bar i {
background: #d9534f;
}
.boot-failed .boot-detail {
color: rgba(250, 248, 245, 0.7);
}
.boot-reload {
margin-top: 12px;
padding: 6px 14px;
border: 1px solid rgba(250, 248, 245, 0.25);
border-radius: 6px;
background: transparent;
color: #faf8f5;
font: inherit;
font-size: 12.5px;
cursor: pointer;
}
@keyframes boot-draw {
to {
stroke-dashoffset: 0;
}
}
@keyframes boot-fade {
to {
opacity: 0;
}
}
@keyframes boot-show {
to {
opacity: 1;
}
}
@keyframes boot-rise {
to {
opacity: 1;
transform: none;
}
}
@media (max-width: 520px) {
.boot-foot {
justify-content: center;
text-align: center;
}
}
/* Nothing moves for anyone who asked for that: the finished picture, and a bar that steps. */
@media (prefers-reduced-motion: reduce) {
.boot-by,
.boot-word,
.boot-edition,
.boot-progress,
.boot-mark .b {
animation: none !important;
opacity: 1;
transform: none;
}
.boot-mark .o {
animation: none !important;
opacity: 0;
}
.boot-bar i,
.boot {
transition: none;
}
}
</style>
<script>
// Inkvec Studio Lite's loading screen, before the app's bundle arrives. Inlined into the
// head of index.html (and allowed by its own hash in the page's content policy), so it runs
// before the first paint:
//
// - `framed` when the page is inside another page's frame (Hugging Face shows the Space in
// one), so the loading screen sits below the same gap and hairline the app will;
// - `boot-go` once the two faces have loaded (or 700 ms have passed), which starts the
// entrance, so it never plays on a fallback font;
// - a failsafe: if the app's own script has not taken the screen over in 30 s (blocked, or
// a network that dropped it), say so and offer a reload instead of a bar that never moves.
//
// Everything after that is lib/web/chrome.ts: real progress, and the hand-over.
(function () {
var root = document.documentElement;
var framed = false;
try {
framed = window.self !== window.top;
} catch (e) {
framed = true;
}
if (framed) root.classList.add("framed");
var go = function () {
root.classList.add("boot-go");
};
try {
Promise.race([
Promise.all([document.fonts.load('500 60px "Playfair Studio"'), document.fonts.load('400 13px "Inter Studio"')]),
new Promise(function (resolve) {
setTimeout(resolve, 700);
}),
]).then(go, go);
} catch (e) {
go();
}
setTimeout(function () {
var boot = document.getElementById("boot");
if (!boot || window.__inkvecBoot) return;
boot.classList.add("boot-failed");
var status = document.getElementById("boot-status");
var detail = document.getElementById("boot-detail");
if (status) status.textContent = "The Studio did not load";
if (detail) {
detail.textContent = "Its script never arrived. Check the connection, then reload.";
var b = document.createElement("button");
b.className = "boot-reload";
b.textContent = "Reload";
b.onclick = function () {
location.reload();
};
detail.parentNode.appendChild(b);
}
}, 30000);
})();
</script>
</head>
<body>
<div id="boot" class="boot" role="status" aria-live="polite" aria-label="Inkvec Studio Lite is starting">
<div class="boot-grid" aria-hidden="true"></div>
<div class="boot-glow" aria-hidden="true"></div>
<div class="boot-stage">
<svg class="boot-mark" viewBox="254.5 140.5 514.25 742.25" aria-hidden="true"><path class="o" pathLength="1" d="M511.3 140.6c-23.3 79.8-103 178.5-144.9 232.75L335.45 415.4a467.73 467.73 0 00-64.8 115.4c-65.5 193.1 80.8 351.3 237.85 351.7 21.26 1.1 42.56-1.3 63.06-7 90.8-18.87 211.87-120.04 195.47-280.9-17.9-164.8-187.55-272.65-251.8-443.84Zm10.2 374.9a61.05 61.05 0 00-67.1 81.6 61.05 61.05 0 00104.3 17.26 61.05 61.05 0 00-37.2-98.86ZM511.4 817.65l177.16-201.3-43-.15a44.56 44.56 0 00-36.2 18.47l-97.8 111.67-102.2-116.67c-16.06-18.94-38.06-12-74.9-13.4 5.7 7.3 159.75 179.73 176.93 201.4Z" /><path class="b" d="M511.3 140.6c-23.3 79.8-103 178.5-144.9 232.75L335.45 415.4a467.73 467.73 0 00-64.8 115.4c-65.5 193.1 80.8 351.3 237.85 351.7 21.26 1.1 42.56-1.3 63.06-7 90.8-18.87 211.87-120.04 195.47-280.9-17.9-164.8-187.55-272.65-251.8-443.84Zm10.2 374.9a61.05 61.05 0 00-67.1 81.6 61.05 61.05 0 00104.3 17.26 61.05 61.05 0 00-37.2-98.86ZM511.4 817.65l177.16-201.3-43-.15a44.56 44.56 0 00-36.2 18.47l-97.8 111.67-102.2-116.67c-16.06-18.94-38.06-12-74.9-13.4 5.7 7.3 159.75 179.73 176.93 201.4Z" /></svg>
<p class="boot-by">LogoLabs</p>
<h1 class="boot-word">Inkvec</h1>
<p class="boot-edition">Studio Lite</p>
<div class="boot-progress">
<div class="boot-bar" id="boot-bar" role="progressbar" aria-label="Loading Inkvec Studio Lite" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><i id="boot-fill"></i></div>
<div class="boot-row"><span id="boot-status">Loading the Studio</span><span id="boot-pct" class="boot-num">0%</span></div>
<div class="boot-detail boot-num" id="boot-detail"></div>
</div>
</div>
<footer class="boot-foot">
<span>Runs in your browser. Your image never leaves this computer.</span>
<span>Version 0.2.4 · Apache-2.0 · logolabs.org</span>
</footer>
</div>
<div id="app"></div>
<div id="overlays"></div>
<div id="toasts" role="status" aria-live="polite"></div>
</body>
</html>