tamga-ui 0.2.1 → 0.3.1

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/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.1 · MIT · https://tamga.org.tr */
30
2
  :root {
31
- /* The gap an overlay floats above its trigger. 8px, so the offset shadow (2px) clears the edge
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
- /* The whole computed offset, not just the gap: check-scale accepts a token reference, and a
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
- /* The dial's band label sits just under the ring's baseline. Negative and tiny: a position, not
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
- /* Room a raised object needs BESIDE itself so its 2px offset is not clipped by the parent's
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
- /* The instrument marks: a 2px tick and a 6px dot. Below the spacing scale on purpose: these are
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
- /* Smallest radius in the system: the checkbox tick and the skeleton block. --radius-ctl (4px)
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
- /* The ceiling for a wide dialog. Not a scale step but a LIMIT: a preview
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
- /* A raised surface: cards, overlays, popovers. It is barely lighter than the
131
- page on purpose; the edge does the lifting. */
33
+
132
34
  --color-shell: #131832;
133
- /* A row under the pointer, and a selected row's neutral wash. Same value as
134
- sunk, different job. */
35
+
135
36
  --color-hover: #1c2241;
136
- /* Rail and band ARE the page in both themes — a 1px line does the dividing,
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
- /* The navigation rail. Also the page: a sidebar that fills itself becomes a
141
- second surface competing with the content. */
39
+
142
40
  --color-rail: #0f1127;
143
- /* Content that sits IN the page rather than on it: filter bars, table
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
- /* The second weight: labels, secondary rows, anything that supports the
151
- heading without competing with it. */
47
+
152
48
  --color-ink-soft: #d4d4df;
153
- /* The heaviest weight: headings, table values, anything the eye should land
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; /* lightens here — dark ink wants it brighter */
53
+ --color-accent-hover: #78b4ff;
169
54
  --color-accent-active: #4097eb;
170
- --color-accent-ink: #12245c; /* navy ink on the bright face — 5.62:1 */
55
+ --color-accent-ink: #12245c;
171
56
  --color-accent-line: #86a7f3;
172
- /* Must out-chroma the neutral hover it sits next to. At the old C* 16.3 it
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
- /* The brand navy LIFTED, and the lift is the whole point. A base has to clear
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
- /* The wash behind a critical chip or row. A tint, not a fill: it carries no
187
- text of its own. */
63
+
188
64
  --color-critical-bg: #331a12;
189
- /* Not broken yet, but heading there. A threshold crossed, a queue growing, a
190
- stock running low. */
65
+
191
66
  --color-warn: #e8ab3c;
192
- /* The wash behind a warning chip or row. */
67
+
193
68
  --color-warn-bg: #33260f;
194
- /* Healthy, and also resolved. One green for both, because a reader should
195
- not have to learn two. */
69
+
196
70
  --color-resolved: #4fd4ac;
197
- /* The wash behind a healthy or resolved chip. */
71
+
198
72
  --color-resolved-bg: #0f2a22;
199
73
  --color-silent: #9494a8;
200
74
  --color-tick: #3f4880;
201
75
  --color-chart-1: #ada072;
202
- /* Teal, the second series. Far enough from resolved's green that a line is
203
- never mistaken for a status. */
76
+
204
77
  --color-chart-2: #5badaf;
205
- /* Blue, the third series. */
78
+
206
79
  --color-chart-3: #6ea7cc;
207
- /* Violet, the fourth series. */
80
+
208
81
  --color-chart-4: #a49ac9;
209
- /* Rose, the fifth and last. Beyond five the eye stops telling series apart
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
- /* A rail item under the pointer. Darker than idle in light, brighter in
216
- dark: the label steps toward the reader. */
86
+
217
87
  --color-nav-hover: #d4d4df;
218
- /* The wash behind a hovered rail item. The current item takes an outline
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
- /* PUNTO DA BURADA, ve uzun süre değildi.
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
- /* native checkboxes are restyled so tables and the kit look identical */
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
- /* DÖRT YANDAN DA YER, yalnız sağ ve alttan değil.
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
- /* Kaydırma çubuğu gizli: ray dar ve bir çubuk orada ikonların yerini
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
- /* ETİKETLİ HÂLİ. Aynı kontrolün ikinci genişliği, ayrı bir bileşen değil:
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
- /* 4px covers the deepest travel in the kit (the primary's +3 from a −1 hover). */
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
- /* a real button: lifts under the cursor, presses flat when clicked */
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
- /* KAPALI BİR DÜĞME YASAK DEĞİL, ATIL. `not-allowed` imleci "buna hakkın
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
- /* İMLEÇ. Kitteki her tıklanabilir sınıf bunu taşıyor (`btn`, `icon-btn`,
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
- /* Room for a LEADING ICON is opt-in. It used to be baked in at 40px, so every plain field —
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
- /* Küçük alanda ikon da içeri geliyor: 40px'lik oyuk 32px'lik bir kutuda
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
- /* ZEMİN `--color-shell`, `--color-input` DEĞİL. Ölçüldü ve düzeltildi:
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
- /* Inactive labels take ink-faint, not nav-idle. nav-idle is an ICON colour —
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
- /* KENDİ YÜZEYİ, kendi hizası. Bir panel ağaçta nerede doğduysa oranın
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
- /* TAM EKRAN PANEL: bir çalışma yüzeyi, bir kutu değil.
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
- /* ---------- steps ---------- */
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
- /* DOLGU `accent`, KENAR `accent-shadow` — düğmenin sözleşmesinin aynısı.
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
- /* KLAVYE VURGUSU FARE HOVER'IYLA AYNI GÖRÜNÜR.
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
- /* A cell that HOSTS AN OVERLAY cannot clip its own content.
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
- /* SEÇİLİ SATIR İKİ ADLA GELEBİLİYOR, VE BİRİ BOYANMIYORDU.
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
- /* `<a href>` pointer'ı tarayıcıdan alır; `href`siz bir `<a>`, bir `<span>`
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
- /* HOVER'DA KENAR RENGİ DEĞİŞMİYOR, ve ilk sürümde değişiyordu. Kitin
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
- /* Vurgu tema kuralını YENMEK ZORUNDA: daha düşük özgüllükte yazıldığında
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
- /* Boş hâl: kesik çizgi "burası dolabilir" diyor, düz kenar "burası boş
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
- /* Ruled paper. The art direction is "an instrument on paper", so the ground
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
- /* content sits above the ruling */
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
- /* Off at portrait size: a 3px bar under 30px of art is noise, not ground. */
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
- /* mono, because it is a SEQUENCE and not a quantity */
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-edge);
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
- /* The category colour is a RULE, not a field. A wall of coloured banners
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
- /* a stopped skeleton must still read as a placeholder, so it keeps the bar —
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
- /* Duran bir çekmece yine de AÇIK olmalı: kayma gidiyor, panel yerinde
2436
- beliriyor. */
1748
+
2437
1749
  .tamga-sheet-start,
2438
1750
  .tamga-sheet-end {
2439
1751
  animation: none;
2440
1752
  }
2441
- /* a stopped spinner must still be a visible mark, never an empty box */
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
- /* keeps a button's width when its label swaps for a loading label */
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;