janela 0.14.3 → 0.15.0

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/README.md CHANGED
@@ -1,3 +1,8 @@
1
+ <picture>
2
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/mmamedel/janela/main/packages/janela/brand/janela-mark-dark.svg">
3
+ <img src="https://raw.githubusercontent.com/mmamedel/janela/main/packages/janela/brand/janela-mark-light.svg" alt="" width="88" align="right">
4
+ </picture>
5
+
1
6
  # janela
2
7
 
3
8
  > *janela* — Portuguese for **window**.
@@ -6,9 +11,9 @@ Desktop and mobile apps in pure TypeScript, compiled to native. No Rust, no
6
11
  Node, no Electron. The backend is TypeScript compiled to a native binary by
7
12
  [scriptc](https://scriptc.dev); the window is the OS webview via
8
13
  [webview/webview](https://github.com/webview/webview). A desktop binary comes
9
- out around 225–420 KB — 225 KB for the smallest template — with no bundled
14
+ out around 240–420 KB — 241 KB for the smallest template — with no bundled
10
15
  browser and no bundled runtime; iOS and Android bundles land around
11
- 228–421 KB. Those are the *starter's* figures, and about 35 KB of each is the
16
+ 244–421 KB. Those are the *starter's* figures, and about 35 KB of each is the
12
17
  native file dialog and worker-thread reader it demonstrates: delete the "Files
13
18
  and the window" card and its two commands and the smallest binary is 212 KB. Per-template figures are in
14
19
  [docs/frontend.md](../../docs/frontend.md).
@@ -31,7 +36,11 @@ desktop-only for now; on mobile they report clearly when called.
31
36
  ## Quick start
32
37
 
33
38
  ```bash
34
- npm install -g janela # or: npx janela init my-app
39
+ pnpm create janela # the front door: prompts, scaffolds, installs
40
+ # (npm create janela@latest / yarn / bun also work)
41
+
42
+ # or drive the CLI yourself:
43
+ npm install -g janela
35
44
  janela --version # which janela you actually have
36
45
  janela init my-app # (or `jn init my-app`)
37
46
  cd my-app
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "janela",
3
- "version": "0.14.3",
3
+ "version": "0.15.0",
4
4
  "description": "Desktop, iOS and Android apps in pure TypeScript, compiled to native. No Rust, no Node, no Electron.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -7,9 +7,7 @@
7
7
  <style>
8
8
  /* Everything here is yours to replace. It is deliberately one file with
9
9
  no dependencies: this template has no bundler, so what you see is what
10
- runs. The mark below is drawn in CSS rather than shipped as an image —
11
- a janela frontend is embedded in the binary, so every asset has to be
12
- inlined anyway, and a window needs no artwork. */
10
+ runs. */
13
11
  :root {
14
12
  color-scheme: light dark;
15
13
  --bg: #f6f6f7;
@@ -17,7 +15,7 @@
17
15
  --text: #18181b;
18
16
  --muted: #71717a;
19
17
  --line: #e4e4e7;
20
- --accent: #2563eb;
18
+ --accent: #1c6fd4;
21
19
  --accent-soft: #eff4ff;
22
20
  --shadow: 0 1px 2px rgb(0 0 0 / 0.04), 0 8px 24px -12px rgb(0 0 0 / 0.12);
23
21
  }
@@ -28,7 +26,7 @@
28
26
  --text: #fafafa;
29
27
  --muted: #a1a1aa;
30
28
  --line: #2e2e34;
31
- --accent: #60a5fa;
29
+ --accent: #58a6ff;
32
30
  --accent-soft: #1d2433;
33
31
  --shadow: 0 1px 2px rgb(0 0 0 / 0.3), 0 8px 24px -12px rgb(0 0 0 / 0.5);
34
32
  }
@@ -49,18 +47,14 @@
49
47
 
50
48
  /* --- header ------------------------------------------------------- */
51
49
  header { text-align: center; margin-bottom: 20px; }
52
- .mark {
53
- width: 56px; height: 44px; margin: 0 auto 14px;
54
- border: 2px solid var(--text); border-radius: 8px;
55
- display: flex; flex-direction: column; overflow: hidden;
56
- }
57
- .mark .bar {
58
- height: 13px; flex: none;
59
- border-bottom: 2px solid var(--text);
60
- display: flex; align-items: center; gap: 3px; padding: 0 4px;
61
- }
62
- .mark .bar i { width: 3px; height: 3px; border-radius: 50%; background: var(--text); }
63
- .mark .pane { flex: 1; background: linear-gradient(135deg, var(--accent), transparent 70%); opacity: 0.85; }
50
+ /* The mark: a round window, which is what janela means. Inlined rather
51
+ than linked, because a janela frontend is embedded in the binary and
52
+ every asset has to be inlined anyway — and inline rather than a CSS
53
+ data URI so ONE copy serves both themes: the frame follows the text
54
+ colour, the glass follows the accent. Percent-encoding a data URI
55
+ would also have cost 4x the bytes. Delete it and the header still
56
+ works. */
57
+ .mark { display: block; width: 56px; height: 56px; margin: 0 auto 14px; }
64
58
  h1 { margin: 0; font-size: 26px; letter-spacing: -0.02em; font-weight: 650; }
65
59
  .sub { margin: 5px 0 0; color: var(--muted); font-size: 13.5px; }
66
60
 
@@ -145,10 +139,7 @@
145
139
  <body>
146
140
  <main>
147
141
  <header>
148
- <div class="mark" aria-hidden="true">
149
- <div class="bar"><i></i><i></i><i></i></div>
150
- <div class="pane"></div>
151
- </div>
142
+ <svg class="mark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 970.64 970.64" role="img" aria-label="janela"><path fill="currentColor" d="M970.64,485.32c0,268.03-217.28,485.32-485.32,485.32S0,753.35,0,485.32,217.28,0,485.32,0s485.32,217.28,485.32,485.32ZM938.11,485.34c0-250.08-202.73-452.8-452.8-452.8S32.51,235.26,32.51,485.34s202.73,452.8,452.8,452.8,452.8-202.73,452.8-452.8Z"/><path fill="currentColor" d="M892.79,485.25c0,225.05-182.44,407.49-407.49,407.49S77.82,710.3,77.82,485.25,260.26,77.77,485.31,77.77s407.49,182.44,407.49,407.49ZM470.27,112.09v335.5c0,1.05,13.11,12.99,15.36,14.43,1.65-2.06,14.64-13.4,14.64-14.43V112.59c0-1.1-2.44-1.43-3.45-1.55-8.42-.99-18.1.83-26.55,1.05ZM858.27,438.09c-20.14-166.94-158.46-303.59-325-324v324h325ZM437.27,115.09c-21.65,1.62-44.22,7.07-65,13.5-137.62,42.61-242.41,165.92-260,309.5h325V115.09ZM109.27,500.09h338.5c1,0,12.36-12.44,13.54-14.5,0-1-12.54-14.5-13.54-14.5H109.27c-1.81,9.94-.24,19.09,0,29ZM861.27,471.09h-338.5c-1,0-13.53,13.5-13.54,14.5.52,2.76,3.61,3.57,5.57,5.47,1.64,1.59,7.37,9.03,7.97,9.03h338.5c.9-9.78.9-19.22,0-29ZM500.27,860.09v-336.5c0-1.03-12.98-12.37-14.64-14.43-2.26,1.44-15.36,13.37-15.36,14.43v336.5h30ZM437.27,533.09H112.27c19.95,166.03,159.46,303.1,325,323v-323ZM858.27,533.09h-325v324c165.97-22.51,304.48-156.63,325-324Z"/><path fill="var(--accent)" d="M858.27,438.09h-325V114.09c166.54,20.41,304.86,157.06,325,324Z"/><path fill="var(--accent)" d="M858.27,533.09c-20.52,167.37-159.03,301.49-325,324v-324h325Z"/><path fill="var(--accent)" d="M437.27,533.09v323c-165.54-19.9-305.05-156.97-325-323h325Z"/><path fill="var(--accent)" d="M437.27,115.09v323H112.27c17.6-143.57,122.38-266.89,260-309.5,20.78-6.43,43.34-11.88,65-13.5ZM324.93,239.42c-5.22-5.22-14.48-5.8-20.62-1.79-23.51,27.2-56.28,50.77-79.07,77.93-3.21,3.83-6.62,7.81-7,13.05-.97,13.35,13.8,21.88,24.98,14.93,28.09-28.84,58.16-56.14,84.78-86.22,2.71-5.58,1.25-13.58-3.07-17.9ZM375.06,280.3c-4.15.41-7.65,2.76-10.8,5.27-2.42,1.93-17.06,17.64-18.19,19.81-7.64,14.76,7.17,29.85,21.55,22.56,2.83-1.44,19.3-18.18,21.64-21.36,8.21-11.17-.52-27.62-14.2-26.28ZM310.03,344.3c-2.88.42-6.45,2.49-8.78,4.26-4.52,3.45-32.55,31.28-34.83,35.17-8.84,15.07,8.47,31.23,23.59,21.59,4.35-2.77,34.16-32.7,36.28-36.72,6.36-12.04-2.95-26.26-16.27-24.31Z"/><path fill="var(--card)" d="M500.27,860.09h-30v-336.5c0-1.05,13.11-12.99,15.36-14.43,1.65,2.06,14.64,13.4,14.64,14.43v336.5Z"/><path fill="var(--card)" d="M470.27,112.09c8.45-.22,18.13-2.04,26.55-1.05,1.01.12,3.45.46,3.45,1.55v335c0,1.03-12.98,12.37-14.64,14.43-2.26-1.44-15.36-13.37-15.36-14.43V112.09Z"/><path fill="var(--card)" d="M109.27,500.09c-.24-9.91-1.81-19.06,0-29h338.5c1,0,13.54,13.5,13.54,14.5-1.17,2.06-12.54,14.5-13.54,14.5H109.27Z"/><path fill="var(--card)" d="M861.27,471.09c.9,9.78.9,19.22,0,29h-338.5c-.6,0-6.34-7.44-7.97-9.03-1.96-1.9-5.04-2.72-5.57-5.47,0-1,12.54-14.5,13.54-14.5h338.5Z"/><path fill="currentColor" d="M324.93,239.42c4.32,4.32,5.78,12.32,3.07,17.9-26.62,30.07-56.7,57.37-84.78,86.22-11.18,6.94-25.95-1.58-24.98-14.93.38-5.24,3.79-9.22,7-13.05,22.8-27.16,55.56-50.73,79.07-77.93,6.13-4.01,15.39-3.43,20.62,1.79Z"/><path fill="currentColor" d="M310.03,344.3c13.33-1.95,22.63,12.27,16.27,24.31-2.12,4.02-31.93,33.94-36.28,36.72-15.12,9.64-32.44-6.52-23.59-21.59,2.28-3.89,30.31-31.72,34.83-35.17,2.33-1.78,5.9-3.84,8.78-4.26Z"/><path fill="currentColor" d="M375.06,280.3c13.69-1.35,22.42,15.11,14.2,26.28-2.34,3.18-18.81,19.93-21.64,21.36-14.39,7.3-29.19-7.8-21.55-22.56,1.13-2.18,15.76-17.88,18.19-19.81,3.16-2.51,6.65-4.86,10.8-5.27Z"/></svg>
152
143
  <h1>__NAME__</h1>
153
144
  <p class="sub">TypeScript, compiled to a native binary. No Rust, no Node, no Electron.</p>
154
145
  </header>
@@ -64,14 +64,7 @@ export default function App() {
64
64
  return (
65
65
  <main>
66
66
  <header>
67
- <div className="mark" aria-hidden="true">
68
- <div className="bar">
69
- <i />
70
- <i />
71
- <i />
72
- </div>
73
- <div className="pane" />
74
- </div>
67
+ <svg class="mark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 970.64 970.64" role="img" aria-label="janela"><path fill="currentColor" d="M970.64,485.32c0,268.03-217.28,485.32-485.32,485.32S0,753.35,0,485.32,217.28,0,485.32,0s485.32,217.28,485.32,485.32ZM938.11,485.34c0-250.08-202.73-452.8-452.8-452.8S32.51,235.26,32.51,485.34s202.73,452.8,452.8,452.8,452.8-202.73,452.8-452.8Z" /><path fill="currentColor" d="M892.79,485.25c0,225.05-182.44,407.49-407.49,407.49S77.82,710.3,77.82,485.25,260.26,77.77,485.31,77.77s407.49,182.44,407.49,407.49ZM470.27,112.09v335.5c0,1.05,13.11,12.99,15.36,14.43,1.65-2.06,14.64-13.4,14.64-14.43V112.59c0-1.1-2.44-1.43-3.45-1.55-8.42-.99-18.1.83-26.55,1.05ZM858.27,438.09c-20.14-166.94-158.46-303.59-325-324v324h325ZM437.27,115.09c-21.65,1.62-44.22,7.07-65,13.5-137.62,42.61-242.41,165.92-260,309.5h325V115.09ZM109.27,500.09h338.5c1,0,12.36-12.44,13.54-14.5,0-1-12.54-14.5-13.54-14.5H109.27c-1.81,9.94-.24,19.09,0,29ZM861.27,471.09h-338.5c-1,0-13.53,13.5-13.54,14.5.52,2.76,3.61,3.57,5.57,5.47,1.64,1.59,7.37,9.03,7.97,9.03h338.5c.9-9.78.9-19.22,0-29ZM500.27,860.09v-336.5c0-1.03-12.98-12.37-14.64-14.43-2.26,1.44-15.36,13.37-15.36,14.43v336.5h30ZM437.27,533.09H112.27c19.95,166.03,159.46,303.1,325,323v-323ZM858.27,533.09h-325v324c165.97-22.51,304.48-156.63,325-324Z" /><path fill="var(--accent)" d="M858.27,438.09h-325V114.09c166.54,20.41,304.86,157.06,325,324Z" /><path fill="var(--accent)" d="M858.27,533.09c-20.52,167.37-159.03,301.49-325,324v-324h325Z" /><path fill="var(--accent)" d="M437.27,533.09v323c-165.54-19.9-305.05-156.97-325-323h325Z" /><path fill="var(--accent)" d="M437.27,115.09v323H112.27c17.6-143.57,122.38-266.89,260-309.5,20.78-6.43,43.34-11.88,65-13.5ZM324.93,239.42c-5.22-5.22-14.48-5.8-20.62-1.79-23.51,27.2-56.28,50.77-79.07,77.93-3.21,3.83-6.62,7.81-7,13.05-.97,13.35,13.8,21.88,24.98,14.93,28.09-28.84,58.16-56.14,84.78-86.22,2.71-5.58,1.25-13.58-3.07-17.9ZM375.06,280.3c-4.15.41-7.65,2.76-10.8,5.27-2.42,1.93-17.06,17.64-18.19,19.81-7.64,14.76,7.17,29.85,21.55,22.56,2.83-1.44,19.3-18.18,21.64-21.36,8.21-11.17-.52-27.62-14.2-26.28ZM310.03,344.3c-2.88.42-6.45,2.49-8.78,4.26-4.52,3.45-32.55,31.28-34.83,35.17-8.84,15.07,8.47,31.23,23.59,21.59,4.35-2.77,34.16-32.7,36.28-36.72,6.36-12.04-2.95-26.26-16.27-24.31Z" /><path fill="var(--card)" d="M500.27,860.09h-30v-336.5c0-1.05,13.11-12.99,15.36-14.43,1.65,2.06,14.64,13.4,14.64,14.43v336.5Z" /><path fill="var(--card)" d="M470.27,112.09c8.45-.22,18.13-2.04,26.55-1.05,1.01.12,3.45.46,3.45,1.55v335c0,1.03-12.98,12.37-14.64,14.43-2.26-1.44-15.36-13.37-15.36-14.43V112.09Z" /><path fill="var(--card)" d="M109.27,500.09c-.24-9.91-1.81-19.06,0-29h338.5c1,0,13.54,13.5,13.54,14.5-1.17,2.06-12.54,14.5-13.54,14.5H109.27Z" /><path fill="var(--card)" d="M861.27,471.09c.9,9.78.9,19.22,0,29h-338.5c-.6,0-6.34-7.44-7.97-9.03-1.96-1.9-5.04-2.72-5.57-5.47,0-1,12.54-14.5,13.54-14.5h338.5Z" /><path fill="currentColor" d="M324.93,239.42c4.32,4.32,5.78,12.32,3.07,17.9-26.62,30.07-56.7,57.37-84.78,86.22-11.18,6.94-25.95-1.58-24.98-14.93.38-5.24,3.79-9.22,7-13.05,22.8-27.16,55.56-50.73,79.07-77.93,6.13-4.01,15.39-3.43,20.62,1.79Z" /><path fill="currentColor" d="M310.03,344.3c13.33-1.95,22.63,12.27,16.27,24.31-2.12,4.02-31.93,33.94-36.28,36.72-15.12,9.64-32.44-6.52-23.59-21.59,2.28-3.89,30.31-31.72,34.83-35.17,2.33-1.78,5.9-3.84,8.78-4.26Z" /><path fill="currentColor" d="M375.06,280.3c13.69-1.35,22.42,15.11,14.2,26.28-2.34,3.18-18.81,19.93-21.64,21.36-14.39,7.3-29.19-7.8-21.55-22.56,1.13-2.18,15.76-17.88,18.19-19.81,3.16-2.51,6.65-4.86,10.8-5.27Z" /></svg>
75
68
  <h1>__NAME__</h1>
76
69
  <p className="sub">TypeScript, compiled to a native binary. No Rust, no Node, no Electron.</p>
77
70
  </header>
@@ -1,10 +1,6 @@
1
1
  /* The janela starter's look. Shared by every template so a project scaffolded
2
2
  with --template vue looks the same as one scaffolded without a framework.
3
- All of it is yours to replace.
4
-
5
- The window mark in App is drawn in CSS rather than shipped as an image: a
6
- janela frontend is embedded in the binary, so every asset has to be inlined
7
- anyway, and a window needs no artwork. */
3
+ All of it is yours to replace. */
8
4
 
9
5
  :root {
10
6
  color-scheme: light dark;
@@ -13,7 +9,7 @@
13
9
  --text: #18181b;
14
10
  --muted: #71717a;
15
11
  --line: #e4e4e7;
16
- --accent: #2563eb;
12
+ --accent: #1c6fd4;
17
13
  --accent-soft: #eff4ff;
18
14
  --shadow: 0 1px 2px rgb(0 0 0 / 0.04), 0 8px 24px -12px rgb(0 0 0 / 0.12);
19
15
  }
@@ -24,7 +20,7 @@
24
20
  --text: #fafafa;
25
21
  --muted: #a1a1aa;
26
22
  --line: #2e2e34;
27
- --accent: #60a5fa;
23
+ --accent: #58a6ff;
28
24
  --accent-soft: #1d2433;
29
25
  --shadow: 0 1px 2px rgb(0 0 0 / 0.3), 0 8px 24px -12px rgb(0 0 0 / 0.5);
30
26
  }
@@ -45,18 +41,14 @@ main { width: 100%; max-width: 760px; padding: 26px 22px 32px; }
45
41
 
46
42
  /* --- header ------------------------------------------------------- */
47
43
  header { text-align: center; margin-bottom: 20px; }
48
- .mark {
49
- width: 56px; height: 44px; margin: 0 auto 14px;
50
- border: 2px solid var(--text); border-radius: 8px;
51
- display: flex; flex-direction: column; overflow: hidden;
52
- }
53
- .mark .bar {
54
- height: 13px; flex: none;
55
- border-bottom: 2px solid var(--text);
56
- display: flex; align-items: center; gap: 3px; padding: 0 4px;
57
- }
58
- .mark .bar i { width: 3px; height: 3px; border-radius: 50%; background: var(--text); }
59
- .mark .pane { flex: 1; background: linear-gradient(135deg, var(--accent), transparent 70%); opacity: 0.85; }
44
+ /* The mark: a round window, which is what janela means. Inlined rather
45
+ than linked, because a janela frontend is embedded in the binary and
46
+ every asset has to be inlined anyway — and inline rather than a CSS
47
+ data URI so ONE copy serves both themes: the frame follows the text
48
+ colour, the glass follows the accent. Percent-encoding a data URI
49
+ would also have cost 4x the bytes. Delete it and the header still
50
+ works. */
51
+ .mark { display: block; width: 56px; height: 56px; margin: 0 auto 14px; }
60
52
  h1 { margin: 0; font-size: 26px; letter-spacing: -0.02em; font-weight: 650; }
61
53
  .sub { margin: 5px 0 0; color: var(--muted); font-size: 13.5px; }
62
54
 
@@ -59,14 +59,7 @@ export default function App() {
59
59
  return (
60
60
  <main>
61
61
  <header>
62
- <div class="mark" aria-hidden="true">
63
- <div class="bar">
64
- <i />
65
- <i />
66
- <i />
67
- </div>
68
- <div class="pane" />
69
- </div>
62
+ <svg class="mark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 970.64 970.64" role="img" aria-label="janela"><path fill="currentColor" d="M970.64,485.32c0,268.03-217.28,485.32-485.32,485.32S0,753.35,0,485.32,217.28,0,485.32,0s485.32,217.28,485.32,485.32ZM938.11,485.34c0-250.08-202.73-452.8-452.8-452.8S32.51,235.26,32.51,485.34s202.73,452.8,452.8,452.8,452.8-202.73,452.8-452.8Z"/><path fill="currentColor" d="M892.79,485.25c0,225.05-182.44,407.49-407.49,407.49S77.82,710.3,77.82,485.25,260.26,77.77,485.31,77.77s407.49,182.44,407.49,407.49ZM470.27,112.09v335.5c0,1.05,13.11,12.99,15.36,14.43,1.65-2.06,14.64-13.4,14.64-14.43V112.59c0-1.1-2.44-1.43-3.45-1.55-8.42-.99-18.1.83-26.55,1.05ZM858.27,438.09c-20.14-166.94-158.46-303.59-325-324v324h325ZM437.27,115.09c-21.65,1.62-44.22,7.07-65,13.5-137.62,42.61-242.41,165.92-260,309.5h325V115.09ZM109.27,500.09h338.5c1,0,12.36-12.44,13.54-14.5,0-1-12.54-14.5-13.54-14.5H109.27c-1.81,9.94-.24,19.09,0,29ZM861.27,471.09h-338.5c-1,0-13.53,13.5-13.54,14.5.52,2.76,3.61,3.57,5.57,5.47,1.64,1.59,7.37,9.03,7.97,9.03h338.5c.9-9.78.9-19.22,0-29ZM500.27,860.09v-336.5c0-1.03-12.98-12.37-14.64-14.43-2.26,1.44-15.36,13.37-15.36,14.43v336.5h30ZM437.27,533.09H112.27c19.95,166.03,159.46,303.1,325,323v-323ZM858.27,533.09h-325v324c165.97-22.51,304.48-156.63,325-324Z"/><path fill="var(--accent)" d="M858.27,438.09h-325V114.09c166.54,20.41,304.86,157.06,325,324Z"/><path fill="var(--accent)" d="M858.27,533.09c-20.52,167.37-159.03,301.49-325,324v-324h325Z"/><path fill="var(--accent)" d="M437.27,533.09v323c-165.54-19.9-305.05-156.97-325-323h325Z"/><path fill="var(--accent)" d="M437.27,115.09v323H112.27c17.6-143.57,122.38-266.89,260-309.5,20.78-6.43,43.34-11.88,65-13.5ZM324.93,239.42c-5.22-5.22-14.48-5.8-20.62-1.79-23.51,27.2-56.28,50.77-79.07,77.93-3.21,3.83-6.62,7.81-7,13.05-.97,13.35,13.8,21.88,24.98,14.93,28.09-28.84,58.16-56.14,84.78-86.22,2.71-5.58,1.25-13.58-3.07-17.9ZM375.06,280.3c-4.15.41-7.65,2.76-10.8,5.27-2.42,1.93-17.06,17.64-18.19,19.81-7.64,14.76,7.17,29.85,21.55,22.56,2.83-1.44,19.3-18.18,21.64-21.36,8.21-11.17-.52-27.62-14.2-26.28ZM310.03,344.3c-2.88.42-6.45,2.49-8.78,4.26-4.52,3.45-32.55,31.28-34.83,35.17-8.84,15.07,8.47,31.23,23.59,21.59,4.35-2.77,34.16-32.7,36.28-36.72,6.36-12.04-2.95-26.26-16.27-24.31Z"/><path fill="var(--card)" d="M500.27,860.09h-30v-336.5c0-1.05,13.11-12.99,15.36-14.43,1.65,2.06,14.64,13.4,14.64,14.43v336.5Z"/><path fill="var(--card)" d="M470.27,112.09c8.45-.22,18.13-2.04,26.55-1.05,1.01.12,3.45.46,3.45,1.55v335c0,1.03-12.98,12.37-14.64,14.43-2.26-1.44-15.36-13.37-15.36-14.43V112.09Z"/><path fill="var(--card)" d="M109.27,500.09c-.24-9.91-1.81-19.06,0-29h338.5c1,0,13.54,13.5,13.54,14.5-1.17,2.06-12.54,14.5-13.54,14.5H109.27Z"/><path fill="var(--card)" d="M861.27,471.09c.9,9.78.9,19.22,0,29h-338.5c-.6,0-6.34-7.44-7.97-9.03-1.96-1.9-5.04-2.72-5.57-5.47,0-1,12.54-14.5,13.54-14.5h338.5Z"/><path fill="currentColor" d="M324.93,239.42c4.32,4.32,5.78,12.32,3.07,17.9-26.62,30.07-56.7,57.37-84.78,86.22-11.18,6.94-25.95-1.58-24.98-14.93.38-5.24,3.79-9.22,7-13.05,22.8-27.16,55.56-50.73,79.07-77.93,6.13-4.01,15.39-3.43,20.62,1.79Z"/><path fill="currentColor" d="M310.03,344.3c13.33-1.95,22.63,12.27,16.27,24.31-2.12,4.02-31.93,33.94-36.28,36.72-15.12,9.64-32.44-6.52-23.59-21.59,2.28-3.89,30.31-31.72,34.83-35.17,2.33-1.78,5.9-3.84,8.78-4.26Z"/><path fill="currentColor" d="M375.06,280.3c13.69-1.35,22.42,15.11,14.2,26.28-2.34,3.18-18.81,19.93-21.64,21.36-14.39,7.3-29.19-7.8-21.55-22.56,1.13-2.18,15.76-17.88,18.19-19.81,3.16-2.51,6.65-4.86,10.8-5.27Z"/></svg>
70
63
  <h1>__NAME__</h1>
71
64
  <p class="sub">TypeScript, compiled to a native binary. No Rust, no Node, no Electron.</p>
72
65
  </header>
@@ -1,10 +1,6 @@
1
1
  /* The janela starter's look. Shared by every template so a project scaffolded
2
2
  with --template vue looks the same as one scaffolded without a framework.
3
- All of it is yours to replace.
4
-
5
- The window mark in App is drawn in CSS rather than shipped as an image: a
6
- janela frontend is embedded in the binary, so every asset has to be inlined
7
- anyway, and a window needs no artwork. */
3
+ All of it is yours to replace. */
8
4
 
9
5
  :root {
10
6
  color-scheme: light dark;
@@ -13,7 +9,7 @@
13
9
  --text: #18181b;
14
10
  --muted: #71717a;
15
11
  --line: #e4e4e7;
16
- --accent: #2563eb;
12
+ --accent: #1c6fd4;
17
13
  --accent-soft: #eff4ff;
18
14
  --shadow: 0 1px 2px rgb(0 0 0 / 0.04), 0 8px 24px -12px rgb(0 0 0 / 0.12);
19
15
  }
@@ -24,7 +20,7 @@
24
20
  --text: #fafafa;
25
21
  --muted: #a1a1aa;
26
22
  --line: #2e2e34;
27
- --accent: #60a5fa;
23
+ --accent: #58a6ff;
28
24
  --accent-soft: #1d2433;
29
25
  --shadow: 0 1px 2px rgb(0 0 0 / 0.3), 0 8px 24px -12px rgb(0 0 0 / 0.5);
30
26
  }
@@ -45,18 +41,14 @@ main { width: 100%; max-width: 760px; padding: 26px 22px 32px; }
45
41
 
46
42
  /* --- header ------------------------------------------------------- */
47
43
  header { text-align: center; margin-bottom: 20px; }
48
- .mark {
49
- width: 56px; height: 44px; margin: 0 auto 14px;
50
- border: 2px solid var(--text); border-radius: 8px;
51
- display: flex; flex-direction: column; overflow: hidden;
52
- }
53
- .mark .bar {
54
- height: 13px; flex: none;
55
- border-bottom: 2px solid var(--text);
56
- display: flex; align-items: center; gap: 3px; padding: 0 4px;
57
- }
58
- .mark .bar i { width: 3px; height: 3px; border-radius: 50%; background: var(--text); }
59
- .mark .pane { flex: 1; background: linear-gradient(135deg, var(--accent), transparent 70%); opacity: 0.85; }
44
+ /* The mark: a round window, which is what janela means. Inlined rather
45
+ than linked, because a janela frontend is embedded in the binary and
46
+ every asset has to be inlined anyway — and inline rather than a CSS
47
+ data URI so ONE copy serves both themes: the frame follows the text
48
+ colour, the glass follows the accent. Percent-encoding a data URI
49
+ would also have cost 4x the bytes. Delete it and the header still
50
+ works. */
51
+ .mark { display: block; width: 56px; height: 56px; margin: 0 auto 14px; }
60
52
  h1 { margin: 0; font-size: 26px; letter-spacing: -0.02em; font-weight: 650; }
61
53
  .sub { margin: 5px 0 0; color: var(--muted); font-size: 13.5px; }
62
54
 
@@ -58,10 +58,7 @@
58
58
 
59
59
  <main>
60
60
  <header>
61
- <div class="mark" aria-hidden="true">
62
- <div class="bar"><i></i><i></i><i></i></div>
63
- <div class="pane"></div>
64
- </div>
61
+ <svg class="mark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 970.64 970.64" role="img" aria-label="janela"><path fill="currentColor" d="M970.64,485.32c0,268.03-217.28,485.32-485.32,485.32S0,753.35,0,485.32,217.28,0,485.32,0s485.32,217.28,485.32,485.32ZM938.11,485.34c0-250.08-202.73-452.8-452.8-452.8S32.51,235.26,32.51,485.34s202.73,452.8,452.8,452.8,452.8-202.73,452.8-452.8Z"/><path fill="currentColor" d="M892.79,485.25c0,225.05-182.44,407.49-407.49,407.49S77.82,710.3,77.82,485.25,260.26,77.77,485.31,77.77s407.49,182.44,407.49,407.49ZM470.27,112.09v335.5c0,1.05,13.11,12.99,15.36,14.43,1.65-2.06,14.64-13.4,14.64-14.43V112.59c0-1.1-2.44-1.43-3.45-1.55-8.42-.99-18.1.83-26.55,1.05ZM858.27,438.09c-20.14-166.94-158.46-303.59-325-324v324h325ZM437.27,115.09c-21.65,1.62-44.22,7.07-65,13.5-137.62,42.61-242.41,165.92-260,309.5h325V115.09ZM109.27,500.09h338.5c1,0,12.36-12.44,13.54-14.5,0-1-12.54-14.5-13.54-14.5H109.27c-1.81,9.94-.24,19.09,0,29ZM861.27,471.09h-338.5c-1,0-13.53,13.5-13.54,14.5.52,2.76,3.61,3.57,5.57,5.47,1.64,1.59,7.37,9.03,7.97,9.03h338.5c.9-9.78.9-19.22,0-29ZM500.27,860.09v-336.5c0-1.03-12.98-12.37-14.64-14.43-2.26,1.44-15.36,13.37-15.36,14.43v336.5h30ZM437.27,533.09H112.27c19.95,166.03,159.46,303.1,325,323v-323ZM858.27,533.09h-325v324c165.97-22.51,304.48-156.63,325-324Z"/><path fill="var(--accent)" d="M858.27,438.09h-325V114.09c166.54,20.41,304.86,157.06,325,324Z"/><path fill="var(--accent)" d="M858.27,533.09c-20.52,167.37-159.03,301.49-325,324v-324h325Z"/><path fill="var(--accent)" d="M437.27,533.09v323c-165.54-19.9-305.05-156.97-325-323h325Z"/><path fill="var(--accent)" d="M437.27,115.09v323H112.27c17.6-143.57,122.38-266.89,260-309.5,20.78-6.43,43.34-11.88,65-13.5ZM324.93,239.42c-5.22-5.22-14.48-5.8-20.62-1.79-23.51,27.2-56.28,50.77-79.07,77.93-3.21,3.83-6.62,7.81-7,13.05-.97,13.35,13.8,21.88,24.98,14.93,28.09-28.84,58.16-56.14,84.78-86.22,2.71-5.58,1.25-13.58-3.07-17.9ZM375.06,280.3c-4.15.41-7.65,2.76-10.8,5.27-2.42,1.93-17.06,17.64-18.19,19.81-7.64,14.76,7.17,29.85,21.55,22.56,2.83-1.44,19.3-18.18,21.64-21.36,8.21-11.17-.52-27.62-14.2-26.28ZM310.03,344.3c-2.88.42-6.45,2.49-8.78,4.26-4.52,3.45-32.55,31.28-34.83,35.17-8.84,15.07,8.47,31.23,23.59,21.59,4.35-2.77,34.16-32.7,36.28-36.72,6.36-12.04-2.95-26.26-16.27-24.31Z"/><path fill="var(--card)" d="M500.27,860.09h-30v-336.5c0-1.05,13.11-12.99,15.36-14.43,1.65,2.06,14.64,13.4,14.64,14.43v336.5Z"/><path fill="var(--card)" d="M470.27,112.09c8.45-.22,18.13-2.04,26.55-1.05,1.01.12,3.45.46,3.45,1.55v335c0,1.03-12.98,12.37-14.64,14.43-2.26-1.44-15.36-13.37-15.36-14.43V112.09Z"/><path fill="var(--card)" d="M109.27,500.09c-.24-9.91-1.81-19.06,0-29h338.5c1,0,13.54,13.5,13.54,14.5-1.17,2.06-12.54,14.5-13.54,14.5H109.27Z"/><path fill="var(--card)" d="M861.27,471.09c.9,9.78.9,19.22,0,29h-338.5c-.6,0-6.34-7.44-7.97-9.03-1.96-1.9-5.04-2.72-5.57-5.47,0-1,12.54-14.5,13.54-14.5h338.5Z"/><path fill="currentColor" d="M324.93,239.42c4.32,4.32,5.78,12.32,3.07,17.9-26.62,30.07-56.7,57.37-84.78,86.22-11.18,6.94-25.95-1.58-24.98-14.93.38-5.24,3.79-9.22,7-13.05,22.8-27.16,55.56-50.73,79.07-77.93,6.13-4.01,15.39-3.43,20.62,1.79Z"/><path fill="currentColor" d="M310.03,344.3c13.33-1.95,22.63,12.27,16.27,24.31-2.12,4.02-31.93,33.94-36.28,36.72-15.12,9.64-32.44-6.52-23.59-21.59,2.28-3.89,30.31-31.72,34.83-35.17,2.33-1.78,5.9-3.84,8.78-4.26Z"/><path fill="currentColor" d="M375.06,280.3c13.69-1.35,22.42,15.11,14.2,26.28-2.34,3.18-18.81,19.93-21.64,21.36-14.39,7.3-29.19-7.8-21.55-22.56,1.13-2.18,15.76-17.88,18.19-19.81,3.16-2.51,6.65-4.86,10.8-5.27Z"/></svg>
65
62
  <h1>__NAME__</h1>
66
63
  <p class="sub">TypeScript, compiled to a native binary. No Rust, no Node, no Electron.</p>
67
64
  </header>
@@ -1,10 +1,6 @@
1
1
  /* The janela starter's look. Shared by every template so a project scaffolded
2
2
  with --template vue looks the same as one scaffolded without a framework.
3
- All of it is yours to replace.
4
-
5
- The window mark in App is drawn in CSS rather than shipped as an image: a
6
- janela frontend is embedded in the binary, so every asset has to be inlined
7
- anyway, and a window needs no artwork. */
3
+ All of it is yours to replace. */
8
4
 
9
5
  :root {
10
6
  color-scheme: light dark;
@@ -13,7 +9,7 @@
13
9
  --text: #18181b;
14
10
  --muted: #71717a;
15
11
  --line: #e4e4e7;
16
- --accent: #2563eb;
12
+ --accent: #1c6fd4;
17
13
  --accent-soft: #eff4ff;
18
14
  --shadow: 0 1px 2px rgb(0 0 0 / 0.04), 0 8px 24px -12px rgb(0 0 0 / 0.12);
19
15
  }
@@ -24,7 +20,7 @@
24
20
  --text: #fafafa;
25
21
  --muted: #a1a1aa;
26
22
  --line: #2e2e34;
27
- --accent: #60a5fa;
23
+ --accent: #58a6ff;
28
24
  --accent-soft: #1d2433;
29
25
  --shadow: 0 1px 2px rgb(0 0 0 / 0.3), 0 8px 24px -12px rgb(0 0 0 / 0.5);
30
26
  }
@@ -45,18 +41,14 @@ main { width: 100%; max-width: 760px; padding: 26px 22px 32px; }
45
41
 
46
42
  /* --- header ------------------------------------------------------- */
47
43
  header { text-align: center; margin-bottom: 20px; }
48
- .mark {
49
- width: 56px; height: 44px; margin: 0 auto 14px;
50
- border: 2px solid var(--text); border-radius: 8px;
51
- display: flex; flex-direction: column; overflow: hidden;
52
- }
53
- .mark .bar {
54
- height: 13px; flex: none;
55
- border-bottom: 2px solid var(--text);
56
- display: flex; align-items: center; gap: 3px; padding: 0 4px;
57
- }
58
- .mark .bar i { width: 3px; height: 3px; border-radius: 50%; background: var(--text); }
59
- .mark .pane { flex: 1; background: linear-gradient(135deg, var(--accent), transparent 70%); opacity: 0.85; }
44
+ /* The mark: a round window, which is what janela means. Inlined rather
45
+ than linked, because a janela frontend is embedded in the binary and
46
+ every asset has to be inlined anyway — and inline rather than a CSS
47
+ data URI so ONE copy serves both themes: the frame follows the text
48
+ colour, the glass follows the accent. Percent-encoding a data URI
49
+ would also have cost 4x the bytes. Delete it and the header still
50
+ works. */
51
+ .mark { display: block; width: 56px; height: 56px; margin: 0 auto 14px; }
60
52
  h1 { margin: 0; font-size: 26px; letter-spacing: -0.02em; font-weight: 650; }
61
53
  .sub { margin: 5px 0 0; color: var(--muted); font-size: 13.5px; }
62
54
 
@@ -58,10 +58,7 @@ async function pick() {
58
58
  <template>
59
59
  <main>
60
60
  <header>
61
- <div class="mark" aria-hidden="true">
62
- <div class="bar"><i /><i /><i /></div>
63
- <div class="pane" />
64
- </div>
61
+ <svg class="mark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 970.64 970.64" role="img" aria-label="janela"><path fill="currentColor" d="M970.64,485.32c0,268.03-217.28,485.32-485.32,485.32S0,753.35,0,485.32,217.28,0,485.32,0s485.32,217.28,485.32,485.32ZM938.11,485.34c0-250.08-202.73-452.8-452.8-452.8S32.51,235.26,32.51,485.34s202.73,452.8,452.8,452.8,452.8-202.73,452.8-452.8Z"/><path fill="currentColor" d="M892.79,485.25c0,225.05-182.44,407.49-407.49,407.49S77.82,710.3,77.82,485.25,260.26,77.77,485.31,77.77s407.49,182.44,407.49,407.49ZM470.27,112.09v335.5c0,1.05,13.11,12.99,15.36,14.43,1.65-2.06,14.64-13.4,14.64-14.43V112.59c0-1.1-2.44-1.43-3.45-1.55-8.42-.99-18.1.83-26.55,1.05ZM858.27,438.09c-20.14-166.94-158.46-303.59-325-324v324h325ZM437.27,115.09c-21.65,1.62-44.22,7.07-65,13.5-137.62,42.61-242.41,165.92-260,309.5h325V115.09ZM109.27,500.09h338.5c1,0,12.36-12.44,13.54-14.5,0-1-12.54-14.5-13.54-14.5H109.27c-1.81,9.94-.24,19.09,0,29ZM861.27,471.09h-338.5c-1,0-13.53,13.5-13.54,14.5.52,2.76,3.61,3.57,5.57,5.47,1.64,1.59,7.37,9.03,7.97,9.03h338.5c.9-9.78.9-19.22,0-29ZM500.27,860.09v-336.5c0-1.03-12.98-12.37-14.64-14.43-2.26,1.44-15.36,13.37-15.36,14.43v336.5h30ZM437.27,533.09H112.27c19.95,166.03,159.46,303.1,325,323v-323ZM858.27,533.09h-325v324c165.97-22.51,304.48-156.63,325-324Z"/><path fill="var(--accent)" d="M858.27,438.09h-325V114.09c166.54,20.41,304.86,157.06,325,324Z"/><path fill="var(--accent)" d="M858.27,533.09c-20.52,167.37-159.03,301.49-325,324v-324h325Z"/><path fill="var(--accent)" d="M437.27,533.09v323c-165.54-19.9-305.05-156.97-325-323h325Z"/><path fill="var(--accent)" d="M437.27,115.09v323H112.27c17.6-143.57,122.38-266.89,260-309.5,20.78-6.43,43.34-11.88,65-13.5ZM324.93,239.42c-5.22-5.22-14.48-5.8-20.62-1.79-23.51,27.2-56.28,50.77-79.07,77.93-3.21,3.83-6.62,7.81-7,13.05-.97,13.35,13.8,21.88,24.98,14.93,28.09-28.84,58.16-56.14,84.78-86.22,2.71-5.58,1.25-13.58-3.07-17.9ZM375.06,280.3c-4.15.41-7.65,2.76-10.8,5.27-2.42,1.93-17.06,17.64-18.19,19.81-7.64,14.76,7.17,29.85,21.55,22.56,2.83-1.44,19.3-18.18,21.64-21.36,8.21-11.17-.52-27.62-14.2-26.28ZM310.03,344.3c-2.88.42-6.45,2.49-8.78,4.26-4.52,3.45-32.55,31.28-34.83,35.17-8.84,15.07,8.47,31.23,23.59,21.59,4.35-2.77,34.16-32.7,36.28-36.72,6.36-12.04-2.95-26.26-16.27-24.31Z"/><path fill="var(--card)" d="M500.27,860.09h-30v-336.5c0-1.05,13.11-12.99,15.36-14.43,1.65,2.06,14.64,13.4,14.64,14.43v336.5Z"/><path fill="var(--card)" d="M470.27,112.09c8.45-.22,18.13-2.04,26.55-1.05,1.01.12,3.45.46,3.45,1.55v335c0,1.03-12.98,12.37-14.64,14.43-2.26-1.44-15.36-13.37-15.36-14.43V112.09Z"/><path fill="var(--card)" d="M109.27,500.09c-.24-9.91-1.81-19.06,0-29h338.5c1,0,13.54,13.5,13.54,14.5-1.17,2.06-12.54,14.5-13.54,14.5H109.27Z"/><path fill="var(--card)" d="M861.27,471.09c.9,9.78.9,19.22,0,29h-338.5c-.6,0-6.34-7.44-7.97-9.03-1.96-1.9-5.04-2.72-5.57-5.47,0-1,12.54-14.5,13.54-14.5h338.5Z"/><path fill="currentColor" d="M324.93,239.42c4.32,4.32,5.78,12.32,3.07,17.9-26.62,30.07-56.7,57.37-84.78,86.22-11.18,6.94-25.95-1.58-24.98-14.93.38-5.24,3.79-9.22,7-13.05,22.8-27.16,55.56-50.73,79.07-77.93,6.13-4.01,15.39-3.43,20.62,1.79Z"/><path fill="currentColor" d="M310.03,344.3c13.33-1.95,22.63,12.27,16.27,24.31-2.12,4.02-31.93,33.94-36.28,36.72-15.12,9.64-32.44-6.52-23.59-21.59,2.28-3.89,30.31-31.72,34.83-35.17,2.33-1.78,5.9-3.84,8.78-4.26Z"/><path fill="currentColor" d="M375.06,280.3c13.69-1.35,22.42,15.11,14.2,26.28-2.34,3.18-18.81,19.93-21.64,21.36-14.39,7.3-29.19-7.8-21.55-22.56,1.13-2.18,15.76-17.88,18.19-19.81,3.16-2.51,6.65-4.86,10.8-5.27Z"/></svg>
65
62
  <h1>__NAME__</h1>
66
63
  <p class="sub">TypeScript, compiled to a native binary. No Rust, no Node, no Electron.</p>
67
64
  </header>
@@ -1,10 +1,6 @@
1
1
  /* The janela starter's look. Shared by every template so a project scaffolded
2
2
  with --template vue looks the same as one scaffolded without a framework.
3
- All of it is yours to replace.
4
-
5
- The window mark in App is drawn in CSS rather than shipped as an image: a
6
- janela frontend is embedded in the binary, so every asset has to be inlined
7
- anyway, and a window needs no artwork. */
3
+ All of it is yours to replace. */
8
4
 
9
5
  :root {
10
6
  color-scheme: light dark;
@@ -13,7 +9,7 @@
13
9
  --text: #18181b;
14
10
  --muted: #71717a;
15
11
  --line: #e4e4e7;
16
- --accent: #2563eb;
12
+ --accent: #1c6fd4;
17
13
  --accent-soft: #eff4ff;
18
14
  --shadow: 0 1px 2px rgb(0 0 0 / 0.04), 0 8px 24px -12px rgb(0 0 0 / 0.12);
19
15
  }
@@ -24,7 +20,7 @@
24
20
  --text: #fafafa;
25
21
  --muted: #a1a1aa;
26
22
  --line: #2e2e34;
27
- --accent: #60a5fa;
23
+ --accent: #58a6ff;
28
24
  --accent-soft: #1d2433;
29
25
  --shadow: 0 1px 2px rgb(0 0 0 / 0.3), 0 8px 24px -12px rgb(0 0 0 / 0.5);
30
26
  }
@@ -45,18 +41,14 @@ main { width: 100%; max-width: 760px; padding: 26px 22px 32px; }
45
41
 
46
42
  /* --- header ------------------------------------------------------- */
47
43
  header { text-align: center; margin-bottom: 20px; }
48
- .mark {
49
- width: 56px; height: 44px; margin: 0 auto 14px;
50
- border: 2px solid var(--text); border-radius: 8px;
51
- display: flex; flex-direction: column; overflow: hidden;
52
- }
53
- .mark .bar {
54
- height: 13px; flex: none;
55
- border-bottom: 2px solid var(--text);
56
- display: flex; align-items: center; gap: 3px; padding: 0 4px;
57
- }
58
- .mark .bar i { width: 3px; height: 3px; border-radius: 50%; background: var(--text); }
59
- .mark .pane { flex: 1; background: linear-gradient(135deg, var(--accent), transparent 70%); opacity: 0.85; }
44
+ /* The mark: a round window, which is what janela means. Inlined rather
45
+ than linked, because a janela frontend is embedded in the binary and
46
+ every asset has to be inlined anyway — and inline rather than a CSS
47
+ data URI so ONE copy serves both themes: the frame follows the text
48
+ colour, the glass follows the accent. Percent-encoding a data URI
49
+ would also have cost 4x the bytes. Delete it and the header still
50
+ works. */
51
+ .mark { display: block; width: 56px; height: 56px; margin: 0 auto 14px; }
60
52
  h1 { margin: 0; font-size: 26px; letter-spacing: -0.02em; font-weight: 650; }
61
53
  .sub { margin: 5px 0 0; color: var(--muted); font-size: 13.5px; }
62
54