-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathindex.html
More file actions
100 lines (91 loc) Β· 6.85 KB
/
Copy pathindex.html
File metadata and controls
100 lines (91 loc) Β· 6.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- ββ Manifest & Icons βββββββββββββββββββββββββββββββββ -->
<!-- QNBS-v3: %BASE_URL% substituted by Vite at build time β resolves to / for Vercel/CF edge and /WorldScript-Studio/ for GitHub Pages. -->
<link rel="manifest" href="%BASE_URL%manifest.json" />
<link rel="icon" type="image/svg+xml" href="%BASE_URL%favicon.svg" />
<link rel="apple-touch-icon" href="%BASE_URL%favicon.svg" />
<!-- ββ Viewport & Theme ββββββββββββββββββββββββββββββββ -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes, viewport-fit=cover" />
<meta name="theme-color" content="#020617" media="(prefers-color-scheme: dark)" />
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
<meta name="color-scheme" content="dark light" />
<!-- ββ SEO & Social βββββββββββββββββββββββββββββββββββββ -->
<meta name="description" content="AI-Powered Creative Writing Studio β craft entire novels, characters & worlds with Gemini AI. Works offline." />
<meta name="keywords" content="creative writing, AI writing assistant, novel writer, story generator, character builder, world building" />
<meta name="author" content="WorldScript Studio" />
<meta name="robots" content="index, follow" />
<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:site_name" content="WorldScript Studio" />
<meta property="og:title" content="WorldScript Studio β AI Creative Writing" />
<meta property="og:description" content="Build immersive worlds and craft entire novels with AI. Works offline as a PWA." />
<meta property="og:url" content="https://worldscript-studio.app%BASE_URL%" />
<meta property="og:image" content="%BASE_URL%favicon.svg" />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="WorldScript Studio" />
<meta name="twitter:description" content="AI-Powered Creative Writing Studio β offline-ready PWA." />
<meta name="twitter:image" content="%BASE_URL%favicon.svg" />
<!-- ββ PWA / Mobile Capable ββββββββββββββββββββββββββββ -->
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="WorldScript" />
<meta name="msapplication-TileColor" content="#020617" />
<meta name="msapplication-tap-highlight" content="no" />
<meta name="application-name" content="WorldScript Studio" />
<!-- ββ Security: Content Security Policy βββββββββββββββ -->
<!--
CSP-Strategie:
- script-src: eigene Skripte (Vite ES modules) + 'wasm-unsafe-eval' β REQUIRED for
WebAssembly.compile/instantiate, used by WebLLM, ONNX Runtime Web, Transformers.js,
DuckDB-WASM, Whisper-STT, and Kokoro-TTS (the local-inference stack). NOT the broader
unsafe-eval keyword, which is forbidden; wasm-unsafe-eval only lifts the WASM restriction.
No inline script (moved to index.tsx as of ADR-0013 β see docs/adr/0013-csp-wasm-and-blob-frames.md).
- frame-src: 'self' blob: β Binder-PDF-preview and ManuscriptResearchSplit iframes render
from Blob URLs (IndexedDB-backed assets, no same-origin static file to point at instead).
- style-src: eigene + unsafe-inline (React inline-styles) β keine Fremd-Font-CDN mehr,
CJK/Greek sind ΓΌber @fontsource self-hosted (siehe index.tsx)
- font-src: self + data: β keine Fremd-Font-CDN mehr nΓΆtig (self-hosted, siehe index.tsx)
- connect-src 'self' https://generativelanguage.googleapis.com https://api.openai.com https://api.x.ai https://api.anthropic.com https://openrouter.ai https://api.openrouter.ai https://api.groq.com https://huggingface.co https://us.aws.cdn.hf.co https://api.languagetool.org http://localhost:11434 http://127.0.0.1:11434 http://localhost:1234 http://127.0.0.1:1234 http://localhost:8000 http://127.0.0.1:8000 http://localhost:8010 http://127.0.0.1:8010 wss://y-webrtc-signaling.fly.dev wss://signaling.yjs.dev; arbitrary HTTPS egress and scheme wildcards are forbidden.
The allowlist is maintained in config/csp-connect-src.json, synchronized by csp:sync,
and verified by csp:verify. Runtime preflight rejects unlisted BYOK endpoints clearly.
- img-src: data: URLs fΓΌr Base64-Bilder erlaubt
- Produktions-CSP wird ΓΌber HTTP-Header des Hosts verschΓ€rft (siehe ADR-0004, docs/DEPLOYMENT.md)
-->
<meta http-equiv="Content-Security-Policy"
content="
default-src 'self';
script-src 'self' 'wasm-unsafe-eval';
style-src 'self' 'unsafe-inline';
font-src 'self' data:;
img-src 'self' data: blob:;
connect-src 'self' https://generativelanguage.googleapis.com https://api.openai.com https://api.x.ai https://api.anthropic.com https://openrouter.ai https://api.openrouter.ai https://api.groq.com https://huggingface.co https://us.aws.cdn.hf.co https://api.languagetool.org http://localhost:11434 http://127.0.0.1:11434 http://localhost:1234 http://127.0.0.1:1234 http://localhost:8000 http://127.0.0.1:8000 http://localhost:8010 http://127.0.0.1:8010 wss://y-webrtc-signaling.fly.dev wss://signaling.yjs.dev;
worker-src 'self' blob:;
frame-src 'self' blob:;
manifest-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
" />
<!-- QNBS-v3: CJK/Greek self-hosted via @fontsource in index.tsx (no external font CDN) β "Noto Sans GR" doesn't exist at Google Fonts and 400'd the combined request, silently dropping JP/KR too. -->
<title>WorldScript Studio</title>
</head>
<body>
<!-- QNBS-v3: Aurora low-end-hardware disable moved to index.tsx (ADR-0013) β an inline
script element here would need the unsafe-inline keyword or a hash in script-src; a
same-origin module keeps script-src minimal. -->
<div class="noise-overlay"></div>
<div class="aurora-container">
<div class="aurora-blob blob-1"></div>
<div class="aurora-blob blob-2"></div>
<div class="aurora-blob blob-3"></div>
</div>
<div id="root"></div>
<script type="module" src="/index.tsx"></script>
</body>
</html>