1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! # arama-theme
//!
//! Token-driven styling for arama, backed by the Snora Design system
//! (RFC 010) with a runtime-selectable theme preset (RFC 011).
//!
//! ## Three styling layers
//!
//! A theme switch must move three layers together:
//!
//! * **A — Snora button tokens.** The four button style functions below
//! ([`primary`], [`ghost`], [`secondary`], [`danger`]) resolve the active
//! [`snora::design::Tokens`] from the current preset.
//! * **B — Snora container tokens.** Reserved for future card surfaces;
//! driven by the same [`tokens`].
//! * **C — Base iced theme.** [`iced_theme`] returns the matching iced
//! [`Theme`] for the application's `.theme()` callback, so the window
//! background and all stock iced widgets track the preset.
//!
//! ## Global state
//!
//! The active preset is stored in a global `AtomicU8` — the same lock-free
//! pattern arama uses for the i18n locale — so [`set_theme`] and the lookup
//! functions are safe to call from any thread without lifetime friction in
//! `view()`.
use ;
use ThemePreset;
use ;
use Tokens;
// ---------------------------------------------------------------------------
// Global preset state
// ---------------------------------------------------------------------------
static THEME_ID: AtomicU8 = new;
/// Set the active theme preset. Safe to call from any thread.
/// Return the currently active theme preset.
// ---------------------------------------------------------------------------
// Preset → tokens (layers A / B) and → iced Theme (layer C)
// ---------------------------------------------------------------------------
/// The Snora Design tokens for the active preset.
///
/// Returns an owned `Tokens`; snora's style helpers clone tokens into their
/// style closures anyway, so this avoids any `'static` lifetime constraint.
/// `Tokens` is small and `Clone`; the per-button clone cost in `view()` is
/// negligible.
/// The base iced [`Theme`] for the active preset (layer C).
///
/// iced 0.14 has no built-in high-contrast theme, so the high-contrast
/// presets map to the matching `Light` / `Dark` base. arama's own controls
/// (buttons, and future cards) still get the full high-contrast tokens via
/// layers A / B; only stock iced widgets fall back to the base theme.
// ---------------------------------------------------------------------------
// Button style functions (layer A) — drop-in shape for iced's `.style(...)`
// ---------------------------------------------------------------------------
/// Primary (accent) button style — active navigation item, confirmations.
/// Ghost (transparent) button style — token-driven equivalent of iced's
/// `button::text`, used for inactive navigation items.
/// Secondary button style — non-primary actions such as "Skip".
/// Danger button style — destructive actions such as "Stop".