tamga-ui 0.2.0 → 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 +86 -0
- package/dist/components/appearance.d.ts +78 -0
- package/dist/components/appearance.d.ts.map +1 -0
- package/dist/components/appearance.js +73 -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 +22 -2
- package/dist/components/rail-link.d.ts.map +1 -1
- package/dist/components/rail-link.js +12 -9
- package/dist/components/square-picker.d.ts +41 -0
- package/dist/components/square-picker.d.ts.map +1 -0
- package/dist/components/square-picker.js +90 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/kit.css +237 -729
- 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/image.d.ts +46 -0
- package/dist/lib/image.d.ts.map +1 -0
- package/dist/lib/image.js +95 -0
- 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/app-shell.d.ts.map +1 -1
- package/dist/patterns/app-shell.js +2 -12
- package/dist/patterns/appearance-template.d.ts +105 -0
- package/dist/patterns/appearance-template.d.ts.map +1 -0
- package/dist/patterns/appearance-template.js +23 -0
- package/dist/patterns/index.d.ts +1 -0
- package/dist/patterns/index.d.ts.map +1 -1
- package/dist/patterns/index.js +1 -0
- package/dist/patterns/settings-template.d.ts +12 -1
- package/dist/patterns/settings-template.d.ts.map +1 -1
- package/dist/patterns/settings-template.js +2 -2
- 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
194
|
|
|
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
|
-
|
|
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
573
|
|
|
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
|
-
|
|
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;
|
|
@@ -999,7 +631,7 @@
|
|
|
999
631
|
min-width: 28px;
|
|
1000
632
|
height: 28px;
|
|
1001
633
|
padding: 0 6px;
|
|
1002
|
-
border-radius: var(--radius-
|
|
634
|
+
border-radius: var(--radius-sm);
|
|
1003
635
|
color: var(--color-ink-soft);
|
|
1004
636
|
font-size: var(--text-caption);
|
|
1005
637
|
cursor: pointer;
|
|
@@ -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,9 +852,10 @@
|
|
|
1283
852
|
color: var(--color-accent-line);
|
|
1284
853
|
box-shadow: 2px 2px 0 0 var(--color-accent-line);
|
|
1285
854
|
}
|
|
855
|
+
|
|
1286
856
|
.tamga-step-mark[data-state="done"] {
|
|
1287
|
-
border-color: var(--color-accent-
|
|
1288
|
-
background: var(--color-accent
|
|
857
|
+
border-color: var(--color-accent-shadow);
|
|
858
|
+
background: var(--color-accent);
|
|
1289
859
|
color: var(--color-accent-ink);
|
|
1290
860
|
}
|
|
1291
861
|
.tamga-step-line {
|
|
@@ -1296,28 +866,13 @@
|
|
|
1296
866
|
background: var(--color-edge);
|
|
1297
867
|
}
|
|
1298
868
|
.tamga-step-line[data-done="true"] {
|
|
1299
|
-
background: var(--color-accent
|
|
869
|
+
background: var(--color-accent);
|
|
1300
870
|
}
|
|
1301
871
|
|
|
1302
872
|
.tamga-scrim {
|
|
1303
873
|
background: var(--color-scrim);
|
|
1304
874
|
}
|
|
1305
875
|
|
|
1306
|
-
/* ---------- form controls ---------- */
|
|
1307
|
-
/* checkbox and radio carry the same 1px edge and 1px offset as a mini
|
|
1308
|
-
button, so they read as part of the family rather than browser chrome */
|
|
1309
|
-
/*
|
|
1310
|
-
* SEÇENEK İŞARETİ İLK SATIRIN ORTASINA.
|
|
1311
|
-
*
|
|
1312
|
-
* Etiket tek satırken kutuyu dikeyde ortalamak doğru duruyor; altına bir
|
|
1313
|
-
* açıklama satırı eklenince işaret İKİ SATIRIN ortasına kaçıyor ve neyi
|
|
1314
|
-
* işaretlediği belirsizleşiyor. İşaret ilk satıra ait.
|
|
1315
|
-
*
|
|
1316
|
-
* Sayı UYDURULMUYOR, satırdan hesaplanıyor: `1lh` öğenin kendi satır
|
|
1317
|
-
* kutusu, `18px` de işaretin boyu (yukarıdaki kuralın kendisi), ve fark
|
|
1318
|
-
* ikiye bölününce işaret ilk satırın tam ortasına oturuyor. Punto ya da
|
|
1319
|
-
* satır aralığı değişirse hizalama kendiliğinden düzeliyor.
|
|
1320
|
-
*/
|
|
1321
876
|
.tamga-choice-mark {
|
|
1322
877
|
align-self: flex-start;
|
|
1323
878
|
margin-top: calc((1lh - 18px) / 2);
|
|
@@ -1342,9 +897,10 @@
|
|
|
1342
897
|
border-color: var(--color-accent-line);
|
|
1343
898
|
box-shadow: 1px 1px 0 var(--color-accent-line);
|
|
1344
899
|
}
|
|
900
|
+
|
|
1345
901
|
.tamga-check[data-checked="true"] {
|
|
1346
902
|
background: var(--color-accent);
|
|
1347
|
-
border-color: var(--color-accent);
|
|
903
|
+
border-color: var(--color-accent-shadow);
|
|
1348
904
|
box-shadow: 1px 1px 0 var(--color-accent-shadow);
|
|
1349
905
|
}
|
|
1350
906
|
.tamga-radio[data-checked="true"] {
|
|
@@ -1389,23 +945,6 @@
|
|
|
1389
945
|
transform: translateX(16px);
|
|
1390
946
|
}
|
|
1391
947
|
|
|
1392
|
-
|
|
1393
|
-
/* A skeleton breathes; it never shimmers. A sweeping gradient is the
|
|
1394
|
-
default-SaaS tell and this product has no gradients anywhere else, so one
|
|
1395
|
-
here would be the single exception — and it would be the loudest thing on
|
|
1396
|
-
a page whose whole point is that nothing has arrived yet.
|
|
1397
|
-
Two blocks, not one: the ground never animates, only the bar on top of it.
|
|
1398
|
-
That keeps a floor under the shape so it stays a placeholder at every point
|
|
1399
|
-
in the cycle instead of fading toward the page and back. */
|
|
1400
|
-
/* Progress is an instrument scale, not a bar. The ticks let the value be read
|
|
1401
|
-
without reading the number, which is what a gauge is for.
|
|
1402
|
-
Deliberately NOT the segmented strip form: a segmented horizontal strip is a
|
|
1403
|
-
timeline — one mark per bucket, colour as state — and reusing that shape for
|
|
1404
|
-
completion would read as history rather than as progress.
|
|
1405
|
-
Neutral throughout — progress reports completion, never health, so a status
|
|
1406
|
-
colour here would be a false signal.
|
|
1407
|
-
Note it carries a 2px offset, so it paints outside its box: reserve room in
|
|
1408
|
-
the container or the offset lands on whatever sits below. */
|
|
1409
948
|
.tamga-progress {
|
|
1410
949
|
position: relative;
|
|
1411
950
|
height: 16px;
|
|
@@ -1455,9 +994,7 @@
|
|
|
1455
994
|
color: var(--color-ink-soft);
|
|
1456
995
|
cursor: pointer;
|
|
1457
996
|
}
|
|
1458
|
-
|
|
1459
|
-
İki ayrı görünüş vermek, aynı anlamı ("Enter buna basacak") iki dille
|
|
1460
|
-
anlatmak olurdu; kullanıcının ikisini de öğrenmesi gerekirdi. */
|
|
997
|
+
|
|
1461
998
|
.tamga-option:hover,
|
|
1462
999
|
.tamga-option[data-active] {
|
|
1463
1000
|
background: var(--color-hover);
|
|
@@ -1469,9 +1006,6 @@
|
|
|
1469
1006
|
box-shadow: inset 2px 0 0 var(--color-accent-line);
|
|
1470
1007
|
}
|
|
1471
1008
|
|
|
1472
|
-
/* ---------- feedback and structure ---------- */
|
|
1473
|
-
|
|
1474
|
-
/* inline banner — status wash, no fill, a left rule carries the state */
|
|
1475
1009
|
.tamga-alert {
|
|
1476
1010
|
display: flex;
|
|
1477
1011
|
gap: 16px;
|
|
@@ -1482,7 +1016,6 @@
|
|
|
1482
1016
|
background: var(--color-shell);
|
|
1483
1017
|
}
|
|
1484
1018
|
|
|
1485
|
-
/* the live mark — neutral by rule: running is not a deviation */
|
|
1486
1019
|
.tamga-beacon {
|
|
1487
1020
|
display: inline-block;
|
|
1488
1021
|
width: 8px;
|
|
@@ -1494,7 +1027,6 @@
|
|
|
1494
1027
|
animation: tamga-pulse var(--duration-beacon) var(--ease-breath) infinite;
|
|
1495
1028
|
}
|
|
1496
1029
|
|
|
1497
|
-
/* keeps a button's width when its label swaps for a loading label */
|
|
1498
1030
|
.tamga-swap {
|
|
1499
1031
|
display: grid;
|
|
1500
1032
|
place-items: center;
|
|
@@ -1511,7 +1043,6 @@
|
|
|
1511
1043
|
visibility: hidden;
|
|
1512
1044
|
}
|
|
1513
1045
|
|
|
1514
|
-
|
|
1515
1046
|
.tamga-rule-h {
|
|
1516
1047
|
height: 1px;
|
|
1517
1048
|
width: 100%;
|
|
@@ -1523,15 +1054,6 @@
|
|
|
1523
1054
|
background: var(--color-line);
|
|
1524
1055
|
}
|
|
1525
1056
|
|
|
1526
|
-
/* ---------- lists and tables ---------- */
|
|
1527
|
-
/* row height is fixed so a list never breathes with its content */
|
|
1528
|
-
|
|
1529
|
-
/* Slider topuzu.
|
|
1530
|
-
|
|
1531
|
-
`appearance: none` çubuğu bize bırakıyor ama TOPUZU DA SİLİYOR — ve
|
|
1532
|
-
silinen topuz hata vermiyor, sadece kaydırıcı tutulamaz hâle geliyor.
|
|
1533
|
-
WebKit ve Firefox iki ayrı sözde-eleman kullanıyor; ikisi de yazılmak
|
|
1534
|
-
zorunda, biri unutulursa o tarayıcıda topuz yok. */
|
|
1535
1057
|
.tamga-slider::-webkit-slider-thumb {
|
|
1536
1058
|
appearance: none;
|
|
1537
1059
|
width: 16px;
|
|
@@ -1556,16 +1078,6 @@
|
|
|
1556
1078
|
outline-offset: 4px;
|
|
1557
1079
|
}
|
|
1558
1080
|
|
|
1559
|
-
/* THE GUTTER IS THE ROW'S, not the caller's.
|
|
1560
|
-
*
|
|
1561
|
-
* This class carried no horizontal padding, and every single caller added
|
|
1562
|
-
* `tamga-gutter` by hand: the settings sub-nav, both skeletons, the docs
|
|
1563
|
-
* example. Five out of five is not a convention, it is a missing rule, and
|
|
1564
|
-
* the sixth caller (a blocks recipe) forgot it and rendered edge to edge.
|
|
1565
|
-
*
|
|
1566
|
-
* `.tamga-table` was already doing this correctly through
|
|
1567
|
-
* `td:first-child { padding-left: var(--gutter) }`. A row and a cell sit on
|
|
1568
|
-
* the same left rule; one of them should not need reminding. */
|
|
1569
1081
|
.tamga-list-row {
|
|
1570
1082
|
display: flex;
|
|
1571
1083
|
align-items: center;
|
|
@@ -1596,29 +1108,7 @@
|
|
|
1596
1108
|
white-space: nowrap;
|
|
1597
1109
|
text-overflow: ellipsis;
|
|
1598
1110
|
}
|
|
1599
|
-
|
|
1600
|
-
The truncation trio above (overflow:hidden + nowrap + ellipsis) is right for text and fatal for
|
|
1601
|
-
a row's action menu: the panel is absolutely positioned inside the cell, so `overflow:hidden`
|
|
1602
|
-
cuts it off at the cell's edge. Measured 2026-08-20 — the menu rendered, looked fine, and
|
|
1603
|
-
swallowed every click, because `elementFromPoint` returned the td.
|
|
1604
|
-
Actions never need truncating, so the cell opts out of all three rather than the table losing
|
|
1605
|
-
ellipsis everywhere.
|
|
1606
|
-
|
|
1607
|
-
AND IT REALLY IS ALL THREE. The comment said three, the rule reset two: `white-space: nowrap`
|
|
1608
|
-
stayed, and it is inherited, so every panel opened inside this cell inherited it too. A popover
|
|
1609
|
-
listing an order's products rendered each line on one unbreakable line and spilled past its own
|
|
1610
|
-
edge. The overlay looked broken; the cause was a table rule three levels up. Found 2026-09-09
|
|
1611
|
-
in a consumer panel.
|
|
1612
|
-
|
|
1613
|
-
KIRPMA VE HİZA AYRI İKİ ŞEY. Bu kaçış uzun süre tek parçaydı ve sağa
|
|
1614
|
-
yaslamayı da beraberinde getiriyordu, yani sola yaslı bir hücrede bir ipucu
|
|
1615
|
-
ya da açılır panel barındırmak isteyen, hizasını da feda etmek zorunda
|
|
1616
|
-
kalıyordu. Yakalandığı yer: bir tüketici listesinde durum rozetinin ipucu
|
|
1617
|
-
hücre kenarında kesiliyordu, ve tek çare hücreyi sağa yaslamaktı.
|
|
1618
|
-
|
|
1619
|
-
SEÇİCİ `.tamga-table td` KADAR SPESİFİK OLMAK ZORUNDA: düz
|
|
1620
|
-
`.tamga-cell-open` (0,1,0) yazılırsa kırpma kuralı `.tamga-table td`
|
|
1621
|
-
(0,1,1) onu yener ve sınıf hiçbir şey yapmaz. */
|
|
1111
|
+
|
|
1622
1112
|
.tamga-table td.tamga-cell-open,
|
|
1623
1113
|
.tamga-table th.tamga-cell-open {
|
|
1624
1114
|
overflow: visible;
|
|
@@ -1659,13 +1149,7 @@
|
|
|
1659
1149
|
.tamga-table tbody tr[data-selected="true"] td:first-child {
|
|
1660
1150
|
box-shadow: inset 2px 0 0 var(--color-accent-line);
|
|
1661
1151
|
}
|
|
1662
|
-
|
|
1663
|
-
`SettingsTemplate` menüsündeki açık bölümü `data-active` ile işaretliyor
|
|
1664
|
-
(bir GEZİNME satırı: hangi sayfadasın), liste satırları ise `data-selected`
|
|
1665
|
-
ile (bir SEÇİM: hangi kayıtları işaretledin). İkisi farklı anlam ama aynı
|
|
1666
|
-
görünüm, ve kural yalnız ikincisi için yazılmıştı: ayarlar menüsünde
|
|
1667
|
-
hangi bölümde olduğun hiç görünmüyordu. Hiçbir şey patlamadı, çünkü
|
|
1668
|
-
tarayıcı bilmediği bir nitelik seçicisini sessizce atlıyor. */
|
|
1152
|
+
|
|
1669
1153
|
.tamga-list-row[data-active="true"],
|
|
1670
1154
|
.tamga-list-row[data-selected="true"] {
|
|
1671
1155
|
background: var(--color-accent-bg);
|
|
@@ -1676,28 +1160,13 @@
|
|
|
1676
1160
|
color: var(--color-accent-line);
|
|
1677
1161
|
font-weight: 500;
|
|
1678
1162
|
text-underline-offset: 3px;
|
|
1679
|
-
|
|
1680
|
-
ya da link gibi görünen bir `<button>` almaz ve imleç `auto` kalır. Sınıf
|
|
1681
|
-
kendi imlecini söylemeli. */
|
|
1163
|
+
|
|
1682
1164
|
cursor: pointer;
|
|
1683
1165
|
}
|
|
1684
1166
|
.tamga-link:hover {
|
|
1685
1167
|
text-decoration: underline;
|
|
1686
1168
|
}
|
|
1687
1169
|
|
|
1688
|
-
/* ------------------------------------------------------------------ *
|
|
1689
|
-
* KPI KAROSU: tek bir sayı, büyük.
|
|
1690
|
-
*
|
|
1691
|
-
* REFERANS NOKTASI YUMUŞAK KARTTI (daire ikon rozeti, bulanık gölge, kenar
|
|
1692
|
-
* yok); buradaki karşılığı 1. yasa: 1px kenar, BULANIKSIZ kaymış gölge, ve
|
|
1693
|
-
* daire yerine KARE karo. Kit hiçbir yerde daire kullanmıyor (avatar ve
|
|
1694
|
-
* nokta dışında) ve tek bir daire, kartı ödünç alınmış gösteriyor.
|
|
1695
|
-
*
|
|
1696
|
-
* İKON KARONUN ZEMİNİ `--color-hover`, marka rengi DEĞİL. Bir panoda dört
|
|
1697
|
-
* karo yan yana duruyor; dördünün de ikonu marka renginde parlarsa hiçbiri
|
|
1698
|
-
* öne çıkmıyor ve göz asıl bakması gereken sayıyı en son buluyor. Renk
|
|
1699
|
-
* kartın kendi verisinin (`accent` şeridi) ve dikkat isteyen sayının hakkı.
|
|
1700
|
-
* ------------------------------------------------------------------ */
|
|
1701
1170
|
.tamga-kpi {
|
|
1702
1171
|
position: relative;
|
|
1703
1172
|
display: flex;
|
|
@@ -1726,18 +1195,6 @@
|
|
|
1726
1195
|
color: var(--color-ink-soft);
|
|
1727
1196
|
}
|
|
1728
1197
|
|
|
1729
|
-
/*
|
|
1730
|
-
* FİZİK YALNIZ TIKLANABİLİR KARODA.
|
|
1731
|
-
*
|
|
1732
|
-
* `.tamga-kpi-live` bir stil değil bir SÖZ: bu karo tıklanıyor. Okunan bir
|
|
1733
|
-
* karo hover'da yükselirse tıklanabilir göründüğü hâlde hiçbir şey yapmıyor,
|
|
1734
|
-
* ve kullanıcı bir kez tıklayıp bir daha denemiyor.
|
|
1735
|
-
*
|
|
1736
|
-
* Kaymalar 1. yasanın kendisi: hover'da -1/-1 ve 3px gölge, basınca +2/+2 ve
|
|
1737
|
-
* gölge yok. `--offset-room` tuzağı burada da geçerli — bu karolar bir
|
|
1738
|
-
* ızgarada duruyor ve ızgaranın kendisi kırpmıyor, ama kaydırılan bir kabın
|
|
1739
|
-
* içine konulursa `.tamga-rail-scroll` gibi bir dolgu gerekir.
|
|
1740
|
-
*/
|
|
1741
1198
|
.tamga-kpi-live {
|
|
1742
1199
|
cursor: pointer;
|
|
1743
1200
|
transition:
|
|
@@ -1745,11 +1202,7 @@
|
|
|
1745
1202
|
box-shadow var(--duration-press, 120ms) var(--ease-press, ease-out),
|
|
1746
1203
|
background var(--duration-press, 120ms);
|
|
1747
1204
|
}
|
|
1748
|
-
|
|
1749
|
-
1. yasasında hover üç şey yapar: zemin bir tık koyulaşır, kontrol
|
|
1750
|
-
-1/-1 yükselir, gölge 3px'e çıkar. Kenarın renklenmesi bu dilde yok
|
|
1751
|
-
(`tamga-btn`de de, `tamga-icon-btn`de de yok) ve tek başına bir kartta
|
|
1752
|
-
yapıldığında kart ötekilerden farklı bir şey konuşuyor. */
|
|
1205
|
+
|
|
1753
1206
|
.tamga-kpi-live:hover {
|
|
1754
1207
|
background: var(--color-hover);
|
|
1755
1208
|
transform: translate(-1px, -1px);
|
|
@@ -1760,9 +1213,6 @@
|
|
|
1760
1213
|
box-shadow: 0 0 0 var(--color-edge);
|
|
1761
1214
|
}
|
|
1762
1215
|
|
|
1763
|
-
/* SEÇİLİ HÂL NÖTR, VURGU RENGİ DEĞİL. Vurgu rengi bir EYLEMİN rengi (kaydet,
|
|
1764
|
-
sil); bir filtrenin açık olması bir eylem değil bir DURUM. Vurguya
|
|
1765
|
-
boyandığında listede bir sorun varmış gibi okunuyordu. */
|
|
1766
1216
|
.tamga-kpi-live[data-pressed] {
|
|
1767
1217
|
border-color: var(--color-ink);
|
|
1768
1218
|
background: var(--color-hover);
|
|
@@ -1775,18 +1225,6 @@
|
|
|
1775
1225
|
box-shadow: 0 0 0 var(--color-ink);
|
|
1776
1226
|
}
|
|
1777
1227
|
|
|
1778
|
-
/*
|
|
1779
|
-
* KAROLARIN IZGARASI.
|
|
1780
|
-
*
|
|
1781
|
-
* SÜTUN SAYISI KARO SAYISINDAN geliyor (`--tamga-kpi-cols`), ekrandan
|
|
1782
|
-
* verilmiyor. Elle verilen bir sütun sayısı yeni bir karo eklendiğinde
|
|
1783
|
-
* yalnız o ekranda güncelleniyor, ve tek başına kalan bir karo bütün satırı
|
|
1784
|
-
* kaplayıp panoyu dengesiz gösteriyor.
|
|
1785
|
-
*
|
|
1786
|
-
* Dar ekranda iki sütun, geniş ekranda karo sayısı kadar: bir karo 40px
|
|
1787
|
-
* ikon ve display boyunda bir sayı taşıyor, üçten dar bir sütunda sayı
|
|
1788
|
-
* sarıyor.
|
|
1789
|
-
*/
|
|
1790
1228
|
.tamga-kpi-grid {
|
|
1791
1229
|
display: grid;
|
|
1792
1230
|
gap: 16px;
|
|
@@ -1803,8 +1241,6 @@
|
|
|
1803
1241
|
}
|
|
1804
1242
|
}
|
|
1805
1243
|
|
|
1806
|
-
/* Çekmece kenardan kayarak girer; yön `side` ile aynı olmak zorunda, yoksa
|
|
1807
|
-
kapatma hareketi ters öğretilir. Gerekçe: /docs/sheet */
|
|
1808
1244
|
.tamga-sheet-start {
|
|
1809
1245
|
animation: tamga-sheet-start var(--duration-base) var(--ease-standard);
|
|
1810
1246
|
}
|
|
@@ -1812,14 +1248,179 @@
|
|
|
1812
1248
|
animation: tamga-sheet-end var(--duration-base) var(--ease-standard);
|
|
1813
1249
|
}
|
|
1814
1250
|
|
|
1251
|
+
.tamga-swatch {
|
|
1252
|
+
display: inline-flex;
|
|
1253
|
+
width: var(--control);
|
|
1254
|
+
height: var(--control);
|
|
1255
|
+
align-items: center;
|
|
1256
|
+
justify-content: center;
|
|
1257
|
+
border: 1px solid var(--color-edge);
|
|
1258
|
+
border-radius: var(--radius-ctl);
|
|
1259
|
+
background: var(--color-shell);
|
|
1260
|
+
cursor: pointer;
|
|
1261
|
+
transition:
|
|
1262
|
+
transform var(--duration-press) var(--ease-standard),
|
|
1263
|
+
box-shadow var(--duration-press) var(--ease-standard);
|
|
1264
|
+
}
|
|
1265
|
+
.tamga-swatch > span {
|
|
1266
|
+
width: 20px;
|
|
1267
|
+
height: 20px;
|
|
1268
|
+
border-radius: var(--radius-mark);
|
|
1269
|
+
}
|
|
1270
|
+
.tamga-swatch:hover {
|
|
1271
|
+
transform: translate(-1px, -1px);
|
|
1272
|
+
box-shadow: 3px 3px 0 var(--color-edge);
|
|
1273
|
+
}
|
|
1274
|
+
.tamga-swatch[data-selected="true"] {
|
|
1275
|
+
border-color: var(--color-accent-line);
|
|
1276
|
+
box-shadow: 2px 2px 0 var(--color-accent-line);
|
|
1277
|
+
}
|
|
1278
|
+
.tamga-swatch:active {
|
|
1279
|
+
transform: translate(2px, 2px);
|
|
1280
|
+
box-shadow: 0 0 0 var(--color-edge);
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
.tamga-color-input {
|
|
1284
|
+
width: 36px;
|
|
1285
|
+
height: 36px;
|
|
1286
|
+
padding: 2px;
|
|
1287
|
+
border: 1px solid var(--color-edge);
|
|
1288
|
+
border-radius: var(--radius-ctl);
|
|
1289
|
+
background: var(--color-shell);
|
|
1290
|
+
cursor: pointer;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
.tamga-theme-card {
|
|
1294
|
+
display: flex;
|
|
1295
|
+
flex-direction: column;
|
|
1296
|
+
gap: 8px;
|
|
1297
|
+
padding: 0;
|
|
1298
|
+
border: 0;
|
|
1299
|
+
background: none;
|
|
1300
|
+
cursor: pointer;
|
|
1301
|
+
text-align: center;
|
|
1302
|
+
}
|
|
1303
|
+
.tamga-theme-box {
|
|
1304
|
+
position: relative;
|
|
1305
|
+
display: flex;
|
|
1306
|
+
overflow: hidden;
|
|
1307
|
+
width: 112px;
|
|
1308
|
+
height: 72px;
|
|
1309
|
+
border: 1px solid var(--color-edge);
|
|
1310
|
+
border-radius: var(--radius-card);
|
|
1311
|
+
box-shadow: 2px 2px 0 var(--color-edge);
|
|
1312
|
+
transition:
|
|
1313
|
+
transform var(--duration-press) var(--ease-standard),
|
|
1314
|
+
box-shadow var(--duration-press) var(--ease-standard),
|
|
1315
|
+
border-color var(--duration-press) var(--ease-standard);
|
|
1316
|
+
}
|
|
1317
|
+
.tamga-theme-card:hover .tamga-theme-box {
|
|
1318
|
+
transform: translate(-1px, -1px);
|
|
1319
|
+
box-shadow: 3px 3px 0 var(--color-edge);
|
|
1320
|
+
}
|
|
1321
|
+
.tamga-theme-card:active .tamga-theme-box {
|
|
1322
|
+
transform: translate(2px, 2px);
|
|
1323
|
+
box-shadow: 0 0 0 var(--color-edge);
|
|
1324
|
+
}
|
|
1325
|
+
.tamga-theme-card[data-selected="true"] .tamga-theme-box {
|
|
1326
|
+
border-color: var(--color-accent-line);
|
|
1327
|
+
box-shadow: 2px 2px 0 var(--color-accent-line);
|
|
1328
|
+
}
|
|
1329
|
+
.tamga-theme-name {
|
|
1330
|
+
font-size: var(--text-small);
|
|
1331
|
+
color: var(--color-ink-faint);
|
|
1332
|
+
}
|
|
1333
|
+
.tamga-theme-card[data-selected="true"] .tamga-theme-name {
|
|
1334
|
+
font-weight: 500;
|
|
1335
|
+
color: var(--color-ink);
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
.tamga-theme-half {
|
|
1339
|
+
display: flex;
|
|
1340
|
+
min-width: 0;
|
|
1341
|
+
flex: 1;
|
|
1342
|
+
gap: 4px;
|
|
1343
|
+
padding: 6px;
|
|
1344
|
+
}
|
|
1345
|
+
.tamga-theme-half[data-theme="light"] { background: #f4f2ee; }
|
|
1346
|
+
.tamga-theme-half[data-theme="dark"] { background: #16161a; }
|
|
1347
|
+
|
|
1348
|
+
.tamga-theme-rail {
|
|
1349
|
+
display: flex;
|
|
1350
|
+
width: 12px;
|
|
1351
|
+
flex-shrink: 0;
|
|
1352
|
+
flex-direction: column;
|
|
1353
|
+
gap: 3px;
|
|
1354
|
+
border-radius: 3px;
|
|
1355
|
+
padding: 3px;
|
|
1356
|
+
}
|
|
1357
|
+
.tamga-theme-half[data-theme="light"] .tamga-theme-rail { background: #fcfcfc; }
|
|
1358
|
+
.tamga-theme-half[data-theme="dark"] .tamga-theme-rail { background: #232327; }
|
|
1359
|
+
|
|
1360
|
+
.tamga-theme-body {
|
|
1361
|
+
display: flex;
|
|
1362
|
+
min-width: 0;
|
|
1363
|
+
flex: 1;
|
|
1364
|
+
flex-direction: column;
|
|
1365
|
+
gap: 3px;
|
|
1366
|
+
border-radius: 3px;
|
|
1367
|
+
padding: 4px;
|
|
1368
|
+
}
|
|
1369
|
+
.tamga-theme-half[data-theme="light"] .tamga-theme-body { background: #fcfcfc; }
|
|
1370
|
+
.tamga-theme-half[data-theme="dark"] .tamga-theme-body { background: #232327; }
|
|
1371
|
+
|
|
1372
|
+
.tamga-theme-line {
|
|
1373
|
+
height: 3px;
|
|
1374
|
+
border-radius: 2px;
|
|
1375
|
+
}
|
|
1376
|
+
.tamga-theme-half[data-theme="light"] .tamga-theme-line { background: #d8d4cf; }
|
|
1377
|
+
.tamga-theme-half[data-theme="dark"] .tamga-theme-line { background: #3a3a42; }
|
|
1378
|
+
|
|
1379
|
+
.tamga-theme-half .tamga-theme-line[data-accent="true"] {
|
|
1380
|
+
background: var(--color-accent);
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
.tamga-theme-dot {
|
|
1384
|
+
height: 5px;
|
|
1385
|
+
width: 5px;
|
|
1386
|
+
border-radius: 2px;
|
|
1387
|
+
}
|
|
1388
|
+
.tamga-theme-half[data-theme="light"] .tamga-theme-dot { background: #d8d4cf; }
|
|
1389
|
+
.tamga-theme-half[data-theme="dark"] .tamga-theme-dot { background: #3a3a42; }
|
|
1390
|
+
.tamga-theme-half .tamga-theme-dot[data-accent="true"] {
|
|
1391
|
+
background: var(--color-accent);
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
.tamga-image-field {
|
|
1395
|
+
display: flex;
|
|
1396
|
+
align-items: center;
|
|
1397
|
+
justify-content: center;
|
|
1398
|
+
height: 72px;
|
|
1399
|
+
min-width: 96px;
|
|
1400
|
+
padding: 10px 14px;
|
|
1401
|
+
border: 1px solid var(--color-edge);
|
|
1402
|
+
border-radius: var(--radius-card);
|
|
1403
|
+
background: var(--color-shell);
|
|
1404
|
+
box-shadow: 2px 2px 0 var(--color-edge);
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
.tamga-image-field[data-empty] {
|
|
1408
|
+
border-style: dashed;
|
|
1409
|
+
box-shadow: none;
|
|
1410
|
+
color: var(--color-ink-faint);
|
|
1411
|
+
font-size: var(--text-small);
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
.tamga-settings-panel-accent {
|
|
1415
|
+
border-left: 4px solid var(--color-accent);
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1815
1418
|
.tamga-label {
|
|
1816
1419
|
font-size: var(--text-caption);
|
|
1817
1420
|
font-weight: 500;
|
|
1818
1421
|
color: var(--color-ink-faint);
|
|
1819
1422
|
}
|
|
1820
1423
|
|
|
1821
|
-
/* an identifier-shaped micro-label above a title: mono, wide, quiet. It says
|
|
1822
|
-
what KIND of thing this is before the title says which one. */
|
|
1823
1424
|
.tamga-kicker {
|
|
1824
1425
|
font-family: var(--font-mono);
|
|
1825
1426
|
font-size: var(--text-micro);
|
|
@@ -1829,25 +1430,12 @@
|
|
|
1829
1430
|
color: var(--color-ink-faint);
|
|
1830
1431
|
}
|
|
1831
1432
|
|
|
1832
|
-
/* ---------- the mascot's furniture ---------- */
|
|
1833
|
-
/* The mascot lives INSIDE the instrument, never floating on top of it.
|
|
1834
|
-
Everything here exists to say that in the language the rest of the kit
|
|
1835
|
-
already speaks: a seated recess, ruled paper, a hard floor, a hard
|
|
1836
|
-
shadow. Drop the art on a plain coloured plane and you get somebody
|
|
1837
|
-
else's product with our artwork pasted into it. */
|
|
1838
|
-
|
|
1839
|
-
/* The well: a recess carved into the panel. SEATED physics — sunk ground,
|
|
1840
|
-
no offset, never lifts. The ground defaults to --color-sunk; a call site
|
|
1841
|
-
may pass --art-ground to tint it. */
|
|
1842
1433
|
.tamga-art-well {
|
|
1843
1434
|
position: relative;
|
|
1844
1435
|
background: var(--art-ground, var(--color-sunk));
|
|
1845
1436
|
overflow: hidden;
|
|
1846
1437
|
}
|
|
1847
|
-
|
|
1848
|
-
the figure stands on is squared paper — the same 8px module the layout uses.
|
|
1849
|
-
It also does real work: the grid gives the eye a scale, which is what
|
|
1850
|
-
stops a large drawing from reading as a decorative blob. */
|
|
1438
|
+
|
|
1851
1439
|
.tamga-art-well::before {
|
|
1852
1440
|
content: "";
|
|
1853
1441
|
position: absolute;
|
|
@@ -1858,28 +1446,20 @@
|
|
|
1858
1446
|
opacity: 0.7;
|
|
1859
1447
|
pointer-events: none;
|
|
1860
1448
|
}
|
|
1861
|
-
|
|
1449
|
+
|
|
1862
1450
|
.tamga-art-well > * {
|
|
1863
1451
|
position: relative;
|
|
1864
1452
|
}
|
|
1865
1453
|
|
|
1866
|
-
/* The floor. A character standing on a hard rule reads as standing; the same
|
|
1867
|
-
character with nothing under it reads as falling. One line fixes it. */
|
|
1868
1454
|
.tamga-art-floor {
|
|
1869
1455
|
border-bottom: 1px solid var(--color-edge);
|
|
1870
1456
|
}
|
|
1871
1457
|
|
|
1872
|
-
/* The cast shadow: the elevation formula applied to a character. Our light
|
|
1873
|
-
has always come from the upper left — every offset in the kit lands down
|
|
1874
|
-
and to the right — so the figure's shadow does too. A BAR rather than a copy of
|
|
1875
|
-
his silhouette, deliberately: a body-shaped offset would read as the
|
|
1876
|
-
pressable-object signature, and artwork is not pressable (Yasa: depth means
|
|
1877
|
-
pressable). A bar reads as ground, not as affordance. */
|
|
1878
1458
|
.tamga-art-fig {
|
|
1879
1459
|
position: relative;
|
|
1880
1460
|
display: inline-block;
|
|
1881
1461
|
}
|
|
1882
|
-
|
|
1462
|
+
|
|
1883
1463
|
.tamga-art-fig[data-ground="true"]::after {
|
|
1884
1464
|
content: "";
|
|
1885
1465
|
position: absolute;
|
|
@@ -1891,11 +1471,6 @@
|
|
|
1891
1471
|
pointer-events: none;
|
|
1892
1472
|
}
|
|
1893
1473
|
|
|
1894
|
-
/* The portrait: the figure framed in a window, for use inside a row.
|
|
1895
|
-
72px, not 46px. Every drawing is a SCENE — a figure at a desk, a figure in a
|
|
1896
|
-
boat — and a scene under about 50px is a smudge: the frame reads, the
|
|
1897
|
-
character does not, so the whole thing becomes decoration that costs a row.
|
|
1898
|
-
If it cannot be seen it should not be there. */
|
|
1899
1474
|
.tamga-art-port {
|
|
1900
1475
|
display: flex;
|
|
1901
1476
|
align-items: flex-end;
|
|
@@ -1908,12 +1483,6 @@
|
|
|
1908
1483
|
border-radius: var(--radius-sm);
|
|
1909
1484
|
}
|
|
1910
1485
|
|
|
1911
|
-
/* The base plate: what happens next, as an instrument's legend.
|
|
1912
|
-
A whole-surface empty state that is one short paragraph and two buttons
|
|
1913
|
-
leaves the reader with nothing to do but read the buttons. The steps are
|
|
1914
|
-
the actual answer to "what IS this screen for" — and they are what earns
|
|
1915
|
-
the full width, instead of stretching two sentences across it.
|
|
1916
|
-
Seated: sunk ground, no offset, so it never competes with the action. */
|
|
1917
1486
|
.tamga-art-steps {
|
|
1918
1487
|
display: grid;
|
|
1919
1488
|
border-top: 1px solid var(--color-edge);
|
|
@@ -1942,7 +1511,7 @@
|
|
|
1942
1511
|
border-left: 0;
|
|
1943
1512
|
}
|
|
1944
1513
|
}
|
|
1945
|
-
|
|
1514
|
+
|
|
1946
1515
|
.tamga-art-step-n {
|
|
1947
1516
|
flex-shrink: 0;
|
|
1948
1517
|
font-family: var(--font-mono);
|
|
@@ -1951,9 +1520,6 @@
|
|
|
1951
1520
|
color: var(--color-accent-line);
|
|
1952
1521
|
}
|
|
1953
1522
|
|
|
1954
|
-
/* The stage: the empty state is ONE object made of two materials — a seated
|
|
1955
|
-
well on the left, the raised face on the right, divided by a real edge.
|
|
1956
|
-
Both physics visible at once, which is the whole idea of the kit. */
|
|
1957
1523
|
.tamga-art-stage {
|
|
1958
1524
|
display: flex;
|
|
1959
1525
|
align-items: flex-end;
|
|
@@ -1964,9 +1530,6 @@
|
|
|
1964
1530
|
border-right: 1px solid var(--color-edge);
|
|
1965
1531
|
}
|
|
1966
1532
|
|
|
1967
|
-
/* A full-width shallow band of ruled paper with a floor under it — the
|
|
1968
|
-
mascot's stage when the composition runs on ONE vertical axis rather than
|
|
1969
|
-
splitting left and right. */
|
|
1970
1533
|
.tamga-art-band {
|
|
1971
1534
|
display: flex;
|
|
1972
1535
|
align-items: flex-end;
|
|
@@ -1976,21 +1539,11 @@
|
|
|
1976
1539
|
border-bottom: 1px solid var(--color-edge);
|
|
1977
1540
|
}
|
|
1978
1541
|
|
|
1979
|
-
/* The ticket's divider. It was drawn as a PERFORATION — a dashed rule meaning
|
|
1980
|
-
"tear here" — and v5 proved that wrong on contact: dashed already means
|
|
1981
|
-
"not real content yet" (the logo bounding box,
|
|
1982
|
-
the logo bounding box). A second meaning for the same mark makes a finished
|
|
1983
|
-
empty state read as a placeholder, which is the opposite of what it says.
|
|
1984
|
-
Solid, in the edge colour, like every other divider. Changed here too so
|
|
1985
|
-
the two do not drift — a kit whose copy disagrees with it is not a kit. */
|
|
1986
1542
|
.tamga-art-divider {
|
|
1987
1543
|
height: 0;
|
|
1988
1544
|
border-top: 1px solid var(--color-edge);
|
|
1989
1545
|
}
|
|
1990
1546
|
|
|
1991
|
-
/* A way in, offered as a row rather than a button. An empty screen with two
|
|
1992
|
-
buttons asks a yes/no question; a list of routes answers "what can I even
|
|
1993
|
-
do here", which is the actual question somebody arriving has. */
|
|
1994
1547
|
.tamga-art-route {
|
|
1995
1548
|
display: flex;
|
|
1996
1549
|
width: 100%;
|
|
@@ -2018,9 +1571,6 @@
|
|
|
2018
1571
|
box-shadow: 0 0 0 var(--color-edge);
|
|
2019
1572
|
}
|
|
2020
1573
|
|
|
2021
|
-
/* A logo tile. The mascot's portrait window is 72px because a SCENE needs the room; a service
|
|
2022
|
-
mark is a single glyph and reads at 48. Same frame, different job — sharing the portrait class
|
|
2023
|
-
made every integration card look like it was missing something. */
|
|
2024
1574
|
.tamga-logo-tile {
|
|
2025
1575
|
display: flex;
|
|
2026
1576
|
align-items: center;
|
|
@@ -2037,16 +1587,11 @@
|
|
|
2037
1587
|
height: 40px;
|
|
2038
1588
|
}
|
|
2039
1589
|
|
|
2040
|
-
/* No box at all. For a whole body with nothing in it, where a bordered panel
|
|
2041
|
-
would be a box drawn around a void — the floor rule is the only structure,
|
|
2042
|
-
and it is as wide as the artwork rather than as wide as the screen. */
|
|
2043
1590
|
.tamga-art-blank-floor {
|
|
2044
1591
|
height: 1px;
|
|
2045
1592
|
background: var(--color-edge);
|
|
2046
1593
|
}
|
|
2047
1594
|
|
|
2048
|
-
/* The tile: a card you PICK, so it is raised and it presses — a template
|
|
2049
|
-
that cannot be chosen has no business looking like a card. */
|
|
2050
1595
|
.tamga-art-tile {
|
|
2051
1596
|
display: flex;
|
|
2052
1597
|
flex-direction: column;
|
|
@@ -2062,23 +1607,17 @@
|
|
|
2062
1607
|
box-shadow var(--duration-press) var(--ease-standard),
|
|
2063
1608
|
border-color var(--duration-press) var(--ease-standard);
|
|
2064
1609
|
}
|
|
1610
|
+
|
|
2065
1611
|
.tamga-art-tile:hover {
|
|
2066
1612
|
transform: translate(-1px, -1px);
|
|
2067
|
-
box-shadow: 3px 3px 0 var(--color-
|
|
1613
|
+
box-shadow: 3px 3px 0 var(--color-accent-line);
|
|
2068
1614
|
border-color: var(--color-accent-line);
|
|
2069
1615
|
}
|
|
2070
1616
|
.tamga-art-tile:active {
|
|
2071
1617
|
transform: translate(2px, 2px);
|
|
2072
1618
|
box-shadow: 0 0 0 var(--color-edge);
|
|
2073
1619
|
}
|
|
2074
|
-
|
|
2075
|
-
would out-shout a real event; a 3px spine under the art carries the
|
|
2076
|
-
same information and outranks nothing. */
|
|
2077
|
-
/* The five tones are spelled out rather than composed from a custom property:
|
|
2078
|
-
Tailwind only emits an @theme variable that something actually references,
|
|
2079
|
-
and a var() built inside a template literal is invisible to it — the token
|
|
2080
|
-
resolves to nothing at runtime and the rule silently goes grey. Naming them
|
|
2081
|
-
here is what keeps them alive. */
|
|
1620
|
+
|
|
2082
1621
|
.tamga-art-spine {
|
|
2083
1622
|
height: 3px;
|
|
2084
1623
|
background: var(--color-edge);
|
|
@@ -2171,11 +1710,6 @@
|
|
|
2171
1710
|
animation: tamga-pulse var(--duration-beacon) var(--ease-breath) infinite;
|
|
2172
1711
|
}
|
|
2173
1712
|
|
|
2174
|
-
/* Deep breath, chosen over the shallow one. The shallow version was correct in
|
|
2175
|
-
principle and invisible in practice — on a real page you could not tell a
|
|
2176
|
-
loading panel from a settled one at a glance, which is the only job it has.
|
|
2177
|
-
0.78 → 0.06 at 1.1s is far enough and fast enough to register peripherally
|
|
2178
|
-
without ever becoming a shimmer. */
|
|
2179
1713
|
@keyframes tamga-breathe {
|
|
2180
1714
|
0%,
|
|
2181
1715
|
100% {
|
|
@@ -2186,18 +1720,6 @@
|
|
|
2186
1720
|
}
|
|
2187
1721
|
}
|
|
2188
1722
|
|
|
2189
|
-
/* Al breathing. Slow and tiny on purpose — a mascot that moves a lot turns into
|
|
2190
|
-
a distraction on a screen people watch for events. Whole pixels only, or
|
|
2191
|
-
the pixel art lands on a half pixel and blurs on the way past. */
|
|
2192
|
-
/* Al floats; he never pulses — and that distinction is the whole reason a
|
|
2193
|
-
mascot can share a screen with the beacon at all.
|
|
2194
|
-
Law 3 (v2, 13-design-soul) says the beacon is the only thing that pulses.
|
|
2195
|
-
The mascot is exempt because it moves in a different CHANNEL: the beacon
|
|
2196
|
-
changes BRIGHTNESS, Al changes POSITION. The eye reads a brightness change
|
|
2197
|
-
as "look here" and a slow drift as "this thing is alive", so the two do not
|
|
2198
|
-
compete for the same attention.
|
|
2199
|
-
The price of that exemption: this animation must never touch opacity. If it
|
|
2200
|
-
ever does, Al starts competing with the one real signal on the screen. */
|
|
2201
1723
|
@keyframes tamga-float-loop {
|
|
2202
1724
|
0%,
|
|
2203
1725
|
100% {
|
|
@@ -2215,8 +1737,7 @@
|
|
|
2215
1737
|
.tamga-rise, .tamga-live, .tamga-float, .tamga-beacon[data-live="true"] {
|
|
2216
1738
|
animation: none;
|
|
2217
1739
|
}
|
|
2218
|
-
|
|
2219
|
-
parked near the middle of the breath rather than at either end */
|
|
1740
|
+
|
|
2220
1741
|
.tamga-skeleton::after {
|
|
2221
1742
|
animation: none;
|
|
2222
1743
|
opacity: 0.42;
|
|
@@ -2224,19 +1745,18 @@
|
|
|
2224
1745
|
.tamga-toast {
|
|
2225
1746
|
animation: none;
|
|
2226
1747
|
}
|
|
2227
|
-
|
|
2228
|
-
beliriyor. */
|
|
1748
|
+
|
|
2229
1749
|
.tamga-sheet-start,
|
|
2230
1750
|
.tamga-sheet-end {
|
|
2231
1751
|
animation: none;
|
|
2232
1752
|
}
|
|
2233
|
-
|
|
1753
|
+
|
|
2234
1754
|
.tamga-spin-part {
|
|
2235
1755
|
animation: none !important;
|
|
2236
1756
|
opacity: 0.6 !important;
|
|
2237
1757
|
transform: none !important;
|
|
2238
1758
|
}
|
|
2239
|
-
|
|
1759
|
+
|
|
2240
1760
|
.tamga-swap {
|
|
2241
1761
|
display: grid;
|
|
2242
1762
|
place-items: center;
|
|
@@ -2256,19 +1776,7 @@
|
|
|
2256
1776
|
}
|
|
2257
1777
|
|
|
2258
1778
|
@layer components {
|
|
2259
|
-
|
|
2260
|
-
* SAVE BAR — stuck to the bottom of a scrolling surface.
|
|
2261
|
-
*
|
|
2262
|
-
* WHY THE `::after`. `position: sticky; bottom: 0` aligns the bar's bottom
|
|
2263
|
-
* edge with the surface's CONTENT box, but a surface carries its own bottom
|
|
2264
|
-
* padding, and content was flowing THROUGH the bar in that gap. The
|
|
2265
|
-
* extension covers exactly that padding; the ground is the same colour, so
|
|
2266
|
-
* the seam is invisible. The gap is read from `--surface-pad`, which the
|
|
2267
|
-
* consumer sets on the scrolling surface.
|
|
2268
|
-
*
|
|
2269
|
-
* NEGATIVE MARGIN, not a full-bleed trick: the bar spans the surface edge to
|
|
2270
|
-
* edge while its content stays on the same left rule as everything else.
|
|
2271
|
-
* ------------------------------------------------------------------ */
|
|
1779
|
+
|
|
2272
1780
|
.tamga-save-bar {
|
|
2273
1781
|
position: sticky;
|
|
2274
1782
|
bottom: 0;
|