|
2 | 2 | <html lang="en"> |
3 | 3 | <head> |
4 | 4 | <meta charset="utf-8"/> |
5 | | - <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"/> |
6 | | - <meta name="color-scheme" content="dark"/> |
7 | | - <title>Azimuth — Web flasher</title> |
| 5 | + <meta name="viewport" content="width=device-width,initial-scale=1"/> |
| 6 | + <meta name="color-scheme" content="dark light"/> |
| 7 | + <title>Install Azimuth firmware</title> |
8 | 8 | <script type="module" src="https://unpkg.com/esp-web-tools@10.0.1/dist/web/install-button.js?module"></script> |
9 | 9 | <style> |
10 | | - :root{ |
11 | | - --bg:#0a0e14;--bg2:#121a24;--card:rgba(26,35,50,.92);--bd:rgba(61,158,229,.22); |
12 | | - --tx:#eef4fa;--muted:#8b9cb3;--acc:#3d9ee5;--acc-dim:rgba(61,158,229,.15); |
13 | | - --ok:#4ade80;--shadow:0 8px 32px rgba(0,0,0,.35); |
14 | | - } |
15 | | - *{box-sizing:border-box} |
16 | | - html{-webkit-text-size-adjust:100%} |
17 | | - body{ |
18 | | - margin:0;min-height:100dvh; |
19 | | - font:16px/1.5 system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; |
20 | | - color:var(--tx); |
21 | | - background:var(--bg); |
22 | | - background-image:radial-gradient(ellipse 100% 60% at 50% -15%,#1a4a6e 0%,transparent 55%),radial-gradient(ellipse 80% 50% at 100% 100%,rgba(61,158,229,.08),transparent); |
23 | | - } |
24 | | - .wrap{max-width:34rem;margin:0 auto;padding:clamp(1rem,4vw,2rem) clamp(1rem,3vw,1.25rem) 2.5rem} |
25 | | - .brand{text-align:center;margin-bottom:1.1rem} |
26 | | - .brand h1{font-size:1.35rem;font-weight:700;margin:0;letter-spacing:.02em;background:linear-gradient(165deg,#e8eef5,var(--acc));-webkit-background-clip:text;background-clip:text;color:transparent} |
27 | | - .sub{color:var(--muted);font-size:.8125rem;margin:.5rem 0 0;line-height:1.45} |
28 | | - .card{ |
29 | | - background:var(--card);border:1px solid var(--bd);border-radius:14px;padding:1.1rem 1.15rem;margin-bottom:1rem; |
30 | | - box-shadow:var(--shadow) |
31 | | - } |
32 | | - .hd{font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--acc);margin:0 0 .75rem} |
33 | | - .hint{font-size:.75rem;color:var(--muted);margin:0 0 .85rem;line-height:1.45} |
34 | | - .btn-row{display:flex;flex-direction:column;gap:.65rem;margin-top:.5rem;align-items:stretch} |
35 | | - .btn-row esp-web-install-button{ |
36 | | - --esp-tools-button-color:var(--acc); |
37 | | - --esp-tools-button-text-color:#051018; |
38 | | - --esp-tools-button-border-radius:10px; |
39 | | - display:block;width:100%; |
40 | | - } |
41 | | - .link-card a{color:var(--acc);text-decoration:none;font-weight:600} |
42 | | - .link-card a:hover{text-decoration:underline} |
43 | | - .callout{margin-top:.75rem;padding:.75rem .85rem;border-radius:11px;background:var(--bg2);border:1px solid var(--bd);font-size:.8125rem;color:var(--muted);line-height:1.5} |
44 | | - .callout strong{color:var(--tx)} |
45 | | - code{font-family:ui-monospace,SFMono-Regular,monospace;font-size:.85em;color:var(--acc)} |
46 | | - #msg{margin-top:.75rem;font-size:.8125rem;min-height:1.25em} |
47 | | - .err{color:#f87171} |
| 10 | + :root { |
| 11 | + --bg: #0c1118; |
| 12 | + --bg-elev: #151d28; |
| 13 | + --tx: #e8eef4; |
| 14 | + --tx-soft: #9aa8b8; |
| 15 | + --line: rgba(61, 158, 229, 0.22); |
| 16 | + --accent: #3d9ee5; |
| 17 | + --accent-soft: rgba(61, 158, 229, 0.14); |
| 18 | + --warn-bg: rgba(248, 113, 113, 0.1); |
| 19 | + --warn-bd: rgba(248, 113, 113, 0.35); |
| 20 | + --radius: 16px; |
| 21 | + --font: system-ui, -apple-system, "Segoe UI", sans-serif; |
| 22 | + } |
| 23 | + @media (prefers-color-scheme: light) { |
| 24 | + :root { |
| 25 | + --bg: #f0f4f8; |
| 26 | + --bg-elev: #fff; |
| 27 | + --tx: #0f172a; |
| 28 | + --tx-soft: #5c6b7a; |
| 29 | + --line: rgba(15, 23, 42, 0.12); |
| 30 | + --accent-soft: rgba(61, 158, 229, 0.12); |
| 31 | + --warn-bg: #fff1f2; |
| 32 | + --warn-bd: #fecdd3; |
| 33 | + } |
| 34 | + } |
| 35 | + *, *::before, *::after { box-sizing: border-box; } |
| 36 | + html { -webkit-text-size-adjust: 100%; } |
| 37 | + body { |
| 38 | + margin: 0; |
| 39 | + min-height: 100dvh; |
| 40 | + font: 17px/1.55 var(--font); |
| 41 | + color: var(--tx); |
| 42 | + background: var(--bg); |
| 43 | + } |
| 44 | + .page { |
| 45 | + max-width: 28rem; |
| 46 | + margin: 0 auto; |
| 47 | + padding: 2rem 1.25rem 3rem; |
| 48 | + } |
| 49 | + .logo { |
| 50 | + display: block; |
| 51 | + width: min(220px, 72vw); |
| 52 | + height: auto; |
| 53 | + margin: 0 auto 1.75rem; |
| 54 | + } |
| 55 | + .lede { |
| 56 | + text-align: center; |
| 57 | + font-size: 1.05rem; |
| 58 | + color: var(--tx-soft); |
| 59 | + margin: 0 0 2rem; |
| 60 | + line-height: 1.5; |
| 61 | + } |
| 62 | + .panel { |
| 63 | + background: var(--bg-elev); |
| 64 | + border: 1px solid var(--line); |
| 65 | + border-radius: var(--radius); |
| 66 | + padding: 1.35rem 1.25rem 1.5rem; |
| 67 | + margin-bottom: 1.25rem; |
| 68 | + } |
| 69 | + .panel + .panel { margin-top: 1.5rem; } |
| 70 | + h2 { |
| 71 | + font-size: 1rem; |
| 72 | + font-weight: 650; |
| 73 | + margin: 0 0 0.85rem; |
| 74 | + letter-spacing: -0.02em; |
| 75 | + color: var(--tx); |
| 76 | + } |
| 77 | + p { |
| 78 | + margin: 0 0 1rem; |
| 79 | + color: var(--tx-soft); |
| 80 | + font-size: 0.94rem; |
| 81 | + line-height: 1.55; |
| 82 | + } |
| 83 | + p:last-child { margin-bottom: 0; } |
| 84 | + .browser-problem { |
| 85 | + background: var(--warn-bg); |
| 86 | + border: 1px solid var(--warn-bd); |
| 87 | + border-radius: var(--radius); |
| 88 | + padding: 1rem 1.1rem; |
| 89 | + margin: 0 0 1.15rem; |
| 90 | + font-size: 0.92rem; |
| 91 | + color: var(--tx); |
| 92 | + line-height: 1.5; |
| 93 | + } |
| 94 | + .steps { |
| 95 | + list-style: none; |
| 96 | + padding: 0; |
| 97 | + margin: 0 0 1.25rem; |
| 98 | + counter-reset: s; |
| 99 | + } |
| 100 | + .steps li { |
| 101 | + position: relative; |
| 102 | + padding-left: 2.35rem; |
| 103 | + margin-bottom: 0.85rem; |
| 104 | + color: var(--tx-soft); |
| 105 | + font-size: 0.94rem; |
| 106 | + line-height: 1.5; |
| 107 | + } |
| 108 | + .steps li:last-child { margin-bottom: 0; } |
| 109 | + .steps li::before { |
| 110 | + counter-increment: s; |
| 111 | + content: counter(s); |
| 112 | + position: absolute; |
| 113 | + left: 0; |
| 114 | + top: 0.1rem; |
| 115 | + width: 1.65rem; |
| 116 | + height: 1.65rem; |
| 117 | + border-radius: 50%; |
| 118 | + background: var(--accent-soft); |
| 119 | + color: var(--accent); |
| 120 | + font-size: 0.8rem; |
| 121 | + font-weight: 700; |
| 122 | + display: flex; |
| 123 | + align-items: center; |
| 124 | + justify-content: center; |
| 125 | + } |
| 126 | + .flash-wrap { |
| 127 | + margin-top: 0.25rem; |
| 128 | + } |
| 129 | + .flash-wrap esp-web-install-button { |
| 130 | + --esp-tools-button-color: var(--accent); |
| 131 | + --esp-tools-button-text-color: #071018; |
| 132 | + --esp-tools-button-border-radius: 12px; |
| 133 | + display: block; |
| 134 | + width: 100%; |
| 135 | + } |
| 136 | + details { |
| 137 | + margin-top: 1rem; |
| 138 | + font-size: 0.88rem; |
| 139 | + color: var(--tx-soft); |
| 140 | + line-height: 1.5; |
| 141 | + } |
| 142 | + details summary { |
| 143 | + cursor: pointer; |
| 144 | + color: var(--accent); |
| 145 | + font-weight: 600; |
| 146 | + padding: 0.35rem 0; |
| 147 | + } |
| 148 | + .link-main { |
| 149 | + display: inline-block; |
| 150 | + font-size: 1.05rem; |
| 151 | + font-weight: 600; |
| 152 | + color: var(--accent); |
| 153 | + text-decoration: none; |
| 154 | + word-break: break-all; |
| 155 | + } |
| 156 | + .link-main:hover { text-decoration: underline; } |
| 157 | + code { |
| 158 | + font-family: ui-monospace, "SF Mono", monospace; |
| 159 | + font-size: 0.88em; |
| 160 | + color: var(--accent); |
| 161 | + } |
| 162 | + .fine-print { |
| 163 | + font-size: 0.85rem; |
| 164 | + margin-top: 0.9rem; |
| 165 | + padding-top: 0.9rem; |
| 166 | + border-top: 1px solid var(--line); |
| 167 | + } |
48 | 168 | </style> |
49 | 169 | </head> |
50 | 170 | <body> |
51 | | -<div class="wrap"> |
52 | | - <header class="brand"> |
53 | | - <h1>Azimuth</h1> |
54 | | - <p class="sub">Flash <strong>Azimuth</strong> release firmware over USB — same look as the on-device portal.</p> |
55 | | - </header> |
| 171 | +<div class="page"> |
| 172 | + <picture> |
| 173 | + <source media="(prefers-color-scheme: light)" srcset="logo/AzimuthLogo_Dark.png"/> |
| 174 | + <img class="logo" src="logo/AzimuthLogo_Light.png" width="220" alt="Azimuth"/> |
| 175 | + </picture> |
| 176 | + |
| 177 | + <p class="lede">Put the latest firmware on your tracker from the browser.</p> |
56 | 178 |
|
57 | | - <div class="card"> |
58 | | - <div class="hd">Install firmware</div> |
59 | | - <p class="hint">Use a <strong>USB data</strong> cable. Works in <strong>Chrome</strong> or <strong>Edge</strong> on desktop (Web Serial). Connect your <strong>Seeed XIAO ESP32-C3</strong>, put it in <strong>bootloader</strong> if prompted (hold BOOT, tap RST, release BOOT).</p> |
60 | | - <div class="btn-row"> |
61 | | - <esp-web-install-button manifest="manifest.json"> |
62 | | - <button slot="activate" type="button">Connect & flash Azimuth</button> |
63 | | - </esp-web-install-button> |
| 179 | + <section class="panel" aria-labelledby="h-flash"> |
| 180 | + <h2 id="h-flash">Install</h2> |
| 181 | + <div id="browserProblem" class="browser-problem" hidden role="alert"> |
| 182 | + Use <strong>Chrome</strong> or <strong>Edge</strong> on a <strong>computer</strong> (not a phone). This browser can’t use USB serial, so flashing from here won’t work. |
64 | 183 | </div> |
65 | | - <div class="callout"> |
66 | | - <strong>Factory reset / clean install:</strong> When the installer asks, choose to <strong>erase flash</strong> first. That clears saved Wi‑Fi and portal settings (like “Erase saved settings” on the device). Then the image is written fresh. |
| 184 | + <ol class="steps" id="installSteps"> |
| 185 | + <li>Use a USB cable that carries data (not charge-only).</li> |
| 186 | + <li>Plug in a <strong>Seeed XIAO ESP32-C3</strong>.</li> |
| 187 | + <li>Click the button below and pick the serial port.</li> |
| 188 | + </ol> |
| 189 | + <div id="serialInstaller"> |
| 190 | + <div class="flash-wrap"> |
| 191 | + <esp-web-install-button manifest="manifest.json"> |
| 192 | + <button slot="activate" type="button">Install firmware</button> |
| 193 | + </esp-web-install-button> |
| 194 | + </div> |
| 195 | + <details> |
| 196 | + <summary>Stuck? Bootloader mode</summary> |
| 197 | + Hold <strong>BOOT</strong>, tap <strong>RST</strong>, release <strong>BOOT</strong>, then try the button again. |
| 198 | + </details> |
67 | 199 | </div> |
68 | | - </div> |
| 200 | + </section> |
69 | 201 |
|
70 | | - <div class="card link-card"> |
71 | | - <div class="hd">After flashing</div> |
72 | | - <p class="hint">On your home Wi‑Fi, open the settings portal (mDNS):</p> |
73 | | - <p style="margin:0;font-size:1rem"><a href="http://azimuth.local:8080/" rel="noopener">http://azimuth.local:8080/</a></p> |
74 | | - <p class="hint" style="margin-top:.65rem;margin-bottom:0">If <code>.local</code> does not resolve, use your router’s DHCP list for the board IP and port <strong>8080</strong>. First-time setup can use the <strong>Azimuth-Setup</strong> AP at <code>http://192.168.4.1/</code> (port 80).</p> |
75 | | - </div> |
| 202 | + <section class="panel" aria-labelledby="h-erase"> |
| 203 | + <h2 id="h-erase">Start fresh (optional)</h2> |
| 204 | + <p>If the installer asks whether to erase memory first, say yes if you want Wi‑Fi and saved settings cleared—the same idea as “erase saved settings” on the device.</p> |
| 205 | + </section> |
76 | 206 |
|
77 | | - <p id="msg" class="err" style="display:none"></p> |
| 207 | + <section class="panel" aria-labelledby="h-after"> |
| 208 | + <h2 id="h-after">When it’s done</h2> |
| 209 | + <p>On your home network, open the setup page:</p> |
| 210 | + <p><a class="link-main" href="http://azimuth.local:8080/">azimuth.local:8080</a></p> |
| 211 | + <p class="fine-print">If that link doesn’t open, find the board in your router’s device list and use its IP with port <strong>8080</strong>. Brand-new devices can join Wi‑Fi through the <strong>Azimuth-Setup</strong> network, then open <code>192.168.4.1</code> in the browser (port 80).</p> |
| 212 | + </section> |
78 | 213 | </div> |
79 | 214 | <script> |
80 | | -(function(){ |
81 | | - if(!("serial" in navigator)){ |
82 | | - var m=document.getElementById("msg"); |
83 | | - m.style.display="block"; |
84 | | - m.textContent="This browser does not support Web Serial. Use Chrome or Edge on a desktop to flash."; |
85 | | - } |
| 215 | +(function () { |
| 216 | + if ("serial" in navigator) return; |
| 217 | + var bp = document.getElementById("browserProblem"); |
| 218 | + if (bp) bp.hidden = false; |
| 219 | + var steps = document.getElementById("installSteps"); |
| 220 | + if (steps) steps.hidden = true; |
| 221 | + var el = document.getElementById("serialInstaller"); |
| 222 | + if (el) el.hidden = true; |
86 | 223 | })(); |
87 | 224 | </script> |
88 | 225 | </body> |
|
0 commit comments