tamga-ui 0.2.1 → 0.3.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.
- package/CHANGELOG.md +48 -0
- package/dist/components/chrome.d.ts +11 -1
- package/dist/components/chrome.d.ts.map +1 -1
- package/dist/components/chrome.js +19 -6
- package/dist/components/error-state.d.ts +7 -14
- package/dist/components/error-state.d.ts.map +1 -1
- package/dist/components/overlay.d.ts +7 -16
- package/dist/components/overlay.d.ts.map +1 -1
- package/dist/components/primitives.d.ts +7 -16
- package/dist/components/primitives.d.ts.map +1 -1
- package/dist/components/rail-link.d.ts +8 -1
- package/dist/components/rail-link.d.ts.map +1 -1
- package/dist/components/rail-link.js +2 -1
- package/dist/kit.css +68 -768
- package/dist/lib/color.d.ts +0 -20
- package/dist/lib/color.d.ts.map +1 -1
- package/dist/lib/color.js +0 -22
- package/dist/lib/palette.d.ts +0 -16
- package/dist/lib/palette.d.ts.map +1 -1
- package/dist/lib/palette.js +0 -12
- package/dist/patterns/shared.d.ts +1 -1
- package/dist/patterns/shared.d.ts.map +1 -1
- package/dist/styles.css +1 -3
- package/dist/theme.css +127 -483
- package/package.json +4 -1
package/dist/kit.css
CHANGED
|
@@ -1,222 +1,91 @@
|
|
|
1
|
-
|
|
2
|
-
tamga-ui · KİT
|
|
3
|
-
|
|
4
|
-
Bileşen sınıfları ve fizik. Saf CSS — Tailwind direktifi yok,
|
|
5
|
-
Tailwind'i olmayan bir projede de çalışır.
|
|
6
|
-
|
|
7
|
-
Token'lar theme.css'te. Bu dosya yalnız onları tüketir.
|
|
8
|
-
============================================================== */
|
|
9
|
-
|
|
10
|
-
/* ==============================================================
|
|
11
|
-
THE KIT.
|
|
12
|
-
|
|
13
|
-
This was an isolated island (`.taslak`) while it was a reference. It is not a reference any more
|
|
14
|
-
— it is the product's kit, so the scoping came off: `tamga-*` is global, the tokens sit in the same
|
|
15
|
-
@theme as everything else, and the base layer styles the document rather than a wrapper div.
|
|
16
|
-
|
|
17
|
-
What that replaced: a second, shadcn-derived kit under components/ui with twelve components
|
|
18
|
-
duplicated by name. Two kits meant two answers to "what does a button look like", and Storybook
|
|
19
|
-
showed both. One kit now.
|
|
20
|
-
============================================================== */
|
|
21
|
-
|
|
22
|
-
/* ------------------------------------------------------------------ *
|
|
23
|
-
* Measurements that are NOT on the spacing scale, and why.
|
|
24
|
-
*
|
|
25
|
-
* check-scale forbids invented bracket values and prescribes exactly this escape: name the value
|
|
26
|
-
* next to the tokens with the reason, then use the `var()` form at the call site. Each of these is
|
|
27
|
-
* a mechanic, not a spacing choice — rounding it to a 4px step would break the thing it measures.
|
|
28
|
-
* ------------------------------------------------------------------ */
|
|
29
|
-
/* tamga:sabit-kit — kitin kendi yapısal ölçüleri; temaya bağlı değil. */
|
|
1
|
+
/*! tamga-ui 0.3.0 · MIT · https://tamga.org.tr */
|
|
30
2
|
:root {
|
|
31
|
-
|
|
32
|
-
with room to read as detached rather than stuck.
|
|
33
|
-
TR: Bir katmanın tetikleyicisinin üstünde durduğu boşluk. 8px, yani 2px'lik kaydırma
|
|
34
|
-
gölgesi kenarı yapışık değil ayrık okunacak kadar rahat geçiyor. */
|
|
3
|
+
|
|
35
4
|
--overlay-gap: 8px;
|
|
36
|
-
|
|
37
|
-
token that still needs arithmetic at the call site is half a token.
|
|
38
|
-
TR: Yalnız boşluk değil hesaplanmış kaydırmanın tamamı: check-scale bir token
|
|
39
|
-
referansını kabul ediyor, ve çağrı yerinde hâlâ aritmetik isteyen bir token yarım
|
|
40
|
-
token. */
|
|
5
|
+
|
|
41
6
|
--overlay-below: calc(100% + var(--overlay-gap));
|
|
42
7
|
--overlay-above: calc(100% + var(--overlay-gap));
|
|
43
|
-
|
|
44
|
-
a spacing step.
|
|
45
|
-
TR: Kadranın bant etiketi halkanın taban çizgisinin hemen altında duruyor. Negatif
|
|
46
|
-
ve çok küçük: bir boşluk adımı değil bir konum. */
|
|
8
|
+
|
|
47
9
|
--dial-label-drop: -4px;
|
|
48
|
-
|
|
49
|
-
overflow. 3px, one more than the offset, which is the clipping trap in §2.
|
|
50
|
-
TR: Yükseltilmiş bir nesnenin, 2px'lik kaydırması üst öğenin taşmasıyla kırpılmasın
|
|
51
|
-
diye YANINDA ihtiyaç duyduğu yer. 3px, kaydırmadan bir fazla; §2'deki kırpılma
|
|
52
|
-
tuzağı tam olarak bu. */
|
|
10
|
+
|
|
53
11
|
--offset-room: 3px;
|
|
54
|
-
|
|
55
|
-
read as marks, not as boxes, and 4px is already too heavy for a dial tick.
|
|
56
|
-
TR: Gösterge işaretleri: 2px'lik bir çentik ve 6px'lik bir nokta. Boşluk ölçeğinin
|
|
57
|
-
altında, bilerek: bunlar kutu değil işaret olarak okunuyor, ve 4px bir kadran
|
|
58
|
-
çentiği için şimdiden ağır. */
|
|
12
|
+
|
|
59
13
|
--mark-tick: 2px;
|
|
60
14
|
--mark-dot: 6px;
|
|
61
15
|
|
|
62
|
-
/* Adım işaretinin karesi ve iki adımı bağlayan çizginin uzunluğu. Bir ölçek
|
|
63
|
-
adımı değil: işaret, iki haneli bir sayı ile bir çentik glifinin İKİSİNİ
|
|
64
|
-
birden tutması gereken en küçük kare. Sabit olması şart, çünkü adım
|
|
65
|
-
tamamlandığında büyüyen bir işaret şeridin tamamını kaydırıyor.
|
|
66
|
-
TR: Adım işaretinin karesi ve iki adımı bağlayan çizginin uzunluğu. Bir
|
|
67
|
-
ölçek adımı değil: iki haneli bir sayıyı da çentik glifini de tutabilen en
|
|
68
|
-
küçük kare. Sabit olmak zorunda, yoksa tamamlanan adım şeridi kaydırıyor. */
|
|
69
16
|
--step-mark: 24px;
|
|
70
17
|
--step-line: 28px;
|
|
71
|
-
|
|
72
|
-
reads as a control; these are neither.
|
|
73
|
-
TR: Sistemdeki en küçük yarıçap: onay kutusunun çentiği ve iskelet bloğu.
|
|
74
|
-
--radius-ctl (4px) bir kontrol gibi okunuyor; bunların ikisi de kontrol değil. */
|
|
18
|
+
|
|
75
19
|
--radius-mark: 3px;
|
|
76
|
-
|
|
77
|
-
should be able to take the whole screen and still not grow without end,
|
|
78
|
-
because at 2000px a list stops being readable. 3rem is the shell's own
|
|
79
|
-
margin.
|
|
80
|
-
TR: Geniş diyaloğun tavanı. Bir ölçek adımı değil bir SINIR: bir önizleme ekranın
|
|
81
|
-
tamamını alabilmeli ama sonsuz da genişlememeli, çünkü 2000 pikselde bir liste artık
|
|
82
|
-
okunmuyor. 3rem, kabuğun kendi kenar boşluğu. */
|
|
20
|
+
|
|
83
21
|
--dialog-wide: min(96rem, calc(100vw - 3rem));
|
|
84
22
|
|
|
85
|
-
/* Where a dense table stops shrinking and starts scrolling. Content-driven, not a scale step:
|
|
86
|
-
it is the width at which the narrowest column stops being readable.
|
|
87
|
-
TR: Sık bir tablonun küçülmeyi bırakıp kaydırmaya başladığı yer. Bir ölçek adımı
|
|
88
|
-
değil içerikten gelen bir sayı: en dar sütunun okunmaz olduğu genişlik. */
|
|
89
23
|
--table-min: 720px;
|
|
90
24
|
--table-min-wide: 980px;
|
|
91
25
|
--table-min-widest: 1080px;
|
|
92
26
|
}
|
|
93
27
|
|
|
94
|
-
/* tamga:kit-koyu */
|
|
95
28
|
.dark {
|
|
96
29
|
|
|
97
30
|
color-scheme: dark;
|
|
98
31
|
|
|
99
|
-
/* The neutral ramp is tinted toward the accent hue, specified in LCh — never
|
|
100
|
-
in HSL, and never by copying another product's numbers. Two earlier attempts
|
|
101
|
-
failed and both failures are the reason this comment is long.
|
|
102
|
-
|
|
103
|
-
1st: matched Sentry's HSL saturation (14%). HSL S is not perceptual chroma —
|
|
104
|
-
at identical S and L, violet at 258° carries ~1.4x the real chroma of blue.
|
|
105
|
-
Matching their number guaranteed a weaker tint. The ramp read grey.
|
|
106
|
-
|
|
107
|
-
2nd: rebuilt in LCh at hue 277° with raised chroma. Still grey, for a worse
|
|
108
|
-
reason: 277° is the middle of the Tailwind slate band (271–283°), and the
|
|
109
|
-
chroma sat under slate's own (slate-900 is C* 14.45). A colour inside that
|
|
110
|
-
hue band and below that chroma IS the industry-default dark grey. Raising
|
|
111
|
-
chroma alone had only made it a more saturated slate.
|
|
112
|
-
|
|
113
|
-
What actually makes a tint read as a tint is hue distance from the neutral
|
|
114
|
-
band, not chroma. Sentry gets away with LOW chroma (5.5–12.7) because its
|
|
115
|
-
hue sits at 299–304° — about 20° clear of slate, where nothing generic
|
|
116
|
-
lives. Our blue does not have that luxury: blue IS the neutral band.
|
|
117
|
-
|
|
118
|
-
So: hue 291°, the true LCh hue of our own primary #12245c, which clears
|
|
119
|
-
slate's edge — and chroma pushed past slate's 14.45 to cover the fact that
|
|
120
|
-
we clear it by 8° where Sentry clears it by 20°. Exceeding Sentry's chroma
|
|
121
|
-
is not an inconsistency; it is what equal perception costs on a blue axis.
|
|
122
|
-
L* is pinned exactly where it already sat, so the ramp gains colour without
|
|
123
|
-
moving a single contrast value.
|
|
124
|
-
L* 5.9 -> C* 16 L* 19.9 -> C* 26 L* 85.1 -> C* 6.0
|
|
125
|
-
L* 9.3 -> C* 19 L* 27.9 -> C* 31 L* 94.4 -> C* 2.8
|
|
126
|
-
L* 14.2 -> C* 22 L* 61.9 -> C* 11
|
|
127
|
-
Light stays warm paper on purpose: paper by day, instrument screen by night,
|
|
128
|
-
and a cool ground makes the warm status colours separate harder. */
|
|
129
32
|
--color-page: #0f1127;
|
|
130
|
-
|
|
131
|
-
page on purpose; the edge does the lifting. */
|
|
33
|
+
|
|
132
34
|
--color-shell: #131832;
|
|
133
|
-
|
|
134
|
-
sunk, different job. */
|
|
35
|
+
|
|
135
36
|
--color-hover: #1c2241;
|
|
136
|
-
|
|
137
|
-
never a fill. Dark briefly had them 1.9 ΔL* off the page: too small to read
|
|
138
|
-
as a surface, too large to be the same one. */
|
|
37
|
+
|
|
139
38
|
--color-band: #0f1127;
|
|
140
|
-
|
|
141
|
-
second surface competing with the content. */
|
|
39
|
+
|
|
142
40
|
--color-rail: #0f1127;
|
|
143
|
-
|
|
144
|
-
headers, code blocks, sub-panels. */
|
|
41
|
+
|
|
145
42
|
--color-sunk: #1c2241;
|
|
146
43
|
--color-line: #262d54;
|
|
147
44
|
--color-edge: #363e6e;
|
|
148
45
|
--color-chart-fill: #1c2241;
|
|
149
46
|
--color-ink-faint: #9494a8;
|
|
150
|
-
|
|
151
|
-
heading without competing with it. */
|
|
47
|
+
|
|
152
48
|
--color-ink-soft: #d4d4df;
|
|
153
|
-
|
|
154
|
-
on first. */
|
|
49
|
+
|
|
155
50
|
--color-ink: #efeef4;
|
|
156
51
|
|
|
157
|
-
/* Dark inverts the face, and it has to. The rule across both themes is that
|
|
158
|
-
the FACE is the layer furthest from the ground and the BASE is the brand
|
|
159
|
-
navy. Light's ground is paper, so the face goes mid-dark and carries white
|
|
160
|
-
ink. Dark's ground is near-black, and there white ink is what kills the
|
|
161
|
-
press: it caps the fill at L* 47, while the base has to reach L* 26 just to
|
|
162
|
-
separate from the page — leaving at most 21 ΔL* between the two layers,
|
|
163
|
-
less than light already has. Dark ink lifts that ceiling, the face goes to
|
|
164
|
-
L* 66, and the layers separate by 50. Hue sits at 272° rather than light's
|
|
165
|
-
284° to stay plainly blue at high lightness, where 284° starts to read
|
|
166
|
-
periwinkle. */
|
|
167
52
|
--color-accent: #53a4fa;
|
|
168
|
-
--color-accent-hover: #78b4ff;
|
|
53
|
+
--color-accent-hover: #78b4ff;
|
|
169
54
|
--color-accent-active: #4097eb;
|
|
170
|
-
--color-accent-ink: #12245c;
|
|
55
|
+
--color-accent-ink: #12245c;
|
|
171
56
|
--color-accent-line: #86a7f3;
|
|
172
|
-
|
|
173
|
-
fell UNDER hover's C* 22, so a selected row read duller than a hovered one. */
|
|
57
|
+
|
|
174
58
|
--color-accent-bg: #0f2458;
|
|
175
|
-
|
|
176
|
-
two things at once — the face above it and the ground behind it — and light
|
|
177
|
-
manages both without help (79 ΔL* off the paper, 29 off the face). Dropped
|
|
178
|
-
into dark unchanged, #12245c clears the face by 50 but the page by only 10,
|
|
179
|
-
so it sinks into the page and the button loses its base entirely. Being
|
|
180
|
-
bright next to the face is not enough; it also has to be visibly NOT the
|
|
181
|
-
page. L* 30 buys 24 off the page and still leaves 36 off the face. */
|
|
59
|
+
|
|
182
60
|
--color-accent-shadow: #344479;
|
|
183
61
|
|
|
184
|
-
/* Status stays warm against the cool ground — deviation separates harder. */
|
|
185
62
|
--color-critical: #ff9478;
|
|
186
|
-
|
|
187
|
-
text of its own. */
|
|
63
|
+
|
|
188
64
|
--color-critical-bg: #331a12;
|
|
189
|
-
|
|
190
|
-
stock running low. */
|
|
65
|
+
|
|
191
66
|
--color-warn: #e8ab3c;
|
|
192
|
-
|
|
67
|
+
|
|
193
68
|
--color-warn-bg: #33260f;
|
|
194
|
-
|
|
195
|
-
not have to learn two. */
|
|
69
|
+
|
|
196
70
|
--color-resolved: #4fd4ac;
|
|
197
|
-
|
|
71
|
+
|
|
198
72
|
--color-resolved-bg: #0f2a22;
|
|
199
73
|
--color-silent: #9494a8;
|
|
200
74
|
--color-tick: #3f4880;
|
|
201
75
|
--color-chart-1: #ada072;
|
|
202
|
-
|
|
203
|
-
never mistaken for a status. */
|
|
76
|
+
|
|
204
77
|
--color-chart-2: #5badaf;
|
|
205
|
-
|
|
78
|
+
|
|
206
79
|
--color-chart-3: #6ea7cc;
|
|
207
|
-
|
|
80
|
+
|
|
208
81
|
--color-chart-4: #a49ac9;
|
|
209
|
-
|
|
210
|
-
and a legend stops helping. */
|
|
82
|
+
|
|
211
83
|
--color-chart-5: #ca90a9;
|
|
212
84
|
|
|
213
|
-
/* Same LCh treatment — these echo ramp steps and must not drift off the axis. */
|
|
214
85
|
--color-nav-idle: #89899d;
|
|
215
|
-
|
|
216
|
-
dark: the label steps toward the reader. */
|
|
86
|
+
|
|
217
87
|
--color-nav-hover: #d4d4df;
|
|
218
|
-
|
|
219
|
-
instead, never this fill. */
|
|
88
|
+
|
|
220
89
|
--color-nav-hover-bg: #1c2241;
|
|
221
90
|
--color-scrim: rgba(6, 6, 22, 0.62);
|
|
222
91
|
}
|
|
@@ -225,14 +94,7 @@
|
|
|
225
94
|
|
|
226
95
|
body {
|
|
227
96
|
background: var(--color-shell);
|
|
228
|
-
|
|
229
|
-
Kit `--text-body: 13px`i "THE default: rows, cells, body copy" diye
|
|
230
|
-
tanımlıyordu ama hiçbir yer onu BODY'ye uygulamıyordu. Sonuç: sınıfı
|
|
231
|
-
olan her metin ölçekte, sınıfı olmayan her metin tarayıcının 16px'inde,
|
|
232
|
-
yani aynı ekranda iki ayrı ölçek. Doküman sitesinde görünmedi çünkü o
|
|
233
|
-
kendi okuma ölçeğini yazıyor; bir tüketici panelinde tablo hücreleri %23
|
|
234
|
-
büyük çıktı ve fark oradan yakalandı.
|
|
235
|
-
Tüketici kendi ölçeğini isterse yine yazabilir; bu bir varsayılan. */
|
|
97
|
+
|
|
236
98
|
font-size: var(--text-body);
|
|
237
99
|
line-height: 1.5;
|
|
238
100
|
font-variant-numeric: tabular-nums;
|
|
@@ -256,7 +118,7 @@
|
|
|
256
118
|
*::-webkit-scrollbar-track {
|
|
257
119
|
background: transparent;
|
|
258
120
|
}
|
|
259
|
-
|
|
121
|
+
|
|
260
122
|
input[type="checkbox"] {
|
|
261
123
|
appearance: none;
|
|
262
124
|
-webkit-appearance: none;
|
|
@@ -307,27 +169,15 @@
|
|
|
307
169
|
|
|
308
170
|
@layer components {
|
|
309
171
|
|
|
310
|
-
/* ---------- structure ---------- */
|
|
311
|
-
|
|
312
|
-
/* the one left line every page shares */
|
|
313
172
|
.tamga-gutter {
|
|
314
173
|
padding-left: var(--gutter);
|
|
315
174
|
padding-right: var(--gutter);
|
|
316
175
|
}
|
|
317
176
|
|
|
318
|
-
/* a full-bleed rule, still used for page bands and inside cards */
|
|
319
177
|
.tamga-section {
|
|
320
178
|
border-bottom: 1px solid var(--color-line);
|
|
321
179
|
}
|
|
322
180
|
|
|
323
|
-
/* a card is a button that grew: same 1px edge, same soft 2px offset */
|
|
324
|
-
/* The working surface: one card that holds a whole screen.
|
|
325
|
-
The chrome around it — rail, header, ground — is all --color-page and has
|
|
326
|
-
no dividing line, so it reads as one continuous frame. This is the only
|
|
327
|
-
thing on top of that frame, which is why it takes the control radius
|
|
328
|
-
rather than the card radius: at this size the sharper corner keeps it
|
|
329
|
-
reading as a plane, and it stays in the same family as the buttons inside
|
|
330
|
-
it. A softer corner here would make the whole screen look like a widget. */
|
|
331
181
|
.tamga-surface {
|
|
332
182
|
background: var(--color-page);
|
|
333
183
|
border: 1px solid var(--color-edge);
|
|
@@ -341,26 +191,15 @@
|
|
|
341
191
|
box-shadow: 2px 2px 0 var(--color-edge);
|
|
342
192
|
overflow: hidden;
|
|
343
193
|
}
|
|
344
|
-
/* Kırpmayı kapatan kaçış yolu.
|
|
345
|
-
|
|
346
|
-
`.tamga-card`'ın `overflow: hidden`'ı tabloların köşe yuvarlaması için
|
|
347
|
-
gerekli — ve aynı satır, kartın İÇİNDE açılan her paneli kesiyor:
|
|
348
|
-
bir Combobox listesi, bir DatePicker takvimi, bir satır menüsü. Panel
|
|
349
|
-
çalışıyor, tıklanıyor, ama yarısı görünmüyor. Z-index bunu çözmez;
|
|
350
|
-
hiçbir yığın sırası bir `overflow` kırpmasını aşamaz.
|
|
351
194
|
|
|
352
|
-
`CellActions` aynı tuzağın tablo hücresi karşılığıydı ve ayrı çözülmüştü;
|
|
353
|
-
bu, kart seviyesindeki hâli. */
|
|
354
195
|
.tamga-card-open {
|
|
355
196
|
overflow: visible;
|
|
356
197
|
}
|
|
357
198
|
|
|
358
|
-
/* a second column, opened by one full-height rule */
|
|
359
199
|
.tamga-col {
|
|
360
200
|
border-left: 1px solid var(--color-line);
|
|
361
201
|
}
|
|
362
202
|
|
|
363
|
-
/* section heading sits on the gutter with no box of its own */
|
|
364
203
|
.tamga-head {
|
|
365
204
|
display: flex;
|
|
366
205
|
flex-wrap: wrap;
|
|
@@ -371,32 +210,12 @@
|
|
|
371
210
|
padding-bottom: 8px;
|
|
372
211
|
}
|
|
373
212
|
|
|
374
|
-
/* rail item: outlined and lifted when active — never a solid fill */
|
|
375
|
-
/*
|
|
376
|
-
* KAYAN BİR RAY, YÜKSELEN BİR KONTROLÜ KIRPAR.
|
|
377
|
-
*
|
|
378
|
-
* Ölçülen hata: menüsü uzun olan bir kenar çubuğunda `overflow-y: auto`
|
|
379
|
-
* gerekiyor, ama CSS bir eksende `visible` dışında bir değer görünce ÖTEKİ
|
|
380
|
-
* ekseni de `auto`ya çeviriyor. Yani dikey kaydırma isteyen bir kap yatayda
|
|
381
|
-
* da kırpıyor, ve seçili ray girişinin 2px sert kaydırması tam kenarda
|
|
382
|
-
* kesiliyor: düğme sağdan ve alttan eksik görünüyor. Hover'da kaydırma 3px'e
|
|
383
|
-
* çıkıyor, basılınca yer değiştiriyor — üçü de kırpılıyor.
|
|
384
|
-
*
|
|
385
|
-
* Çözüm z-index DEĞİL: hiçbir yığın sırası bir `overflow` kırpmasını aşmaz.
|
|
386
|
-
* Kaydırmanın sığacağı yer AÇILIYOR (`--offset-room`, kaydırmadan bir fazla).
|
|
387
|
-
*/
|
|
388
213
|
.tamga-rail-scroll {
|
|
389
214
|
min-height: 0;
|
|
390
215
|
overflow-y: auto;
|
|
391
|
-
|
|
392
|
-
İlk hâli kaydırma gölgesini (sağ+alt) düşünüp hover'ı unutmuştu: seçili
|
|
393
|
-
giriş hover'da `translate(-1px, -1px)` ile YUKARI ve SOLA kayıyor, ve
|
|
394
|
-
sol kenarda yer olmadığı için oradan kesiliyordu. Simetrik dolgu ayrıca
|
|
395
|
-
ikinci bir şeyi düzeltiyor: dar rayda `items-center` artık gerçekten
|
|
396
|
-
ortalıyor — tek yönlü dolgu ikonları 1.5 piksel sola çekiyordu. */
|
|
216
|
+
|
|
397
217
|
padding: var(--offset-room);
|
|
398
|
-
|
|
399
|
-
daraltıyor. Kaydırma yine çalışıyor. */
|
|
218
|
+
|
|
400
219
|
scrollbar-width: none;
|
|
401
220
|
}
|
|
402
221
|
.tamga-rail-scroll::-webkit-scrollbar {
|
|
@@ -417,10 +236,7 @@
|
|
|
417
236
|
transition: color var(--duration-press) var(--ease-standard), background var(--duration-press) var(--ease-standard), border-color var(--duration-press) var(--ease-standard),
|
|
418
237
|
box-shadow var(--duration-press) var(--ease-standard), transform var(--duration-press) var(--ease-standard);
|
|
419
238
|
}
|
|
420
|
-
|
|
421
|
-
dar ray yalnız ikon taşır, geniş kenar çubuğu ikonun yanına etiketi açar.
|
|
422
|
-
İkiye bölünseydi hover, seçili ve odak fizikleri iki yerde yaşardı ve
|
|
423
|
-
zamanla ayrışırdı. */
|
|
239
|
+
|
|
424
240
|
.tamga-rail-link-wide {
|
|
425
241
|
width: 100%;
|
|
426
242
|
justify-content: flex-start;
|
|
@@ -448,20 +264,6 @@
|
|
|
448
264
|
box-shadow: 0 0 0 var(--color-accent-line);
|
|
449
265
|
}
|
|
450
266
|
|
|
451
|
-
/* ------------------------------------------------------------------ *
|
|
452
|
-
* Press snaps, release eases.
|
|
453
|
-
*
|
|
454
|
-
* Both directions used the same 100ms ease, and on a trackpad TAP that meant the press was never
|
|
455
|
-
* seen: `:active` lasts about 10–40ms on a tap, so the control got a third of the way down and
|
|
456
|
-
* turned round. Holding a physical click gives it the full 100ms, which is why the same button
|
|
457
|
-
* felt right under a click and dead under a tap.
|
|
458
|
-
*
|
|
459
|
-
* So the press is instant and only the RETURN is animated. Even a 15ms tap now bottoms the
|
|
460
|
-
* control out completely, and the 100ms float back is the part the eye actually reads as a
|
|
461
|
-
* click — perception needs the movement, not the dwell.
|
|
462
|
-
*
|
|
463
|
-
* Only the duration changes. Travel, shadow and colour are untouched.
|
|
464
|
-
* ------------------------------------------------------------------ */
|
|
465
267
|
.tamga-btn:not(:disabled):active,
|
|
466
268
|
.tamga-icon-btn:not(:disabled):active,
|
|
467
269
|
.tamga-mini-btn:not(:disabled):active,
|
|
@@ -471,24 +273,6 @@
|
|
|
471
273
|
transition-duration: 0s;
|
|
472
274
|
}
|
|
473
275
|
|
|
474
|
-
/* ------------------------------------------------------------------ *
|
|
475
|
-
* The press-travel hit fix.
|
|
476
|
-
*
|
|
477
|
-
* A raised control moves down-right when pressed — hover sits at −1,−1 and active at +2,+2 (the
|
|
478
|
-
* primary goes to +3,+3), so the box travels 3–4px out from under the pointer. A transform moves
|
|
479
|
-
* the HIT AREA with it, so a pointer resting within that band along the top or left edge ends up
|
|
480
|
-
* over the parent by the time the button comes up. `mousedown` lands on the button, `mouseup`
|
|
481
|
-
* lands on its container, and a `click` event is never born — the control simply does nothing.
|
|
482
|
-
*
|
|
483
|
-
* It shows up on a trackpad TAP far more than on a physical click: a tap has no dwell time and
|
|
484
|
-
* the finger drifts a pixel or two, while a real click holds the pointer still while the box
|
|
485
|
-
* moves. Same defect, different odds — which is exactly why it read as "tap is broken".
|
|
486
|
-
*
|
|
487
|
-
* The fix is a hit extender that reaches back up and left by the travel distance. It rides along
|
|
488
|
-
* with the transform, so once the control has moved it covers precisely the ground the control
|
|
489
|
-
* left behind. It only ever grows up and left, never down or right, so it cannot reach into the
|
|
490
|
-
* next control in a row or a column.
|
|
491
|
-
* ------------------------------------------------------------------ */
|
|
492
276
|
.tamga-btn,
|
|
493
277
|
.tamga-icon-btn,
|
|
494
278
|
.tamga-mini-btn,
|
|
@@ -501,15 +285,11 @@
|
|
|
501
285
|
.tamga-rail-link::after {
|
|
502
286
|
content: "";
|
|
503
287
|
position: absolute;
|
|
504
|
-
|
|
288
|
+
|
|
505
289
|
inset: -4px 0 0 -4px;
|
|
506
290
|
border-radius: inherit;
|
|
507
291
|
}
|
|
508
292
|
|
|
509
|
-
/* ---------- raised objects ---------- */
|
|
510
|
-
/* buttons and the few genuinely detached cards share one soft edge:
|
|
511
|
-
a 1px rule plus the same rule offset by 2px. No hard black. */
|
|
512
|
-
|
|
513
293
|
.tamga-raised {
|
|
514
294
|
border-radius: var(--radius-card);
|
|
515
295
|
border: 1px solid var(--color-edge);
|
|
@@ -517,28 +297,6 @@
|
|
|
517
297
|
box-shadow: 2px 2px 0 var(--color-edge);
|
|
518
298
|
}
|
|
519
299
|
|
|
520
|
-
/* ------------------------------------------------------------------ *
|
|
521
|
-
* TWO PHYSICS, ONE GRAMMAR.
|
|
522
|
-
*
|
|
523
|
-
* RAISED — sits on top of the page, and pressing puts it back down.
|
|
524
|
-
* 1px edge + N px hard offset; press travels the offset and collapses it.
|
|
525
|
-
* Buttons, cards, rail items, segments, the primary action.
|
|
526
|
-
*
|
|
527
|
-
* SEATED — is part of its surface and never lifts at all. It answers by
|
|
528
|
-
* FILLING or by drawing a rule, not by travelling.
|
|
529
|
-
* Tabs (underline), switches (filled track), checkboxes and radios
|
|
530
|
-
* (filled box), chips (edge only — and chips are not even interactive).
|
|
531
|
-
*
|
|
532
|
-
* The split is not decoration. A tab is not an object lying on the page,
|
|
533
|
-
* it is part of the bar; pushing it "down" would be a lie about what it is.
|
|
534
|
-
* v5 inherits the same two-physics idea under the names .press-surface and
|
|
535
|
-
* .seated-surface — the grammar matches even though the surfaces differ.
|
|
536
|
-
*
|
|
537
|
-
* The rule that follows from it: DEPTH MEANS PRESSABLE. Anything that
|
|
538
|
-
* cannot be pressed does not get an offset, which is exactly why the chip
|
|
539
|
-
* lost the one it briefly had.
|
|
540
|
-
* ------------------------------------------------------------------ */
|
|
541
|
-
|
|
542
300
|
.tamga-btn {
|
|
543
301
|
border-radius: var(--radius-ctl);
|
|
544
302
|
display: inline-flex;
|
|
@@ -558,7 +316,7 @@
|
|
|
558
316
|
cursor: pointer;
|
|
559
317
|
white-space: nowrap;
|
|
560
318
|
}
|
|
561
|
-
|
|
319
|
+
|
|
562
320
|
.tamga-btn:not(:disabled):hover {
|
|
563
321
|
background: var(--color-hover);
|
|
564
322
|
transform: translate(-1px, -1px);
|
|
@@ -568,15 +326,7 @@
|
|
|
568
326
|
transform: translate(2px, 2px);
|
|
569
327
|
box-shadow: 0 0 0 var(--color-edge);
|
|
570
328
|
}
|
|
571
|
-
|
|
572
|
-
yok" diyor; oysa kaydet düğmesi değişiklik olmadığı için kapalı, ve
|
|
573
|
-
kullanıcı bir şey yanlış yapmış değil. İmleç bir suçlama taşımamalı. */
|
|
574
|
-
/* SÜRERKEN YÜKSELMİYOR AMA SOLMUYOR DA. `disabled` görünümü "bu düğme
|
|
575
|
-
kapalı" der; oysa çalışan bir düğme kapalı değil MEŞGUL, ve soldurmak
|
|
576
|
-
kullanıcıya işin durduğunu düşündürüyor. Spinner zaten durumu söylüyor. */
|
|
577
|
-
/* `:disabled` de eşleşiyor (kilit onunla kuruluyor) ve aynı özgüllükte,
|
|
578
|
-
sonra geldiği için kazanıyordu: meşgul bir düğme "atıl" imleci
|
|
579
|
-
gösteriyordu. İkisi birden yazılıyor, böylece sıra değil anlam kazanıyor. */
|
|
329
|
+
|
|
580
330
|
.tamga-btn[data-busy]:disabled {
|
|
581
331
|
opacity: 1;
|
|
582
332
|
cursor: progress;
|
|
@@ -593,9 +343,6 @@
|
|
|
593
343
|
cursor: default;
|
|
594
344
|
}
|
|
595
345
|
|
|
596
|
-
/* The edge is the BASE colour, not the pressed colour. A keycap and the base
|
|
597
|
-
it sits on are one object seen from two sides, so they share an outline —
|
|
598
|
-
that is what stops a bright face from floating free of its own shadow. */
|
|
599
346
|
.tamga-btn-primary {
|
|
600
347
|
background: var(--color-accent);
|
|
601
348
|
border-color: var(--color-accent-shadow);
|
|
@@ -613,14 +360,6 @@
|
|
|
613
360
|
box-shadow: 0 0 0 var(--color-accent-shadow);
|
|
614
361
|
}
|
|
615
362
|
|
|
616
|
-
/* Success and danger are the same object in two colours: outlined, never
|
|
617
|
-
filled. The fill belongs to the one primary action on a page — publishing a
|
|
618
|
-
draft and deleting a record are both important, but neither is THE
|
|
619
|
-
action, and filling them would put two shouting buttons in one view.
|
|
620
|
-
This rule was missing entirely for a while: the class was used in five
|
|
621
|
-
places and defined in none, so every "success" button silently rendered as
|
|
622
|
-
a plain neutral one. Green belongs to resolved, which is exactly what this
|
|
623
|
-
button does — it is the one place the resolved colour touches a control. */
|
|
624
363
|
.tamga-btn-success {
|
|
625
364
|
background: var(--color-shell);
|
|
626
365
|
border-color: var(--color-resolved);
|
|
@@ -649,12 +388,6 @@
|
|
|
649
388
|
box-shadow: 0 0 0 var(--color-critical);
|
|
650
389
|
}
|
|
651
390
|
|
|
652
|
-
/* The one member of the family that is not an object on the page: no edge,
|
|
653
|
-
no offset, and therefore no lift. Cancel and dismiss have to stay out of
|
|
654
|
-
the way, and anything raised competes with the action beside it.
|
|
655
|
-
This rule was missing entirely — the class was used and never written, so
|
|
656
|
-
every ghost button silently rendered as a full secondary button, edge and
|
|
657
|
-
offset included. The same hole .tamga-btn-success had. */
|
|
658
391
|
.tamga-btn-ghost {
|
|
659
392
|
background: transparent;
|
|
660
393
|
border-color: transparent;
|
|
@@ -674,12 +407,6 @@
|
|
|
674
407
|
transform: none;
|
|
675
408
|
}
|
|
676
409
|
|
|
677
|
-
/* A button that reads as a link. Same element, same keyboard behaviour, no
|
|
678
|
-
surface at all — for the rare navigation that sits in a row of buttons and
|
|
679
|
-
must not compete with them.
|
|
680
|
-
It is a BUTTON, not an <a>: use this when the click runs code. If it
|
|
681
|
-
navigates, use a real anchor with .tamga-link, because a link that is not an
|
|
682
|
-
anchor cannot be opened in a new tab and is a lie to a screen reader. */
|
|
683
410
|
.tamga-btn-link {
|
|
684
411
|
height: auto;
|
|
685
412
|
padding: 0;
|
|
@@ -732,33 +459,8 @@
|
|
|
732
459
|
box-shadow: 0 0 0 var(--color-edge);
|
|
733
460
|
}
|
|
734
461
|
|
|
735
|
-
/* Sayı girdisinin artır/azalt okları.
|
|
736
|
-
|
|
737
|
-
`mini-btn` KULLANILAMAZ ve ilk sürüm onu kullanıyordu: o 32×32 bir
|
|
738
|
-
kontrol, ikisi üst üste 65px eder, girdi ise 40px. Oklar kutunun dışına
|
|
739
|
-
taşıyordu — çalışıyorlardı ama alanın içinde durmuyorlardı.
|
|
740
|
-
|
|
741
|
-
Bir spinner ayrı bir şekildir: alanın SAĞ KENARINA yapışır, yüksekliğini
|
|
742
|
-
ondan alır ve kendi kutusu yoktur — girdiden tek bir dikey kuralla
|
|
743
|
-
ayrılır. Yükselmez; bu boyutta bir offset kenardan taşar (mini butonun
|
|
744
|
-
yükselmemesiyle aynı gerekçe, Yasa 1'in boyut istisnası). */
|
|
745
|
-
/* Sayfalayıcının sayfa düğmesi.
|
|
746
|
-
|
|
747
|
-
`.tamga-option` KULLANILAMAZ ve ilk sürüm onu kullanıyordu — üstelik
|
|
748
|
-
kodun yanındaki yorumda "seçili sayfa dolgu almaz" yazarken. Yorum
|
|
749
|
-
doğruydu, sınıf yalanlıyordu: `.tamga-option[data-selected]` bir DOLGU ve
|
|
750
|
-
sola oturan bir iç iz veriyor. Sonuç ekranda üç ayrı yanlış oldu — dolu
|
|
751
|
-
bir blok, sayının solunda başıboş duran dikey bir çizgi, ve `width: 100%`
|
|
752
|
-
olduğu için esneyen bir kutu.
|
|
753
|
-
|
|
754
|
-
Sayfa düğmesi rail'in dilini konuşur: seçili olan YÜKSELMEZ, oturur —
|
|
755
|
-
kabuk zemini, aksan kenarı, 2px sert offset. Yasa 2: "buradasın" bir
|
|
756
|
-
eylem değildir. */
|
|
757
462
|
.tamga-page {
|
|
758
|
-
|
|
759
|
-
`mini-btn`, `tab`, `segment`, `option`, `switch`); sayfalayıcı tek
|
|
760
|
-
istisnaydı ve bu bir gözden kaçmaydı. Tailwind v4 önyüklemesi artık
|
|
761
|
-
`button`a imleç vermiyor, yani eksiklik doğrudan görünüyor. */
|
|
463
|
+
|
|
762
464
|
cursor: pointer;
|
|
763
465
|
display: inline-flex;
|
|
764
466
|
height: 40px;
|
|
@@ -863,24 +565,12 @@
|
|
|
863
565
|
border: 1px solid var(--color-edge);
|
|
864
566
|
background: var(--color-shell);
|
|
865
567
|
color: var(--color-ink);
|
|
866
|
-
|
|
867
|
-
name, title, email — opened with an empty inset that read as a rendering fault. A field
|
|
868
|
-
reserves space for a thing it has only when it has it. */
|
|
568
|
+
|
|
869
569
|
padding: 0 16px;
|
|
870
570
|
font-size: var(--text-body);
|
|
871
571
|
outline: none;
|
|
872
572
|
}
|
|
873
|
-
/* Çok satırlı hâli.
|
|
874
|
-
|
|
875
|
-
`.tamga-input` `padding: 0 16px` taşıyor ve tek satır için bu DOĞRU: sabit
|
|
876
|
-
`height` metni zaten dikeyde ortalıyor, dikey padding eklemek onu bozardı.
|
|
877
573
|
|
|
878
|
-
Ama bir `<textarea>` aynı sınıfı alıp yüksekliğini `rows`'tan aldığında o
|
|
879
|
-
sıfır padding görünür bir hataya dönüşüyor: ilk satır üst kenara YAPIŞIYOR.
|
|
880
|
-
Aynı sınıfın iki farklı yükseklik modelinde farklı davranması gerekiyor, ve
|
|
881
|
-
ayrım elemanın kendisinde — o yüzden seçici `textarea`, bir modifier değil.
|
|
882
|
-
Çağıranın hatırlaması gereken bir sınıf olsaydı, unutulduğu her yerde metin
|
|
883
|
-
kenara yapışırdı. */
|
|
884
574
|
textarea.tamga-input {
|
|
885
575
|
height: auto;
|
|
886
576
|
padding-top: 10px;
|
|
@@ -893,41 +583,16 @@
|
|
|
893
583
|
padding-left: 40px;
|
|
894
584
|
}
|
|
895
585
|
|
|
896
|
-
/* Yoğun bir yerdeki alan: bir tablo başlığındaki filtre satırı, bir araç
|
|
897
|
-
çubuğu, bir satır içi düzeltme.
|
|
898
|
-
|
|
899
|
-
NEDEN AYRI BİR ÖLÇÜ DEĞİL. 32px `.tamga-btn-sm` ile AYNI basamak, ve bu
|
|
900
|
-
tesadüf değil: filtre kutusunun yanında duran "Temizle" düğmesi de `sm`
|
|
901
|
-
oluyor, ikisi aynı satırda birbirini tutuyor. Yeni bir yükseklik uydurmak,
|
|
902
|
-
yan yana gelen iki kontrolün 2px kayması demekti.
|
|
903
|
-
|
|
904
|
-
NE ZAMAN KULLANILMAZ. Bir formun kendi alanları. Orada alan ASIL iştir ve
|
|
905
|
-
40px onun hakkı; küçültmek yalnız yardımcı bir yüzeyde, verinin kendisinden
|
|
906
|
-
daha çok yer kaplamasın diye. */
|
|
907
586
|
.tamga-input-sm {
|
|
908
587
|
height: 32px;
|
|
909
588
|
padding: 0 10px;
|
|
910
589
|
font-size: var(--text-small);
|
|
911
590
|
}
|
|
912
|
-
|
|
913
|
-
alanın yarısını yutuyordu. */
|
|
591
|
+
|
|
914
592
|
.tamga-input-sm[data-leading="true"] {
|
|
915
593
|
padding-left: 30px;
|
|
916
594
|
}
|
|
917
595
|
|
|
918
|
-
/* `Code`'un dış kutusu.
|
|
919
|
-
*
|
|
920
|
-
* KOPYALAMA DÜĞMESİ MUTLAK KONUMLU ve sağ üste sabitli. Tek satırlık bir
|
|
921
|
-
* gövdede bu bir hataya dönüşüyordu: kutu 42px, düğme 32px, üstte 9px altta
|
|
922
|
-
* 1.5px kalıyordu; düğme ortalı değil ALTA YAPIŞIK görünüyordu.
|
|
923
|
-
*
|
|
924
|
-
* İki kural birlikte çözüyor. `min-height` düğmenin altına ve üstüne eşit
|
|
925
|
-
* boşluk bırakacak kadar yer açıyor (8 + 32 + 8), ve dikey ortalama tek
|
|
926
|
-
* satırlık gövdeyi o yüksekliğin ortasına alıyor, yani metnin ortası ile
|
|
927
|
-
* düğmenin ortası aynı yere düşüyor. Çok satırlı bir gövdede kutu zaten
|
|
928
|
-
* daha uzun: ortalamanın etkisi kalmıyor, düğme sağ üstte kalıyor ve orası
|
|
929
|
-
* bir kod bloğu için doğru yer.
|
|
930
|
-
*/
|
|
931
596
|
.tamga-code-block {
|
|
932
597
|
min-height: 48px;
|
|
933
598
|
display: flex;
|
|
@@ -935,41 +600,10 @@
|
|
|
935
600
|
justify-content: center;
|
|
936
601
|
}
|
|
937
602
|
|
|
938
|
-
/*
|
|
939
|
-
* YAZAR METNİ. Bir ürünün açıklaması, bir bilgi tabanı yazısı, bir notun
|
|
940
|
-
* gövdesi: kitin denetlemediği, insanın yazdığı HTML.
|
|
941
|
-
*
|
|
942
|
-
* NEDEN BİR SINIF, BİLEŞEN DEĞİL. Buraya gelen şey zaten bir HTML dizgisi;
|
|
943
|
-
* sarmalayan bir bileşen ona `dangerouslySetInnerHTML`den başka bir şey
|
|
944
|
-
* yapamaz, ve o kararı çağıran vermeli. Kitin katkısı biçim: gelen etiketler
|
|
945
|
-
* kitin kendi ölçeğinde ve kendi renginde çizilsin.
|
|
946
|
-
*
|
|
947
|
-
* NE TEMİZLEMEZ. Bu bir güvenlik sınırı DEĞİL. Hangi etiketin geçeceğine
|
|
948
|
-
* ürün karar veriyor, çünkü beyaz liste ürünün vitrinine ait bir kural.
|
|
949
|
-
*
|
|
950
|
-
* SIFIRLAMA GEREKİYOR ÇÜNKÜ tarayıcının kendi başlık ve liste ölçüleri
|
|
951
|
-
* kitin ölçeğiyle ilgisiz: `h3` 1.17em, `ul` 40px girinti. Ölçek dışından
|
|
952
|
-
* gelen bir sayı, uydurulmuş bir sayı kadar yanlış.
|
|
953
|
-
*/
|
|
954
|
-
/*
|
|
955
|
-
* EDİTÖR: araç çubuğu + yazma alanı, tek bir kutu gibi.
|
|
956
|
-
*
|
|
957
|
-
* Çubuk ile alan AYRI ÖĞELER ama TEK bir kenarlık taşıyorlar; iki ayrı
|
|
958
|
-
* kutu, aralarındaki çift çizgiyle "burada iki şey var" der, oysa burada
|
|
959
|
-
* bir tane var.
|
|
960
|
-
*
|
|
961
|
-
* ODAK DIŞ KUTUDA. Yazılan yer içerideki `contenteditable`; odak halkası
|
|
962
|
-
* ona verilirse çubuk halkanın dışında kalıyor ve kontrolün sınırı
|
|
963
|
-
* belirsizleşiyor. `:focus-within` odağı dışarı taşıyor.
|
|
964
|
-
*/
|
|
965
603
|
.tamga-editor {
|
|
966
604
|
border: 1px solid var(--color-edge);
|
|
967
605
|
border-radius: var(--radius-ctl);
|
|
968
|
-
|
|
969
|
-
`--color-input` shadcn geleneğinden gelen bir KENAR rengi (#d2cec8),
|
|
970
|
-
dolgu değil. Onunla boyanan alan girdiden çok DEVRE DIŞI bir kutuya
|
|
971
|
-
benziyordu. Metin kutularının gerçek zemini `--color-shell`, ve editör
|
|
972
|
-
de bir metin kutusu. */
|
|
606
|
+
|
|
973
607
|
background: var(--color-shell);
|
|
974
608
|
overflow: hidden;
|
|
975
609
|
}
|
|
@@ -990,8 +624,6 @@
|
|
|
990
624
|
background: var(--color-sunk);
|
|
991
625
|
}
|
|
992
626
|
|
|
993
|
-
/* Biçim düğmesi. AÇIK OLAN DURUM DOLU ZEMİNLE söyleniyor, yalnız renkle
|
|
994
|
-
değil: bir düğmenin basılı olduğunu tek başına renk anlatamaz. */
|
|
995
627
|
.tamga-editor-btn {
|
|
996
628
|
display: inline-flex;
|
|
997
629
|
align-items: center;
|
|
@@ -1016,9 +648,6 @@
|
|
|
1016
648
|
cursor: default;
|
|
1017
649
|
}
|
|
1018
650
|
|
|
1019
|
-
/* Bağlantı adresi satırı: çubuğun ALTINDA açılıyor, üstünde değil, çünkü
|
|
1020
|
-
çubuk yerinde kalmalı; açılan bir şey düğmelerin yerini oynatırsa
|
|
1021
|
-
kullanıcı ikinci düğmeyi kaybediyor. */
|
|
1022
651
|
.tamga-editor-link {
|
|
1023
652
|
display: flex;
|
|
1024
653
|
align-items: center;
|
|
@@ -1089,10 +718,6 @@
|
|
|
1089
718
|
color: var(--color-ink-faint);
|
|
1090
719
|
}
|
|
1091
720
|
|
|
1092
|
-
/* An invalid field carries the critical colour on its edge only — never a
|
|
1093
|
-
wash. The message under it is what explains the problem; the field just
|
|
1094
|
-
has to be findable. Paired with aria-invalid by the Input component, so
|
|
1095
|
-
the state is not only visible. */
|
|
1096
721
|
.tamga-input-invalid, .tamga-input-invalid:focus {
|
|
1097
722
|
border-color: var(--color-critical);
|
|
1098
723
|
box-shadow: 2px 2px 0 var(--color-critical);
|
|
@@ -1103,13 +728,6 @@
|
|
|
1103
728
|
outline: none;
|
|
1104
729
|
}
|
|
1105
730
|
|
|
1106
|
-
/* A chip is FLAT, and that is load-bearing rather than shy.
|
|
1107
|
-
In this system depth means "you can press this" — so a raised chip promises
|
|
1108
|
-
a press it cannot deliver. It carried a 2px offset for two days and the
|
|
1109
|
-
promise was the problem: nothing about a status label is clickable.
|
|
1110
|
-
Weight comes from the 1px edge in its own colour instead. Anything that
|
|
1111
|
-
genuinely needs to be pressed stops being a chip and becomes a mini button,
|
|
1112
|
-
which already exists and already lifts. */
|
|
1113
731
|
.tamga-chip {
|
|
1114
732
|
border-radius: var(--radius-ctl);
|
|
1115
733
|
display: inline-flex;
|
|
@@ -1127,20 +745,6 @@
|
|
|
1127
745
|
font-size: var(--text-caption);
|
|
1128
746
|
}
|
|
1129
747
|
|
|
1130
|
-
/* AKTİF ÇİZGİ SEKMENİN KENDİ KENARLIĞI, dışarı taşan bir `::after` değil.
|
|
1131
|
-
*
|
|
1132
|
-
* Önce şöyleydi: `position: absolute; bottom: -1px`, yani işaret sekmenin
|
|
1133
|
-
* kutusunun BİR PİKSEL ALTINA çiziliyordu ve şeridin kendi alt çizgisinin
|
|
1134
|
-
* üstüne oturuyordu. Duran bir şeritte doğru görünüyor.
|
|
1135
|
-
*
|
|
1136
|
-
* Ama şerit KAYDIRILABİLİR olduğu anda kayboluyor. `overflow-x: auto` veren
|
|
1137
|
-
* bir kap, CSS gereği `overflow-y`yi de `auto` yapıyor (bir eksen `visible`
|
|
1138
|
-
* değilse öteki de olamaz), ve kutunun dışına çizilen o bir piksel kırpılıyor.
|
|
1139
|
-
* On dokuz sekmeli bir şeritte aktif sekme işaretsiz kalıyordu: şerit kitin
|
|
1140
|
-
* şeridine "benzemiyordu" ve sebebi buydu.
|
|
1141
|
-
*
|
|
1142
|
-
* Kenarlık kutunun İÇİNDE: kırpılacak bir taşma yok. Saydam bir kenarlık
|
|
1143
|
-
* her sekmede duruyor ki aktif olunca yükseklik değişmesin. */
|
|
1144
748
|
.tamga-tab {
|
|
1145
749
|
display: inline-flex;
|
|
1146
750
|
align-items: center;
|
|
@@ -1155,8 +759,6 @@
|
|
|
1155
759
|
border-color var(--duration-press) var(--ease-standard);
|
|
1156
760
|
}
|
|
1157
761
|
|
|
1158
|
-
/* Kapalı sekme: yerinde ama gidilemez. Solgun ve tıklanamaz, ama YOK
|
|
1159
|
-
değil, çünkü orada bir şey olduğunu bilmek kullanıcının işine yarıyor. */
|
|
1160
762
|
.tamga-tab[data-disabled] {
|
|
1161
763
|
color: var(--color-ink-faint);
|
|
1162
764
|
cursor: default;
|
|
@@ -1170,16 +772,12 @@
|
|
|
1170
772
|
border-bottom-color: var(--color-accent-line);
|
|
1171
773
|
}
|
|
1172
774
|
|
|
1173
|
-
/* segmented control: one of N, so it follows the rail — outlined and
|
|
1174
|
-
lifted when chosen, never filled. Filling is reserved for actions. */
|
|
1175
775
|
.tamga-segment {
|
|
1176
776
|
display: inline-flex;
|
|
1177
777
|
align-items: center;
|
|
1178
778
|
gap: 8px;
|
|
1179
779
|
}
|
|
1180
|
-
|
|
1181
|
-
icons clear at 3:1, text needs 4.5:1, and as text it measured 3.29:1 on
|
|
1182
|
-
paper. Same glyph colour, wrong job. */
|
|
780
|
+
|
|
1183
781
|
.tamga-segment > button {
|
|
1184
782
|
display: inline-flex;
|
|
1185
783
|
align-items: center;
|
|
@@ -1215,26 +813,15 @@
|
|
|
1215
813
|
box-shadow: 0 0 0 var(--color-accent-line);
|
|
1216
814
|
}
|
|
1217
815
|
|
|
1218
|
-
/* ---------- overlay plane ---------- */
|
|
1219
|
-
/* Same language as everything else — 1px edge, hard offset, no blur.
|
|
1220
|
-
The offset jumps to 6px, past the 4px page maximum, and that gap is
|
|
1221
|
-
what says "this is floating, not part of the page". */
|
|
1222
816
|
.tamga-overlay {
|
|
1223
817
|
border: 1px solid var(--color-edge);
|
|
1224
818
|
border-radius: var(--radius-card);
|
|
1225
819
|
background: var(--color-shell);
|
|
1226
820
|
box-shadow: 6px 6px 0 var(--color-edge);
|
|
1227
|
-
|
|
1228
|
-
hizasını miras alıyordu: bir tablo hücresinin içinde açıldığında
|
|
1229
|
-
(`.tamga-cell-actions` sağa yaslar) panelin İÇİNDEKİ metin de sağa
|
|
1230
|
-
yaslanıyordu. Bir yüzey başladığı yerde metin akışı da yeniden başlar. */
|
|
821
|
+
|
|
1231
822
|
text-align: start;
|
|
1232
823
|
}
|
|
1233
|
-
|
|
1234
|
-
Kenar, yarıçap ve kaydırma gölgesi kalkıyor — üçü de "bu şey sayfanın
|
|
1235
|
-
üstünde duruyor" demek için var, ve sayfanın tamamını kaplayan bir şeyin
|
|
1236
|
-
altında sayfa kalmıyor. Dikey akış: başlık ile ayak yerinde kalırken gövde
|
|
1237
|
-
kendi içinde kayıyor. */
|
|
824
|
+
|
|
1238
825
|
.tamga-overlay-full {
|
|
1239
826
|
display: flex;
|
|
1240
827
|
height: 100%;
|
|
@@ -1243,25 +830,7 @@
|
|
|
1243
830
|
border-radius: 0;
|
|
1244
831
|
box-shadow: none;
|
|
1245
832
|
}
|
|
1246
|
-
|
|
1247
|
-
/*
|
|
1248
|
-
* ADIM ŞERİDİ, ve üç durumu üç FARKLI FİZİKLE söylüyor.
|
|
1249
|
-
*
|
|
1250
|
-
* Önce üçü de aynı şeydi: ince kenarlı bir daire, yalnız rengi değişiyordu.
|
|
1251
|
-
* Renk tek başına bir hiyerarşi kurmuyor — ve daire, kitin hiçbir yerde
|
|
1252
|
-
* kullanmadığı bir şekil. Kit tam yuvarlağı yalnız avatarda ve noktada
|
|
1253
|
-
* kullanıyor; bir adım işareti bir kontrol boyunda bir işarettir, o yüzden
|
|
1254
|
-
* kontrolün yarıçapını alıyor.
|
|
1255
|
-
*
|
|
1256
|
-
* ÜÇ DURUM, ÜÇ FİZİK (13 Yasa 1: 1px kenar + kaydırılmış tam renk):
|
|
1257
|
-
* gelecek düz durur — henüz bir şey olmadı
|
|
1258
|
-
* şimdiki YÜKSELİR — 2px sert kaydırma, aksan renginde: buradasın
|
|
1259
|
-
* biten OTURUR — dolu aksan, kaydırma yok: bitmiş bir iş kalkmaz
|
|
1260
|
-
*
|
|
1261
|
-
* ÇİZGİ DE BİLGİ TAŞIYOR. Geçilen aralık aksan, kalanı kenar rengi: şerit
|
|
1262
|
-
* yalnız adımları saymıyor, ne kadar yol alındığını da gösteriyor. 1px
|
|
1263
|
-
* `--color-line` idi ve kâğıdın üstünde neredeyse görünmüyordu.
|
|
1264
|
-
*/
|
|
833
|
+
|
|
1265
834
|
.tamga-step-mark {
|
|
1266
835
|
display: inline-flex;
|
|
1267
836
|
width: var(--step-mark);
|
|
@@ -1283,11 +852,7 @@
|
|
|
1283
852
|
color: var(--color-accent-line);
|
|
1284
853
|
box-shadow: 2px 2px 0 0 var(--color-accent-line);
|
|
1285
854
|
}
|
|
1286
|
-
|
|
1287
|
-
Burada dolgu `accent-line` idi: o bir METİN token'ı, sayfaya karşı 4.5
|
|
1288
|
-
arayarak üretiliyor, yani yüzden hep daha koyu. Sonuç ekranda şuydu: biten
|
|
1289
|
-
adımlar koyu, aynı ekrandaki her düğme ve rozet açık. Üstündeki mürekkep de
|
|
1290
|
-
`accent`e göre ölçülüyordu, `accent-line`a göre değil. */
|
|
855
|
+
|
|
1291
856
|
.tamga-step-mark[data-state="done"] {
|
|
1292
857
|
border-color: var(--color-accent-shadow);
|
|
1293
858
|
background: var(--color-accent);
|
|
@@ -1308,21 +873,6 @@
|
|
|
1308
873
|
background: var(--color-scrim);
|
|
1309
874
|
}
|
|
1310
875
|
|
|
1311
|
-
/* ---------- form controls ---------- */
|
|
1312
|
-
/* checkbox and radio carry the same 1px edge and 1px offset as a mini
|
|
1313
|
-
button, so they read as part of the family rather than browser chrome */
|
|
1314
|
-
/*
|
|
1315
|
-
* SEÇENEK İŞARETİ İLK SATIRIN ORTASINA.
|
|
1316
|
-
*
|
|
1317
|
-
* Etiket tek satırken kutuyu dikeyde ortalamak doğru duruyor; altına bir
|
|
1318
|
-
* açıklama satırı eklenince işaret İKİ SATIRIN ortasına kaçıyor ve neyi
|
|
1319
|
-
* işaretlediği belirsizleşiyor. İşaret ilk satıra ait.
|
|
1320
|
-
*
|
|
1321
|
-
* Sayı UYDURULMUYOR, satırdan hesaplanıyor: `1lh` öğenin kendi satır
|
|
1322
|
-
* kutusu, `18px` de işaretin boyu (yukarıdaki kuralın kendisi), ve fark
|
|
1323
|
-
* ikiye bölününce işaret ilk satırın tam ortasına oturuyor. Punto ya da
|
|
1324
|
-
* satır aralığı değişirse hizalama kendiliğinden düzeliyor.
|
|
1325
|
-
*/
|
|
1326
876
|
.tamga-choice-mark {
|
|
1327
877
|
align-self: flex-start;
|
|
1328
878
|
margin-top: calc((1lh - 18px) / 2);
|
|
@@ -1347,9 +897,10 @@
|
|
|
1347
897
|
border-color: var(--color-accent-line);
|
|
1348
898
|
box-shadow: 1px 1px 0 var(--color-accent-line);
|
|
1349
899
|
}
|
|
900
|
+
|
|
1350
901
|
.tamga-check[data-checked="true"] {
|
|
1351
902
|
background: var(--color-accent);
|
|
1352
|
-
border-color: var(--color-accent);
|
|
903
|
+
border-color: var(--color-accent-shadow);
|
|
1353
904
|
box-shadow: 1px 1px 0 var(--color-accent-shadow);
|
|
1354
905
|
}
|
|
1355
906
|
.tamga-radio[data-checked="true"] {
|
|
@@ -1394,23 +945,6 @@
|
|
|
1394
945
|
transform: translateX(16px);
|
|
1395
946
|
}
|
|
1396
947
|
|
|
1397
|
-
|
|
1398
|
-
/* A skeleton breathes; it never shimmers. A sweeping gradient is the
|
|
1399
|
-
default-SaaS tell and this product has no gradients anywhere else, so one
|
|
1400
|
-
here would be the single exception — and it would be the loudest thing on
|
|
1401
|
-
a page whose whole point is that nothing has arrived yet.
|
|
1402
|
-
Two blocks, not one: the ground never animates, only the bar on top of it.
|
|
1403
|
-
That keeps a floor under the shape so it stays a placeholder at every point
|
|
1404
|
-
in the cycle instead of fading toward the page and back. */
|
|
1405
|
-
/* Progress is an instrument scale, not a bar. The ticks let the value be read
|
|
1406
|
-
without reading the number, which is what a gauge is for.
|
|
1407
|
-
Deliberately NOT the segmented strip form: a segmented horizontal strip is a
|
|
1408
|
-
timeline — one mark per bucket, colour as state — and reusing that shape for
|
|
1409
|
-
completion would read as history rather than as progress.
|
|
1410
|
-
Neutral throughout — progress reports completion, never health, so a status
|
|
1411
|
-
colour here would be a false signal.
|
|
1412
|
-
Note it carries a 2px offset, so it paints outside its box: reserve room in
|
|
1413
|
-
the container or the offset lands on whatever sits below. */
|
|
1414
948
|
.tamga-progress {
|
|
1415
949
|
position: relative;
|
|
1416
950
|
height: 16px;
|
|
@@ -1460,9 +994,7 @@
|
|
|
1460
994
|
color: var(--color-ink-soft);
|
|
1461
995
|
cursor: pointer;
|
|
1462
996
|
}
|
|
1463
|
-
|
|
1464
|
-
İki ayrı görünüş vermek, aynı anlamı ("Enter buna basacak") iki dille
|
|
1465
|
-
anlatmak olurdu; kullanıcının ikisini de öğrenmesi gerekirdi. */
|
|
997
|
+
|
|
1466
998
|
.tamga-option:hover,
|
|
1467
999
|
.tamga-option[data-active] {
|
|
1468
1000
|
background: var(--color-hover);
|
|
@@ -1474,9 +1006,6 @@
|
|
|
1474
1006
|
box-shadow: inset 2px 0 0 var(--color-accent-line);
|
|
1475
1007
|
}
|
|
1476
1008
|
|
|
1477
|
-
/* ---------- feedback and structure ---------- */
|
|
1478
|
-
|
|
1479
|
-
/* inline banner — status wash, no fill, a left rule carries the state */
|
|
1480
1009
|
.tamga-alert {
|
|
1481
1010
|
display: flex;
|
|
1482
1011
|
gap: 16px;
|
|
@@ -1487,7 +1016,6 @@
|
|
|
1487
1016
|
background: var(--color-shell);
|
|
1488
1017
|
}
|
|
1489
1018
|
|
|
1490
|
-
/* the live mark — neutral by rule: running is not a deviation */
|
|
1491
1019
|
.tamga-beacon {
|
|
1492
1020
|
display: inline-block;
|
|
1493
1021
|
width: 8px;
|
|
@@ -1499,7 +1027,6 @@
|
|
|
1499
1027
|
animation: tamga-pulse var(--duration-beacon) var(--ease-breath) infinite;
|
|
1500
1028
|
}
|
|
1501
1029
|
|
|
1502
|
-
/* keeps a button's width when its label swaps for a loading label */
|
|
1503
1030
|
.tamga-swap {
|
|
1504
1031
|
display: grid;
|
|
1505
1032
|
place-items: center;
|
|
@@ -1516,7 +1043,6 @@
|
|
|
1516
1043
|
visibility: hidden;
|
|
1517
1044
|
}
|
|
1518
1045
|
|
|
1519
|
-
|
|
1520
1046
|
.tamga-rule-h {
|
|
1521
1047
|
height: 1px;
|
|
1522
1048
|
width: 100%;
|
|
@@ -1528,15 +1054,6 @@
|
|
|
1528
1054
|
background: var(--color-line);
|
|
1529
1055
|
}
|
|
1530
1056
|
|
|
1531
|
-
/* ---------- lists and tables ---------- */
|
|
1532
|
-
/* row height is fixed so a list never breathes with its content */
|
|
1533
|
-
|
|
1534
|
-
/* Slider topuzu.
|
|
1535
|
-
|
|
1536
|
-
`appearance: none` çubuğu bize bırakıyor ama TOPUZU DA SİLİYOR — ve
|
|
1537
|
-
silinen topuz hata vermiyor, sadece kaydırıcı tutulamaz hâle geliyor.
|
|
1538
|
-
WebKit ve Firefox iki ayrı sözde-eleman kullanıyor; ikisi de yazılmak
|
|
1539
|
-
zorunda, biri unutulursa o tarayıcıda topuz yok. */
|
|
1540
1057
|
.tamga-slider::-webkit-slider-thumb {
|
|
1541
1058
|
appearance: none;
|
|
1542
1059
|
width: 16px;
|
|
@@ -1561,16 +1078,6 @@
|
|
|
1561
1078
|
outline-offset: 4px;
|
|
1562
1079
|
}
|
|
1563
1080
|
|
|
1564
|
-
/* THE GUTTER IS THE ROW'S, not the caller's.
|
|
1565
|
-
*
|
|
1566
|
-
* This class carried no horizontal padding, and every single caller added
|
|
1567
|
-
* `tamga-gutter` by hand: the settings sub-nav, both skeletons, the docs
|
|
1568
|
-
* example. Five out of five is not a convention, it is a missing rule, and
|
|
1569
|
-
* the sixth caller (a blocks recipe) forgot it and rendered edge to edge.
|
|
1570
|
-
*
|
|
1571
|
-
* `.tamga-table` was already doing this correctly through
|
|
1572
|
-
* `td:first-child { padding-left: var(--gutter) }`. A row and a cell sit on
|
|
1573
|
-
* the same left rule; one of them should not need reminding. */
|
|
1574
1081
|
.tamga-list-row {
|
|
1575
1082
|
display: flex;
|
|
1576
1083
|
align-items: center;
|
|
@@ -1601,29 +1108,7 @@
|
|
|
1601
1108
|
white-space: nowrap;
|
|
1602
1109
|
text-overflow: ellipsis;
|
|
1603
1110
|
}
|
|
1604
|
-
|
|
1605
|
-
The truncation trio above (overflow:hidden + nowrap + ellipsis) is right for text and fatal for
|
|
1606
|
-
a row's action menu: the panel is absolutely positioned inside the cell, so `overflow:hidden`
|
|
1607
|
-
cuts it off at the cell's edge. Measured 2026-08-20 — the menu rendered, looked fine, and
|
|
1608
|
-
swallowed every click, because `elementFromPoint` returned the td.
|
|
1609
|
-
Actions never need truncating, so the cell opts out of all three rather than the table losing
|
|
1610
|
-
ellipsis everywhere.
|
|
1611
|
-
|
|
1612
|
-
AND IT REALLY IS ALL THREE. The comment said three, the rule reset two: `white-space: nowrap`
|
|
1613
|
-
stayed, and it is inherited, so every panel opened inside this cell inherited it too. A popover
|
|
1614
|
-
listing an order's products rendered each line on one unbreakable line and spilled past its own
|
|
1615
|
-
edge. The overlay looked broken; the cause was a table rule three levels up. Found 2026-09-09
|
|
1616
|
-
in a consumer panel.
|
|
1617
|
-
|
|
1618
|
-
KIRPMA VE HİZA AYRI İKİ ŞEY. Bu kaçış uzun süre tek parçaydı ve sağa
|
|
1619
|
-
yaslamayı da beraberinde getiriyordu, yani sola yaslı bir hücrede bir ipucu
|
|
1620
|
-
ya da açılır panel barındırmak isteyen, hizasını da feda etmek zorunda
|
|
1621
|
-
kalıyordu. Yakalandığı yer: bir tüketici listesinde durum rozetinin ipucu
|
|
1622
|
-
hücre kenarında kesiliyordu, ve tek çare hücreyi sağa yaslamaktı.
|
|
1623
|
-
|
|
1624
|
-
SEÇİCİ `.tamga-table td` KADAR SPESİFİK OLMAK ZORUNDA: düz
|
|
1625
|
-
`.tamga-cell-open` (0,1,0) yazılırsa kırpma kuralı `.tamga-table td`
|
|
1626
|
-
(0,1,1) onu yener ve sınıf hiçbir şey yapmaz. */
|
|
1111
|
+
|
|
1627
1112
|
.tamga-table td.tamga-cell-open,
|
|
1628
1113
|
.tamga-table th.tamga-cell-open {
|
|
1629
1114
|
overflow: visible;
|
|
@@ -1664,13 +1149,7 @@
|
|
|
1664
1149
|
.tamga-table tbody tr[data-selected="true"] td:first-child {
|
|
1665
1150
|
box-shadow: inset 2px 0 0 var(--color-accent-line);
|
|
1666
1151
|
}
|
|
1667
|
-
|
|
1668
|
-
`SettingsTemplate` menüsündeki açık bölümü `data-active` ile işaretliyor
|
|
1669
|
-
(bir GEZİNME satırı: hangi sayfadasın), liste satırları ise `data-selected`
|
|
1670
|
-
ile (bir SEÇİM: hangi kayıtları işaretledin). İkisi farklı anlam ama aynı
|
|
1671
|
-
görünüm, ve kural yalnız ikincisi için yazılmıştı: ayarlar menüsünde
|
|
1672
|
-
hangi bölümde olduğun hiç görünmüyordu. Hiçbir şey patlamadı, çünkü
|
|
1673
|
-
tarayıcı bilmediği bir nitelik seçicisini sessizce atlıyor. */
|
|
1152
|
+
|
|
1674
1153
|
.tamga-list-row[data-active="true"],
|
|
1675
1154
|
.tamga-list-row[data-selected="true"] {
|
|
1676
1155
|
background: var(--color-accent-bg);
|
|
@@ -1681,28 +1160,13 @@
|
|
|
1681
1160
|
color: var(--color-accent-line);
|
|
1682
1161
|
font-weight: 500;
|
|
1683
1162
|
text-underline-offset: 3px;
|
|
1684
|
-
|
|
1685
|
-
ya da link gibi görünen bir `<button>` almaz ve imleç `auto` kalır. Sınıf
|
|
1686
|
-
kendi imlecini söylemeli. */
|
|
1163
|
+
|
|
1687
1164
|
cursor: pointer;
|
|
1688
1165
|
}
|
|
1689
1166
|
.tamga-link:hover {
|
|
1690
1167
|
text-decoration: underline;
|
|
1691
1168
|
}
|
|
1692
1169
|
|
|
1693
|
-
/* ------------------------------------------------------------------ *
|
|
1694
|
-
* KPI KAROSU: tek bir sayı, büyük.
|
|
1695
|
-
*
|
|
1696
|
-
* REFERANS NOKTASI YUMUŞAK KARTTI (daire ikon rozeti, bulanık gölge, kenar
|
|
1697
|
-
* yok); buradaki karşılığı 1. yasa: 1px kenar, BULANIKSIZ kaymış gölge, ve
|
|
1698
|
-
* daire yerine KARE karo. Kit hiçbir yerde daire kullanmıyor (avatar ve
|
|
1699
|
-
* nokta dışında) ve tek bir daire, kartı ödünç alınmış gösteriyor.
|
|
1700
|
-
*
|
|
1701
|
-
* İKON KARONUN ZEMİNİ `--color-hover`, marka rengi DEĞİL. Bir panoda dört
|
|
1702
|
-
* karo yan yana duruyor; dördünün de ikonu marka renginde parlarsa hiçbiri
|
|
1703
|
-
* öne çıkmıyor ve göz asıl bakması gereken sayıyı en son buluyor. Renk
|
|
1704
|
-
* kartın kendi verisinin (`accent` şeridi) ve dikkat isteyen sayının hakkı.
|
|
1705
|
-
* ------------------------------------------------------------------ */
|
|
1706
1170
|
.tamga-kpi {
|
|
1707
1171
|
position: relative;
|
|
1708
1172
|
display: flex;
|
|
@@ -1731,18 +1195,6 @@
|
|
|
1731
1195
|
color: var(--color-ink-soft);
|
|
1732
1196
|
}
|
|
1733
1197
|
|
|
1734
|
-
/*
|
|
1735
|
-
* FİZİK YALNIZ TIKLANABİLİR KARODA.
|
|
1736
|
-
*
|
|
1737
|
-
* `.tamga-kpi-live` bir stil değil bir SÖZ: bu karo tıklanıyor. Okunan bir
|
|
1738
|
-
* karo hover'da yükselirse tıklanabilir göründüğü hâlde hiçbir şey yapmıyor,
|
|
1739
|
-
* ve kullanıcı bir kez tıklayıp bir daha denemiyor.
|
|
1740
|
-
*
|
|
1741
|
-
* Kaymalar 1. yasanın kendisi: hover'da -1/-1 ve 3px gölge, basınca +2/+2 ve
|
|
1742
|
-
* gölge yok. `--offset-room` tuzağı burada da geçerli — bu karolar bir
|
|
1743
|
-
* ızgarada duruyor ve ızgaranın kendisi kırpmıyor, ama kaydırılan bir kabın
|
|
1744
|
-
* içine konulursa `.tamga-rail-scroll` gibi bir dolgu gerekir.
|
|
1745
|
-
*/
|
|
1746
1198
|
.tamga-kpi-live {
|
|
1747
1199
|
cursor: pointer;
|
|
1748
1200
|
transition:
|
|
@@ -1750,11 +1202,7 @@
|
|
|
1750
1202
|
box-shadow var(--duration-press, 120ms) var(--ease-press, ease-out),
|
|
1751
1203
|
background var(--duration-press, 120ms);
|
|
1752
1204
|
}
|
|
1753
|
-
|
|
1754
|
-
1. yasasında hover üç şey yapar: zemin bir tık koyulaşır, kontrol
|
|
1755
|
-
-1/-1 yükselir, gölge 3px'e çıkar. Kenarın renklenmesi bu dilde yok
|
|
1756
|
-
(`tamga-btn`de de, `tamga-icon-btn`de de yok) ve tek başına bir kartta
|
|
1757
|
-
yapıldığında kart ötekilerden farklı bir şey konuşuyor. */
|
|
1205
|
+
|
|
1758
1206
|
.tamga-kpi-live:hover {
|
|
1759
1207
|
background: var(--color-hover);
|
|
1760
1208
|
transform: translate(-1px, -1px);
|
|
@@ -1765,9 +1213,6 @@
|
|
|
1765
1213
|
box-shadow: 0 0 0 var(--color-edge);
|
|
1766
1214
|
}
|
|
1767
1215
|
|
|
1768
|
-
/* SEÇİLİ HÂL NÖTR, VURGU RENGİ DEĞİL. Vurgu rengi bir EYLEMİN rengi (kaydet,
|
|
1769
|
-
sil); bir filtrenin açık olması bir eylem değil bir DURUM. Vurguya
|
|
1770
|
-
boyandığında listede bir sorun varmış gibi okunuyordu. */
|
|
1771
1216
|
.tamga-kpi-live[data-pressed] {
|
|
1772
1217
|
border-color: var(--color-ink);
|
|
1773
1218
|
background: var(--color-hover);
|
|
@@ -1780,18 +1225,6 @@
|
|
|
1780
1225
|
box-shadow: 0 0 0 var(--color-ink);
|
|
1781
1226
|
}
|
|
1782
1227
|
|
|
1783
|
-
/*
|
|
1784
|
-
* KAROLARIN IZGARASI.
|
|
1785
|
-
*
|
|
1786
|
-
* SÜTUN SAYISI KARO SAYISINDAN geliyor (`--tamga-kpi-cols`), ekrandan
|
|
1787
|
-
* verilmiyor. Elle verilen bir sütun sayısı yeni bir karo eklendiğinde
|
|
1788
|
-
* yalnız o ekranda güncelleniyor, ve tek başına kalan bir karo bütün satırı
|
|
1789
|
-
* kaplayıp panoyu dengesiz gösteriyor.
|
|
1790
|
-
*
|
|
1791
|
-
* Dar ekranda iki sütun, geniş ekranda karo sayısı kadar: bir karo 40px
|
|
1792
|
-
* ikon ve display boyunda bir sayı taşıyor, üçten dar bir sütunda sayı
|
|
1793
|
-
* sarıyor.
|
|
1794
|
-
*/
|
|
1795
1228
|
.tamga-kpi-grid {
|
|
1796
1229
|
display: grid;
|
|
1797
1230
|
gap: 16px;
|
|
@@ -1808,8 +1241,6 @@
|
|
|
1808
1241
|
}
|
|
1809
1242
|
}
|
|
1810
1243
|
|
|
1811
|
-
/* Çekmece kenardan kayarak girer; yön `side` ile aynı olmak zorunda, yoksa
|
|
1812
|
-
kapatma hareketi ters öğretilir. Gerekçe: /docs/sheet */
|
|
1813
1244
|
.tamga-sheet-start {
|
|
1814
1245
|
animation: tamga-sheet-start var(--duration-base) var(--ease-standard);
|
|
1815
1246
|
}
|
|
@@ -1817,18 +1248,6 @@
|
|
|
1817
1248
|
animation: tamga-sheet-end var(--duration-base) var(--ease-standard);
|
|
1818
1249
|
}
|
|
1819
1250
|
|
|
1820
|
-
/* ------------------------------------------------------------------ *
|
|
1821
|
-
* GÖRÜNÜM AYARLARININ PARÇALARI.
|
|
1822
|
-
*
|
|
1823
|
-
* Üçü de bir üründe doğdu ve kite AYNI GEREKÇEYLE taşındı: her panelin bir
|
|
1824
|
-
* görünüm ayarı oluyor, ve kit onu vermediğinde her ürün kendi hex kutusunu
|
|
1825
|
-
* çiziyor. Kiti kuran bir ekip "renk seçimi" deyince altı hazır
|
|
1826
|
-
* kutuyu değil, çıplak bir metin girdisi elde ediyordu.
|
|
1827
|
-
* ------------------------------------------------------------------ */
|
|
1828
|
-
|
|
1829
|
-
/* Marka rengi kutusu. Seçili olan kitin fiziğiyle işaretli: 1px kenar artı
|
|
1830
|
-
2px sert kaydırma. Kutunun İÇİNE çentik konmuyor, çentiğin kontrastı
|
|
1831
|
-
seçilen renge göre değişiyor ve açık bir renkte kayboluyor. */
|
|
1832
1251
|
.tamga-swatch {
|
|
1833
1252
|
display: inline-flex;
|
|
1834
1253
|
width: var(--control);
|
|
@@ -1861,7 +1280,6 @@
|
|
|
1861
1280
|
box-shadow: 0 0 0 var(--color-edge);
|
|
1862
1281
|
}
|
|
1863
1282
|
|
|
1864
|
-
/* Tarayıcının kendi renk kutusu, kitin kenarlığıyla. */
|
|
1865
1283
|
.tamga-color-input {
|
|
1866
1284
|
width: 36px;
|
|
1867
1285
|
height: 36px;
|
|
@@ -1872,19 +1290,6 @@
|
|
|
1872
1290
|
cursor: pointer;
|
|
1873
1291
|
}
|
|
1874
1292
|
|
|
1875
|
-
/* ------------------------------------------------------------------ *
|
|
1876
|
-
* TEMA KARTI — panelin minyatürü.
|
|
1877
|
-
*
|
|
1878
|
-
* "Açık · Koyu · Sistem" üç kelimeydi, ve bir tema seçimi kelimeyle
|
|
1879
|
-
* yapılmıyor: kullanıcı sonucu görmek istiyor. Her seçenek panelin
|
|
1880
|
-
* minyatürünü çiziyor (ray, gövde, satırlar) ve "Sistem" ikisini bir karede
|
|
1881
|
-
* yan yana gösteriyor, çünkü anlamı tam olarak bu.
|
|
1882
|
-
*
|
|
1883
|
-
* MİNYATÜR SABİT RENKLERLE, ve kitin tek istisnası bu. Seçenekler o an
|
|
1884
|
-
* yürürlükteki temayı değil SEÇİLİRSE ne olacağını gösteriyor; token
|
|
1885
|
-
* kullanılsaydı üçü de aynı görünürdü. Tek token: marka vurgusu, çünkü
|
|
1886
|
-
* önizlemenin yarısı o.
|
|
1887
|
-
* ------------------------------------------------------------------ */
|
|
1888
1293
|
.tamga-theme-card {
|
|
1889
1294
|
display: flex;
|
|
1890
1295
|
flex-direction: column;
|
|
@@ -1970,9 +1375,7 @@
|
|
|
1970
1375
|
}
|
|
1971
1376
|
.tamga-theme-half[data-theme="light"] .tamga-theme-line { background: #d8d4cf; }
|
|
1972
1377
|
.tamga-theme-half[data-theme="dark"] .tamga-theme-line { background: #3a3a42; }
|
|
1973
|
-
|
|
1974
|
-
`[data-theme] .tamga-theme-line` onu eziyor ve marka rengi önizlemede hiç
|
|
1975
|
-
görünmüyor. */
|
|
1378
|
+
|
|
1976
1379
|
.tamga-theme-half .tamga-theme-line[data-accent="true"] {
|
|
1977
1380
|
background: var(--color-accent);
|
|
1978
1381
|
}
|
|
@@ -1988,10 +1391,6 @@
|
|
|
1988
1391
|
background: var(--color-accent);
|
|
1989
1392
|
}
|
|
1990
1393
|
|
|
1991
|
-
/* Yüklenen görselin durduğu kutu. Çıplak duran bir logo "buraya yüklendi"
|
|
1992
|
-
demiyor, "burada unutulmuş" diyor. Yükseklik sabit: logo geniş, amblem
|
|
1993
|
-
kare, ve ikisi farklı yükseklikte kutularda dursaydı bloklar hizasız
|
|
1994
|
-
görünürdü. */
|
|
1995
1394
|
.tamga-image-field {
|
|
1996
1395
|
display: flex;
|
|
1997
1396
|
align-items: center;
|
|
@@ -2004,8 +1403,7 @@
|
|
|
2004
1403
|
background: var(--color-shell);
|
|
2005
1404
|
box-shadow: 2px 2px 0 var(--color-edge);
|
|
2006
1405
|
}
|
|
2007
|
-
|
|
2008
|
-
kaldı" diyor. */
|
|
1406
|
+
|
|
2009
1407
|
.tamga-image-field[data-empty] {
|
|
2010
1408
|
border-style: dashed;
|
|
2011
1409
|
box-shadow: none;
|
|
@@ -2013,9 +1411,6 @@
|
|
|
2013
1411
|
font-size: var(--text-small);
|
|
2014
1412
|
}
|
|
2015
1413
|
|
|
2016
|
-
/* Ayar bölümü, sol kenarında marka rengi. `SettingsPanel`in `accent`
|
|
2017
|
-
varyantı: bir görünüm ekranında bloklar birbirinden ayrılmalı ve ayıran
|
|
2018
|
-
şey rengin kendisi olmalı, çünkü ekranın konusu o. */
|
|
2019
1414
|
.tamga-settings-panel-accent {
|
|
2020
1415
|
border-left: 4px solid var(--color-accent);
|
|
2021
1416
|
}
|
|
@@ -2026,8 +1421,6 @@
|
|
|
2026
1421
|
color: var(--color-ink-faint);
|
|
2027
1422
|
}
|
|
2028
1423
|
|
|
2029
|
-
/* an identifier-shaped micro-label above a title: mono, wide, quiet. It says
|
|
2030
|
-
what KIND of thing this is before the title says which one. */
|
|
2031
1424
|
.tamga-kicker {
|
|
2032
1425
|
font-family: var(--font-mono);
|
|
2033
1426
|
font-size: var(--text-micro);
|
|
@@ -2037,25 +1430,12 @@
|
|
|
2037
1430
|
color: var(--color-ink-faint);
|
|
2038
1431
|
}
|
|
2039
1432
|
|
|
2040
|
-
/* ---------- the mascot's furniture ---------- */
|
|
2041
|
-
/* The mascot lives INSIDE the instrument, never floating on top of it.
|
|
2042
|
-
Everything here exists to say that in the language the rest of the kit
|
|
2043
|
-
already speaks: a seated recess, ruled paper, a hard floor, a hard
|
|
2044
|
-
shadow. Drop the art on a plain coloured plane and you get somebody
|
|
2045
|
-
else's product with our artwork pasted into it. */
|
|
2046
|
-
|
|
2047
|
-
/* The well: a recess carved into the panel. SEATED physics — sunk ground,
|
|
2048
|
-
no offset, never lifts. The ground defaults to --color-sunk; a call site
|
|
2049
|
-
may pass --art-ground to tint it. */
|
|
2050
1433
|
.tamga-art-well {
|
|
2051
1434
|
position: relative;
|
|
2052
1435
|
background: var(--art-ground, var(--color-sunk));
|
|
2053
1436
|
overflow: hidden;
|
|
2054
1437
|
}
|
|
2055
|
-
|
|
2056
|
-
the figure stands on is squared paper — the same 8px module the layout uses.
|
|
2057
|
-
It also does real work: the grid gives the eye a scale, which is what
|
|
2058
|
-
stops a large drawing from reading as a decorative blob. */
|
|
1438
|
+
|
|
2059
1439
|
.tamga-art-well::before {
|
|
2060
1440
|
content: "";
|
|
2061
1441
|
position: absolute;
|
|
@@ -2066,28 +1446,20 @@
|
|
|
2066
1446
|
opacity: 0.7;
|
|
2067
1447
|
pointer-events: none;
|
|
2068
1448
|
}
|
|
2069
|
-
|
|
1449
|
+
|
|
2070
1450
|
.tamga-art-well > * {
|
|
2071
1451
|
position: relative;
|
|
2072
1452
|
}
|
|
2073
1453
|
|
|
2074
|
-
/* The floor. A character standing on a hard rule reads as standing; the same
|
|
2075
|
-
character with nothing under it reads as falling. One line fixes it. */
|
|
2076
1454
|
.tamga-art-floor {
|
|
2077
1455
|
border-bottom: 1px solid var(--color-edge);
|
|
2078
1456
|
}
|
|
2079
1457
|
|
|
2080
|
-
/* The cast shadow: the elevation formula applied to a character. Our light
|
|
2081
|
-
has always come from the upper left — every offset in the kit lands down
|
|
2082
|
-
and to the right — so the figure's shadow does too. A BAR rather than a copy of
|
|
2083
|
-
his silhouette, deliberately: a body-shaped offset would read as the
|
|
2084
|
-
pressable-object signature, and artwork is not pressable (Yasa: depth means
|
|
2085
|
-
pressable). A bar reads as ground, not as affordance. */
|
|
2086
1458
|
.tamga-art-fig {
|
|
2087
1459
|
position: relative;
|
|
2088
1460
|
display: inline-block;
|
|
2089
1461
|
}
|
|
2090
|
-
|
|
1462
|
+
|
|
2091
1463
|
.tamga-art-fig[data-ground="true"]::after {
|
|
2092
1464
|
content: "";
|
|
2093
1465
|
position: absolute;
|
|
@@ -2099,11 +1471,6 @@
|
|
|
2099
1471
|
pointer-events: none;
|
|
2100
1472
|
}
|
|
2101
1473
|
|
|
2102
|
-
/* The portrait: the figure framed in a window, for use inside a row.
|
|
2103
|
-
72px, not 46px. Every drawing is a SCENE — a figure at a desk, a figure in a
|
|
2104
|
-
boat — and a scene under about 50px is a smudge: the frame reads, the
|
|
2105
|
-
character does not, so the whole thing becomes decoration that costs a row.
|
|
2106
|
-
If it cannot be seen it should not be there. */
|
|
2107
1474
|
.tamga-art-port {
|
|
2108
1475
|
display: flex;
|
|
2109
1476
|
align-items: flex-end;
|
|
@@ -2116,12 +1483,6 @@
|
|
|
2116
1483
|
border-radius: var(--radius-sm);
|
|
2117
1484
|
}
|
|
2118
1485
|
|
|
2119
|
-
/* The base plate: what happens next, as an instrument's legend.
|
|
2120
|
-
A whole-surface empty state that is one short paragraph and two buttons
|
|
2121
|
-
leaves the reader with nothing to do but read the buttons. The steps are
|
|
2122
|
-
the actual answer to "what IS this screen for" — and they are what earns
|
|
2123
|
-
the full width, instead of stretching two sentences across it.
|
|
2124
|
-
Seated: sunk ground, no offset, so it never competes with the action. */
|
|
2125
1486
|
.tamga-art-steps {
|
|
2126
1487
|
display: grid;
|
|
2127
1488
|
border-top: 1px solid var(--color-edge);
|
|
@@ -2150,7 +1511,7 @@
|
|
|
2150
1511
|
border-left: 0;
|
|
2151
1512
|
}
|
|
2152
1513
|
}
|
|
2153
|
-
|
|
1514
|
+
|
|
2154
1515
|
.tamga-art-step-n {
|
|
2155
1516
|
flex-shrink: 0;
|
|
2156
1517
|
font-family: var(--font-mono);
|
|
@@ -2159,9 +1520,6 @@
|
|
|
2159
1520
|
color: var(--color-accent-line);
|
|
2160
1521
|
}
|
|
2161
1522
|
|
|
2162
|
-
/* The stage: the empty state is ONE object made of two materials — a seated
|
|
2163
|
-
well on the left, the raised face on the right, divided by a real edge.
|
|
2164
|
-
Both physics visible at once, which is the whole idea of the kit. */
|
|
2165
1523
|
.tamga-art-stage {
|
|
2166
1524
|
display: flex;
|
|
2167
1525
|
align-items: flex-end;
|
|
@@ -2172,9 +1530,6 @@
|
|
|
2172
1530
|
border-right: 1px solid var(--color-edge);
|
|
2173
1531
|
}
|
|
2174
1532
|
|
|
2175
|
-
/* A full-width shallow band of ruled paper with a floor under it — the
|
|
2176
|
-
mascot's stage when the composition runs on ONE vertical axis rather than
|
|
2177
|
-
splitting left and right. */
|
|
2178
1533
|
.tamga-art-band {
|
|
2179
1534
|
display: flex;
|
|
2180
1535
|
align-items: flex-end;
|
|
@@ -2184,21 +1539,11 @@
|
|
|
2184
1539
|
border-bottom: 1px solid var(--color-edge);
|
|
2185
1540
|
}
|
|
2186
1541
|
|
|
2187
|
-
/* The ticket's divider. It was drawn as a PERFORATION — a dashed rule meaning
|
|
2188
|
-
"tear here" — and v5 proved that wrong on contact: dashed already means
|
|
2189
|
-
"not real content yet" (the logo bounding box,
|
|
2190
|
-
the logo bounding box). A second meaning for the same mark makes a finished
|
|
2191
|
-
empty state read as a placeholder, which is the opposite of what it says.
|
|
2192
|
-
Solid, in the edge colour, like every other divider. Changed here too so
|
|
2193
|
-
the two do not drift — a kit whose copy disagrees with it is not a kit. */
|
|
2194
1542
|
.tamga-art-divider {
|
|
2195
1543
|
height: 0;
|
|
2196
1544
|
border-top: 1px solid var(--color-edge);
|
|
2197
1545
|
}
|
|
2198
1546
|
|
|
2199
|
-
/* A way in, offered as a row rather than a button. An empty screen with two
|
|
2200
|
-
buttons asks a yes/no question; a list of routes answers "what can I even
|
|
2201
|
-
do here", which is the actual question somebody arriving has. */
|
|
2202
1547
|
.tamga-art-route {
|
|
2203
1548
|
display: flex;
|
|
2204
1549
|
width: 100%;
|
|
@@ -2226,9 +1571,6 @@
|
|
|
2226
1571
|
box-shadow: 0 0 0 var(--color-edge);
|
|
2227
1572
|
}
|
|
2228
1573
|
|
|
2229
|
-
/* A logo tile. The mascot's portrait window is 72px because a SCENE needs the room; a service
|
|
2230
|
-
mark is a single glyph and reads at 48. Same frame, different job — sharing the portrait class
|
|
2231
|
-
made every integration card look like it was missing something. */
|
|
2232
1574
|
.tamga-logo-tile {
|
|
2233
1575
|
display: flex;
|
|
2234
1576
|
align-items: center;
|
|
@@ -2245,16 +1587,11 @@
|
|
|
2245
1587
|
height: 40px;
|
|
2246
1588
|
}
|
|
2247
1589
|
|
|
2248
|
-
/* No box at all. For a whole body with nothing in it, where a bordered panel
|
|
2249
|
-
would be a box drawn around a void — the floor rule is the only structure,
|
|
2250
|
-
and it is as wide as the artwork rather than as wide as the screen. */
|
|
2251
1590
|
.tamga-art-blank-floor {
|
|
2252
1591
|
height: 1px;
|
|
2253
1592
|
background: var(--color-edge);
|
|
2254
1593
|
}
|
|
2255
1594
|
|
|
2256
|
-
/* The tile: a card you PICK, so it is raised and it presses — a template
|
|
2257
|
-
that cannot be chosen has no business looking like a card. */
|
|
2258
1595
|
.tamga-art-tile {
|
|
2259
1596
|
display: flex;
|
|
2260
1597
|
flex-direction: column;
|
|
@@ -2270,23 +1607,17 @@
|
|
|
2270
1607
|
box-shadow var(--duration-press) var(--ease-standard),
|
|
2271
1608
|
border-color var(--duration-press) var(--ease-standard);
|
|
2272
1609
|
}
|
|
1610
|
+
|
|
2273
1611
|
.tamga-art-tile:hover {
|
|
2274
1612
|
transform: translate(-1px, -1px);
|
|
2275
|
-
box-shadow: 3px 3px 0 var(--color-
|
|
1613
|
+
box-shadow: 3px 3px 0 var(--color-accent-line);
|
|
2276
1614
|
border-color: var(--color-accent-line);
|
|
2277
1615
|
}
|
|
2278
1616
|
.tamga-art-tile:active {
|
|
2279
1617
|
transform: translate(2px, 2px);
|
|
2280
1618
|
box-shadow: 0 0 0 var(--color-edge);
|
|
2281
1619
|
}
|
|
2282
|
-
|
|
2283
|
-
would out-shout a real event; a 3px spine under the art carries the
|
|
2284
|
-
same information and outranks nothing. */
|
|
2285
|
-
/* The five tones are spelled out rather than composed from a custom property:
|
|
2286
|
-
Tailwind only emits an @theme variable that something actually references,
|
|
2287
|
-
and a var() built inside a template literal is invisible to it — the token
|
|
2288
|
-
resolves to nothing at runtime and the rule silently goes grey. Naming them
|
|
2289
|
-
here is what keeps them alive. */
|
|
1620
|
+
|
|
2290
1621
|
.tamga-art-spine {
|
|
2291
1622
|
height: 3px;
|
|
2292
1623
|
background: var(--color-edge);
|
|
@@ -2379,11 +1710,6 @@
|
|
|
2379
1710
|
animation: tamga-pulse var(--duration-beacon) var(--ease-breath) infinite;
|
|
2380
1711
|
}
|
|
2381
1712
|
|
|
2382
|
-
/* Deep breath, chosen over the shallow one. The shallow version was correct in
|
|
2383
|
-
principle and invisible in practice — on a real page you could not tell a
|
|
2384
|
-
loading panel from a settled one at a glance, which is the only job it has.
|
|
2385
|
-
0.78 → 0.06 at 1.1s is far enough and fast enough to register peripherally
|
|
2386
|
-
without ever becoming a shimmer. */
|
|
2387
1713
|
@keyframes tamga-breathe {
|
|
2388
1714
|
0%,
|
|
2389
1715
|
100% {
|
|
@@ -2394,18 +1720,6 @@
|
|
|
2394
1720
|
}
|
|
2395
1721
|
}
|
|
2396
1722
|
|
|
2397
|
-
/* Al breathing. Slow and tiny on purpose — a mascot that moves a lot turns into
|
|
2398
|
-
a distraction on a screen people watch for events. Whole pixels only, or
|
|
2399
|
-
the pixel art lands on a half pixel and blurs on the way past. */
|
|
2400
|
-
/* Al floats; he never pulses — and that distinction is the whole reason a
|
|
2401
|
-
mascot can share a screen with the beacon at all.
|
|
2402
|
-
Law 3 (v2, 13-design-soul) says the beacon is the only thing that pulses.
|
|
2403
|
-
The mascot is exempt because it moves in a different CHANNEL: the beacon
|
|
2404
|
-
changes BRIGHTNESS, Al changes POSITION. The eye reads a brightness change
|
|
2405
|
-
as "look here" and a slow drift as "this thing is alive", so the two do not
|
|
2406
|
-
compete for the same attention.
|
|
2407
|
-
The price of that exemption: this animation must never touch opacity. If it
|
|
2408
|
-
ever does, Al starts competing with the one real signal on the screen. */
|
|
2409
1723
|
@keyframes tamga-float-loop {
|
|
2410
1724
|
0%,
|
|
2411
1725
|
100% {
|
|
@@ -2423,8 +1737,7 @@
|
|
|
2423
1737
|
.tamga-rise, .tamga-live, .tamga-float, .tamga-beacon[data-live="true"] {
|
|
2424
1738
|
animation: none;
|
|
2425
1739
|
}
|
|
2426
|
-
|
|
2427
|
-
parked near the middle of the breath rather than at either end */
|
|
1740
|
+
|
|
2428
1741
|
.tamga-skeleton::after {
|
|
2429
1742
|
animation: none;
|
|
2430
1743
|
opacity: 0.42;
|
|
@@ -2432,19 +1745,18 @@
|
|
|
2432
1745
|
.tamga-toast {
|
|
2433
1746
|
animation: none;
|
|
2434
1747
|
}
|
|
2435
|
-
|
|
2436
|
-
beliriyor. */
|
|
1748
|
+
|
|
2437
1749
|
.tamga-sheet-start,
|
|
2438
1750
|
.tamga-sheet-end {
|
|
2439
1751
|
animation: none;
|
|
2440
1752
|
}
|
|
2441
|
-
|
|
1753
|
+
|
|
2442
1754
|
.tamga-spin-part {
|
|
2443
1755
|
animation: none !important;
|
|
2444
1756
|
opacity: 0.6 !important;
|
|
2445
1757
|
transform: none !important;
|
|
2446
1758
|
}
|
|
2447
|
-
|
|
1759
|
+
|
|
2448
1760
|
.tamga-swap {
|
|
2449
1761
|
display: grid;
|
|
2450
1762
|
place-items: center;
|
|
@@ -2464,19 +1776,7 @@
|
|
|
2464
1776
|
}
|
|
2465
1777
|
|
|
2466
1778
|
@layer components {
|
|
2467
|
-
|
|
2468
|
-
* SAVE BAR — stuck to the bottom of a scrolling surface.
|
|
2469
|
-
*
|
|
2470
|
-
* WHY THE `::after`. `position: sticky; bottom: 0` aligns the bar's bottom
|
|
2471
|
-
* edge with the surface's CONTENT box, but a surface carries its own bottom
|
|
2472
|
-
* padding, and content was flowing THROUGH the bar in that gap. The
|
|
2473
|
-
* extension covers exactly that padding; the ground is the same colour, so
|
|
2474
|
-
* the seam is invisible. The gap is read from `--surface-pad`, which the
|
|
2475
|
-
* consumer sets on the scrolling surface.
|
|
2476
|
-
*
|
|
2477
|
-
* NEGATIVE MARGIN, not a full-bleed trick: the bar spans the surface edge to
|
|
2478
|
-
* edge while its content stays on the same left rule as everything else.
|
|
2479
|
-
* ------------------------------------------------------------------ */
|
|
1779
|
+
|
|
2480
1780
|
.tamga-save-bar {
|
|
2481
1781
|
position: sticky;
|
|
2482
1782
|
bottom: 0;
|