2<html lang="en">
3 <head>
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1" />
6 <title>shtns-webgpu — spherical harmonic transforms in the browser</title>
7 <style>
8 :root {
9 --bg: #ffffff;
10 --ink: #1f2328;
11 --ink-2: #57606a;
12 --line: #d0d7de;
13 --accent: #0969da;
14 color-scheme: light dark;
15 }
16 @media (prefers-color-scheme: dark) {
17 :root {
18 --bg: #14171a;
19 --ink: #e6e9ec;
20 --ink-2: #9aa4af;
21 --line: #333b44;
22 --accent: #58a6ff;
23 }
24 }
25 body {
26 margin: 0;
27 background: var(--bg);
28 color: var(--ink);
29 font: 15px/1.5 system-ui, -apple-system, sans-serif;
30 }
31 main { max-width: 940px; margin: 0 auto; padding: 20px 16px 48px; }
32 h1 { font-size: 20px; margin: 0 0 2px; }
33 .sub { color: var(--ink-2); margin: 0 0 16px; font-size: 13px; }
34 .controls {
35 display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center;
36 padding: 10px 0 14px;
37 }
38 .controls label { color: var(--ink-2); font-size: 13px; }
39 select, input[type="number"], button {
40 font: inherit; font-size: 13px;
41 color: var(--ink); background: var(--bg);
42 border: 1px solid var(--line); border-radius: 6px;
43 padding: 4px 8px;
44 }
45 input[type="number"] { width: 5em; }
46 button { cursor: pointer; }
47 button:hover { border-color: var(--accent); }
48 #map {
49 width: 100%; display: block; border: 1px solid var(--line); border-radius: 6px;
50 background: var(--bg);
51 }
52 .bar-row { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
53 #colorbar { border: 1px solid var(--line); border-radius: 3px; }
54 .bar-row span { font-size: 12px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
55 .stats { margin-top: 10px; font-size: 13px; color: var(--ink-2); }
56 .stats b { color: var(--ink); font-weight: 600; }
57 #hover { min-height: 1.2em; font-variant-numeric: tabular-nums; }
58 #err { color: #b35900; white-space: pre-wrap; }
59 </style>
60 </head>
61 <body>
62 <main>
63 <h1>shtns-webgpu</h1>
64 <p class="sub">
65 fp32 spherical harmonic transforms on WebGPU, modeled on
66 <a href="https://nschaeff.bitbucket.io/shtns/">SHTNS</a> — scalar synthesis
67 and analysis on a Gauss grid.
68 </p>
69 <div class="controls">
70 <label>size
71 <select id="preset">
72 <option value="31">lmax 31 (32×64)</option>
73 <option value="63">lmax 63 (64×128)</option>
74 <option value="127" selected>lmax 127 (128×256)</option>
75 <option value="255">lmax 255 (256×512)</option>
76 </select>
77 </label>
78 <label>source
79 <select id="source">
80 <option value="single" selected>single mode Y<sub>l</sub><sup>m</sup></option>
81 <option value="random">random spectrum</option>
82 <option value="bandpass">random, l ∈ [lmax/3, 2·lmax/3]</option>
83 </select>
84 </label>
85 <label id="lmWrap">l <input id="inpL" type="number" min="0" value="8" />
86 m <input id="inpM" type="number" min="0" value="5" /></label>
87 <button id="reroll">new random seed</button>
88 </div>
89 <canvas id="map"></canvas>
90 <div class="bar-row">
91 <span id="vmin"></span>
92 <canvas id="colorbar" width="256" height="12"></canvas>
93 <span id="vmax"></span>
94 <span style="flex:1"></span>
95 <span id="hover"></span>
96 </div>
97 <p class="stats" id="stats"></p>
98 <p class="stats" id="err"></p>
99 </main>
100 <script type="module" src="/src/demo/main.ts"></script>
101 </body>
102</html>