1package soy.iko.opencode.ui.theme
3import android.app.Activity
4import android.content.Context
5import android.content.ContextWrapper
7import androidx.compose.foundation.isSystemInDarkTheme
8import androidx.compose.material3.MaterialTheme
9import androidx.compose.material3.darkColorScheme
10import androidx.compose.material3.dynamicDarkColorScheme
11import androidx.compose.material3.dynamicLightColorScheme
12import androidx.compose.material3.lightColorScheme
13import androidx.compose.runtime.Composable
14import androidx.compose.runtime.SideEffect
15import androidx.compose.ui.graphics.Color
16import androidx.compose.ui.platform.LocalContext
17import androidx.compose.ui.platform.LocalView
18import androidx.core.view.WindowCompat
21 * Tokyo Night — a dark, muted blue/purple palette. Every Material 3 color role is set
22 * explicitly (not just primary/secondary/tertiary) so components that read `error`,
23 * `primaryContainer`, `surfaceVariant`, `outline`, etc. match the brand instead of
24 * falling back to stock M3 defaults that clash with it.
26 * Source palette (Tokyo Night):
27 * bg #1A1B26 fg #C0CAF5 blue #7AA2F7 cyan #7DCFFF
28 * green #9ECE6A magenta #BB9AF7 red #F7768E yellow #E0AF68
29 * comment #565F89 gutter #414868
31private val DarkColors = darkColorScheme(
32 primary = Color(0xFF7AA2F7),
33 onPrimary = Color(0xFF112036),
34 primaryContainer = Color(0xFF2A3A5C),
35 onPrimaryContainer = Color(0xFFD6E2FF),
36 secondary = Color(0xFF9ECE6A),
37 onSecondary = Color(0xFF13260A),
38 secondaryContainer = Color(0xFF2B3B1F),
39 onSecondaryContainer = Color(0xFFD2F0A0),
40 tertiary = Color(0xFFBB9AF7),
41 onTertiary = Color(0xFF221036),
42 tertiaryContainer = Color(0xFF3A2A55),
43 onTertiaryContainer = Color(0xFFE6D6FF),
44 error = Color(0xFFF7768E),
45 onError = Color(0xFF370610),
46 errorContainer = Color(0xFF5C1A24),
47 onErrorContainer = Color(0xFFFFD9DE),
48 background = Color(0xFF1A1B26),
49 onBackground = Color(0xFFC0CAF5),
50 surface = Color(0xFF1F2335),
51 onSurface = Color(0xFFC0CAF5),
52 surfaceVariant = Color(0xFF2D3247),
53 onSurfaceVariant = Color(0xFF9AA5CE),
54 surfaceTint = Color(0xFF7AA2F7),
55 inverseSurface = Color(0xFFC0CAF5),
56 inverseOnSurface = Color(0xFF1A1B26),
57 outline = Color(0xFF565F89),
58 outlineVariant = Color(0xFF414868),
59 scrim = Color(0xFF000000),
63 * Tokyo Night Light — the day-mode counterpart. Pairs the same hue family with a soft
64 * off-white background so the brand identity survives a light setting instead of
65 * snapping to stock M3 purple-grey.
67private val LightColors = lightColorScheme(
68 primary = Color(0xFF34548A),
69 onPrimary = Color(0xFFFFFFFF),
70 primaryContainer = Color(0xFFD6E2FF),
71 onPrimaryContainer = Color(0xFF001A41),
72 secondary = Color(0xFF485E30),
73 onSecondary = Color(0xFFFFFFFF),
74 secondaryContainer = Color(0xFFC8F0A0),
75 onSecondaryContainer = Color(0xFF0E2000),
76 tertiary = Color(0xFF5A4A78),
77 onTertiary = Color(0xFFFFFFFF),
78 tertiaryContainer = Color(0xFFE6D6FF),
79 onTertiaryContainer = Color(0xFF180038),
80 error = Color(0xFF9B1C2E),
81 onError = Color(0xFFFFFFFF),
82 errorContainer = Color(0xFFFFD9DE),
83 onErrorContainer = Color(0xFF410008),
84 background = Color(0xFFF6F7FB),
85 onBackground = Color(0xFF1A1B26),
86 surface = Color(0xFFF1F3FA),
87 onSurface = Color(0xFF1A1B26),
88 surfaceVariant = Color(0xFFE0E4F0),
89 onSurfaceVariant = Color(0xFF444B6E),
90 surfaceTint = Color(0xFF34548A),
91 inverseSurface = Color(0xFF2D3247),
92 inverseOnSurface = Color(0xFFEEF0FB),
93 outline = Color(0xFF747DAA),
94 outlineVariant = Color(0xFFC3C8DA),
95 scrim = Color(0xFF000000),
100 darkTheme: Boolean = isSystemInDarkTheme(),
101 dynamicColor: Boolean = false,
102 content: @Composable () -> Unit,
104 val context = LocalContext.current
105 val colorScheme = when {
106 dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ->
107 if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
108 darkTheme -> DarkColors
111 val view = LocalView.current
112 if (!view.isInEditMode) {
114 val window = view.context.findActivity()?.window ?: return@SideEffect
115 WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
119 colorScheme = colorScheme,
120 typography = OpencodeTypography,
121 shapes = OpencodeShapes,
127 * Preview swatches for the Tokyo Night palettes, exposed so the Settings theme picker
128 * can show color dots without reaching into the (otherwise private) full color schemes.
129 * Each list is [primary, secondary, tertiary, background].
131val DarkPaletteSwatches: List<Color> = listOf(
133 DarkColors.secondary,
135 DarkColors.background,
137val LightPaletteSwatches: List<Color> = listOf(
139 LightColors.secondary,
140 LightColors.tertiary,
141 LightColors.background,
144private tailrec fun Context.findActivity(): Activity? = when (this) {
146 is ContextWrapper -> baseContext.findActivity()
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list