create-vidra-app 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-vidra-app",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Scaffold a new Vidra application (React + .NET MAUI)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -181,58 +181,87 @@ const App = () => {
181
181
  windowSupport.setFullscreen);
182
182
 
183
183
  return (
184
- <div className="container">
185
- <h1>{{appTitle}}</h1>
186
- <p className="subtitle">React + .NET MAUI</p>
187
-
188
- <div className="card">
189
- <p className="counter">
190
- Counter: <strong>{count}</strong>
191
- <span className="counter-hint">Incremented by .NET every 10s</span>
192
- </p>
193
- </div>
194
-
195
- <div className="card">
196
- <p className="result">{info}</p>
197
-
198
- <div className="actions">
199
- <button onClick={handleGetAppInfo}>Get App Info</button>
200
- <button onClick={handleReadClipboard}>Read Clipboard</button>
201
- <button onClick={handleNotification}>Send Notification</button>
202
- <button onClick={handleCapabilities}>List Capabilities</button>
203
- </div>
204
-
205
- {caps && (
206
- <pre className="capabilities">{JSON.stringify(caps, null, 2)}</pre>
207
- )}
208
- </div>
209
-
210
- <div className="card">
211
- <p className="window-summary">{windowSummary}</p>
212
-
213
- <div className="actions">
214
- <button onClick={handleGetWindowInfo}>Get Window Info</button>
215
- <button onClick={handleRenameWindow}>Rename Window</button>
216
- <button onClick={handleResizeWindow}>Resize Window</button>
217
- {windowSupport?.center && <button onClick={handleCenterWindow}>Center Window</button>}
218
- {windowSupport?.maximize && (
219
- <>
220
- <button onClick={handleMaximizeWindow}>Maximize Window</button>
221
- <button onClick={handleRestoreWindow}>Restore Window</button>
222
- </>
184
+ <div className="app">
185
+ <main className="container">
186
+ <header className="hero">
187
+ <span className="badge">
188
+ <span className="dot" />
189
+ React + .NET MAUI
190
+ </span>
191
+ <h1 className="title">{{appTitle}}</h1>
192
+ <p className="tagline">
193
+ A cross-platform desktop app with a native bridge.
194
+ </p>
195
+ </header>
196
+
197
+ <section className="card counter-card">
198
+ <div className="counter-meta">
199
+ <span className="counter-label">Live counter</span>
200
+ <span className="counter-sub">Incremented by .NET every 10s</span>
201
+ </div>
202
+ <span className="counter-value">{count}</span>
203
+ </section>
204
+
205
+ <section className="card">
206
+ <h2 className="card-title">Native modules</h2>
207
+
208
+ <div className="actions">
209
+ <button onClick={handleGetAppInfo}>Get App Info</button>
210
+ <button onClick={handleReadClipboard}>Read Clipboard</button>
211
+ <button onClick={handleNotification}>Send Notification</button>
212
+ <button onClick={handleCapabilities}>List Capabilities</button>
213
+ </div>
214
+
215
+ <p className="result">{info}</p>
216
+
217
+ {caps && (
218
+ <pre className="capabilities">{JSON.stringify(caps, null, 2)}</pre>
223
219
  )}
224
- {windowSupport?.minimize && (
225
- <button onClick={handleMinimizeWindow}>Minimize Window</button>
220
+ </section>
221
+
222
+ <section className="card">
223
+ <h2 className="card-title">Window controls</h2>
224
+
225
+ <div className="actions">
226
+ <button onClick={handleGetWindowInfo}>Get Window Info</button>
227
+ <button onClick={handleRenameWindow}>Rename Window</button>
228
+ <button onClick={handleResizeWindow}>Resize Window</button>
229
+ {windowSupport?.center && (
230
+ <button onClick={handleCenterWindow}>Center Window</button>
231
+ )}
232
+ {windowSupport?.maximize && (
233
+ <>
234
+ <button onClick={handleMaximizeWindow}>Maximize Window</button>
235
+ <button onClick={handleRestoreWindow}>Restore Window</button>
236
+ </>
237
+ )}
238
+ {windowSupport?.minimize && (
239
+ <button onClick={handleMinimizeWindow}>Minimize Window</button>
240
+ )}
241
+ </div>
242
+
243
+ <p className="window-summary">{windowSummary}</p>
244
+
245
+ {!showsAdvancedWindowActions && windowSupport && (
246
+ <p className="note">
247
+ This runtime currently supports title and size updates only.
248
+ Unsupported window actions are hidden automatically based on native
249
+ support metadata.
250
+ </p>
226
251
  )}
227
- </div>
252
+ </section>
228
253
 
229
- {!showsAdvancedWindowActions && windowSupport && (
230
- <p className="result">
231
- This runtime currently supports title and size updates only. Unsupported window actions
232
- are hidden automatically based on native support metadata.
233
- </p>
234
- )}
235
- </div>
254
+ <footer className="footer">
255
+ Built with{" "}
256
+ <a
257
+ href="https://github.com/rzamfiriu/vidra"
258
+ target="_blank"
259
+ rel="noreferrer"
260
+ >
261
+ Vidra
262
+ </a>
263
+ </footer>
264
+ </main>
236
265
  </div>
237
266
  );
238
267
  };
@@ -7,103 +7,338 @@
7
7
  }
8
8
 
9
9
  :root {
10
- --bg: #0f0f12;
11
- --surface: #1a1a22;
12
- --border: #2a2a35;
13
- --text: #e4e4e8;
14
- --text-muted: #8888a0;
15
- --accent: #6366f1;
16
- --accent-hover: #818cf8;
17
- --radius: 12px;
10
+ color-scheme: dark;
11
+
12
+ --bg: #0a0a0c;
13
+ --bg-elev: rgba(255, 255, 255, 0.04);
14
+ --fill: rgba(255, 255, 255, 0.045);
15
+ --fill-2: rgba(255, 255, 255, 0.06);
16
+ --border: rgba(255, 255, 255, 0.09);
17
+ --border-strong: rgba(255, 255, 255, 0.16);
18
+
19
+ --text: #f4f4f6;
20
+ --text-muted: #9a9aa6;
21
+ --title-fade: rgba(244, 244, 246, 0.55);
22
+
23
+ --accent: #c8f751;
24
+ --accent-soft: rgba(200, 247, 81, 0.14);
25
+ --accent-border: rgba(200, 247, 81, 0.5);
26
+ --dot-glow: rgba(200, 247, 81, 0.25);
27
+ --ring: rgba(200, 247, 81, 0.4);
28
+
29
+ --glow-1: rgba(200, 247, 81, 0.12);
30
+ --glow-2: rgba(255, 168, 120, 0.07);
31
+ --shadow: 0 24px 60px -24px rgba(0, 0, 0, 0.75);
32
+
33
+ --radius: 16px;
34
+ --radius-sm: 10px;
35
+ --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter,
36
+ system-ui, sans-serif;
37
+ --font-mono: "SF Mono", ui-monospace, SFMono-Regular, "JetBrains Mono",
38
+ "Cascadia Code", Menlo, Consolas, monospace;
18
39
  }
19
40
 
41
+ @media (prefers-color-scheme: light) {
42
+ :root {
43
+ color-scheme: light;
44
+
45
+ --bg: #f7f7f5;
46
+ --bg-elev: rgba(255, 255, 255, 0.7);
47
+ --fill: rgba(0, 0, 0, 0.035);
48
+ --fill-2: rgba(0, 0, 0, 0.05);
49
+ --border: rgba(0, 0, 0, 0.1);
50
+ --border-strong: rgba(0, 0, 0, 0.18);
51
+
52
+ --text: #15151a;
53
+ --text-muted: #5f5f6b;
54
+ --title-fade: rgba(21, 21, 26, 0.5);
55
+
56
+ --accent: #5b9d00;
57
+ --accent-soft: rgba(91, 157, 0, 0.12);
58
+ --accent-border: rgba(91, 157, 0, 0.55);
59
+ --dot-glow: rgba(91, 157, 0, 0.22);
60
+ --ring: rgba(91, 157, 0, 0.35);
61
+
62
+ --glow-1: rgba(91, 157, 0, 0.1);
63
+ --glow-2: rgba(255, 150, 90, 0.08);
64
+ --shadow: 0 24px 50px -28px rgba(0, 0, 0, 0.3);
65
+ }
66
+ }
67
+
68
+ html,
20
69
  body {
21
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
70
+ height: 100%;
22
71
  background: var(--bg);
72
+ }
73
+
74
+ body {
75
+ font-family: var(--font-sans);
23
76
  color: var(--text);
24
77
  min-height: 100dvh;
25
78
  display: flex;
26
- align-items: center;
79
+ justify-content: center;
80
+ line-height: 1.5;
81
+ -webkit-font-smoothing: antialiased;
82
+ text-rendering: optimizeLegibility;
83
+ }
84
+
85
+ /* Ambient background glows for depth. */
86
+ body::before {
87
+ content: "";
88
+ position: fixed;
89
+ inset: 0;
90
+ z-index: 0;
91
+ pointer-events: none;
92
+ background:
93
+ radial-gradient(60% 50% at 22% -5%, var(--glow-1), transparent 60%),
94
+ radial-gradient(50% 45% at 92% 0%, var(--glow-2), transparent 55%);
95
+ }
96
+
97
+ .app {
98
+ position: relative;
99
+ z-index: 1;
100
+ width: 100%;
101
+ display: flex;
27
102
  justify-content: center;
28
103
  }
29
104
 
30
105
  .container {
31
- max-width: 760px;
32
106
  width: 100%;
33
- padding: 2rem;
107
+ max-width: 720px;
108
+ padding: clamp(1.5rem, 3vw, 3.5rem) 1.5rem 3rem;
109
+ animation: rise 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) both;
110
+ }
111
+
112
+ @keyframes rise {
113
+ from {
114
+ opacity: 0;
115
+ transform: translateY(10px);
116
+ }
117
+ }
118
+
119
+ /* Hero -------------------------------------------------------------------- */
120
+
121
+ .hero {
34
122
  text-align: center;
123
+ margin-bottom: 2rem;
124
+ }
125
+
126
+ .badge {
127
+ display: inline-flex;
128
+ align-items: center;
129
+ gap: 0.5rem;
130
+ padding: 0.35rem 0.85rem;
131
+ font-size: 0.8rem;
132
+ font-weight: 500;
133
+ color: var(--text-muted);
134
+ background: var(--bg-elev);
135
+ border: 1px solid var(--border);
136
+ border-radius: 999px;
137
+ -webkit-backdrop-filter: blur(8px);
138
+ backdrop-filter: blur(8px);
139
+ }
140
+
141
+ .badge .dot {
142
+ width: 7px;
143
+ height: 7px;
144
+ border-radius: 50%;
145
+ background: var(--accent);
146
+ box-shadow: 0 0 0 3px var(--dot-glow);
35
147
  }
36
148
 
37
- h1 {
38
- font-size: 2.5rem;
149
+ .title {
150
+ margin-top: 1.1rem;
151
+ font-size: clamp(2.4rem, 6vw, 3.4rem);
39
152
  font-weight: 700;
40
- letter-spacing: -0.02em;
153
+ letter-spacing: -0.035em;
154
+ line-height: 1.02;
155
+ color: var(--text);
156
+ background: linear-gradient(180deg, var(--text), var(--title-fade));
157
+ -webkit-background-clip: text;
158
+ background-clip: text;
159
+ -webkit-text-fill-color: transparent;
41
160
  }
42
161
 
43
- .subtitle {
162
+ .tagline {
163
+ margin-top: 0.8rem;
44
164
  color: var(--text-muted);
45
- margin-top: 0.25rem;
46
- margin-bottom: 2rem;
165
+ font-size: 1rem;
47
166
  }
48
167
 
168
+ /* Cards ------------------------------------------------------------------- */
169
+
49
170
  .card {
50
- background: var(--surface);
171
+ background: var(--bg-elev);
51
172
  border: 1px solid var(--border);
52
173
  border-radius: var(--radius);
53
174
  padding: 1.5rem;
54
175
  margin-top: 1rem;
176
+ -webkit-backdrop-filter: blur(12px);
177
+ backdrop-filter: blur(12px);
178
+ box-shadow: var(--shadow);
179
+ transition: border-color 0.2s ease;
55
180
  }
56
181
 
57
- .result {
58
- min-height: 2rem;
59
- margin-bottom: 1.25rem;
60
- font-size: 0.95rem;
182
+ .card:hover {
183
+ border-color: var(--border-strong);
184
+ }
185
+
186
+ .card-title {
187
+ font-size: 0.76rem;
188
+ font-weight: 600;
189
+ text-transform: uppercase;
190
+ letter-spacing: 0.09em;
61
191
  color: var(--text-muted);
62
- word-break: break-word;
192
+ margin-bottom: 1.1rem;
63
193
  }
64
194
 
65
- .window-summary {
66
- min-height: 2rem;
67
- margin-bottom: 1.25rem;
68
- font-size: 0.95rem;
195
+ /* Counter ----------------------------------------------------------------- */
196
+
197
+ .counter-card {
198
+ display: flex;
199
+ align-items: center;
200
+ justify-content: space-between;
201
+ gap: 1rem;
202
+ }
203
+
204
+ .counter-meta {
205
+ display: flex;
206
+ flex-direction: column;
207
+ gap: 0.25rem;
208
+ }
209
+
210
+ .counter-label {
211
+ font-size: 0.76rem;
212
+ font-weight: 600;
213
+ text-transform: uppercase;
214
+ letter-spacing: 0.09em;
215
+ color: var(--text-muted);
216
+ }
217
+
218
+ .counter-sub {
219
+ font-size: 0.88rem;
69
220
  color: var(--text-muted);
70
- word-break: break-word;
71
221
  }
72
222
 
223
+ .counter-value {
224
+ font-family: var(--font-mono);
225
+ font-size: clamp(2.6rem, 9vw, 3.6rem);
226
+ font-weight: 700;
227
+ line-height: 1;
228
+ letter-spacing: -0.02em;
229
+ color: var(--accent);
230
+ font-variant-numeric: tabular-nums;
231
+ }
232
+
233
+ /* Actions ----------------------------------------------------------------- */
234
+
73
235
  .actions {
74
236
  display: flex;
75
237
  flex-wrap: wrap;
76
- gap: 0.5rem;
77
- justify-content: center;
238
+ gap: 0.55rem;
78
239
  }
79
240
 
80
241
  button {
81
- background: var(--accent);
82
- color: white;
83
- border: none;
84
- border-radius: 8px;
85
- padding: 0.6rem 1.2rem;
86
- font-size: 0.9rem;
242
+ font-family: inherit;
243
+ font-size: 0.875rem;
87
244
  font-weight: 500;
245
+ color: var(--text);
246
+ background: var(--fill-2);
247
+ border: 1px solid var(--border);
248
+ border-radius: var(--radius-sm);
249
+ padding: 0.55rem 0.95rem;
88
250
  cursor: pointer;
89
- transition: background 0.15s;
251
+ transition:
252
+ background 0.15s ease,
253
+ border-color 0.15s ease,
254
+ transform 0.1s ease;
90
255
  }
91
256
 
92
257
  button:hover {
93
- background: var(--accent-hover);
258
+ background: var(--accent-soft);
259
+ border-color: var(--accent-border);
94
260
  }
95
261
 
96
262
  button:active {
97
- transform: scale(0.97);
263
+ transform: translateY(1px);
264
+ }
265
+
266
+ button:focus-visible {
267
+ outline: none;
268
+ border-color: var(--accent);
269
+ box-shadow: 0 0 0 3px var(--ring);
270
+ }
271
+
272
+ /* Status + output --------------------------------------------------------- */
273
+
274
+ .result,
275
+ .window-summary {
276
+ margin-top: 1.1rem;
277
+ padding: 0.8rem 0.95rem;
278
+ font-family: var(--font-mono);
279
+ font-size: 0.82rem;
280
+ line-height: 1.5;
281
+ color: var(--text-muted);
282
+ background: var(--fill);
283
+ border: 1px solid var(--border);
284
+ border-radius: var(--radius-sm);
285
+ word-break: break-word;
98
286
  }
99
287
 
100
288
  .capabilities {
101
- margin-top: 1rem;
289
+ margin-top: 0.85rem;
102
290
  text-align: left;
103
- font-size: 0.8rem;
104
- color: var(--text-muted);
105
- background: var(--bg);
106
- border-radius: 8px;
291
+ font-family: var(--font-mono);
292
+ font-size: 0.78rem;
293
+ line-height: 1.5;
294
+ color: var(--text);
295
+ background: var(--fill-2);
296
+ border: 1px solid var(--border);
297
+ border-radius: var(--radius-sm);
107
298
  padding: 1rem;
108
299
  overflow-x: auto;
109
300
  }
301
+
302
+ .capabilities::-webkit-scrollbar {
303
+ height: 8px;
304
+ }
305
+
306
+ .capabilities::-webkit-scrollbar-thumb {
307
+ background: var(--border-strong);
308
+ border-radius: 999px;
309
+ }
310
+
311
+ .note {
312
+ margin-top: 1rem;
313
+ font-size: 0.85rem;
314
+ color: var(--text-muted);
315
+ }
316
+
317
+ /* Footer ------------------------------------------------------------------ */
318
+
319
+ .footer {
320
+ margin-top: 2rem;
321
+ text-align: center;
322
+ font-size: 0.82rem;
323
+ color: var(--text-muted);
324
+ }
325
+
326
+ .footer a {
327
+ color: var(--text);
328
+ text-decoration: none;
329
+ border-bottom: 1px solid var(--border-strong);
330
+ transition: border-color 0.15s ease;
331
+ }
332
+
333
+ .footer a:hover {
334
+ border-bottom-color: var(--accent);
335
+ }
336
+
337
+ @media (prefers-reduced-motion: reduce) {
338
+ *,
339
+ *::before,
340
+ *::after {
341
+ animation: none !important;
342
+ transition: none !important;
343
+ }
344
+ }