Skip to content

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.

CategoryComponentWhat it is
ActionsIcon tileA tinted glass square with one glyph.
ActionsButtonA pill button: filled, glass or outline.
ActionsToggleA switch for an on or off setting.
FormsText fieldA glass text field: label, control, help or error.
NavigationNav barThe bottom tab bar with its notch, and the top bar.
IndicatorsCloud barCloud cover as a glowing track.
CardsVisibility cardThe Astr zone with five rating bars.
CardsMoon cardThe painted moon for the phase angle.
CardsConditions cardHeadline, cloud bar and the four rise and set cells.
CardsSky state backgroundThe six illustrated skies.
GraphsConditions graphCloud, moon, prime view and now on one night.
GraphsCloud cover graphThe 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.

TokenValueUsed for
surface#0C0F11the 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#1B3766card outline
borderSubtle#0C1E33inner panel outline
accent#448AFFExplore button, zone pill outline
accentSecondary#3A96FFcloud fill, lit rating bars
cardRadius, innerRadius16, 12card and inner panel corners
miniCard164 by 154visibility and moon cards
conditionsCard345 by 242the 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)),  ];}

Conventions

So the site and the app stay one language as the site grows.

RuleWhy
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.