Skip to content

First-run setup: the Wi-Fi network is a dropdown, Cloud is Recommended, and the phone setup asks one thing at a time (W-1073) - #374

Merged
wr merged 14 commits into
mainfrom
wells/w-1073-first-run-setup-wi-fi-network-as-a-dropdown-cloud
Oct 18, 2026
Merged

wr merged 14 commits into
mainfrom
wells/w-1073-first-run-setup-wi-fi-network-as-a-dropdown-cloud

Conversation

@wr

@wr wr commented Oct 18, 2026 •

Copy link
Copy Markdown
Owner

Three changes to the first run, from the walkthrough of a new kit.

Screens, today and after, side by side: https://claude.ai/artifact/T4omY22whjoz3UnwBW1kUB (private to Wells)

What changed

Written for someone who has never heard of BirdNET (a kit opened as a gift): the default path needs no technical word, and the technical choices are a link off it.

  • Kit setup portal, Wi-Fi (firmware/src/ff_portal.h): the networks are one dropdown, strongest first, with Other… for a hidden network, instead of a list that could run off the screen plus a separate Network field (the Macintosh mini setup page's pattern). It starts on "Choose a network", not the strongest network nearby, which may be a neighbour's; Save waits for a choice. An open network hides the password. A frame that knows its network (the KEY3 hold) has it chosen.
  • Kit setup portal, own server: on Cloud the page asks only for the Wi-Fi. I have my own Featherframe server under Save opens one field, Your Featherframe server ("Leave it blank to find it on your network."), and becomes Use Featherframe Cloud instead. A frame already on its own server opens with the field showing. "After you save, your frame will show a QR code."
  • Cloud's "Set up your frame" page (hosted/src/pages.ts), after a look at Sonos's and Oura's setup flows: full screens, as a phone app's setup is drawn, not a card. A column on a computer.
    • Welcome: the marketing page's scene full-bleed, cycling through its four birds: the site's clips of the cardinal, Eastern Bluebird, Tufted Titmouse and Black-capped Chickadee joined into one 24 s loop (public domain and CC BY-SA excerpts; the one playing is credited in the video's corner in the site's own words; six seconds each, each cropped to keep its bird clear of the frame, 4:3, 720 wide, no sound, 740 KB). The page follows the video's clock: each bird's "New detection" a moment after it lands, then the walnut frame, hanging off the video's bottom edge, repaints to its illustration. The frame is the kit being set up, from what it reported of its panel: the 13" colour frame for an EE02, the 10" gray one otherwise. It is cut in two, the walnut over a screen of its own, so only the screen repaints, dark, then light, then the illustration, as e-paper does. Only while the welcome shows; the cardinal, still, with reduced motion or no script. The Worker answers the video by byte range (util.rangeResponse, tested), since Safari plays nothing otherwise; a full cycle checked in WebKit. "Hear a bird outside. See it on your frame." "Your frame will show the latest bird heard near you, as a 19th-century illustration. Setting it up takes about two minutes." Get started, and I already have an account, which goes straight to the email as Sign in ("We'll email you a code to add this frame.").
    • Choose a station near you (1 of 2): "Your frame will show the birds heard by a station near you. Stations are microphones that people set up at home and share on BirdWeather." A ZIP code or town search with the usual location arrow inside it ("Use current location") beside Find; stations near the phone's guessed place, nearest first: each one's distance large on the right ("2 mi / away"), "38 kinds of birds this week" under its name, and the nearest tagged Closest. A search or location that fails is a callout that says what to do ("Location is off. Turn on location for this browser in your phone's settings, or enter your ZIP code or town."), not a muted line. I have my own BirdNET station swaps in Your BirdNET station: "Your frame will show the birds your station hears. Which one do you have?", BirdNET-Pi / BirdNET-Go, and once one is chosen, What happens next: "You'll create your account. The Featherframe webapp will show you how to connect your BirdNET-Pi. It takes a few minutes. Your frame will show the next bird your station hears."
    • Create your account (2 of 2): Email, "We'll send you a link to confirm your account. Your email address will never be shared or sold to anyone.", Set up frame.
    • Type and states: body text and list rows 17 px, field labels 15 px; the chosen row tinted and ringed in the accent. Location off, a place not found and no stations nearby are notices (gray, an "i"), with balanced lines so no word stands alone; only a failed request is a warning (red, a "!"). The video's credit fades between clips and stops short of the frame. The wordmark's face is preloaded and set to wait rather than flash Georgia. The email step opens with its field focused; while any field has the keyboard up, the button follows the form instead of sitting at the bottom of the screen, so the keyboard never covers it.
    • Color: the buttons, the chosen radio and the Closest tag are walnut a shade lighter at the top (a vertical gradient with a faint top edge, picked from seven colorways); links stay walnut. The chosen row is a warm tint with its radio filled, no ring. Location off is a tooltip from the location button over the page, gone at the next tap or keystroke, so nothing below moves; the button shows the page's spinner while it looks.
    • Each screen: a big title, one line, the field, the main button at the bottom of the screen in the same place every time, a back arrow. Still one form and one POST with the same fields; a page shown again for an error opens on that error's screen; Enter never posts a half-filled form. Eleven small webp files (each kit's frame and its screen showing each bird) and the video from site/public, bundled into the Worker and served like its icons.
  • Future tense for what comes next on the kit's page and in the welcome email ("Its first picture will appear within a minute").
  • docs/STYLE.md: future tense for what comes next; sign-ups read like everyone else's; first run is written for someone who has never heard of BirdNET, with technical choices as a link and never "No" as a default answer; the first-run pages may say "birds".

Verified

  • Cloud: vitest 319 passed (new: the steps, the error's step, the colour kit's frame, telling the kits apart, what comes next for an own detector); tsc --noEmit clean.
  • Setup page in WebKit at phone width (360, 390, 440), light and dark: both kits' welcome and a repaint frame by frame (only the screen changes), the credit's fade and its distance from the frame, stations found, location refused, a failed request, BirdNET-Go chosen, the email step focused and blurred; the script face loads with display: block; no script errors.
  • Portal: rendered with firmware/tools/portal_preview.py and driven in headless Chrome at phone width: choosing a network fills the form, an open network hides the password, Other… shows Network name, the placeholder blocks Save, a known frame's network is chosen, Save goes through to Connected, no script errors, light and dark.
  • Setup page: driven through every path in headless Chrome: Continue waits for a station, Back, BirdNET-Go skips the station, Enter, and the final POST carries source, station, email, tz and km as before.

Not covered

  • On a kit: the portal is not flashed yet (CI builds the firmware). It ships with the next firmware release.
  • On Cloud: not deployed. It goes out with the next wrangler deploy; that deploy is also the first bundle with .webp and .mp4 files (new rules globs beside the PNGs, about 800 KB in all; a dry run needs Docker, which isn't running here).

Wiki, when this ships

The setup page and Change Wi-Fi steps describe the old list and the one-page setup. This goes to the wiki with the release and the deploy, not before (check_copy.py --wiki clean):

diff --git a/Flash-the-frame.md b/Flash-the-frame.md
index d0f20a7..ab9f8fc 100644
--- a/Flash-the-frame.md
+++ b/Flash-the-frame.md
@@ -29,7 +29,7 @@ Firmware from the installer starts on Featherframe Cloud, and then shows a six-l
 1. Hold **KEY3** for 3 seconds. The frame opens **Featherframe-Setup**.
 2. On your phone, join **Featherframe-Setup**.
 3. Tap **Connect to Wi-Fi**. Leave **Network** and **Password** blank to keep the frame's Wi-Fi.
-4. Under **Server**, choose **Self-hosted**.
+4. Tap **I have my own Featherframe server**.
 5. Enter your server's address with `http://` and the port, for example `http://birdnet.local:8181`. Or leave it blank, and the frame finds the server on your network.
 6. Tap **Save**.
 
diff --git a/Set-up-your-frame.md b/Set-up-your-frame.md
index 802c943..6076ba0 100644
--- a/Set-up-your-frame.md
+++ b/Set-up-your-frame.md
@@ -15,10 +15,9 @@ Connect the frame to power. The screen shows three setup steps, and the light br
 ## 2. Connect it to Wi-Fi
 
 1. On your phone, open the Wi-Fi settings and join **Featherframe-Setup**. The **Connect to Wi-Fi** page opens.
-2. Tap your Wi-Fi network. If it isn't in the list, tap **Refresh**, or type its name under **Network**.
-3. Enter its password under **Password**.
-4. Under **Server**, keep **Featherframe Cloud**.
-5. Tap **Save**.
+2. Choose your Wi-Fi network under **Network**. If it isn't there, tap **Refresh**. For a hidden network, choose **Other…** and type its name.
+3. Enter its password under **Password**. An open network has none.
+4. Tap **Save**.
 
 On Android, if your phone asks whether to stay connected to a network without internet, choose to stay connected.
 
@@ -41,11 +40,14 @@ The code works for a day, and the frame says when it expires. If it expires, the
 
 ## 4. Fill in the setup page
 
-1. Enter your email address. You'll use it to sign in to your Featherframe webapp.
-2. Under **Detection source**, choose where the frame's species come from:
-   - **A BirdWeather station near me:** no equipment needed. Choose a station near where the frame will hang. To look somewhere else, type a ZIP code or town and tap **Find**, or tap **Use my location**. If no station is near you, type a larger town nearby and choose the closest one.
-   - **My BirdNET-Pi** or **My BirdNET-Go:** your own detector. You'll connect it after setup. See [Detection sources](Detection-sources).
-3. Tap **Set up frame**.
+1. Tap **Get started**.
+2. Choose a station near where the frame will hang, then tap **Continue**. Stations are microphones that people set up at home and share on BirdWeather, and the frame will show the birds the one you choose hears. To look somewhere else, type a ZIP code or town and tap **Find**, or tap the arrow in the search box to use your current location. If no station is near you, type a larger town nearby and choose the closest one.
+3. Under **Create your account**, enter your email. You'll use it to sign in to your Featherframe webapp.
+4. Tap **Set up frame**.
+
+If you have your own BirdNET-Pi or BirdNET-Go, tap **I have my own BirdNET station** in step 2 and choose it instead. You'll connect it after setup. See [Detection sources](Detection-sources).
+
+If you already have a Featherframe Cloud account, tap **I already have an account** instead of **Get started**, and enter your email. We'll email you a code that adds the frame.
 
 Your phone is now signed in to your Featherframe webapp, at [cloud.featherframe.app](https://cloud.featherframe.app).
 
diff --git a/Style-guide.md b/Style-guide.md
index 5844191..4acaf97 100644
--- a/Style-guide.md
+++ b/Style-guide.md
@@ -44,6 +44,13 @@ in the repository, which wins if they disagree.
 - **Typography.** Sentence case for headings, labels and buttons. En dash
   for number ranges (1–5). Curly quotes are optional; be consistent within
   a page.
+- **Future tense for what comes next.** "After you save, your frame will
+  show a code", not "your frame shows a code". What is always true stays in
+  the present: "the frame shows the latest detection". A "when" clause stays
+  present too: "When the frame shows a code, scan it."
+- **Sign-up and sign-in read like everyone else's.** "Create your account",
+  "Email", "We'll send you a link to confirm it." Not "You'll sign in with
+  it to manage your frame."
 - **Times, as people write them.** A 12-hour clock with AM and PM: 7:00 PM,
   6:30 AM. A span of time takes an arrow: 10:00 PM → 6:00 AM, Sunset →
   Sunrise. A recent moment is relative: just now, 4 min ago, 2 hours ago,
@@ -86,8 +93,10 @@ of Asia*, *The Birds of Great Britain*.
 
 **"Bird."** In the webapp, never use "bird" for a detection, a species or an
 update: "a new detection reaches the frame", not "a new bird shows up".
-Names and titles that contain the word are fine. The wiki, README and
-marketing page may say "bird" where a person would.
+Names and titles that contain the word are fine. The wiki, README,
+marketing page and the first-run setup pages (the kit's Wi-Fi page, Cloud's
+"Set up your frame") may say "bird" where a person would: "Your frame will
+show the birds heard by a station near you."
 
 **"Plate."** A plate is a numbered sheet of a printed book. The webapp never
 says it (an owner sees illustrations). Docs may, once the page has said what
@@ -117,6 +126,12 @@ a plate is, and the corner mark cites one ("Plate CLIX").
 - **Errors say what to do**, not what broke inside.
 - **No architecture.** A section never opens with an intro about how the
   system works.
+- **First run is written for someone who has never heard of BirdNET** (a kit
+  opened as a gift). The default path needs no technical word and can be
+  taken with confidence. A technical choice (a detector of your own, a
+  server of your own) is a link off the default, for those who know to look
+  for it: "I have my own BirdNET station". Never make "No" the default
+  answer.
 
 ## The frame's own screens
 
diff --git a/Troubleshooting.md b/Troubleshooting.md
index e51370f..318576e 100644
--- a/Troubleshooting.md
+++ b/Troubleshooting.md
@@ -107,7 +107,7 @@ In your Featherframe webapp, go to **Detection source**, and paste the URL of th
 2. On your phone, join **Featherframe-Setup**.
 3. Tap **Connect to Wi-Fi**.
 4. Tap **Show networks**.
-5. Tap the new network.
+5. Choose the new network under **Network**.
 6. Enter its password under **Password**.
 7. Tap **Save**.

Refs W-1073

…d, and the phone setup asks one thing at a time (W-1073)

- The kit's setup portal shows the networks as one dropdown, strongest
  first, with "Other…" for a hidden network, instead of a list that could
  run off the screen plus a separate Network field. An open network hides
  the password. Save waits for a network to be chosen. A frame that knows
  its network has it chosen already.
- Under Server, Featherframe Cloud is tagged Recommended and Self-hosted
  Advanced.
- Cloud's "Set up your frame" page is three steps: detection source, then a
  BirdWeather station (skipped for a BirdNET-Pi or BirdNET-Go), then the
  email. Still one form and one POST; a page shown again for an error opens
  on that error's step. Without its script, every step shows at once.

Refs: W-1073
@linear-code

linear-code Bot commented Oct 18, 2026

Copy link
Copy Markdown

W-1073

wr added 10 commits October 18, 2026 00:13
… is, a normal sign-up, future tense (W-1073)

- Step 1 asks "Do you have a bird detector?" with No (a BirdWeather station
  near you, no equipment) or Yes, BirdNET-Pi / Yes, BirdNET-Go.
- The station step says what BirdWeather is, and "Use my location" is
  "Find stations near me", above the ZIP code search.
- The last step is "Create your account": Email, "We'll send you a link to
  confirm it."
- What happens next is said in the future tense, on the kit's setup page and
  in the welcome email ("your frame will show a QR code").
- The page sits at the top, so nothing above a step moves between steps.
- docs/STYLE.md: future tense for what comes next; sign-ups read like
  everyone else's.

Refs: W-1073
…first, BirdNET and your own server behind a link (W-1073)

- Cloud's setup page is two steps. Step 1 is "Choose a station near you",
  in plain words ("Your frame will show the birds heard by a station near
  you. Stations are microphones that people set up at home and share on
  BirdWeather."), each station "2 mi away · 38 kinds of birds this week".
  "I have a BirdNET-Pi or BirdNET-Go" swaps in a choice of the two. Step 2
  is Create your account. No question is answered with a default "No".
- The kit's Wi-Fi page asks only for the Wi-Fi on Cloud: the server choice
  is behind "I have my own Featherframe server". A frame already on its own
  server shows the choice open.
- docs/STYLE.md: first run is written for someone who has never heard of
  BirdNET; the first-run pages may say "birds".

Refs: W-1073
… a plain own-server switch (W-1073)

- Cloud's setup page opens each step on the setup screens' own wren, cut
  from the boot art: flying in on step 1, perched on step 2 (two small webp
  files bundled into the Worker and served like its icons, so a page load
  wakes nothing). The big wordmark, the title, the bar and "Step 1 of 2" give
  way to a smaller wordmark and two dots beside each step's heading.
- The station search has the usual location arrow inside the field ("Use
  current location"), beside Find, instead of a "Find stations near me"
  button.
- "I have my own BirdNET station" is the link to a detector of one's own.
- The kit's Wi-Fi page: "I have my own Featherframe server" opens one field,
  Your Featherframe server (blank finds it on the network), and becomes "Use
  Featherframe Cloud instead". No second choice to make.

Refs: W-1073
… it, the frame turns to it (W-1073)

The wren from the boot screens said nothing about what happens. Step 1 now
opens on a small strip: Audubon's singing Carolina Wren (cut in colour from
Havell plate 78), notes travelling to a garden microphone, a dot to a
Featherframe, and the frame turning from the Northern Cardinal to the
Carolina Wren plate as the gray kit draws it. It plays once; with reduced
motion it is its last frame. Step 2 shows the frame with the wren. Three
small webp files, served like the Worker's icons.

Refs: W-1073
…a feeder, "New detection", the frame turns to it (W-1073)

The song-to-microphone strip read like a diagram. Step 1 now opens on the
marketing page's own scene: the U.S. Fish and Wildlife Service's cardinal
at a feeder (public domain), the phone's "New detection · Northern Cardinal
· Just now" sliding in, and the walnut frame on the feeder repainting from
the Carolina Wren to the cardinal. It plays once; with reduced motion it is
its end. Step 2 shows the walnut frame with the cardinal. Three small webp
files, served like the Worker's icons.

Refs: W-1073
…nal scene, then one question a screen (W-1073)

After a look at Sonos's and Oura's setup flows on Mobbin: the page is now
full screens, not a card. A welcome on the cardinal at the feeder with the
"New detection" and the frame repainting, "Hear a bird outside. See it on
your frame.", Get started and "I already have an account" (straight to the
email, as Sign in). Then "Choose a station near you" and "Create your
account": a big title, one line, the field, the button at the bottom of the
screen, a back arrow and "1 of 2". Same form and POST underneath.

Refs: W-1073
…me hanging off its foot (W-1073)

The welcome's scene is now the site's own U.S. Fish and Wildlife Service
cardinal video (public domain), cropped to 4:3, 720 wide, no sound, 300 KB,
looping, with the walnut frame overlapping the video's bottom edge. It
plays only on the welcome, and with reduced motion it is its still.

Safari asks for a video in byte ranges and plays nothing from a server that
answers each with the whole file, so the Worker answers that file by range
(util.rangeResponse, tested). Checked in WebKit: it asks bytes=0-1, then the
rest, and plays.

Refs: W-1073
The welcome's video is now the site's four clips joined into one 24 s loop
(cardinal, Eastern Bluebird, Tufted Titmouse, Black-capped Chickadee; six
seconds each, each cropped to keep its bird clear of the frame; 740 KB).
The page follows the video's clock: a bird's "New detection" a moment after
it lands, then the frame repaints to its illustration. The walnut frames
are the site's renders, the bluebird's and the chickadee's laid onto the
cardinal's from the site's screen images and toned to match. With reduced
motion, or no script, it is the cardinal, still. Checked a full cycle in
WebKit.

Refs: W-1073
… (W-1073)

Three of the four clips are CC BY-SA: the credit for the one playing sits in
the video's corner, in the site's own words.

Refs: W-1073
…arer errors and stations (W-1073)

The welcome's frame is cut in two, the walnut over a screen of its own, so
a repaint flashes only the screen. The page shows the kit being set up:
the 13-inch colour frame for an EE02, the 10-inch gray one otherwise, from
what the kit reported of its panel.

A location or search that fails is a callout that says what to do, not a
muted line. Each station shows its distance on the right, and the nearest
is tagged Closest. Choosing BirdNET-Pi or BirdNET-Go says what happens
next. The email hint promises the address is never shared or sold.

Refs: W-1073
@wr
wr force-pushed the wells/w-1073-first-run-setup-wi-fi-network-as-a-dropdown-cloud branch from 9e1a842 to 18173fc Compare October 18, 2026 14:24
wr added 3 commits October 18, 2026 10:43
…t alarm (W-1073)

Body text and list rows are 17 px, field labels 15 px. The chosen station
or detector is tinted and ringed in the accent, where its 7 % tint was
nearly the page's own gray. A location that is off, a place not found and
no stations nearby are notices; only a failed request is a warning, and
the notice's lines are balanced so no word stands alone. The video's
credit fades between clips and stops short of the frame. The wordmark's
face is preloaded and never shown in a stand-in. The email step opens with
its field focused, and while a field has the keyboard up the button
follows the form, so the keyboard never covers it.

Refs: W-1073
…a tooltip (W-1073)

The chosen station or detector is a warm tint with its radio filled in the
accent; the ring around it is gone. Location off, a browser that can't
share it, or a location not found is a tooltip from the location button,
over the page, gone at the next tap or keystroke, so nothing below moves;
the button shows the page's spinner while it looks. The buttons, the
radio and the Closest tag take their fill from --accent-fill, so the
accent can be a gradient.

Refs: W-1073
…W-1073)

Wells's pick of the colorways: the buttons, the chosen radio and the
Closest tag are a vertical walnut gradient, barely lighter at the top, with
a faint top edge; dark mode lightens the same way. Links stay walnut.

Refs: W-1073
@wr
wr merged commit 85c14c3 into main Oct 18, 2026
6 checks passed
@wr
wr deleted the wells/w-1073-first-run-setup-wi-fi-network-as-a-dropdown-cloud branch October 18, 2026 16:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant