States
How the UI communicates status — present, loading, empty, or wrong. Semantic colors (success / info / warning / error) carry meaning and never use the rebindable accent.
Badges
.across-badgeCompact status labels. The neutral badge is the default; semantic variants tint their text and ground. An optional dot signals live/active.
<span class="across-badge">Default</span>
<span class="across-badge across-badge--success"><span class="dot"></span>Live</span>
<span class="across-badge across-badge--warning">Stale</span>
Alerts
.across-alertInline messages bound to a region of the page (vs. the floating banner). A leading icon + accent rail carries the semantic; the ground stays paper.
<div class="across-alert across-alert--success">
<i class="ph-light ph-check-circle"></i>
<div><strong>Saved. </strong>All settings synced.</div>
</div>
Empty & Error States
.across-statePlaceholders for "nothing here yet" and "something went wrong" — an icon, a one-line title, a short explanation, and a single next action.
No pinned cities yet
Add a city to keep its time and weather close at hand.
Couldn't load rates
We lost the connection to the rate feed. Check your network.
<div class="across-state across-state--empty">
<div class="across-state__icon"><i class="ph-light ph-bookmark-simple"></i></div>
<h4 class="across-state__title">No pinned cities yet</h4>
<p class="across-state__desc">Add a city to keep it close at hand.</p>
<button class="across-btn across-btn--sm">Add a city</button>
</div>
Loading
.across-skeleton · .across-spinner · .across-progressThe only sanctioned ambient motion, and only while genuinely loading. Skeletons hold layout; the spinner marks an in-flight action; progress shows determinate or indeterminate work.
<span class="across-skeleton" style="width:70%;height:28px"></span>
<span class="across-spinner"></span>
<div class="across-progress"><div class="across-progress__bar" style="width:68%"></div></div>
<div class="across-progress"><div class="across-progress__bar across-progress__bar--indeterminate"></div></div>
Sync Status
.across-sync-statusA quiet awareness pill for local / synced / syncing / error / conflict. The dot is static by ruling — only a genuinely in-flight sync may pulse it (the motion budget); once settled it holds still, paired with a mono timestamp when liveness needs to read.
<span class="across-sync-status" data-state="synced">
<span class="across-sync-status__dot"></span>Saved · 2 min ago
</span>
<!-- data-state: local | synced | syncing | error | conflict -->

