Components · States

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-badge

Compact status labels. The neutral badge is the default; semantic variants tint their text and ground. An optional dot signals live/active.

Default Live Beta Stale Offline
HTML
<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-alert

Inline messages bound to a region of the page (vs. the floating banner). A leading icon + accent rail carries the semantic; the ground stays paper.

Saved. All settings synced across devices.
Heads up. Rates are mid-market and refresh every 8 seconds.
Stale data. CHF → EUR hasn't updated in 5 minutes.
Couldn't connect. Check your network and try again.
HTML
<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-state

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

HTML
<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-progress

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

Fetching latest rates…
HTML
<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-status

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

Saved · 2 min ago Syncing… Local only Couldn't sync Sync conflict
HTML
<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 -->