Components
Components
The widgets the app draws, redrawn for the web at their real sizes from the app's own colours, spacing and artwork. Each component has its own page with a preview, React and Flutter code, variants, an API table and the tokens it uses.
All components
Grouped by what they do. Every page has the same layout: Preview, Implementation (React and Flutter), Variants, API reference and Design tokens.
| Category | Component | What it is |
|---|---|---|
| Actions | Icon tile | A tinted glass square with one glyph. |
| Actions | Button | A pill button: filled, glass or outline. |
| Actions | Toggle | A switch for an on or off setting. |
| Forms | Text field | A glass text field: label, control, help or error. |
| Navigation | Nav bar | The bottom tab bar with its notch, and the top bar. |
| Indicators | Cloud bar | Cloud cover as a glowing track. |
| Cards | Visibility card | The Astr zone with five rating bars. |
| Cards | Moon card | The painted moon for the phase angle. |
| Cards | Conditions card | Headline, cloud bar and the four rise and set cells. |
| Cards | Sky state background | The six illustrated skies. |
| Graphs | Conditions graph | Cloud, moon, prime view and now on one night. |
| Graphs | Cloud cover graph | The hourly cloud area. |
Tokens
Every widget is built from three Dart files. One pixel on this page is one logical pixel in the app, so the previews are the real sizes.
| Token | Value | Used for |
|---|---|---|
| surface | #0C0F11 | the app background |
| surfaceOverlay | #0C0F11 at 50% | card fill, behind a 2 px blur |
| surfaceGlass | #0C0F11 at 80% | inner panels: the cloud bar and time cells |
| borderPrimary | #1B3766 | card outline |
| borderSubtle | #0C1E33 | inner panel outline |
| accent | #448AFF | Explore button, zone pill outline |
| accentSecondary | #3A96FF | cloud fill, lit rating bars |
| cardRadius, innerRadius | 16, 12 | card and inner panel corners |
| miniCard | 164 by 154 | visibility and moon cards |
| conditionsCard | 345 by 242 | the headline card |
Dart source
app_colors.dart · AppColors
class AppColors { const AppColors._(); static const Color surface = Color(0xFF0C0F11); static const Color oledBlack = Color(0xFF000000); static const Color surfaceOverlay = Color(0x800C0F11); static const Color surfaceGlass = Color(0xCC0C0F11); static const Color accent = Color(0xFF448AFF); static const Color accentSecondary = Color(0xFF3A96FF); static const Color borderPrimary = Color(0xFF1B3766); static const Color borderSubtle = Color(0xFF0C1E33); static const Color borderSurface = Color(0xFF303A46); static const Color textPrimary = Color(0xFFF4F5F5); static const Color textSecondary = Color(0xFFDDDFE2); static const Color textMuted = Color(0xFFB3B7BC); static const Color textSubdued = Color(0xFF7D8792); static const Color zonePillFill = Color(0x333A96FF); static const Color zonePillText = Color(0xFFB0D5FF); static const Color ratingBarActive = Color(0xFF3A96FF); static const Color ratingBarInactive = Color(0x4D3C4957); static const Color cloudTrack = Color(0x4D3C4957); static const List<BoxShadow> glowShadow = <BoxShadow>[ BoxShadow(color: Color(0x40FFFFFF), blurRadius: 1), BoxShadow(color: Color(0xFF3A7FFF), blurRadius: 12.2, offset: Offset(0, 1)), ];}app-ui.css
.app-ui {--app-surface: #0c0f11;--app-overlay: rgb(12 15 17 / 0.5);--app-glass: rgb(12 15 17 / 0.8);--app-accent: #448aff;--app-accent-2: #3a96ff;--app-border-primary: #1b3766;--app-border-subtle: #0c1e33;--app-glow: 0 0 1px rgb(255 255 255 / 0.25), 0 1px 12.2px #3a7fff;}Conventions
So the site and the app stay one language as the site grows.
| Rule | Why |
|---|---|
| The app's Dart is the source of truth. The web redraw follows it. | A change belongs in the app first; the page then follows. |
| One CSS pixel is one logical pixel in the app. | Previews are the real sizes, so spacing carries over unchanged. |
React uses the CSS in app-ui.css, Flutter uses the Dart tokens. | Neither side invents a value the other does not have. |
| Colour comes from a system stop, never a new hex, for anything new. | The glass tile and button take their tones from the stops. |
| Each component page shows source that is read from the file that draws the preview. | The code on the page cannot drift from the component. |