randomvisitor commited on
Commit
34648ae
Β·
verified Β·
1 Parent(s): c9dad1d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +250 -279
app.py CHANGED
@@ -1,291 +1,262 @@
1
- <!DOCTYPE html>
2
- <html class="dark" lang="en">
3
- <head>
4
- <meta charset="utf-8"/>
5
- <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
6
- <title>COSMIC SCALE - Grounding App</title>
7
- <script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
8
- <link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;600;700;800;900&display=swap" rel="stylesheet"/>
9
- <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
10
- <script id="tailwind-config">
11
- tailwind.config = {
12
- darkMode: "class",
13
- theme: {
14
- extend: {
15
- colors: {
16
- "on-primary-fixed": "#00174b",
17
- "on-surface-variant": "#c3c6d7",
18
- "surface-container-low": "#1c1b1b",
19
- "on-primary": "#002a77",
20
- "surface-variant": "#353534",
21
- "surface-elevation-1": "#141414",
22
- "outline-variant": "#434654",
23
- "on-surface": "#e5e2e1",
24
- "surface": "#131313",
25
- "secondary-container": "#454747",
26
- "error-container": "#93000a",
27
- "surface-bright": "#3a3939",
28
- "border-subtle": "#2D2D2D",
29
- "surface-tint": "#b4c5ff",
30
- "surface-container-highest": "#353534",
31
- "inverse-primary": "#0953d8",
32
- "inverse-on-surface": "#313030",
33
- "surface-container": "#201f1f",
34
- "on-error-container": "#ffdad6",
35
- "on-background": "#e5e2e1",
36
- "secondary": "#c6c6c7",
37
- "tertiary": "#ffb68a",
38
- "surface-container-high": "#2a2a2a",
39
- "inverse-surface": "#e5e2e1",
40
- "surface-dim": "#131313",
41
- "primary-fixed-dim": "#b4c5ff",
42
- "error": "#ffb4ab",
43
- "primary-container": "#618bff",
44
- "outline": "#8d90a0",
45
- "primary-fixed": "#dbe1ff",
46
- "primary": "#b4c5ff",
47
- "tertiary-container": "#e37115",
48
- "background": "#131313",
49
- "on-error": "#690005",
50
- "text-muted": "#A1A1A1",
51
- "on-secondary": "#2f3131",
52
- "surface-elevation-2": "#1F1F1F",
53
- "surface-container-lowest": "#0e0e0e",
54
- "on-primary-container": "#002469",
55
- },
56
- borderRadius: {
57
- DEFAULT: "1rem", lg: "2rem", xl: "3rem", full: "9999px"
58
- },
59
- spacing: {
60
- "margin-mobile": "20px",
61
- "unit": "4px",
62
- "gutter": "24px",
63
- "section-gap": "120px",
64
- "container-max": "1280px",
65
- "margin-desktop": "64px"
66
- },
67
- fontFamily: {
68
- "headline-lg": ["Hanken Grotesk"],
69
- "headline-md": ["Hanken Grotesk"],
70
- "label-sm": ["Hanken Grotesk"],
71
- "body-lg": ["Hanken Grotesk"],
72
- "display-xl": ["Hanken Grotesk"],
73
- "body-md": ["Hanken Grotesk"],
74
- "label-md": ["Hanken Grotesk"]
75
- },
76
- fontSize: {
77
- "headline-lg": ["40px", {lineHeight:"1.2",letterSpacing:"-0.01em",fontWeight:"800"}],
78
- "headline-md": ["28px", {lineHeight:"1.3",fontWeight:"700"}],
79
- "label-sm": ["12px", {lineHeight:"1.1",fontWeight:"700"}],
80
- "body-lg": ["18px", {lineHeight:"1.6",fontWeight:"400"}],
81
- "display-xl": ["64px", {lineHeight:"1.1",letterSpacing:"-0.02em",fontWeight:"900"}],
82
- "body-md": ["16px", {lineHeight:"1.5",fontWeight:"400"}],
83
- "label-md": ["14px", {lineHeight:"1.2",fontWeight:"600"}]
84
  }
85
- }
86
  }
87
- }
88
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  <style>
90
- body {
91
- background-color: #131313;
92
- color: #e5e2e1;
93
- font-family: 'Hanken Grotesk', sans-serif;
 
 
 
94
  -webkit-font-smoothing: antialiased;
95
- min-height: max(884px, 100dvh);
96
  }
97
- .material-symbols-outlined {
98
- font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
 
 
 
 
 
 
 
 
 
 
 
99
  }
100
- .crisp-border { border: 1px solid #2D2D2D; }
101
- .crisp-border:focus-within { border-color: #b4c5ff; }
102
- .scale-card-active { border-color: #b4c5ff !important; background-color: #1a1a1a; }
103
- .fade-in { animation: fadeIn 0.8s ease-out forwards; }
104
- @keyframes fadeIn {
105
- from { opacity: 0; transform: translateY(10px); }
106
- to { opacity: 1; transform: translateY(0); }
 
 
 
107
  }
108
- #realityCheck { transition: opacity 0.7s ease, transform 0.7s ease; }
109
- </style>
110
- </head>
111
- <body class="dark overflow-x-hidden">
112
-
113
- <!-- Header -->
114
- <header class="bg-background fixed top-0 w-full z-50 border-b border-border-subtle flex items-center justify-between px-margin-mobile md:px-margin-desktop h-16">
115
- <div class="flex items-center gap-4">
116
- <span class="material-symbols-outlined text-primary hover:opacity-80 transition-opacity cursor-pointer">menu</span>
117
- <h1 class="font-headline-md text-headline-md font-bold text-on-background tracking-tighter">COSMIC SCALE</h1>
118
- </div>
119
- <div class="flex items-center">
120
- <span class="material-symbols-outlined text-on-surface-variant hover:opacity-80 transition-opacity cursor-pointer">account_circle</span>
121
- </div>
122
- </header>
123
-
124
- <main class="min-h-screen pt-32 pb-40 px-margin-mobile md:px-margin-desktop flex flex-col items-center max-w-container-max mx-auto">
125
-
126
- <!-- Hero -->
127
- <section class="text-center mb-16 fade-in" style="animation-delay:0.1s">
128
- <h2 class="font-display-xl text-[48px] md:text-display-xl mb-4 leading-tight">πŸͺ The Cosmic Scale-Out</h2>
129
- <p class="font-body-lg text-body-lg text-text-muted max-w-2xl mx-auto px-4">
130
- Anxiety grounding for busy minds. Reframe your tiny daily struggles against the grand architecture of time and space.
131
- </p>
132
- </section>
133
-
134
- <!-- Interface -->
135
- <div class="w-full max-w-2xl mx-auto space-y-12">
136
-
137
- <!-- Worry input -->
138
- <div class="space-y-4 fade-in" style="animation-delay:0.2s">
139
- <label class="font-label-md text-label-md uppercase tracking-widest text-primary block">
140
- What are you spiraling about right now?
141
- </label>
142
- <div class="crisp-border bg-surface-container-lowest rounded-lg overflow-hidden transition-all duration-300">
143
- <textarea id="anxietyInput"
144
- class="w-full bg-transparent border-none focus:ring-0 p-6 text-on-surface font-body-lg resize-none min-h-[120px]"
145
- placeholder="e.g., I'm stressed about a presentation or a flight delay..."></textarea>
146
- </div>
147
- </div>
148
-
149
- <!-- Scale selection -->
150
- <div class="space-y-4 fade-in" style="animation-delay:0.3s">
151
- <label class="font-label-md text-label-md uppercase tracking-widest text-primary block">
152
- Choose your cosmic scale factor:
153
- </label>
154
- <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
155
- <button class="scale-card crisp-border bg-surface-container-low p-6 rounded-lg text-left transition-all duration-200 group hover:bg-surface-elevation-1 active:scale-95"
156
- data-scale="A colony of ants living in your wall" onclick="selectScale(this)">
157
- <span class="material-symbols-outlined text-primary mb-4 block group-hover:scale-110 transition-transform">bug_report</span>
158
- <p class="font-label-md text-label-md text-on-surface">A colony of ants living in your wall</p>
159
- </button>
160
- <button class="scale-card crisp-border bg-surface-container-low p-6 rounded-lg text-left transition-all duration-200 group hover:bg-surface-elevation-1 active:scale-95"
161
- data-scale="The 4.5 billion year geological history of the Earth" onclick="selectScale(this)">
162
- <span class="material-symbols-outlined text-primary mb-4 block group-hover:scale-110 transition-transform">public</span>
163
- <p class="font-label-md text-label-md text-on-surface">The 4.5 billion year geological history of the Earth</p>
164
- </button>
165
- <button class="scale-card crisp-border bg-surface-container-low p-6 rounded-lg text-left transition-all duration-200 group hover:bg-surface-elevation-1 active:scale-95"
166
- data-scale="A distant, indifferent supernova dying in another galaxy" onclick="selectScale(this)">
167
- <span class="material-symbols-outlined text-primary mb-4 block group-hover:scale-110 transition-transform">flare</span>
168
- <p class="font-label-md text-label-md text-on-surface">A distant, indifferent supernova dying in another galaxy</p>
169
- </button>
170
- </div>
171
- </div>
172
-
173
- <!-- Submit -->
174
- <div class="flex flex-col items-center pt-4 fade-in" style="animation-delay:0.4s">
175
- <button onclick="handWorryToUniverse()"
176
- class="bg-on-background text-background font-label-md text-label-md px-12 py-5 rounded-full font-bold hover:opacity-90 transition-all active:scale-95 flex items-center gap-3">
177
- <span id="btnLabel">Hand Worry to the Universe</span>
178
- <span class="material-symbols-outlined" id="btnIcon">auto_awesome</span>
179
- </button>
180
- </div>
181
-
182
- <!-- Output -->
183
- <div id="realityCheck" class="hidden opacity-0 translate-y-4">
184
- <div class="crisp-border bg-surface p-8 rounded-lg relative overflow-hidden">
185
- <div class="absolute inset-0 opacity-10 pointer-events-none">
186
- <div class="absolute w-full h-full bg-[radial-gradient(circle_at_center,_#b4c5ff_0%,_transparent_70%)] blur-3xl"></div>
187
- </div>
188
- <div class="relative z-10 text-center">
189
- <h3 class="font-label-md text-label-md uppercase tracking-[0.2em] text-primary mb-6">πŸͺ Reality Check</h3>
190
- <p class="font-headline-md text-headline-md italic leading-relaxed text-on-surface-variant" id="outputMessage"></p>
191
- </div>
192
- </div>
193
- </div>
194
-
195
- </div>
196
- </main>
197
-
198
- <!-- Bottom nav -->
199
- <nav class="bg-background fixed bottom-0 w-full z-50 border-t border-border-subtle flex justify-around items-center h-20 pb-safe px-4">
200
- <div class="flex flex-col items-center justify-center text-text-muted hover:text-primary transition-colors cursor-pointer">
201
- <span class="material-symbols-outlined">self_care</span>
202
- <span class="font-label-sm text-label-sm mt-1">Ground</span>
203
- </div>
204
- <div class="flex flex-col items-center justify-center bg-primary-container text-on-primary-container rounded-full px-4 py-1 active:scale-90 duration-200 cursor-pointer">
205
- <span class="material-symbols-outlined">public</span>
206
- <span class="font-label-sm text-label-sm mt-1">Scale</span>
207
- </div>
208
- <div class="flex flex-col items-center justify-center text-text-muted hover:text-primary transition-colors cursor-pointer">
209
- <span class="material-symbols-outlined">history</span>
210
- <span class="font-label-sm text-label-sm mt-1">History</span>
211
- </div>
212
- <div class="flex flex-col items-center justify-center text-text-muted hover:text-primary transition-colors cursor-pointer">
213
- <span class="material-symbols-outlined">person</span>
214
- <span class="font-label-sm text-label-sm mt-1">Profile</span>
215
- </div>
216
- </nav>
217
-
218
- <script>
219
- let selectedScale = null;
220
-
221
- function selectScale(el) {
222
- document.querySelectorAll('.scale-card').forEach(c => c.classList.remove('scale-card-active'));
223
- el.classList.add('scale-card-active');
224
- selectedScale = el.getAttribute('data-scale');
225
  }
226
 
227
- async function handWorryToUniverse() {
228
- const worry = document.getElementById('anxietyInput').value.trim();
229
- const rc = document.getElementById('realityCheck');
230
- const out = document.getElementById('outputMessage');
231
- const btn = document.getElementById('btnLabel');
232
- const icon = document.getElementById('btnIcon');
233
-
234
- if (!worry) { alert("Please state what's on your mind first."); return; }
235
- if (!selectedScale) { alert("Please choose a cosmic scale factor."); return; }
236
-
237
- // Loading state
238
- btn.textContent = 'Consulting the cosmos…';
239
- icon.textContent = 'sync';
240
- icon.classList.add('animate-spin');
241
- rc.classList.add('hidden', 'opacity-0', 'translate-y-4');
242
-
243
- try {
244
- const SYSTEM_PROMPT =
245
- "You are a wise, slightly witty, and deeply philosophical cosmic guide. " +
246
- "The user will share a minor daily human anxiety. Reframe their problem entirely from the " +
247
- "perspective of their chosen cosmic scale. Keep your response strictly under 4 sentences. " +
248
- "Make it comforting but funny, proving how wonderfully small their problem is in the grand timeline of reality.";
249
-
250
- const formatted =
251
- `<|im_start|>system\n${SYSTEM_PROMPT}<|im_end|>\n` +
252
- `<|im_start|>user\nMy worry is: '${worry}'. Reframe it from this perspective: ${selectedScale}.<|im_end|>\n` +
253
- `<|im_start|>assistant\n`;
254
-
255
- const resp = await fetch(
256
- "https://api-inference.huggingface.co/models/Qwen/Qwen2.5-7B-Instruct",
257
- {
258
- method: "POST",
259
- headers: { "Content-Type": "application/json" },
260
- body: JSON.stringify({
261
- inputs: formatted,
262
- parameters: { max_new_tokens: 200, temperature: 0.7, return_full_text: false }
263
- })
264
- }
265
- );
266
- const data = await resp.json();
267
- let text = "The stars are misaligned. Try pressing the button once more.";
268
- if (Array.isArray(data) && data[0]?.generated_text) {
269
- text = data[0].generated_text.replace(/<\|im_end\|>/g, '').trim();
270
- } else if (data?.error) {
271
- text = `The universe is aligning its vectors: ${data.error}. Give it a moment and try again!`;
272
- }
273
- out.textContent = `"${text}"`;
274
- } catch (e) {
275
- out.textContent = '"The universe is momentarily disconnected. Take a deep breath and try again!"';
276
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
 
278
- // Reset button
279
- btn.textContent = 'Hand Worry to the Universe';
280
- icon.textContent = 'auto_awesome';
281
- icon.classList.remove('animate-spin');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
- // Reveal output
284
- rc.classList.remove('hidden');
285
- requestAnimationFrame(() => {
286
- rc.classList.remove('opacity-0', 'translate-y-4');
287
- });
 
 
 
 
288
  }
289
- </script>
290
- </body>
291
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+
4
+ API_URL = "https://api-inference.huggingface.co/models/Qwen/Qwen2.5-7B-Instruct"
5
+
6
+ SYSTEM_PROMPT = (
7
+ "You are a wise, slightly witty, and deeply philosophical cosmic guide. "
8
+ "The user will share a minor daily human anxiety. Reframe their problem entirely from the "
9
+ "perspective of their chosen cosmic scale. Keep your response strictly under 4 sentences. "
10
+ "Make it comforting but funny, proving how wonderfully small their problem is in the grand timeline of reality."
11
+ )
12
+
13
+ def generate_cosmic_response(worry, scale):
14
+ if not worry.strip():
15
+ return "Please type a worry so the universe can handle it!"
16
+
17
+ formatted_prompt = (
18
+ f"<|im_start|>system\n{SYSTEM_PROMPT}<|im_end|>\n"
19
+ f"<|im_start|>user\nMy worry is: '{worry}'. Reframe it from this perspective: {scale}.<|im_end|>\n"
20
+ f"<|im_start|>assistant\n"
21
+ )
22
+
23
+ payload = {
24
+ "inputs": formatted_prompt,
25
+ "parameters": {
26
+ "max_new_tokens": 200,
27
+ "temperature": 0.7,
28
+ "return_full_text": False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  }
 
30
  }
31
+
32
+ try:
33
+ response = requests.post(API_URL, json=payload, timeout=12)
34
+ output = response.json()
35
+ if isinstance(output, list) and len(output) > 0:
36
+ generated_text = output[0].get('generated_text', '').strip()
37
+ return generated_text.replace("<|im_end|>", "").strip()
38
+ elif isinstance(output, dict) and "error" in output:
39
+ return f"The universe is aligning its vectors: {output['error']}. Give it a brief moment and try again!"
40
+ return "The stars are misaligned. Try pressing the button once more."
41
+ except Exception as e:
42
+ return "The universe is momentarily disconnected. Take a deep breath and try again!"
43
+
44
+
45
+ head = """
46
+ <link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;600;700;800;900&display=swap" rel="stylesheet"/>
47
+ <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
48
  <style>
49
+ /* ── Reset & base ── */
50
+ *, *::before, *::after { box-sizing: border-box; }
51
+
52
+ body, .gradio-container {
53
+ background-color: #131313 !important;
54
+ color: #e5e2e1 !important;
55
+ font-family: 'Hanken Grotesk', sans-serif !important;
56
  -webkit-font-smoothing: antialiased;
 
57
  }
58
+
59
+ /* Hide default Gradio chrome we don't need */
60
+ .gradio-container > .main > .wrap { padding: 0 !important; }
61
+ footer { display: none !important; }
62
+
63
+ /* ── All text visible ── */
64
+ p, span, label, div, h1, h2, h3, h4, h5, h6,
65
+ .prose, .prose p,
66
+ [data-testid="markdown"], [data-testid="markdown"] p {
67
+ color: #e5e2e1 !important;
68
+ font-family: 'Hanken Grotesk', sans-serif !important;
69
+ overflow: visible !important;
70
+ max-height: none !important;
71
  }
72
+
73
+ /* ── Hero title ── */
74
+ .cosmic-title [data-testid="markdown"] p,
75
+ .cosmic-title p {
76
+ font-size: clamp(36px, 6vw, 64px) !important;
77
+ font-weight: 900 !important;
78
+ line-height: 1.1 !important;
79
+ letter-spacing: -0.02em !important;
80
+ color: #e5e2e1 !important;
81
+ text-align: center !important;
82
  }
83
+
84
+ /* ── Subtitle ── */
85
+ .cosmic-subtitle [data-testid="markdown"] p,
86
+ .cosmic-subtitle p {
87
+ font-size: 18px !important;
88
+ font-weight: 400 !important;
89
+ line-height: 1.6 !important;
90
+ color: #A1A1A1 !important;
91
+ text-align: center !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  }
93
 
94
+ /* ── Section labels ── */
95
+ .cosmic-label [data-testid="markdown"] p,
96
+ .cosmic-label p {
97
+ font-size: 14px !important;
98
+ font-weight: 700 !important;
99
+ letter-spacing: 0.15em !important;
100
+ text-transform: uppercase !important;
101
+ color: #b4c5ff !important;
102
+ }
103
+
104
+ /* ── Textbox ── */
105
+ .gradio-container textarea {
106
+ background-color: #0e0e0e !important;
107
+ color: #e5e2e1 !important;
108
+ border: 1px solid #2D2D2D !important;
109
+ border-radius: 12px !important;
110
+ font-family: 'Hanken Grotesk', sans-serif !important;
111
+ font-size: 18px !important;
112
+ padding: 20px 24px !important;
113
+ }
114
+ .gradio-container textarea:focus {
115
+ border-color: #b4c5ff !important;
116
+ outline: none !important;
117
+ box-shadow: none !important;
118
+ }
119
+ .gradio-container .label-wrap { display: none !important; }
120
+
121
+ /* ── Radio cards ── */
122
+ .gradio-container .wrap.svelte-1p9xokt,
123
+ .gradio-container fieldset { border: none !important; background: transparent !important; }
124
+
125
+ /* Style each radio item as a card */
126
+ .gradio-container .block.svelte-1p9xokt label,
127
+ .gradio-container .wrap label,
128
+ .gradio-container input[type="radio"] + span {
129
+ background-color: #1c1b1b !important;
130
+ border: 1px solid #2D2D2D !important;
131
+ border-radius: 12px !important;
132
+ padding: 20px !important;
133
+ color: #e5e2e1 !important;
134
+ font-size: 14px !important;
135
+ font-weight: 600 !important;
136
+ transition: border-color 0.2s, background-color 0.2s !important;
137
+ cursor: pointer !important;
138
+ }
139
+ .gradio-container input[type="radio"]:checked + span,
140
+ .gradio-container .selected label {
141
+ border-color: #b4c5ff !important;
142
+ background-color: #1a1a1a !important;
143
+ }
144
+
145
+ /* ── Primary button ── */
146
+ .gradio-container button.primary,
147
+ #component-submit button {
148
+ background: #e5e2e1 !important;
149
+ color: #131313 !important;
150
+ font-family: 'Hanken Grotesk', sans-serif !important;
151
+ font-size: 14px !important;
152
+ font-weight: 700 !important;
153
+ letter-spacing: 0.02em !important;
154
+ border: none !important;
155
+ border-radius: 9999px !important;
156
+ padding: 16px 48px !important;
157
+ cursor: pointer !important;
158
+ transition: opacity 0.2s !important;
159
+ }
160
+ .gradio-container button.primary:hover { opacity: 0.88 !important; }
161
 
162
+ /* ── Output card ── */
163
+ #reality-check-box {
164
+ background-color: #131313 !important;
165
+ border: 1px solid #2D2D2D !important;
166
+ border-radius: 12px !important;
167
+ padding: 32px !important;
168
+ position: relative !important;
169
+ overflow: hidden !important;
170
+ }
171
+ #reality-check-box::before {
172
+ content: '';
173
+ position: absolute;
174
+ inset: 0;
175
+ background: radial-gradient(circle at center, rgba(180,197,255,0.08) 0%, transparent 70%);
176
+ pointer-events: none;
177
+ }
178
+ #reality-check-box [data-testid="markdown"] p,
179
+ #reality-check-box p {
180
+ font-size: 24px !important;
181
+ font-weight: 700 !important;
182
+ line-height: 1.3 !important;
183
+ color: #c3c6d7 !important;
184
+ font-style: italic !important;
185
+ text-align: center !important;
186
+ }
187
 
188
+ /* ── Reality Check label above output ── */
189
+ .reality-label [data-testid="markdown"] p,
190
+ .reality-label p {
191
+ font-size: 12px !important;
192
+ font-weight: 700 !important;
193
+ letter-spacing: 0.2em !important;
194
+ text-transform: uppercase !important;
195
+ color: #b4c5ff !important;
196
+ text-align: center !important;
197
  }
198
+ </style>
199
+ """
200
+
201
+ SCALES = [
202
+ "A colony of ants living in your wall",
203
+ "The 4.5 billion year geological history of the Earth",
204
+ "A distant, indifferent supernova dying in another galaxy",
205
+ ]
206
+
207
+ with gr.Blocks(theme=gr.themes.Base(), head=head, css="") as demo:
208
+
209
+ # ── Hero ──
210
+ with gr.Column(elem_classes=["cosmic-title"]):
211
+ gr.Markdown("# πŸͺ The Cosmic Scale-Out")
212
+ with gr.Column(elem_classes=["cosmic-subtitle"]):
213
+ gr.Markdown(
214
+ "Anxiety grounding for busy minds. "
215
+ "Reframe your tiny daily struggles against the grand architecture of time and space."
216
+ )
217
+
218
+ gr.HTML("<div style='height:32px'></div>")
219
+
220
+ with gr.Column():
221
+ # Worry input
222
+ with gr.Column(elem_classes=["cosmic-label"]):
223
+ gr.Markdown("What are you spiraling about right now?")
224
+ worry_input = gr.Textbox(
225
+ placeholder="e.g., I'm stressed about a presentation or a flight delay...",
226
+ lines=4,
227
+ show_label=False,
228
+ )
229
+
230
+ gr.HTML("<div style='height:16px'></div>")
231
+
232
+ # Scale selector
233
+ with gr.Column(elem_classes=["cosmic-label"]):
234
+ gr.Markdown("Choose your cosmic scale factor:")
235
+ perspective_input = gr.Radio(
236
+ choices=SCALES,
237
+ value=SCALES[0],
238
+ show_label=False,
239
+ )
240
+
241
+ gr.HTML("<div style='height:8px'></div>")
242
+
243
+ # Submit β€” centred
244
+ with gr.Row():
245
+ gr.HTML("<div style='flex:1'></div>")
246
+ submit_btn = gr.Button("Hand Worry to the Universe ✨", variant="primary", elem_id="component-submit")
247
+ gr.HTML("<div style='flex:1'></div>")
248
+
249
+ gr.HTML("<div style='height:24px'></div>")
250
+
251
+ # Output
252
+ with gr.Column(elem_classes=["reality-label"]):
253
+ gr.Markdown("πŸͺ Reality Check")
254
+ output_text = gr.Markdown(elem_id="reality-check-box")
255
+
256
+ submit_btn.click(
257
+ fn=generate_cosmic_response,
258
+ inputs=[worry_input, perspective_input],
259
+ outputs=output_text,
260
+ )
261
+
262
+ demo.launch()