index.html
Rama main · réplica de lectura del repositorio original.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Apply theme before first paint to prevent FOUC / light-flash on refresh.
Mirrors next-themes config in App.tsx: attribute="class", defaultTheme="system",
enableSystem, storageKey="theme". Must stay in sync with that ThemeProvider. -->
<script>
(function () {
try {
var stored = localStorage.getItem('theme');
var theme = stored || 'system';
if (theme === 'system') {
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
var root = document.documentElement;
root.classList.remove('light', 'dark');
root.classList.add(theme);
root.style.colorScheme = theme;
} catch (e) {}
})();
</script>
<!-- BRANDLESS defaults only. Real per-site values are injected by:
· api/html.ts on Vercel, which serves THIS shell with the page's own
title, description, OG/Twitter, canonical and hreflang filled in —
for every reader, browsers and crawlers alike (src/lib/seo-shell.ts)
· react-helmet-async (SeoHead.tsx) once the SPA hydrates (keeps the
head in sync on client-side navigation, adds JSON-LD)
Never hardcode a brand here — a self-hosted instance must advertise the
CUSTOMER's identity and domain, not FlowWink's. -->
<title>Website</title>
<!-- Google Fonts: shared defaults plus 2026 display options. Keep external font loading in HTML, not CSS. -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=PT+Serif:ital,wght@0,400;0,700;1,400&family=Playfair+Display:ital,wght@0,400;0,600;0,700;1,400;1,600&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap">
<!-- Structural OG/Twitter only — api/html.ts replaces these with the page's
own on Vercel; react-helmet does the same once the SPA runs. -->
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary_large_image" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<!-- Runtime Supabase config (see RUNTIME_ENV_DEFINES in vite.config.ts).
The bundle reads __FLOWWINK_RUNTIME__.<key>; assembled here from the
build-time values (%VITE_*% is replaced by Vite) with optional
overrides from /runtime-config.js (regenerated from container env by
the Docker entrypoint). Classic blocking scripts: must run before the
module bundle below evaluates. -->
<script src="/runtime-config.js"></script>
<script>
(function () {
var overrides = globalThis.__FLOWWINK_ENV__ || {};
globalThis.__FLOWWINK_RUNTIME__ = {
VITE_SUPABASE_URL: overrides.VITE_SUPABASE_URL || "__BAKED_VITE_SUPABASE_URL__",
VITE_SUPABASE_PUBLISHABLE_KEY: overrides.VITE_SUPABASE_PUBLISHABLE_KEY || "__BAKED_VITE_SUPABASE_PUBLISHABLE_KEY__",
VITE_SUPABASE_PROJECT_ID: overrides.VITE_SUPABASE_PROJECT_ID || "__BAKED_VITE_SUPABASE_PROJECT_ID__",
};
})();
</script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>