1:root {
2 --bg: #f4f5f7;
3 --card: #ffffff;
4 --text: #1c1e21;
5 --muted: #5f646b;
6 --border: #dfe2e6;
7 --accent: #1f5fa8;
8 --ok: #1a7f37;
9 --bad: #b42318;
10 font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
11 color: var(--text);
12 background: var(--bg);
13 line-height: 1.45;
14}
16* {
17 box-sizing: border-box;
18}
20body {
21 margin: 0;
22}
24.app {
25 max-width: 1100px;
26 margin: 0 auto;
27 padding: 16px 16px 48px;
28}
30.app-header h1 {
31 margin: 8px 0 4px;
32 font-size: 1.7rem;
33}
35.app-header p,
36.hint {
37 color: var(--muted);
38 margin: 0 0 16px;
39 max-width: 70em;
40}
42.app-footer {
43 color: var(--muted);
44 font-size: 0.85rem;
45 margin-top: 16px;
46}
48.card {
49 background: var(--card);
50 border: 1px solid var(--border);
51 border-radius: 8px;
52 padding: 14px 16px 16px;
53 margin-bottom: 16px;
54}
56.card h2 {
57 margin: 0 0 10px;
58 font-size: 1.15rem;
59}
61.card h3 {
62 margin: 0;
63 font-size: 0.95rem;
64 color: var(--muted);
65 font-weight: 600;
66}
68.tone {
69 border-top: 4px solid;
70 flex: 1 1 380px;
71 min-width: 0;
72}
74.tone-header {
75 display: flex;
76 align-items: center;
77 justify-content: space-between;
78 gap: 8px;
79}
81.columns {
82 display: flex;
83 gap: 16px;
84 flex-wrap: wrap;
85 margin-bottom: 16px;
86}
88.columns .card {
89 margin-bottom: 0;
90}
92.plot {
93 display: block;
94 width: 100%;
95 background: #fff;
96}
98.waveform-plot {
99 height: 170px;
100}
102.stem-plot {
103 height: 120px;
104}
106.plot-label {
107 font-size: 0.8rem;
108 color: var(--muted);
109 margin: 10px 0 2px;
110}
112.controls-header {
113 display: flex;
114 align-items: center;
115 justify-content: space-between;
116 flex-wrap: wrap;
117 gap: 8px;
118 margin: 14px 0 6px;
119}
121.button-row {
122 display: flex;
123 align-items: center;
124 gap: 8px;
125 flex-wrap: wrap;
126}
128.spacer {
129 flex: 1;
130}
132button {
133 font: inherit;
134 font-size: 0.9rem;
135 padding: 6px 12px;
136 border-radius: 6px;
137 border: 1px solid var(--border);
138 background: #fff;
139 color: var(--text);
140 cursor: pointer;
141}
143button:hover:not(:disabled) {
144 background: #f0f2f5;
145}
147button:disabled {
148 opacity: 0.5;
149 cursor: default;
150}
152button.primary {
153 background: var(--accent);
154 border-color: var(--accent);
155 color: #fff;
156}
158button.primary:hover:not(:disabled) {
159 background: #184c87;
160}
162button.answer {
163 font-weight: 600;
164 min-width: 100px;
165}
167button.small {
168 font-size: 0.8rem;
169 padding: 4px 10px;
170}
172.playing-indicator {
173 color: var(--muted);
174 font-size: 0.9rem;
175 min-width: 8em;
176}
178.global-controls {
179 display: flex;
180 flex-wrap: wrap;
181 gap: 10px 24px;
182 align-items: center;
183}
185.global-controls label {
186 display: flex;
187 align-items: center;
188 gap: 8px;
189 font-size: 0.9rem;
190}
192.global-controls label > span {
193 white-space: nowrap;
194}
196.f0-range {
197 width: 180px;
198}
200select {
201 font: inherit;
202 font-size: 0.9rem;
203 padding: 4px 6px;
204 border-radius: 6px;
205 border: 1px solid var(--border);
206 background: #fff;
207}
209.slider-grid {
210 display: grid;
211 grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
212 gap: 2px 24px;
213}
215.slider-row {
216 display: grid;
217 grid-template-columns: 1.6em 1fr 5.5em 1.2em;
218 align-items: center;
219 gap: 6px;
220}
222.slider-label {
223 font-variant-numeric: tabular-nums;
224 color: var(--muted);
225 font-size: 0.85rem;
226 text-align: right;
227}
229.slider-unit {
230 color: var(--muted);
231 font-size: 0.85rem;
232}
234input[type='range'] {
235 width: 100%;
236 min-width: 80px;
237 accent-color: var(--accent);
238}
240.slider-value {
241 font: inherit;
242 font-size: 0.85rem;
243 width: 5.5em;
244 padding: 2px 4px;
245 border: 1px solid var(--border);
246 border-radius: 4px;
247}
249.blind-controls {
250 margin: 8px 0;
251}
253.feedback {
254 min-height: 1.6em;
255 margin: 6px 0 12px;
256 font-size: 0.95rem;
257}
259.feedback .ok {
260 color: var(--ok);
261 font-weight: 600;
262}
264.feedback .bad {
265 color: var(--bad);
266 font-weight: 600;
267}
269.stats {
270 display: flex;
271 flex-wrap: wrap;
272 gap: 8px 28px;
273 align-items: flex-end;
274 padding-top: 10px;
275 border-top: 1px solid var(--border);
276}
278.stats > div {
279 display: flex;
280 flex-direction: column;
281}
283.stat-label {
284 font-size: 0.75rem;
285 color: var(--muted);
286}
288.stat-value {
289 font-size: 1.15rem;
290 font-variant-numeric: tabular-nums;
291}
293.stat-value small {
294 font-size: 0.8rem;
295 color: var(--muted);
296}
298kbd {
299 font-family: inherit;
300 font-size: 0.85em;
301 border: 1px solid var(--border);
302 border-bottom-width: 2px;
303 border-radius: 4px;
304 padding: 0 5px;
305 background: #fafbfc;
306}
308.cycle-controls {
309 display: flex;
310 align-items: center;
311 flex-wrap: wrap;
312 gap: 8px 20px;
313 margin: 4px 0 12px;
314}
316.cycle-controls label {
317 display: flex;
318 align-items: center;
319 gap: 8px;
320 font-size: 0.9rem;
321}
323.cycle-controls label > span {
324 white-space: nowrap;
325}
327.cycle-range {
328 width: 220px;
329}
331.cycle-period {
332 color: var(--muted);
333 font-variant-numeric: tabular-nums;
334}
336.cycle-position {
337 display: flex;
338 align-items: center;
339 gap: 10px;
340 max-width: 520px;
341}
343.cycle-end {
344 font-weight: 700;
345}
347.cycle-a {
348 color: #1f5fa8;
349}
351.cycle-b {
352 color: #d9641e;
353}
355.cycle-track {
356 position: relative;
357 flex: 1;
358 height: 8px;
359 border-radius: 4px;
360 background: linear-gradient(90deg, #1f5fa8, #d9641e);
361}
363.cycle-marker {
364 position: absolute;
365 top: 50%;
366 width: 16px;
367 height: 16px;
368 border-radius: 50%;
369 background: #fff;
370 border: 2px solid var(--text);
371 transform: translate(-50%, -50%);
372 transition: opacity 0.2s;
373}
375.error {
376 color: var(--bad);
377 margin-top: 8px;
378 font-size: 0.9rem;
379}
381@media (max-width: 600px) {
382 .slider-row {
383 grid-template-columns: 1.6em 1fr 4.5em 1.2em;
384 }
385}