bh 6.2.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,189 @@
1
+ /* One Dark, Atom — https://github.com/atom/atom/tree/master/packages/one-dark-ui
2
+ One Light's page is the light one and One Dark's the dark one. One Dark
3
+ carries no pink, so its purple serves both, and its orange serves
4
+ brown. The mid neutral is derived.
5
+
6
+ Bootstrap builds a family by mixing one base toward `--bs-white` below
7
+ the 500 step and toward `--bs-black` above it, and inlines that base
8
+ into all thirteen — so a palette restates the thirteen rather than the
9
+ one. Upstream's order and upstream's shapes with only the base swapped,
10
+ so a later Bootstrap diffs against this file. */
11
+ :root {
12
+ /* The page, and the two colors every ramp below is mixed with.
13
+ `--bs-bg-body` reads `--bs-white` in light mode and `--bs-gray-975` in
14
+ dark, so repainting these two is what moves the page itself. */
15
+ --bs-white: #fafafa;
16
+ --bs-black: #282c34;
17
+
18
+ /* The neutrals, which every surface, border and text token Bootstrap ships
19
+ derives from. */
20
+ --bs-gray-025: color-mix(in lab, var(--bs-white) 94%, #8b91a0);
21
+ --bs-gray-050: color-mix(in lab, var(--bs-white) 90%, #8b91a0);
22
+ --bs-gray-100: color-mix(in lab, var(--bs-white) 80%, #8b91a0);
23
+ --bs-gray-200: color-mix(in lab, var(--bs-white) 60%, #8b91a0);
24
+ --bs-gray-300: color-mix(in lab, var(--bs-white) 40%, #8b91a0);
25
+ --bs-gray-400: color-mix(in lab, var(--bs-white) 20%, #8b91a0);
26
+ --bs-gray-500: #8b91a0;
27
+ --bs-gray-600: color-mix(in lab, var(--bs-black) 16%, #8b91a0);
28
+ --bs-gray-700: color-mix(in lab, var(--bs-black) 32%, #8b91a0);
29
+ --bs-gray-800: color-mix(in lab, var(--bs-black) 48%, #8b91a0);
30
+ --bs-gray-900: color-mix(in lab, var(--bs-black) 64%, #8b91a0);
31
+ --bs-gray-950: color-mix(in lab, var(--bs-black) 76%, #8b91a0);
32
+ --bs-gray-975: color-mix(in lab, var(--bs-black) 88%, #8b91a0);
33
+
34
+ --bs-blue-025: color-mix(in lab, var(--bs-white) 94%, #61afef);
35
+ --bs-blue-050: color-mix(in lab, var(--bs-white) 90%, #61afef);
36
+ --bs-blue-100: color-mix(in lab, var(--bs-white) 80%, #61afef);
37
+ --bs-blue-200: color-mix(in lab, var(--bs-white) 60%, #61afef);
38
+ --bs-blue-300: color-mix(in lab, var(--bs-white) 40%, #61afef);
39
+ --bs-blue-400: color-mix(in lab, var(--bs-white) 20%, #61afef);
40
+ --bs-blue-500: #61afef;
41
+ --bs-blue-600: color-mix(in lab, var(--bs-black) 16%, #61afef);
42
+ --bs-blue-700: color-mix(in lab, var(--bs-black) 32%, #61afef);
43
+ --bs-blue-800: color-mix(in lab, var(--bs-black) 48%, #61afef);
44
+ --bs-blue-900: color-mix(in lab, var(--bs-black) 64%, #61afef);
45
+ --bs-blue-950: color-mix(in lab, var(--bs-black) 76%, #61afef);
46
+ --bs-blue-975: color-mix(in lab, var(--bs-black) 88%, #61afef);
47
+
48
+ --bs-brown-025: color-mix(in lab, var(--bs-white) 94%, #d19a66);
49
+ --bs-brown-050: color-mix(in lab, var(--bs-white) 90%, #d19a66);
50
+ --bs-brown-100: color-mix(in lab, var(--bs-white) 80%, #d19a66);
51
+ --bs-brown-200: color-mix(in lab, var(--bs-white) 60%, #d19a66);
52
+ --bs-brown-300: color-mix(in lab, var(--bs-white) 40%, #d19a66);
53
+ --bs-brown-400: color-mix(in lab, var(--bs-white) 20%, #d19a66);
54
+ --bs-brown-500: #d19a66;
55
+ --bs-brown-600: color-mix(in lab, var(--bs-black) 16%, #d19a66);
56
+ --bs-brown-700: color-mix(in lab, var(--bs-black) 32%, #d19a66);
57
+ --bs-brown-800: color-mix(in lab, var(--bs-black) 48%, #d19a66);
58
+ --bs-brown-900: color-mix(in lab, var(--bs-black) 64%, #d19a66);
59
+ --bs-brown-950: color-mix(in lab, var(--bs-black) 76%, #d19a66);
60
+ --bs-brown-975: color-mix(in lab, var(--bs-black) 88%, #d19a66);
61
+
62
+ --bs-cyan-025: color-mix(in lab, var(--bs-white) 94%, #56b6c2);
63
+ --bs-cyan-050: color-mix(in lab, var(--bs-white) 90%, #56b6c2);
64
+ --bs-cyan-100: color-mix(in lab, var(--bs-white) 80%, #56b6c2);
65
+ --bs-cyan-200: color-mix(in lab, var(--bs-white) 60%, #56b6c2);
66
+ --bs-cyan-300: color-mix(in lab, var(--bs-white) 40%, #56b6c2);
67
+ --bs-cyan-400: color-mix(in lab, var(--bs-white) 20%, #56b6c2);
68
+ --bs-cyan-500: #56b6c2;
69
+ --bs-cyan-600: color-mix(in lab, var(--bs-black) 16%, #56b6c2);
70
+ --bs-cyan-700: color-mix(in lab, var(--bs-black) 32%, #56b6c2);
71
+ --bs-cyan-800: color-mix(in lab, var(--bs-black) 48%, #56b6c2);
72
+ --bs-cyan-900: color-mix(in lab, var(--bs-black) 64%, #56b6c2);
73
+ --bs-cyan-950: color-mix(in lab, var(--bs-black) 76%, #56b6c2);
74
+ --bs-cyan-975: color-mix(in lab, var(--bs-black) 88%, #56b6c2);
75
+
76
+ --bs-green-025: color-mix(in lab, var(--bs-white) 94%, #98c379);
77
+ --bs-green-050: color-mix(in lab, var(--bs-white) 90%, #98c379);
78
+ --bs-green-100: color-mix(in lab, var(--bs-white) 80%, #98c379);
79
+ --bs-green-200: color-mix(in lab, var(--bs-white) 60%, #98c379);
80
+ --bs-green-300: color-mix(in lab, var(--bs-white) 40%, #98c379);
81
+ --bs-green-400: color-mix(in lab, var(--bs-white) 20%, #98c379);
82
+ --bs-green-500: #98c379;
83
+ --bs-green-600: color-mix(in lab, var(--bs-black) 16%, #98c379);
84
+ --bs-green-700: color-mix(in lab, var(--bs-black) 32%, #98c379);
85
+ --bs-green-800: color-mix(in lab, var(--bs-black) 48%, #98c379);
86
+ --bs-green-900: color-mix(in lab, var(--bs-black) 64%, #98c379);
87
+ --bs-green-950: color-mix(in lab, var(--bs-black) 76%, #98c379);
88
+ --bs-green-975: color-mix(in lab, var(--bs-black) 88%, #98c379);
89
+
90
+ --bs-orange-025: color-mix(in lab, var(--bs-white) 94%, #d19a66);
91
+ --bs-orange-050: color-mix(in lab, var(--bs-white) 90%, #d19a66);
92
+ --bs-orange-100: color-mix(in lab, var(--bs-white) 80%, #d19a66);
93
+ --bs-orange-200: color-mix(in lab, var(--bs-white) 60%, #d19a66);
94
+ --bs-orange-300: color-mix(in lab, var(--bs-white) 40%, #d19a66);
95
+ --bs-orange-400: color-mix(in lab, var(--bs-white) 20%, #d19a66);
96
+ --bs-orange-500: #d19a66;
97
+ --bs-orange-600: color-mix(in lab, var(--bs-black) 16%, #d19a66);
98
+ --bs-orange-700: color-mix(in lab, var(--bs-black) 32%, #d19a66);
99
+ --bs-orange-800: color-mix(in lab, var(--bs-black) 48%, #d19a66);
100
+ --bs-orange-900: color-mix(in lab, var(--bs-black) 64%, #d19a66);
101
+ --bs-orange-950: color-mix(in lab, var(--bs-black) 76%, #d19a66);
102
+ --bs-orange-975: color-mix(in lab, var(--bs-black) 88%, #d19a66);
103
+
104
+ --bs-pink-025: color-mix(in lab, var(--bs-white) 94%, #c678dd);
105
+ --bs-pink-050: color-mix(in lab, var(--bs-white) 90%, #c678dd);
106
+ --bs-pink-100: color-mix(in lab, var(--bs-white) 80%, #c678dd);
107
+ --bs-pink-200: color-mix(in lab, var(--bs-white) 60%, #c678dd);
108
+ --bs-pink-300: color-mix(in lab, var(--bs-white) 40%, #c678dd);
109
+ --bs-pink-400: color-mix(in lab, var(--bs-white) 20%, #c678dd);
110
+ --bs-pink-500: #c678dd;
111
+ --bs-pink-600: color-mix(in lab, var(--bs-black) 16%, #c678dd);
112
+ --bs-pink-700: color-mix(in lab, var(--bs-black) 32%, #c678dd);
113
+ --bs-pink-800: color-mix(in lab, var(--bs-black) 48%, #c678dd);
114
+ --bs-pink-900: color-mix(in lab, var(--bs-black) 64%, #c678dd);
115
+ --bs-pink-950: color-mix(in lab, var(--bs-black) 76%, #c678dd);
116
+ --bs-pink-975: color-mix(in lab, var(--bs-black) 88%, #c678dd);
117
+
118
+ --bs-purple-025: color-mix(in lab, var(--bs-white) 94%, #c678dd);
119
+ --bs-purple-050: color-mix(in lab, var(--bs-white) 90%, #c678dd);
120
+ --bs-purple-100: color-mix(in lab, var(--bs-white) 80%, #c678dd);
121
+ --bs-purple-200: color-mix(in lab, var(--bs-white) 60%, #c678dd);
122
+ --bs-purple-300: color-mix(in lab, var(--bs-white) 40%, #c678dd);
123
+ --bs-purple-400: color-mix(in lab, var(--bs-white) 20%, #c678dd);
124
+ --bs-purple-500: #c678dd;
125
+ --bs-purple-600: color-mix(in lab, var(--bs-black) 16%, #c678dd);
126
+ --bs-purple-700: color-mix(in lab, var(--bs-black) 32%, #c678dd);
127
+ --bs-purple-800: color-mix(in lab, var(--bs-black) 48%, #c678dd);
128
+ --bs-purple-900: color-mix(in lab, var(--bs-black) 64%, #c678dd);
129
+ --bs-purple-950: color-mix(in lab, var(--bs-black) 76%, #c678dd);
130
+ --bs-purple-975: color-mix(in lab, var(--bs-black) 88%, #c678dd);
131
+
132
+ --bs-red-025: color-mix(in lab, var(--bs-white) 94%, #e06c75);
133
+ --bs-red-050: color-mix(in lab, var(--bs-white) 90%, #e06c75);
134
+ --bs-red-100: color-mix(in lab, var(--bs-white) 80%, #e06c75);
135
+ --bs-red-200: color-mix(in lab, var(--bs-white) 60%, #e06c75);
136
+ --bs-red-300: color-mix(in lab, var(--bs-white) 40%, #e06c75);
137
+ --bs-red-400: color-mix(in lab, var(--bs-white) 20%, #e06c75);
138
+ --bs-red-500: #e06c75;
139
+ --bs-red-600: color-mix(in lab, var(--bs-black) 16%, #e06c75);
140
+ --bs-red-700: color-mix(in lab, var(--bs-black) 32%, #e06c75);
141
+ --bs-red-800: color-mix(in lab, var(--bs-black) 48%, #e06c75);
142
+ --bs-red-900: color-mix(in lab, var(--bs-black) 64%, #e06c75);
143
+ --bs-red-950: color-mix(in lab, var(--bs-black) 76%, #e06c75);
144
+ --bs-red-975: color-mix(in lab, var(--bs-black) 88%, #e06c75);
145
+
146
+ --bs-yellow-025: color-mix(in lab, var(--bs-white) 94%, #e5c07b);
147
+ --bs-yellow-050: color-mix(in lab, var(--bs-white) 90%, #e5c07b);
148
+ --bs-yellow-100: color-mix(in lab, var(--bs-white) 80%, #e5c07b);
149
+ --bs-yellow-200: color-mix(in lab, var(--bs-white) 60%, #e5c07b);
150
+ --bs-yellow-300: color-mix(in lab, var(--bs-white) 40%, #e5c07b);
151
+ --bs-yellow-400: color-mix(in lab, var(--bs-white) 20%, #e5c07b);
152
+ --bs-yellow-500: #e5c07b;
153
+ --bs-yellow-600: color-mix(in lab, var(--bs-black) 16%, #e5c07b);
154
+ --bs-yellow-700: color-mix(in lab, var(--bs-black) 32%, #e5c07b);
155
+ --bs-yellow-800: color-mix(in lab, var(--bs-black) 48%, #e5c07b);
156
+ --bs-yellow-900: color-mix(in lab, var(--bs-black) 64%, #e5c07b);
157
+ --bs-yellow-950: color-mix(in lab, var(--bs-black) 76%, #e5c07b);
158
+ --bs-yellow-975: color-mix(in lab, var(--bs-black) 88%, #e5c07b);
159
+
160
+ /* Text, stated rather than left to the ramp. Bootstrap pairs a low step as
161
+ a light surface with that same step as dark-mode text, which a palette
162
+ built for its own contrast does not agree with. */
163
+ --bs-fg-1: light-dark(#202126, #ffffff);
164
+ --bs-fg-body: light-dark(#383a42, #abb2bf);
165
+ --bs-fg-2: light-dark(#5c6370, #939aa8);
166
+
167
+ /* The label a solid fill carries, for the four families Bootstrap has
168
+ spent on a meaning and this palette has repainted. Upstream's own shape:
169
+ it gives warning and info a dark label for the same reason. */
170
+ --bs-danger-contrast: var(--bs-gray-975);
171
+ --bs-success-contrast: var(--bs-gray-975);
172
+ --bs-warning-contrast: var(--bs-gray-975);
173
+ --bs-info-contrast: var(--bs-gray-975);
174
+
175
+ /* The accent this palette leads with, as the primary color: the same nine
176
+ `_color.html.erb` writes, from blue and the label that reads on it. Here
177
+ rather than only in the page because a reader may swap this file for
178
+ another one, and the primary has to travel with it. A host naming its
179
+ own color still wins, its block coming after this file. */
180
+ --bs-primary-base: var(--bs-blue-500);
181
+ --bs-primary-fg: light-dark(var(--bs-blue-600), var(--bs-blue-400));
182
+ --bs-primary-fg-emphasis: light-dark(var(--bs-blue-800), var(--bs-blue-200));
183
+ --bs-primary-bg: var(--bs-blue-500);
184
+ --bs-primary-bg-subtle: light-dark(var(--bs-blue-100), var(--bs-blue-900));
185
+ --bs-primary-bg-muted: light-dark(var(--bs-blue-200), var(--bs-blue-800));
186
+ --bs-primary-border: light-dark(var(--bs-blue-300), var(--bs-blue-600));
187
+ --bs-primary-focus-ring: light-dark(color-mix(in oklch, var(--bs-blue-500) 50%, var(--bs-bg-body)), color-mix(in oklch, var(--bs-blue-500) 75%, var(--bs-bg-body)));
188
+ --bs-primary-contrast: var(--bs-gray-975);
189
+ }
@@ -0,0 +1,188 @@
1
+ /* Solarized, Ethan Schoonover — https://ethanschoonover.com/solarized/
2
+ base3 is the light page and base03 the dark one, both Solarized itself.
3
+ yellow serves brown, the warmest tone Solarized has.
4
+
5
+ Bootstrap builds a family by mixing one base toward `--bs-white` below
6
+ the 500 step and toward `--bs-black` above it, and inlines that base
7
+ into all thirteen — so a palette restates the thirteen rather than the
8
+ one. Upstream's order and upstream's shapes with only the base swapped,
9
+ so a later Bootstrap diffs against this file. */
10
+ :root {
11
+ /* The page, and the two colors every ramp below is mixed with.
12
+ `--bs-bg-body` reads `--bs-white` in light mode and `--bs-gray-975` in
13
+ dark, so repainting these two is what moves the page itself. */
14
+ --bs-white: #fdf6e3;
15
+ --bs-black: #002b36;
16
+
17
+ /* The neutrals, which every surface, border and text token Bootstrap ships
18
+ derives from. */
19
+ --bs-gray-025: color-mix(in lab, var(--bs-white) 94%, #839496);
20
+ --bs-gray-050: color-mix(in lab, var(--bs-white) 90%, #839496);
21
+ --bs-gray-100: color-mix(in lab, var(--bs-white) 80%, #839496);
22
+ --bs-gray-200: color-mix(in lab, var(--bs-white) 60%, #839496);
23
+ --bs-gray-300: color-mix(in lab, var(--bs-white) 40%, #839496);
24
+ --bs-gray-400: color-mix(in lab, var(--bs-white) 20%, #839496);
25
+ --bs-gray-500: #839496;
26
+ --bs-gray-600: color-mix(in lab, var(--bs-black) 16%, #839496);
27
+ --bs-gray-700: color-mix(in lab, var(--bs-black) 32%, #839496);
28
+ --bs-gray-800: color-mix(in lab, var(--bs-black) 48%, #839496);
29
+ --bs-gray-900: color-mix(in lab, var(--bs-black) 64%, #839496);
30
+ --bs-gray-950: color-mix(in lab, var(--bs-black) 76%, #839496);
31
+ --bs-gray-975: color-mix(in lab, var(--bs-black) 88%, #839496);
32
+
33
+ --bs-blue-025: color-mix(in lab, var(--bs-white) 94%, #268bd2);
34
+ --bs-blue-050: color-mix(in lab, var(--bs-white) 90%, #268bd2);
35
+ --bs-blue-100: color-mix(in lab, var(--bs-white) 80%, #268bd2);
36
+ --bs-blue-200: color-mix(in lab, var(--bs-white) 60%, #268bd2);
37
+ --bs-blue-300: color-mix(in lab, var(--bs-white) 40%, #268bd2);
38
+ --bs-blue-400: color-mix(in lab, var(--bs-white) 20%, #268bd2);
39
+ --bs-blue-500: #268bd2;
40
+ --bs-blue-600: color-mix(in lab, var(--bs-black) 16%, #268bd2);
41
+ --bs-blue-700: color-mix(in lab, var(--bs-black) 32%, #268bd2);
42
+ --bs-blue-800: color-mix(in lab, var(--bs-black) 48%, #268bd2);
43
+ --bs-blue-900: color-mix(in lab, var(--bs-black) 64%, #268bd2);
44
+ --bs-blue-950: color-mix(in lab, var(--bs-black) 76%, #268bd2);
45
+ --bs-blue-975: color-mix(in lab, var(--bs-black) 88%, #268bd2);
46
+
47
+ --bs-brown-025: color-mix(in lab, var(--bs-white) 94%, #b58900);
48
+ --bs-brown-050: color-mix(in lab, var(--bs-white) 90%, #b58900);
49
+ --bs-brown-100: color-mix(in lab, var(--bs-white) 80%, #b58900);
50
+ --bs-brown-200: color-mix(in lab, var(--bs-white) 60%, #b58900);
51
+ --bs-brown-300: color-mix(in lab, var(--bs-white) 40%, #b58900);
52
+ --bs-brown-400: color-mix(in lab, var(--bs-white) 20%, #b58900);
53
+ --bs-brown-500: #b58900;
54
+ --bs-brown-600: color-mix(in lab, var(--bs-black) 16%, #b58900);
55
+ --bs-brown-700: color-mix(in lab, var(--bs-black) 32%, #b58900);
56
+ --bs-brown-800: color-mix(in lab, var(--bs-black) 48%, #b58900);
57
+ --bs-brown-900: color-mix(in lab, var(--bs-black) 64%, #b58900);
58
+ --bs-brown-950: color-mix(in lab, var(--bs-black) 76%, #b58900);
59
+ --bs-brown-975: color-mix(in lab, var(--bs-black) 88%, #b58900);
60
+
61
+ --bs-cyan-025: color-mix(in lab, var(--bs-white) 94%, #2aa198);
62
+ --bs-cyan-050: color-mix(in lab, var(--bs-white) 90%, #2aa198);
63
+ --bs-cyan-100: color-mix(in lab, var(--bs-white) 80%, #2aa198);
64
+ --bs-cyan-200: color-mix(in lab, var(--bs-white) 60%, #2aa198);
65
+ --bs-cyan-300: color-mix(in lab, var(--bs-white) 40%, #2aa198);
66
+ --bs-cyan-400: color-mix(in lab, var(--bs-white) 20%, #2aa198);
67
+ --bs-cyan-500: #2aa198;
68
+ --bs-cyan-600: color-mix(in lab, var(--bs-black) 16%, #2aa198);
69
+ --bs-cyan-700: color-mix(in lab, var(--bs-black) 32%, #2aa198);
70
+ --bs-cyan-800: color-mix(in lab, var(--bs-black) 48%, #2aa198);
71
+ --bs-cyan-900: color-mix(in lab, var(--bs-black) 64%, #2aa198);
72
+ --bs-cyan-950: color-mix(in lab, var(--bs-black) 76%, #2aa198);
73
+ --bs-cyan-975: color-mix(in lab, var(--bs-black) 88%, #2aa198);
74
+
75
+ --bs-green-025: color-mix(in lab, var(--bs-white) 94%, #859900);
76
+ --bs-green-050: color-mix(in lab, var(--bs-white) 90%, #859900);
77
+ --bs-green-100: color-mix(in lab, var(--bs-white) 80%, #859900);
78
+ --bs-green-200: color-mix(in lab, var(--bs-white) 60%, #859900);
79
+ --bs-green-300: color-mix(in lab, var(--bs-white) 40%, #859900);
80
+ --bs-green-400: color-mix(in lab, var(--bs-white) 20%, #859900);
81
+ --bs-green-500: #859900;
82
+ --bs-green-600: color-mix(in lab, var(--bs-black) 16%, #859900);
83
+ --bs-green-700: color-mix(in lab, var(--bs-black) 32%, #859900);
84
+ --bs-green-800: color-mix(in lab, var(--bs-black) 48%, #859900);
85
+ --bs-green-900: color-mix(in lab, var(--bs-black) 64%, #859900);
86
+ --bs-green-950: color-mix(in lab, var(--bs-black) 76%, #859900);
87
+ --bs-green-975: color-mix(in lab, var(--bs-black) 88%, #859900);
88
+
89
+ --bs-orange-025: color-mix(in lab, var(--bs-white) 94%, #cb4b16);
90
+ --bs-orange-050: color-mix(in lab, var(--bs-white) 90%, #cb4b16);
91
+ --bs-orange-100: color-mix(in lab, var(--bs-white) 80%, #cb4b16);
92
+ --bs-orange-200: color-mix(in lab, var(--bs-white) 60%, #cb4b16);
93
+ --bs-orange-300: color-mix(in lab, var(--bs-white) 40%, #cb4b16);
94
+ --bs-orange-400: color-mix(in lab, var(--bs-white) 20%, #cb4b16);
95
+ --bs-orange-500: #cb4b16;
96
+ --bs-orange-600: color-mix(in lab, var(--bs-black) 16%, #cb4b16);
97
+ --bs-orange-700: color-mix(in lab, var(--bs-black) 32%, #cb4b16);
98
+ --bs-orange-800: color-mix(in lab, var(--bs-black) 48%, #cb4b16);
99
+ --bs-orange-900: color-mix(in lab, var(--bs-black) 64%, #cb4b16);
100
+ --bs-orange-950: color-mix(in lab, var(--bs-black) 76%, #cb4b16);
101
+ --bs-orange-975: color-mix(in lab, var(--bs-black) 88%, #cb4b16);
102
+
103
+ --bs-pink-025: color-mix(in lab, var(--bs-white) 94%, #d33682);
104
+ --bs-pink-050: color-mix(in lab, var(--bs-white) 90%, #d33682);
105
+ --bs-pink-100: color-mix(in lab, var(--bs-white) 80%, #d33682);
106
+ --bs-pink-200: color-mix(in lab, var(--bs-white) 60%, #d33682);
107
+ --bs-pink-300: color-mix(in lab, var(--bs-white) 40%, #d33682);
108
+ --bs-pink-400: color-mix(in lab, var(--bs-white) 20%, #d33682);
109
+ --bs-pink-500: #d33682;
110
+ --bs-pink-600: color-mix(in lab, var(--bs-black) 16%, #d33682);
111
+ --bs-pink-700: color-mix(in lab, var(--bs-black) 32%, #d33682);
112
+ --bs-pink-800: color-mix(in lab, var(--bs-black) 48%, #d33682);
113
+ --bs-pink-900: color-mix(in lab, var(--bs-black) 64%, #d33682);
114
+ --bs-pink-950: color-mix(in lab, var(--bs-black) 76%, #d33682);
115
+ --bs-pink-975: color-mix(in lab, var(--bs-black) 88%, #d33682);
116
+
117
+ --bs-purple-025: color-mix(in lab, var(--bs-white) 94%, #6c71c4);
118
+ --bs-purple-050: color-mix(in lab, var(--bs-white) 90%, #6c71c4);
119
+ --bs-purple-100: color-mix(in lab, var(--bs-white) 80%, #6c71c4);
120
+ --bs-purple-200: color-mix(in lab, var(--bs-white) 60%, #6c71c4);
121
+ --bs-purple-300: color-mix(in lab, var(--bs-white) 40%, #6c71c4);
122
+ --bs-purple-400: color-mix(in lab, var(--bs-white) 20%, #6c71c4);
123
+ --bs-purple-500: #6c71c4;
124
+ --bs-purple-600: color-mix(in lab, var(--bs-black) 16%, #6c71c4);
125
+ --bs-purple-700: color-mix(in lab, var(--bs-black) 32%, #6c71c4);
126
+ --bs-purple-800: color-mix(in lab, var(--bs-black) 48%, #6c71c4);
127
+ --bs-purple-900: color-mix(in lab, var(--bs-black) 64%, #6c71c4);
128
+ --bs-purple-950: color-mix(in lab, var(--bs-black) 76%, #6c71c4);
129
+ --bs-purple-975: color-mix(in lab, var(--bs-black) 88%, #6c71c4);
130
+
131
+ --bs-red-025: color-mix(in lab, var(--bs-white) 94%, #dc322f);
132
+ --bs-red-050: color-mix(in lab, var(--bs-white) 90%, #dc322f);
133
+ --bs-red-100: color-mix(in lab, var(--bs-white) 80%, #dc322f);
134
+ --bs-red-200: color-mix(in lab, var(--bs-white) 60%, #dc322f);
135
+ --bs-red-300: color-mix(in lab, var(--bs-white) 40%, #dc322f);
136
+ --bs-red-400: color-mix(in lab, var(--bs-white) 20%, #dc322f);
137
+ --bs-red-500: #dc322f;
138
+ --bs-red-600: color-mix(in lab, var(--bs-black) 16%, #dc322f);
139
+ --bs-red-700: color-mix(in lab, var(--bs-black) 32%, #dc322f);
140
+ --bs-red-800: color-mix(in lab, var(--bs-black) 48%, #dc322f);
141
+ --bs-red-900: color-mix(in lab, var(--bs-black) 64%, #dc322f);
142
+ --bs-red-950: color-mix(in lab, var(--bs-black) 76%, #dc322f);
143
+ --bs-red-975: color-mix(in lab, var(--bs-black) 88%, #dc322f);
144
+
145
+ --bs-yellow-025: color-mix(in lab, var(--bs-white) 94%, #b58900);
146
+ --bs-yellow-050: color-mix(in lab, var(--bs-white) 90%, #b58900);
147
+ --bs-yellow-100: color-mix(in lab, var(--bs-white) 80%, #b58900);
148
+ --bs-yellow-200: color-mix(in lab, var(--bs-white) 60%, #b58900);
149
+ --bs-yellow-300: color-mix(in lab, var(--bs-white) 40%, #b58900);
150
+ --bs-yellow-400: color-mix(in lab, var(--bs-white) 20%, #b58900);
151
+ --bs-yellow-500: #b58900;
152
+ --bs-yellow-600: color-mix(in lab, var(--bs-black) 16%, #b58900);
153
+ --bs-yellow-700: color-mix(in lab, var(--bs-black) 32%, #b58900);
154
+ --bs-yellow-800: color-mix(in lab, var(--bs-black) 48%, #b58900);
155
+ --bs-yellow-900: color-mix(in lab, var(--bs-black) 64%, #b58900);
156
+ --bs-yellow-950: color-mix(in lab, var(--bs-black) 76%, #b58900);
157
+ --bs-yellow-975: color-mix(in lab, var(--bs-black) 88%, #b58900);
158
+
159
+ /* Text, stated rather than left to the ramp. Bootstrap pairs a low step as
160
+ a light surface with that same step as dark-mode text, which a palette
161
+ built for its own contrast does not agree with. */
162
+ --bs-fg-1: light-dark(#073642, #eee8d5);
163
+ --bs-fg-body: light-dark(#586e75, #93a1a1);
164
+ --bs-fg-2: light-dark(#657b83, #839496);
165
+
166
+ /* The label a solid fill carries, for the four families Bootstrap has
167
+ spent on a meaning and this palette has repainted. Upstream's own shape:
168
+ it gives warning and info a dark label for the same reason. */
169
+ --bs-danger-contrast: var(--bs-white);
170
+ --bs-success-contrast: var(--bs-gray-975);
171
+ --bs-warning-contrast: var(--bs-gray-975);
172
+ --bs-info-contrast: var(--bs-gray-975);
173
+
174
+ /* The accent this palette leads with, as the primary color: the same nine
175
+ `_color.html.erb` writes, from blue and the label that reads on it. Here
176
+ rather than only in the page because a reader may swap this file for
177
+ another one, and the primary has to travel with it. A host naming its
178
+ own color still wins, its block coming after this file. */
179
+ --bs-primary-base: var(--bs-blue-500);
180
+ --bs-primary-fg: light-dark(var(--bs-blue-600), var(--bs-blue-400));
181
+ --bs-primary-fg-emphasis: light-dark(var(--bs-blue-800), var(--bs-blue-200));
182
+ --bs-primary-bg: var(--bs-blue-500);
183
+ --bs-primary-bg-subtle: light-dark(var(--bs-blue-100), var(--bs-blue-900));
184
+ --bs-primary-bg-muted: light-dark(var(--bs-blue-200), var(--bs-blue-800));
185
+ --bs-primary-border: light-dark(var(--bs-blue-300), var(--bs-blue-600));
186
+ --bs-primary-focus-ring: light-dark(color-mix(in oklch, var(--bs-blue-500) 50%, var(--bs-bg-body)), color-mix(in oklch, var(--bs-blue-500) 75%, var(--bs-bg-body)));
187
+ --bs-primary-contrast: var(--bs-gray-975);
188
+ }
@@ -0,0 +1,189 @@
1
+ /* Tokyo Night, enkia — https://github.com/enkia/tokyo-night-vscode-theme
2
+ Tokyo Night Day is the light page and Tokyo Night's own the dark one.
3
+ its magenta serves purple and pink, its orange serves brown. The mid
4
+ neutral is derived.
5
+
6
+ Bootstrap builds a family by mixing one base toward `--bs-white` below
7
+ the 500 step and toward `--bs-black` above it, and inlines that base
8
+ into all thirteen — so a palette restates the thirteen rather than the
9
+ one. Upstream's order and upstream's shapes with only the base swapped,
10
+ so a later Bootstrap diffs against this file. */
11
+ :root {
12
+ /* The page, and the two colors every ramp below is mixed with.
13
+ `--bs-bg-body` reads `--bs-white` in light mode and `--bs-gray-975` in
14
+ dark, so repainting these two is what moves the page itself. */
15
+ --bs-white: #e1e2e7;
16
+ --bs-black: #1a1b26;
17
+
18
+ /* The neutrals, which every surface, border and text token Bootstrap ships
19
+ derives from. */
20
+ --bs-gray-025: color-mix(in lab, var(--bs-white) 94%, #8189a8);
21
+ --bs-gray-050: color-mix(in lab, var(--bs-white) 90%, #8189a8);
22
+ --bs-gray-100: color-mix(in lab, var(--bs-white) 80%, #8189a8);
23
+ --bs-gray-200: color-mix(in lab, var(--bs-white) 60%, #8189a8);
24
+ --bs-gray-300: color-mix(in lab, var(--bs-white) 40%, #8189a8);
25
+ --bs-gray-400: color-mix(in lab, var(--bs-white) 20%, #8189a8);
26
+ --bs-gray-500: #8189a8;
27
+ --bs-gray-600: color-mix(in lab, var(--bs-black) 16%, #8189a8);
28
+ --bs-gray-700: color-mix(in lab, var(--bs-black) 32%, #8189a8);
29
+ --bs-gray-800: color-mix(in lab, var(--bs-black) 48%, #8189a8);
30
+ --bs-gray-900: color-mix(in lab, var(--bs-black) 64%, #8189a8);
31
+ --bs-gray-950: color-mix(in lab, var(--bs-black) 76%, #8189a8);
32
+ --bs-gray-975: color-mix(in lab, var(--bs-black) 88%, #8189a8);
33
+
34
+ --bs-blue-025: color-mix(in lab, var(--bs-white) 94%, #7aa2f7);
35
+ --bs-blue-050: color-mix(in lab, var(--bs-white) 90%, #7aa2f7);
36
+ --bs-blue-100: color-mix(in lab, var(--bs-white) 80%, #7aa2f7);
37
+ --bs-blue-200: color-mix(in lab, var(--bs-white) 60%, #7aa2f7);
38
+ --bs-blue-300: color-mix(in lab, var(--bs-white) 40%, #7aa2f7);
39
+ --bs-blue-400: color-mix(in lab, var(--bs-white) 20%, #7aa2f7);
40
+ --bs-blue-500: #7aa2f7;
41
+ --bs-blue-600: color-mix(in lab, var(--bs-black) 16%, #7aa2f7);
42
+ --bs-blue-700: color-mix(in lab, var(--bs-black) 32%, #7aa2f7);
43
+ --bs-blue-800: color-mix(in lab, var(--bs-black) 48%, #7aa2f7);
44
+ --bs-blue-900: color-mix(in lab, var(--bs-black) 64%, #7aa2f7);
45
+ --bs-blue-950: color-mix(in lab, var(--bs-black) 76%, #7aa2f7);
46
+ --bs-blue-975: color-mix(in lab, var(--bs-black) 88%, #7aa2f7);
47
+
48
+ --bs-brown-025: color-mix(in lab, var(--bs-white) 94%, #ff9e64);
49
+ --bs-brown-050: color-mix(in lab, var(--bs-white) 90%, #ff9e64);
50
+ --bs-brown-100: color-mix(in lab, var(--bs-white) 80%, #ff9e64);
51
+ --bs-brown-200: color-mix(in lab, var(--bs-white) 60%, #ff9e64);
52
+ --bs-brown-300: color-mix(in lab, var(--bs-white) 40%, #ff9e64);
53
+ --bs-brown-400: color-mix(in lab, var(--bs-white) 20%, #ff9e64);
54
+ --bs-brown-500: #ff9e64;
55
+ --bs-brown-600: color-mix(in lab, var(--bs-black) 16%, #ff9e64);
56
+ --bs-brown-700: color-mix(in lab, var(--bs-black) 32%, #ff9e64);
57
+ --bs-brown-800: color-mix(in lab, var(--bs-black) 48%, #ff9e64);
58
+ --bs-brown-900: color-mix(in lab, var(--bs-black) 64%, #ff9e64);
59
+ --bs-brown-950: color-mix(in lab, var(--bs-black) 76%, #ff9e64);
60
+ --bs-brown-975: color-mix(in lab, var(--bs-black) 88%, #ff9e64);
61
+
62
+ --bs-cyan-025: color-mix(in lab, var(--bs-white) 94%, #7dcfff);
63
+ --bs-cyan-050: color-mix(in lab, var(--bs-white) 90%, #7dcfff);
64
+ --bs-cyan-100: color-mix(in lab, var(--bs-white) 80%, #7dcfff);
65
+ --bs-cyan-200: color-mix(in lab, var(--bs-white) 60%, #7dcfff);
66
+ --bs-cyan-300: color-mix(in lab, var(--bs-white) 40%, #7dcfff);
67
+ --bs-cyan-400: color-mix(in lab, var(--bs-white) 20%, #7dcfff);
68
+ --bs-cyan-500: #7dcfff;
69
+ --bs-cyan-600: color-mix(in lab, var(--bs-black) 16%, #7dcfff);
70
+ --bs-cyan-700: color-mix(in lab, var(--bs-black) 32%, #7dcfff);
71
+ --bs-cyan-800: color-mix(in lab, var(--bs-black) 48%, #7dcfff);
72
+ --bs-cyan-900: color-mix(in lab, var(--bs-black) 64%, #7dcfff);
73
+ --bs-cyan-950: color-mix(in lab, var(--bs-black) 76%, #7dcfff);
74
+ --bs-cyan-975: color-mix(in lab, var(--bs-black) 88%, #7dcfff);
75
+
76
+ --bs-green-025: color-mix(in lab, var(--bs-white) 94%, #9ece6a);
77
+ --bs-green-050: color-mix(in lab, var(--bs-white) 90%, #9ece6a);
78
+ --bs-green-100: color-mix(in lab, var(--bs-white) 80%, #9ece6a);
79
+ --bs-green-200: color-mix(in lab, var(--bs-white) 60%, #9ece6a);
80
+ --bs-green-300: color-mix(in lab, var(--bs-white) 40%, #9ece6a);
81
+ --bs-green-400: color-mix(in lab, var(--bs-white) 20%, #9ece6a);
82
+ --bs-green-500: #9ece6a;
83
+ --bs-green-600: color-mix(in lab, var(--bs-black) 16%, #9ece6a);
84
+ --bs-green-700: color-mix(in lab, var(--bs-black) 32%, #9ece6a);
85
+ --bs-green-800: color-mix(in lab, var(--bs-black) 48%, #9ece6a);
86
+ --bs-green-900: color-mix(in lab, var(--bs-black) 64%, #9ece6a);
87
+ --bs-green-950: color-mix(in lab, var(--bs-black) 76%, #9ece6a);
88
+ --bs-green-975: color-mix(in lab, var(--bs-black) 88%, #9ece6a);
89
+
90
+ --bs-orange-025: color-mix(in lab, var(--bs-white) 94%, #ff9e64);
91
+ --bs-orange-050: color-mix(in lab, var(--bs-white) 90%, #ff9e64);
92
+ --bs-orange-100: color-mix(in lab, var(--bs-white) 80%, #ff9e64);
93
+ --bs-orange-200: color-mix(in lab, var(--bs-white) 60%, #ff9e64);
94
+ --bs-orange-300: color-mix(in lab, var(--bs-white) 40%, #ff9e64);
95
+ --bs-orange-400: color-mix(in lab, var(--bs-white) 20%, #ff9e64);
96
+ --bs-orange-500: #ff9e64;
97
+ --bs-orange-600: color-mix(in lab, var(--bs-black) 16%, #ff9e64);
98
+ --bs-orange-700: color-mix(in lab, var(--bs-black) 32%, #ff9e64);
99
+ --bs-orange-800: color-mix(in lab, var(--bs-black) 48%, #ff9e64);
100
+ --bs-orange-900: color-mix(in lab, var(--bs-black) 64%, #ff9e64);
101
+ --bs-orange-950: color-mix(in lab, var(--bs-black) 76%, #ff9e64);
102
+ --bs-orange-975: color-mix(in lab, var(--bs-black) 88%, #ff9e64);
103
+
104
+ --bs-pink-025: color-mix(in lab, var(--bs-white) 94%, #bb9af7);
105
+ --bs-pink-050: color-mix(in lab, var(--bs-white) 90%, #bb9af7);
106
+ --bs-pink-100: color-mix(in lab, var(--bs-white) 80%, #bb9af7);
107
+ --bs-pink-200: color-mix(in lab, var(--bs-white) 60%, #bb9af7);
108
+ --bs-pink-300: color-mix(in lab, var(--bs-white) 40%, #bb9af7);
109
+ --bs-pink-400: color-mix(in lab, var(--bs-white) 20%, #bb9af7);
110
+ --bs-pink-500: #bb9af7;
111
+ --bs-pink-600: color-mix(in lab, var(--bs-black) 16%, #bb9af7);
112
+ --bs-pink-700: color-mix(in lab, var(--bs-black) 32%, #bb9af7);
113
+ --bs-pink-800: color-mix(in lab, var(--bs-black) 48%, #bb9af7);
114
+ --bs-pink-900: color-mix(in lab, var(--bs-black) 64%, #bb9af7);
115
+ --bs-pink-950: color-mix(in lab, var(--bs-black) 76%, #bb9af7);
116
+ --bs-pink-975: color-mix(in lab, var(--bs-black) 88%, #bb9af7);
117
+
118
+ --bs-purple-025: color-mix(in lab, var(--bs-white) 94%, #bb9af7);
119
+ --bs-purple-050: color-mix(in lab, var(--bs-white) 90%, #bb9af7);
120
+ --bs-purple-100: color-mix(in lab, var(--bs-white) 80%, #bb9af7);
121
+ --bs-purple-200: color-mix(in lab, var(--bs-white) 60%, #bb9af7);
122
+ --bs-purple-300: color-mix(in lab, var(--bs-white) 40%, #bb9af7);
123
+ --bs-purple-400: color-mix(in lab, var(--bs-white) 20%, #bb9af7);
124
+ --bs-purple-500: #bb9af7;
125
+ --bs-purple-600: color-mix(in lab, var(--bs-black) 16%, #bb9af7);
126
+ --bs-purple-700: color-mix(in lab, var(--bs-black) 32%, #bb9af7);
127
+ --bs-purple-800: color-mix(in lab, var(--bs-black) 48%, #bb9af7);
128
+ --bs-purple-900: color-mix(in lab, var(--bs-black) 64%, #bb9af7);
129
+ --bs-purple-950: color-mix(in lab, var(--bs-black) 76%, #bb9af7);
130
+ --bs-purple-975: color-mix(in lab, var(--bs-black) 88%, #bb9af7);
131
+
132
+ --bs-red-025: color-mix(in lab, var(--bs-white) 94%, #f7768e);
133
+ --bs-red-050: color-mix(in lab, var(--bs-white) 90%, #f7768e);
134
+ --bs-red-100: color-mix(in lab, var(--bs-white) 80%, #f7768e);
135
+ --bs-red-200: color-mix(in lab, var(--bs-white) 60%, #f7768e);
136
+ --bs-red-300: color-mix(in lab, var(--bs-white) 40%, #f7768e);
137
+ --bs-red-400: color-mix(in lab, var(--bs-white) 20%, #f7768e);
138
+ --bs-red-500: #f7768e;
139
+ --bs-red-600: color-mix(in lab, var(--bs-black) 16%, #f7768e);
140
+ --bs-red-700: color-mix(in lab, var(--bs-black) 32%, #f7768e);
141
+ --bs-red-800: color-mix(in lab, var(--bs-black) 48%, #f7768e);
142
+ --bs-red-900: color-mix(in lab, var(--bs-black) 64%, #f7768e);
143
+ --bs-red-950: color-mix(in lab, var(--bs-black) 76%, #f7768e);
144
+ --bs-red-975: color-mix(in lab, var(--bs-black) 88%, #f7768e);
145
+
146
+ --bs-yellow-025: color-mix(in lab, var(--bs-white) 94%, #e0af68);
147
+ --bs-yellow-050: color-mix(in lab, var(--bs-white) 90%, #e0af68);
148
+ --bs-yellow-100: color-mix(in lab, var(--bs-white) 80%, #e0af68);
149
+ --bs-yellow-200: color-mix(in lab, var(--bs-white) 60%, #e0af68);
150
+ --bs-yellow-300: color-mix(in lab, var(--bs-white) 40%, #e0af68);
151
+ --bs-yellow-400: color-mix(in lab, var(--bs-white) 20%, #e0af68);
152
+ --bs-yellow-500: #e0af68;
153
+ --bs-yellow-600: color-mix(in lab, var(--bs-black) 16%, #e0af68);
154
+ --bs-yellow-700: color-mix(in lab, var(--bs-black) 32%, #e0af68);
155
+ --bs-yellow-800: color-mix(in lab, var(--bs-black) 48%, #e0af68);
156
+ --bs-yellow-900: color-mix(in lab, var(--bs-black) 64%, #e0af68);
157
+ --bs-yellow-950: color-mix(in lab, var(--bs-black) 76%, #e0af68);
158
+ --bs-yellow-975: color-mix(in lab, var(--bs-black) 88%, #e0af68);
159
+
160
+ /* Text, stated rather than left to the ramp. Bootstrap pairs a low step as
161
+ a light surface with that same step as dark-mode text, which a palette
162
+ built for its own contrast does not agree with. */
163
+ --bs-fg-1: light-dark(#1a1b26, #c0caf5);
164
+ --bs-fg-body: light-dark(#343b58, #a9b1d6);
165
+ --bs-fg-2: light-dark(#565f89, #8b93b5);
166
+
167
+ /* The label a solid fill carries, for the four families Bootstrap has
168
+ spent on a meaning and this palette has repainted. Upstream's own shape:
169
+ it gives warning and info a dark label for the same reason. */
170
+ --bs-danger-contrast: var(--bs-gray-975);
171
+ --bs-success-contrast: var(--bs-gray-975);
172
+ --bs-warning-contrast: var(--bs-gray-975);
173
+ --bs-info-contrast: var(--bs-gray-975);
174
+
175
+ /* The accent this palette leads with, as the primary color: the same nine
176
+ `_color.html.erb` writes, from blue and the label that reads on it. Here
177
+ rather than only in the page because a reader may swap this file for
178
+ another one, and the primary has to travel with it. A host naming its
179
+ own color still wins, its block coming after this file. */
180
+ --bs-primary-base: var(--bs-blue-500);
181
+ --bs-primary-fg: light-dark(var(--bs-blue-600), var(--bs-blue-400));
182
+ --bs-primary-fg-emphasis: light-dark(var(--bs-blue-800), var(--bs-blue-200));
183
+ --bs-primary-bg: var(--bs-blue-500);
184
+ --bs-primary-bg-subtle: light-dark(var(--bs-blue-100), var(--bs-blue-900));
185
+ --bs-primary-bg-muted: light-dark(var(--bs-blue-200), var(--bs-blue-800));
186
+ --bs-primary-border: light-dark(var(--bs-blue-300), var(--bs-blue-600));
187
+ --bs-primary-focus-ring: light-dark(color-mix(in oklch, var(--bs-blue-500) 50%, var(--bs-bg-body)), color-mix(in oklch, var(--bs-blue-500) 75%, var(--bs-bg-body)));
188
+ --bs-primary-contrast: var(--bs-gray-975);
189
+ }
data/build.mjs CHANGED
@@ -2,6 +2,7 @@
2
2
  // at, which is also what the gem ships. Every URL inside is relative to the file holding it,
3
3
  // so one build answers from the gem and from a CDN carrying the package alike.
4
4
  import { build } from 'esbuild'
5
+ import { cpSync, mkdirSync } from 'node:fs'
5
6
 
6
7
  await build({
7
8
  entryPoints: ['app/javascript/bh.js', 'app/stylesheets/bh.css'],
@@ -13,3 +14,8 @@ await build({
13
14
  alias: { bootstrap: './vendor/bootstrap.bundle.min.js' },
14
15
  logLevel: 'info',
15
16
  })
17
+
18
+ // The nine palettes are not bundled: a page links one at a time and swaps it for another,
19
+ // which is the whole point of them, so they are copied beside the stylesheet as they are.
20
+ mkdirSync('public/bh/theme', { recursive: true })
21
+ cpSync('app/stylesheets/theme', 'public/bh/theme', { recursive: true })
@@ -8,6 +8,7 @@ en:
8
8
  more: '%{first} + %{count} more'
9
9
  no_results: Nothing matches that
10
10
  okay: Okay
11
+ photo: Photo
11
12
  search: Search
12
13
  send: Send
13
14
  typing: Typing
@@ -8,12 +8,16 @@ module Bh
8
8
  include Asides, Asks
9
9
 
10
10
  # `messages` as a thread that opens at its newest and, where `url` is given, a field
11
- # under it that posts the next message there, suggesting `hints` one at a time.
12
- def chat_with(messages:, url: nil, hints: [])
13
- parts = [bh_chat_messages(messages)]
11
+ # under it that posts the next message there, suggesting `hints` one at a time. A
12
+ # `note` stands over the whole thread: what this conversation is about, or the other
13
+ # way to reach whoever is on the far end of it.
14
+ def chat_with(messages:, url: nil, hints: [], note: nil)
15
+ parts = [bh_chat_note(note), bh_chat_messages(messages)]
14
16
  parts.push bh_chat_ask(url, hints) if url
15
17
 
16
- tag.div safe_join(parts, "\n"), class: 'chat-thread', data: { controller: 'thread' }
18
+ said = safe_join parts.compact, "\n"
19
+
20
+ tag.div said, class: 'chat-thread', data: { controller: 'thread' }
17
21
  end
18
22
 
19
23
  private
@@ -30,13 +34,36 @@ module Bh
30
34
  safe_join parts.compact, "\n"
31
35
  end
32
36
 
37
+ # Said over the thread rather than in it, so it is not one of the turns: nobody
38
+ # said this, and a bubble would claim somebody had.
39
+ def bh_chat_note(note)
40
+ tag.p note, class: 'chat-note' if note.present?
41
+ end
42
+
33
43
  def bh_chat_bubble(message)
34
44
  side = Asides::SIDES.fetch message.side
35
- return tag.p message.text, class: "chat-bubble chat-#{side}" if message.text
45
+ said = bh_chat_said message
46
+ return tag.p said, class: "chat-bubble chat-#{side}" if said
36
47
 
37
48
  tag.p safe_join(Array.new(3) { tag.span }), class: "chat-bubble chat-#{side} chat-typing",
38
49
  aria: { label: t('bh.typing') }
39
50
  end
51
+
52
+ # The words and then the pictures, which is the order a phone lays a picture
53
+ # message out in -- and nothing at all where a message has neither yet.
54
+ def bh_chat_said(message)
55
+ pictures = Array(message.photos).map { |photo| bh_chat_photo photo }
56
+
57
+ safe_join([message.text, *pictures].compact_blank, "\n").presence
58
+ end
59
+
60
+ # A picture in the bubble, opening full size in a tab of its own: what fits beside
61
+ # words is rarely what somebody wants to look at.
62
+ def bh_chat_photo(url)
63
+ tag.a href: url, target: :_blank, rel: 'noopener' do
64
+ tag.img src: url, alt: t('bh.photo'), class: 'chat-photo', loading: :lazy
65
+ end
66
+ end
40
67
  end
41
68
  end
42
69
  end