uhr: sleep sounds, sunrise alarm, reorder world clock, rename timers; 0.2.0
- own generated sleep sounds (rain, waves, brown noise) with sleep timer and fade-out - sunrise: 15 min before the bedtime wake alarm, a full-screen screen brightens from ember to daylight - world clock: long-press drag to reorder, with haptic ticks; order persists - timers: tap the title to rename Co-Authored-By: Claude Opus 5.5 <[email protected]>
@@ -11,11 +11,11 @@ Device checks on a Pixel 10 Pro XL (Android 16) via a debug-only activity that s
|
||||
| S03 Time picker | 2026-10-17 | done | – | – |
|
||||
| S04 Sound picker | 2026-10-17 | done | – | own file not device-tested |
|
||||
| S05 Pause alarm | 2026-10-17 | done | – | – |
|
||||
| S06 Clock | 2026-10-17 | done | reorder cities | city names offline via ICU exemplar cities |
|
||||
| S06 Clock | 2026-10-17 | done | – | city names offline via ICU exemplar cities |
|
||||
| S07 Add city | 2026-10-17 | done | – | – |
|
||||
| S08 Timer | 2026-10-17 | done | label edit UI | verified on device: 5 s timer rang in the background, stopped from the notification |
|
||||
| S08 Timer | 2026-10-17 | done | – | verified on device: 5 s timer rang in the background, stopped from the notification |
|
||||
| S09 Stopwatch | 2026-10-17 | done | – | – |
|
||||
| S10 Bedtime | 2026-10-17 | partial | sunrise alarm, sleep sounds | – |
|
||||
| S10 Bedtime | 2026-10-17 | done | sunrise full-screen not confirmed on device | sleep sounds generated in-house; the sunrise needs the full-screen-intent permission, which Android 14+ does not grant sideloaded apps by default (the app asks) |
|
||||
| S11 Ringing | 2026-10-17 | done | – | – |
|
||||
| S12 Timer ringing | 2026-10-17 | done | – | shares the ringing screen |
|
||||
| S13 Settings | 2026-10-17 | done | timer sound picker, home time zone | – |
|
||||
|
||||
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 54 KiB |
@@ -65,6 +65,10 @@ object WColor {
|
||||
val timerProgress = Color(0xFF7EC4A8)
|
||||
val nightText = Color(0xFFC4433A)
|
||||
val nightBg = Color(0xFF000000)
|
||||
val sunriseNight = Color(0xFF0D0710)
|
||||
val sunriseEmber = Color(0xFF5A1A10)
|
||||
val sunriseDay = Color(0xFFFFD9A0)
|
||||
val sunriseSun = Color(0xFFFFF3D6)
|
||||
}
|
||||
|
||||
object WType {
|
||||
|
||||
@@ -1,45 +1,230 @@
|
||||
{
|
||||
"_about": "Uhr tokens. Roles read by eye from replica/uhr/screens/ref-01..07 (Pixel Clock, dark first). Own values, no brand colour copied; on Android 12+ dynamic colour (wallpaper) replaces the accent roles. Check: python3 ~/.claude/skills/replica-design/contrast.py replica/uhr/design/tokens.json",
|
||||
"color": {
|
||||
"bg": "#f8f9ff", "surface": "#ffffff", "card": "#eef0f6", "card-high": "#e2e5ec",
|
||||
"border": "#c3c6cf", "border-input": "#73777f",
|
||||
"text": "#191c20", "text-muted": "#43474e", "text-off": "#5c6068",
|
||||
"accent": "#2f5ea8", "on-accent": "#ffffff",
|
||||
"accent-container": "#d6e3ff", "on-accent-container": "#001b3e",
|
||||
"fab": "#a8c7fa", "on-fab": "#0b2a55",
|
||||
"chip-on": "#2f5ea8", "on-chip-on": "#ffffff",
|
||||
"secondary-pill": "#dfe2eb", "on-secondary-pill": "#191c20",
|
||||
"stop": "#ffd8e4", "on-stop": "#4a1426",
|
||||
"bg": "#f8f9ff",
|
||||
"surface": "#ffffff",
|
||||
"card": "#eef0f6",
|
||||
"card-high": "#e2e5ec",
|
||||
"border": "#c3c6cf",
|
||||
"border-input": "#73777f",
|
||||
"text": "#191c20",
|
||||
"text-muted": "#43474e",
|
||||
"text-off": "#5c6068",
|
||||
"accent": "#2f5ea8",
|
||||
"on-accent": "#ffffff",
|
||||
"accent-container": "#d6e3ff",
|
||||
"on-accent-container": "#001b3e",
|
||||
"fab": "#a8c7fa",
|
||||
"on-fab": "#0b2a55",
|
||||
"chip-on": "#2f5ea8",
|
||||
"on-chip-on": "#ffffff",
|
||||
"secondary-pill": "#dfe2eb",
|
||||
"on-secondary-pill": "#191c20",
|
||||
"stop": "#ffd8e4",
|
||||
"on-stop": "#4a1426",
|
||||
"danger": "#ba1a1a",
|
||||
"nav": "#eceef4", "nav-indicator": "#d6e3ff",
|
||||
|
||||
"dark-bg": "#111318", "dark-surface": "#111318", "dark-card": "#1d2024", "dark-card-high": "#272a2f",
|
||||
"dark-border": "#43474e", "dark-border-input": "#8d9199",
|
||||
"dark-text": "#e2e2e9", "dark-text-muted": "#c3c6cf", "dark-text-off": "#9a9ea6",
|
||||
"dark-accent": "#a8c7fa", "dark-on-accent": "#062e6f",
|
||||
"dark-accent-container": "#244a80", "dark-on-accent-container": "#d6e3ff",
|
||||
"dark-fab": "#a8c7fa", "dark-on-fab": "#062e6f",
|
||||
"dark-chip-on": "#a8c7fa", "dark-on-chip-on": "#062e6f",
|
||||
"dark-secondary-pill": "#3a3d43", "dark-on-secondary-pill": "#e2e2e9",
|
||||
"dark-stop": "#f2b8c9", "dark-on-stop": "#4a1426",
|
||||
"nav": "#eceef4",
|
||||
"nav-indicator": "#d6e3ff",
|
||||
"dark-bg": "#111318",
|
||||
"dark-surface": "#111318",
|
||||
"dark-card": "#1d2024",
|
||||
"dark-card-high": "#272a2f",
|
||||
"dark-border": "#43474e",
|
||||
"dark-border-input": "#8d9199",
|
||||
"dark-text": "#e2e2e9",
|
||||
"dark-text-muted": "#c3c6cf",
|
||||
"dark-text-off": "#9a9ea6",
|
||||
"dark-accent": "#a8c7fa",
|
||||
"dark-on-accent": "#062e6f",
|
||||
"dark-accent-container": "#244a80",
|
||||
"dark-on-accent-container": "#d6e3ff",
|
||||
"dark-fab": "#a8c7fa",
|
||||
"dark-on-fab": "#062e6f",
|
||||
"dark-chip-on": "#a8c7fa",
|
||||
"dark-on-chip-on": "#062e6f",
|
||||
"dark-secondary-pill": "#3a3d43",
|
||||
"dark-on-secondary-pill": "#e2e2e9",
|
||||
"dark-stop": "#f2b8c9",
|
||||
"dark-on-stop": "#4a1426",
|
||||
"dark-danger": "#ffb4ab",
|
||||
"dark-nav": "#1d2024", "dark-nav-indicator": "#3a3f47",
|
||||
|
||||
"ring-bg": "#1e5a52", "ring-on": "#b4f1e6", "ring-track": "#2b6e65", "ring-thumb": "#3f9a7f", "on-ring-thumb": "#ffffff",
|
||||
"timer-track": "#3a3d43", "timer-progress": "#7ec4a8",
|
||||
"night-text": "#c4433a", "night-bg": "#000000"
|
||||
"dark-nav": "#1d2024",
|
||||
"dark-nav-indicator": "#3a3f47",
|
||||
"ring-bg": "#1e5a52",
|
||||
"ring-on": "#b4f1e6",
|
||||
"ring-track": "#2b6e65",
|
||||
"ring-thumb": "#3f9a7f",
|
||||
"on-ring-thumb": "#ffffff",
|
||||
"timer-track": "#3a3d43",
|
||||
"timer-progress": "#7ec4a8",
|
||||
"night-text": "#c4433a",
|
||||
"night-bg": "#000000",
|
||||
"sunrise-night": "#0d0710",
|
||||
"sunrise-ember": "#5a1a10",
|
||||
"sunrise-day": "#ffd9a0",
|
||||
"sunrise-sun": "#fff3d6"
|
||||
},
|
||||
"pairs": [
|
||||
["text","bg"],["text","card"],["text","card-high"],["text-muted","bg"],["text-muted","card"],["text-off","card"],
|
||||
["on-accent","accent"],["on-accent-container","accent-container"],["on-fab","fab"],["on-chip-on","chip-on"],
|
||||
["on-secondary-pill","secondary-pill"],["on-stop","stop"],["accent","card"],["danger","card"],["text","nav"],["text","nav-indicator"],
|
||||
["border-input","surface","ui"],
|
||||
["dark-text","dark-bg"],["dark-text","dark-card"],["dark-text","dark-card-high"],["dark-text-muted","dark-bg"],["dark-text-muted","dark-card"],["dark-text-off","dark-card"],
|
||||
["dark-on-accent","dark-accent"],["dark-on-accent-container","dark-accent-container"],["dark-on-fab","dark-fab"],["dark-on-chip-on","dark-chip-on"],
|
||||
["dark-on-secondary-pill","dark-secondary-pill"],["dark-on-stop","dark-stop"],["dark-accent","dark-card"],["dark-danger","dark-card"],
|
||||
["dark-text","dark-nav"],["dark-text","dark-nav-indicator"],["dark-border-input","dark-card","ui"],
|
||||
["ring-on","ring-bg"],["ring-on","ring-track"],["on-ring-thumb","ring-thumb","large"],
|
||||
["timer-progress","dark-card","ui"],["night-text","night-bg","large"]
|
||||
[
|
||||
"text",
|
||||
"bg"
|
||||
],
|
||||
[
|
||||
"text",
|
||||
"card"
|
||||
],
|
||||
[
|
||||
"text",
|
||||
"card-high"
|
||||
],
|
||||
[
|
||||
"text-muted",
|
||||
"bg"
|
||||
],
|
||||
[
|
||||
"text-muted",
|
||||
"card"
|
||||
],
|
||||
[
|
||||
"text-off",
|
||||
"card"
|
||||
],
|
||||
[
|
||||
"on-accent",
|
||||
"accent"
|
||||
],
|
||||
[
|
||||
"on-accent-container",
|
||||
"accent-container"
|
||||
],
|
||||
[
|
||||
"on-fab",
|
||||
"fab"
|
||||
],
|
||||
[
|
||||
"on-chip-on",
|
||||
"chip-on"
|
||||
],
|
||||
[
|
||||
"on-secondary-pill",
|
||||
"secondary-pill"
|
||||
],
|
||||
[
|
||||
"on-stop",
|
||||
"stop"
|
||||
],
|
||||
[
|
||||
"accent",
|
||||
"card"
|
||||
],
|
||||
[
|
||||
"danger",
|
||||
"card"
|
||||
],
|
||||
[
|
||||
"text",
|
||||
"nav"
|
||||
],
|
||||
[
|
||||
"text",
|
||||
"nav-indicator"
|
||||
],
|
||||
[
|
||||
"border-input",
|
||||
"surface",
|
||||
"ui"
|
||||
],
|
||||
[
|
||||
"dark-text",
|
||||
"dark-bg"
|
||||
],
|
||||
[
|
||||
"dark-text",
|
||||
"dark-card"
|
||||
],
|
||||
[
|
||||
"dark-text",
|
||||
"dark-card-high"
|
||||
],
|
||||
[
|
||||
"dark-text-muted",
|
||||
"dark-bg"
|
||||
],
|
||||
[
|
||||
"dark-text-muted",
|
||||
"dark-card"
|
||||
],
|
||||
[
|
||||
"dark-text-off",
|
||||
"dark-card"
|
||||
],
|
||||
[
|
||||
"dark-on-accent",
|
||||
"dark-accent"
|
||||
],
|
||||
[
|
||||
"dark-on-accent-container",
|
||||
"dark-accent-container"
|
||||
],
|
||||
[
|
||||
"dark-on-fab",
|
||||
"dark-fab"
|
||||
],
|
||||
[
|
||||
"dark-on-chip-on",
|
||||
"dark-chip-on"
|
||||
],
|
||||
[
|
||||
"dark-on-secondary-pill",
|
||||
"dark-secondary-pill"
|
||||
],
|
||||
[
|
||||
"dark-on-stop",
|
||||
"dark-stop"
|
||||
],
|
||||
[
|
||||
"dark-accent",
|
||||
"dark-card"
|
||||
],
|
||||
[
|
||||
"dark-danger",
|
||||
"dark-card"
|
||||
],
|
||||
[
|
||||
"dark-text",
|
||||
"dark-nav"
|
||||
],
|
||||
[
|
||||
"dark-text",
|
||||
"dark-nav-indicator"
|
||||
],
|
||||
[
|
||||
"dark-border-input",
|
||||
"dark-card",
|
||||
"ui"
|
||||
],
|
||||
[
|
||||
"ring-on",
|
||||
"ring-bg"
|
||||
],
|
||||
[
|
||||
"ring-on",
|
||||
"ring-track"
|
||||
],
|
||||
[
|
||||
"on-ring-thumb",
|
||||
"ring-thumb",
|
||||
"large"
|
||||
],
|
||||
[
|
||||
"timer-progress",
|
||||
"dark-card",
|
||||
"ui"
|
||||
],
|
||||
[
|
||||
"night-text",
|
||||
"night-bg",
|
||||
"large"
|
||||
]
|
||||
],
|
||||
"font": {
|
||||
"sans": "Roboto Flex (OFL), system fallback",
|
||||
@@ -48,21 +233,88 @@
|
||||
"mono": "tabular figures (fontFeatureSettings tnum) instead of a mono font for the stopwatch"
|
||||
},
|
||||
"type": {
|
||||
"label-sm": {"size": 12, "line": 16, "weight": 500},
|
||||
"label": {"size": 14, "line": 20, "weight": 500},
|
||||
"body-sm": {"size": 14, "line": 20, "weight": 400},
|
||||
"body": {"size": 16, "line": 24, "weight": 400},
|
||||
"title": {"size": 22, "line": 28, "weight": 400},
|
||||
"headline": {"size": 28, "line": 36, "weight": 400},
|
||||
"alarm-time": {"size": 56, "line": 60, "weight": 600},
|
||||
"alarm-ampm": {"size": 20, "line": 24, "weight": 600},
|
||||
"timer-time": {"size": 44, "line": 48, "weight": 400},
|
||||
"clock-big": {"size": 88, "line": 92, "weight": 400},
|
||||
"stopwatch": {"size": 72, "line": 76, "weight": 500},
|
||||
"ringing": {"size": 104, "line": 108, "weight": 400}
|
||||
"label-sm": {
|
||||
"size": 12,
|
||||
"line": 16,
|
||||
"weight": 500
|
||||
},
|
||||
"label": {
|
||||
"size": 14,
|
||||
"line": 20,
|
||||
"weight": 500
|
||||
},
|
||||
"body-sm": {
|
||||
"size": 14,
|
||||
"line": 20,
|
||||
"weight": 400
|
||||
},
|
||||
"body": {
|
||||
"size": 16,
|
||||
"line": 24,
|
||||
"weight": 400
|
||||
},
|
||||
"title": {
|
||||
"size": 22,
|
||||
"line": 28,
|
||||
"weight": 400
|
||||
},
|
||||
"headline": {
|
||||
"size": 28,
|
||||
"line": 36,
|
||||
"weight": 400
|
||||
},
|
||||
"alarm-time": {
|
||||
"size": 56,
|
||||
"line": 60,
|
||||
"weight": 600
|
||||
},
|
||||
"alarm-ampm": {
|
||||
"size": 20,
|
||||
"line": 24,
|
||||
"weight": 600
|
||||
},
|
||||
"timer-time": {
|
||||
"size": 44,
|
||||
"line": 48,
|
||||
"weight": 400
|
||||
},
|
||||
"clock-big": {
|
||||
"size": 88,
|
||||
"line": 92,
|
||||
"weight": 400
|
||||
},
|
||||
"stopwatch": {
|
||||
"size": 72,
|
||||
"line": 76,
|
||||
"weight": 500
|
||||
},
|
||||
"ringing": {
|
||||
"size": 104,
|
||||
"line": 108,
|
||||
"weight": 400
|
||||
}
|
||||
},
|
||||
"space": [
|
||||
0,
|
||||
2,
|
||||
4,
|
||||
8,
|
||||
12,
|
||||
16,
|
||||
20,
|
||||
24,
|
||||
32,
|
||||
48
|
||||
],
|
||||
"radius": {
|
||||
"xs": 8,
|
||||
"sm": 12,
|
||||
"md": 16,
|
||||
"lg": 24,
|
||||
"card": 28,
|
||||
"pill": 999,
|
||||
"nav-indicator": 16
|
||||
},
|
||||
"space": [0, 2, 4, 8, 12, 16, 20, 24, 32, 48],
|
||||
"radius": {"xs": 8, "sm": 12, "md": 16, "lg": 24, "card": 28, "pill": 999, "nav-indicator": 16},
|
||||
"shape": {
|
||||
"fab": "circle 96dp (large, centred above the nav bar)",
|
||||
"stopwatch-primary": "pill 72dp tall, full width",
|
||||
@@ -72,7 +324,14 @@
|
||||
"motion": {
|
||||
"card-expand": "spring dampingRatio 0.85 stiffness 380",
|
||||
"slide-act": "spring back dampingRatio 0.7",
|
||||
"fast": "120ms", "base": "250ms"
|
||||
"fast": "120ms",
|
||||
"base": "250ms"
|
||||
},
|
||||
"layout": {"gutter": 16, "card-gap": 8, "nav-height": 80, "fab-bottom": 16, "card-padding": 20}
|
||||
}
|
||||
"layout": {
|
||||
"gutter": 16,
|
||||
"card-gap": 8,
|
||||
"nav-height": 80,
|
||||
"fab-bottom": 16,
|
||||
"card-padding": 20
|
||||
}
|
||||
}
|
||||
@@ -24,14 +24,14 @@ Missed alarm notification,notifications,should,yes,yes,
|
||||
Snoozed notification with dismiss,notifications,must,yes,yes,
|
||||
World clock: local time and date,clock,must,yes,yes,
|
||||
World clock: add city via search,clock,must,yes,yes,
|
||||
World clock: reorder and swipe to delete,clock,should,yes,partial,swipe to delete only
|
||||
World clock: reorder and swipe to delete,clock,should,yes,yes,"long-press drag; verified on device, order persists"
|
||||
Analog or digital clock style,clock,should,yes,yes,
|
||||
Show seconds,clock,could,yes,yes,
|
||||
Automatic home clock when travelling,clock,could,yes,no,
|
||||
Timer keypad h m s,timer,must,yes,yes,
|
||||
Run several timers at once,timer,must,yes,yes,
|
||||
Timer ring progress +1:00 pause reset delete,timer,must,yes,yes,
|
||||
Timer labels,timer,could,yes,partial,stored and shown; no UI to edit yet
|
||||
Timer labels,timer,could,yes,yes,tap the title to rename
|
||||
Timer runs in background with notification,timer,must,yes,yes,
|
||||
Timer ringing screen,timer,must,yes,yes,
|
||||
Timer sound and vibrate settings,settings,should,yes,partial,vibrate setting only; sound uses default
|
||||
@@ -40,8 +40,8 @@ Stopwatch laps,stopwatch,must,yes,yes,
|
||||
Stopwatch running notification,stopwatch,should,yes,yes,
|
||||
Bedtime schedule with wake-up alarm,bedtime,should,yes,yes,
|
||||
Bedtime reminder notification,bedtime,should,yes,yes,
|
||||
Sunrise alarm (brightening screen),bedtime,could,yes,no,
|
||||
Sleep sounds with timer,bedtime,could,yes,no,own CC0 sounds
|
||||
Sunrise alarm (brightening screen),bedtime,could,yes,partial,scheduled 15 min before the bedtime wake alarm via full-screen notification; full-screen launch not confirmed on device (no keyguard during test)
|
||||
Sleep sounds with timer,bedtime,could,yes,yes,"own generated sounds (rain, waves, brown noise), sleep timer with 20 s fade-out; verified playing on device"
|
||||
Screensaver / bedside clock with night mode,display,could,yes,no,DreamService
|
||||
Digital clock widget,widgets,must,yes,yes,
|
||||
Analog clock widget,widgets,should,yes,yes,
|
||||
|
||||
|