{% if a.guide %}{{ a.title }}{% else %}{{ a.title }}{% endif %}
+{{ a.text }}
+ {{ a.fact }} + {% if a.guide %}Its page in the guide →{% endif %} +diff --git a/site/content/apps/index.md b/site/content/apps/index.md new file mode 100644 index 0000000..e5d5c5b --- /dev/null +++ b/site/content/apps/index.md @@ -0,0 +1,5 @@ ++++ +title = "The Apps" +description = "Everything on the device, an App at a time: what it does, a screen from the device itself, and where its guide is." +template = "apps.html" ++++ diff --git a/site/data/apps.toml b/site/data/apps.toml index f18b1e9..a7c1918 100644 --- a/site/data/apps.toml +++ b/site/data/apps.toml @@ -1,72 +1,133 @@ -# The App cards on the home page. Each says what the firmware does today (docs/milestones/W1.md, Q185): -# what isn't built is marked planned, with its milestone. `icon` is a cell of static/img/icons-*.svg. +# The Apps, in the Launcher's order: the Apps page shows them all, the home page those marked +# `featured`. Each says what the firmware does today (docs/milestones/W1.md, Q185); what isn't +# built is marked planned, with its milestone. `icon` is a cell of static/img/icons-*.svg (three +# across: 0 planned, 1 LoRa, 2 GNSS, 3 Wi-Fi, 4 Gemini, 5 IRC, 6 Notes, 7 System, 8 Storage, +# 9 Settings, 10 SSH, 11 Shell, 12 Games). `screen` is a file in static/screens/, a screenshot +# from the device at 2x; an App without one has none. [[app]] -num = "01" -tag = "LoRa Scanner" -title = "See what is on the air" -text = "Lists every packet it hears with time, RSSI, SNR, sender and hops, reading the Meshtastic or MeshCore header. A Sweep shows signal strength from 863 to 870 MHz. Capture to a pcap for Wireshark." -fact = "Only listens, never transmits" -icon = 1 +tag = "IRC" +title = "Chat from the keyboard" +text = "Join channels and type commands as you would anywhere, with a log a day written to the SD card. It stays connected when you leave the App, and the Launcher marks unread messages." +fact = "Logs to SD" +icon = 5 +guide = "/guide/irc/" + +[[app]] +tag = "Wi-Fi Tools" +title = "Scan the air for networks" +text = "The networks around you, sorted and filtered; how busy each channel is; a tracker that follows one network's signal as you walk. Scans log to a CSV file on the SD card." +fact = "Scans log to CSV" +icon = 3 +guide = "/guide/wifi-tools/" [[app]] -num = "02" tag = "GNSS" -title = "Find your place in the sky" -text = "Position and Sky views show where you are and which satellites you can see. Tracks save to the SD card as GPX, and the clock follows the fix." -fact = "Sky view and GPX Tracks" +title = "Find your place, and your way" +text = "Position, a Sky view of every satellite, and a Compass that leads back to a place you marked. Tracks save to the SD card as GPX, and the clock follows the fix." +fact = "No magnetometer: north from walking, or the sun" icon = 2 +guide = "/guide/gnss/" +screen = "apps/gnss.png" +alt = "The GNSS App's sky view: a circle with the satellites of four constellations as coloured dots, filled when used, and a legend counting them: GPS 6 of 12, GLONASS 3 of 4, Galileo 2 of 2, BeiDou 3 of 3, 3D Fix" +featured = true [[app]] -num = "03" tag = "Gemini" title = "Browse Geminispace" text = "Follow links with Tab and Enter, go Back to where you were, bookmark pages and save them to the SD card to read offline." fact = "Certificates trusted on first use" icon = 4 +guide = "/guide/gemini/" +screen = "apps/gemini.png" +alt = "The Gemini App's start page: Gemini, your bookmarks and Saved Pages, then a few places to start, and a saved page from bbs.geminispace.org" +featured = true [[app]] -num = "04" -tag = "IRC" -title = "Chat from the keyboard" -text = "Join channels and type commands as you would anywhere, with daily logs written to the SD card." -fact = "Logs to SD" -icon = 5 +tag = "LoRa Scanner" +title = "See what is on the air" +text = "Lists every packet it hears with its signal, and reads the Meshtastic and MeshCore headers, and MeshCore's public channel. A Sweep shows signal strength from 863 to 870 MHz. Capture to a pcap for Wireshark." +fact = "Only listens, never transmits" +icon = 1 +guide = "/guide/lora-scanner/" +screen = "apps/lora.png" +alt = "The LoRa Scanner's Sweep: bars of signal strength from 863.0 to 870.0 MHz with peak marks, a waterfall under them, and a footer reading floor -100, 866.3 MHz at -88 dBm" +featured = true [[app]] -num = "05" -tag = "Wi-Fi tools" -title = "Scan the air for networks" -text = "See the networks around you, sort and filter the list, and log scans to a CSV file on the SD card." -fact = "Scans log to CSV" -icon = 3 - -[[app]] -num = "06" -tag = "Notes" -title = "Write it down" -text = "Keep plain text notes on the SD card, of any size: a megabyte opens as fast as a line. There is no save key: the editor writes five seconds after you stop typing, so a power cut never costs the note." -fact = "Plain .txt files in /notes" -icon = 6 - -[[app]] -num = "07" tag = "Storage" title = "Manage the SD card" text = "Browse, copy, cut, rename and delete with a clipboard. Opens text, pictures, hex, captures, tracks and update files. Press w and the card is a web page in your phone's browser: upload and download with nothing to install." fact = "Checks every copy by size" icon = 8 +guide = "/guide/storage/" +screen = "apps/storage.png" +alt = "The Storage App at the top of the SD card: the folders captures, gemini, gnss, irc, notes, pictures, screenshots and system, with 15 GB free" +featured = true + +[[app]] +tag = "Notes" +title = "Write it down" +text = "Keep plain text notes on the SD card, of any size: a megabyte opens as fast as a line. There is no save key: the editor writes five seconds after you stop typing, so a power cut never costs the note." +fact = "Plain .txt files in /notes" +icon = 6 +guide = "/guide/notes/" +screen = "apps/notes.png" +alt = "The Notes App listing the notes in /notes, each under its first line, with its date" + +[[app]] +tag = "SSH" +title = "A terminal on another machine" +text = "Log in to a server with a password or with the device's own key, and run a shell, vim or top on the Cardputer's screen, in sixteen colours. Files go with scp, from the Shell." +fact = "The session stays open when you leave" +icon = 10 +guide = "/guide/ssh/" +screen = "apps/ssh.png" +alt = "The SSH App: a host connected to before, then New connection and This device's key" +featured = true + +[[app]] +tag = "Shell" +title = "The console, on the device" +text = "Every command the firmware's console knows, typed on its own keyboard: the card's files, ping, nslookup, traceroute, a certificate check, the radio and the GNSS receiver. Tab completes." +fact = "The same commands as over USB" +icon = 11 +guide = "/guide/shell/" +screen = "apps/shell.png" +alt = "The Shell after uname -a: roro9stack, its version, xtensa-lx7 esp32s3, and an empty line to type the next command" + +[[app]] +tag = "Games" +title = "For when the radio is quiet" +text = "Pong, Snake and Tetris with its tune, Minesweeper, 2048, and Asteroids steered by leaning the device. Pong can be steered by tilting too." +fact = "The best of each is kept" +icon = 12 +guide = "/guide/games/" +screen = "apps/games.png" +alt = "The Games App: six icons in a row, Pong chosen on a filled tile, and under them Pong and its longest rally" +featured = true [[app]] -num = "08" tag = "System" title = "Watch it think" text = "Per-core load, every task and its spare stack, free heap, network traffic, battery and chip temperature, live." fact = "Live and read-only" icon = 7 +guide = "/guide/system/" +screen = "apps/system.png" +alt = "The System App's overview: the load of both cores, 84 KB of memory free, the network's traffic, the battery at 99 percent, uptime and temperature, and a graph" + +[[app]] +tag = "Settings" +title = "Make it yours" +text = "The device's name and region, brightness and seven colour themes, GNSS and the radio, Wi-Fi networks and a WireGuard VPN, firmware updates and the Debug Console, in five groups." +fact = "Every theme dark and light" +icon = 9 +guide = "/guide/settings/" +screen = "apps/settings.png" +alt = "Settings, in five groups: This device, Display, GNSS and radio, Network and System" [[app]] -num = "09" tag = "Planned" title = "A mesh messenger" text = "Sending and reading messages on a Meshtastic-compatible mesh. The radio listens today, in the LoRa Scanner; transmitting is the next step and waits for a second node to test with." diff --git a/site/static/css/site.css b/site/static/css/site.css index 2b78a2f..f16b0d0 100644 --- a/site/static/css/site.css +++ b/site/static/css/site.css @@ -142,11 +142,32 @@ section { padding-top: 64px; padding-bottom: 64px; } .card .fact::before { content: ""; width: 8px; height: 8px; background: var(--cyan); flex: none; } .card.planned .tag { color: var(--orangetext); } .card.planned .fact::before { background: var(--orange); } -.ic { width: 48px; height: 48px; flex: none; background-image: var(--icons); background-repeat: no-repeat; background-size: 144px 192px; image-rendering: pixelated; } +.ic { width: 48px; height: 48px; flex: none; background-image: var(--icons); background-repeat: no-repeat; background-size: 144px 288px; image-rendering: pixelated; } .i0 { background-position: 0 0; } .i1 { background-position: -48px 0; } .i2 { background-position: -96px 0; } .i3 { background-position: 0 -48px; } .i4 { background-position: -48px -48px; } .i5 { background-position: -96px -48px; } .i6 { background-position: 0 -96px; } .i7 { background-position: -48px -96px; } .i8 { background-position: -96px -96px; } -.i9 { background-position: 0 -144px; } +.i9 { background-position: 0 -144px; } .i10 { background-position: -48px -144px; } .i11 { background-position: -96px -144px; } +.i12 { background-position: 0 -192px; } +/* The Apps page: an App a row, its words beside a screen from the device. */ +.apps { display: flex; flex-direction: column; gap: 24px; margin-top: 40px; } +.app { background: var(--s2); padding: 32px; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 400px); gap: 32px; align-items: center; scroll-margin-top: 96px; } +.app-text { display: flex; flex-direction: column; gap: 16px; min-width: 0; } +.app .card-top { justify-content: flex-start; gap: 16px; } +.app .tag { font: 500 12px/16px var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--cyantext); } +.app h2 { font-size: 24px; line-height: 28px; } +.app h2 a { color: inherit; text-decoration: none; } +.app h2 a:hover, .app h2 a:focus-visible { text-decoration: underline; text-underline-offset: 4px; } +.app p { color: var(--muted); } +.app .fact { display: flex; align-items: center; gap: 8px; font: 500 12px/16px var(--mono); letter-spacing: .04em; } +.app .fact::before { content: ""; width: 8px; height: 8px; background: var(--cyan); flex: none; } +.app.planned .tag { color: var(--orangetext); } +.app.planned .fact::before { background: var(--orange); } +.app-guide { font-size: 14px; } +.app-shot { margin: 0; } +.app-shot img { display: block; width: 100%; height: auto; } +.cards-more { margin-top: 24px; } +.card h3 a { color: inherit; text-decoration: none; } +.card h3 a:hover, .card h3 a:focus-visible { text-decoration: underline; text-underline-offset: 4px; } .cards-note { margin-top: 24px; font-size: 14px; line-height: 20px; color: var(--muted); } /* Real screenshots */ @@ -225,6 +246,7 @@ footer small { display: block; max-width: 760px; } section { padding-top: 48px; padding-bottom: 48px; } .slab, .updates, .cta { padding: 24px; } .panel, .card { padding: 24px; } + .app { grid-template-columns: minmax(0, 1fr); padding: 24px; gap: 24px; } .hero .caption { margin-top: -24px; } .num-row .big { font-size: 48px; line-height: 48px; min-width: 120px; } } diff --git a/site/static/screens/apps/games.png b/site/static/screens/apps/games.png new file mode 100644 index 0000000..e651c7c Binary files /dev/null and b/site/static/screens/apps/games.png differ diff --git a/site/static/screens/apps/gemini.png b/site/static/screens/apps/gemini.png new file mode 100644 index 0000000..01a62bc Binary files /dev/null and b/site/static/screens/apps/gemini.png differ diff --git a/site/static/screens/apps/gnss.png b/site/static/screens/apps/gnss.png new file mode 100644 index 0000000..9d5a7c6 Binary files /dev/null and b/site/static/screens/apps/gnss.png differ diff --git a/site/static/screens/apps/lora.png b/site/static/screens/apps/lora.png new file mode 100644 index 0000000..485819d Binary files /dev/null and b/site/static/screens/apps/lora.png differ diff --git a/site/static/screens/apps/notes.png b/site/static/screens/apps/notes.png new file mode 100644 index 0000000..d6be791 Binary files /dev/null and b/site/static/screens/apps/notes.png differ diff --git a/site/static/screens/apps/settings.png b/site/static/screens/apps/settings.png new file mode 100644 index 0000000..096e242 Binary files /dev/null and b/site/static/screens/apps/settings.png differ diff --git a/site/static/screens/apps/shell.png b/site/static/screens/apps/shell.png new file mode 100644 index 0000000..e409ad7 Binary files /dev/null and b/site/static/screens/apps/shell.png differ diff --git a/site/static/screens/apps/ssh.png b/site/static/screens/apps/ssh.png new file mode 100644 index 0000000..f7bd903 Binary files /dev/null and b/site/static/screens/apps/ssh.png differ diff --git a/site/static/screens/apps/storage.png b/site/static/screens/apps/storage.png new file mode 100644 index 0000000..70f9f74 Binary files /dev/null and b/site/static/screens/apps/storage.png differ diff --git a/site/static/screens/apps/system.png b/site/static/screens/apps/system.png new file mode 100644 index 0000000..15d4cb9 Binary files /dev/null and b/site/static/screens/apps/system.png differ diff --git a/site/templates/apps.html b/site/templates/apps.html new file mode 100644 index 0000000..f7b6ea3 --- /dev/null +++ b/site/templates/apps.html @@ -0,0 +1,32 @@ +{% extends "base.html" %} +{% block title %}The Apps: roro9stack{% endblock %} +{% block description %}{{ page.description }}{% endblock %} +{% block main %} +{% set apps = load_data(path="data/apps.toml", format="toml") %} +
{{ page.description }} On the device, the Launcher shows them as a grid of icons; Fn + h lists the keys of any screen.
+{{ a.text }}
+ {{ a.fact }} + {% if a.guide %}Its page in the guide →{% endif %} +