tamga-ui 0.1.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.
Files changed (207) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +172 -0
  3. package/dist/blocks/count-row.d.ts +29 -0
  4. package/dist/blocks/count-row.d.ts.map +1 -0
  5. package/dist/blocks/count-row.js +19 -0
  6. package/dist/blocks/filter-bar.d.ts +123 -0
  7. package/dist/blocks/filter-bar.d.ts.map +1 -0
  8. package/dist/blocks/filter-bar.js +74 -0
  9. package/dist/blocks/index.d.ts +24 -0
  10. package/dist/blocks/index.d.ts.map +1 -0
  11. package/dist/blocks/index.js +23 -0
  12. package/dist/blocks/save-bar.d.ts +31 -0
  13. package/dist/blocks/save-bar.d.ts.map +1 -0
  14. package/dist/blocks/save-bar.js +21 -0
  15. package/dist/components/a11y.d.ts +21 -0
  16. package/dist/components/a11y.d.ts.map +1 -0
  17. package/dist/components/a11y.js +159 -0
  18. package/dist/components/advanced-input.d.ts +115 -0
  19. package/dist/components/advanced-input.d.ts.map +1 -0
  20. package/dist/components/advanced-input.js +189 -0
  21. package/dist/components/avatar.d.ts +63 -0
  22. package/dist/components/avatar.d.ts.map +1 -0
  23. package/dist/components/avatar.js +54 -0
  24. package/dist/components/badge.d.ts +37 -0
  25. package/dist/components/badge.d.ts.map +1 -0
  26. package/dist/components/badge.js +29 -0
  27. package/dist/components/bar.d.ts +32 -0
  28. package/dist/components/bar.d.ts.map +1 -0
  29. package/dist/components/bar.js +33 -0
  30. package/dist/components/button.d.ts +45 -0
  31. package/dist/components/button.d.ts.map +1 -0
  32. package/dist/components/button.js +56 -0
  33. package/dist/components/chart.d.ts +43 -0
  34. package/dist/components/chart.d.ts.map +1 -0
  35. package/dist/components/chart.js +41 -0
  36. package/dist/components/checkbox.d.ts +13 -0
  37. package/dist/components/checkbox.d.ts.map +1 -0
  38. package/dist/components/checkbox.js +16 -0
  39. package/dist/components/chrome.d.ts +87 -0
  40. package/dist/components/chrome.d.ts.map +1 -0
  41. package/dist/components/chrome.js +107 -0
  42. package/dist/components/combobox.d.ts +31 -0
  43. package/dist/components/combobox.d.ts.map +1 -0
  44. package/dist/components/combobox.js +62 -0
  45. package/dist/components/control-base.d.ts +7 -0
  46. package/dist/components/control-base.d.ts.map +1 -0
  47. package/dist/components/control-base.js +6 -0
  48. package/dist/components/data-table.d.ts +68 -0
  49. package/dist/components/data-table.d.ts.map +1 -0
  50. package/dist/components/data-table.js +50 -0
  51. package/dist/components/date-picker.d.ts +52 -0
  52. package/dist/components/date-picker.d.ts.map +1 -0
  53. package/dist/components/date-picker.js +73 -0
  54. package/dist/components/disclosure.d.ts +31 -0
  55. package/dist/components/disclosure.d.ts.map +1 -0
  56. package/dist/components/disclosure.js +32 -0
  57. package/dist/components/display.d.ts +188 -0
  58. package/dist/components/display.d.ts.map +1 -0
  59. package/dist/components/display.js +190 -0
  60. package/dist/components/empty-state.d.ts +150 -0
  61. package/dist/components/empty-state.d.ts.map +1 -0
  62. package/dist/components/empty-state.js +113 -0
  63. package/dist/components/error-state.d.ts +38 -0
  64. package/dist/components/error-state.d.ts.map +1 -0
  65. package/dist/components/error-state.js +16 -0
  66. package/dist/components/file-upload.d.ts +34 -0
  67. package/dist/components/file-upload.d.ts.map +1 -0
  68. package/dist/components/file-upload.js +34 -0
  69. package/dist/components/gauge.d.ts +47 -0
  70. package/dist/components/gauge.d.ts.map +1 -0
  71. package/dist/components/gauge.js +65 -0
  72. package/dist/components/icon.d.ts +32 -0
  73. package/dist/components/icon.d.ts.map +1 -0
  74. package/dist/components/icon.js +20 -0
  75. package/dist/components/icons.d.ts +19 -0
  76. package/dist/components/icons.d.ts.map +1 -0
  77. package/dist/components/icons.js +39 -0
  78. package/dist/components/input.d.ts +35 -0
  79. package/dist/components/input.d.ts.map +1 -0
  80. package/dist/components/input.js +41 -0
  81. package/dist/components/layout.d.ts +133 -0
  82. package/dist/components/layout.d.ts.map +1 -0
  83. package/dist/components/layout.js +132 -0
  84. package/dist/components/link.d.ts +22 -0
  85. package/dist/components/link.d.ts.map +1 -0
  86. package/dist/components/link.js +2 -0
  87. package/dist/components/live-scope.d.ts +15 -0
  88. package/dist/components/live-scope.d.ts.map +1 -0
  89. package/dist/components/live-scope.js +67 -0
  90. package/dist/components/log-view.d.ts +34 -0
  91. package/dist/components/log-view.d.ts.map +1 -0
  92. package/dist/components/log-view.js +30 -0
  93. package/dist/components/number-input.d.ts +26 -0
  94. package/dist/components/number-input.d.ts.map +1 -0
  95. package/dist/components/number-input.js +57 -0
  96. package/dist/components/overlay.d.ts +257 -0
  97. package/dist/components/overlay.d.ts.map +1 -0
  98. package/dist/components/overlay.js +276 -0
  99. package/dist/components/pagination.d.ts +38 -0
  100. package/dist/components/pagination.d.ts.map +1 -0
  101. package/dist/components/pagination.js +46 -0
  102. package/dist/components/pie.d.ts +40 -0
  103. package/dist/components/pie.d.ts.map +1 -0
  104. package/dist/components/pie.js +74 -0
  105. package/dist/components/primitives.d.ts +96 -0
  106. package/dist/components/primitives.d.ts.map +1 -0
  107. package/dist/components/primitives.js +81 -0
  108. package/dist/components/progress.d.ts +29 -0
  109. package/dist/components/progress.d.ts.map +1 -0
  110. package/dist/components/progress.js +16 -0
  111. package/dist/components/radio-group.d.ts +17 -0
  112. package/dist/components/radio-group.d.ts.map +1 -0
  113. package/dist/components/radio-group.js +23 -0
  114. package/dist/components/rail-link.d.ts +24 -0
  115. package/dist/components/rail-link.d.ts.map +1 -0
  116. package/dist/components/rail-link.js +24 -0
  117. package/dist/components/rich-text.d.ts +51 -0
  118. package/dist/components/rich-text.d.ts.map +1 -0
  119. package/dist/components/rich-text.js +147 -0
  120. package/dist/components/section.d.ts +15 -0
  121. package/dist/components/section.d.ts.map +1 -0
  122. package/dist/components/section.js +8 -0
  123. package/dist/components/segmented.d.ts +13 -0
  124. package/dist/components/segmented.d.ts.map +1 -0
  125. package/dist/components/segmented.js +12 -0
  126. package/dist/components/skeleton.d.ts +69 -0
  127. package/dist/components/skeleton.d.ts.map +1 -0
  128. package/dist/components/skeleton.js +67 -0
  129. package/dist/components/slider.d.ts +18 -0
  130. package/dist/components/slider.d.ts.map +1 -0
  131. package/dist/components/slider.js +15 -0
  132. package/dist/components/sparkline.d.ts +17 -0
  133. package/dist/components/sparkline.d.ts.map +1 -0
  134. package/dist/components/sparkline.js +19 -0
  135. package/dist/components/spinner.d.ts +15 -0
  136. package/dist/components/spinner.d.ts.map +1 -0
  137. package/dist/components/spinner.js +22 -0
  138. package/dist/components/stacked-bar.d.ts +21 -0
  139. package/dist/components/stacked-bar.d.ts.map +1 -0
  140. package/dist/components/stacked-bar.js +41 -0
  141. package/dist/components/surface.d.ts +76 -0
  142. package/dist/components/surface.d.ts.map +1 -0
  143. package/dist/components/surface.js +49 -0
  144. package/dist/components/switch.d.ts +12 -0
  145. package/dist/components/switch.d.ts.map +1 -0
  146. package/dist/components/switch.js +13 -0
  147. package/dist/components/tabs.d.ts +47 -0
  148. package/dist/components/tabs.d.ts.map +1 -0
  149. package/dist/components/tabs.js +12 -0
  150. package/dist/components/timeline-strip.d.ts +19 -0
  151. package/dist/components/timeline-strip.d.ts.map +1 -0
  152. package/dist/components/timeline-strip.js +14 -0
  153. package/dist/components/tone.d.ts +58 -0
  154. package/dist/components/tone.d.ts.map +1 -0
  155. package/dist/components/tone.js +70 -0
  156. package/dist/components/tree-select.d.ts +26 -0
  157. package/dist/components/tree-select.d.ts.map +1 -0
  158. package/dist/components/tree-select.js +59 -0
  159. package/dist/index.d.ts +54 -0
  160. package/dist/index.d.ts.map +1 -0
  161. package/dist/index.js +70 -0
  162. package/dist/kit.css +2248 -0
  163. package/dist/lib/cn.d.ts +10 -0
  164. package/dist/lib/cn.d.ts.map +1 -0
  165. package/dist/lib/cn.js +12 -0
  166. package/dist/lib/color.d.ts +68 -0
  167. package/dist/lib/color.d.ts.map +1 -0
  168. package/dist/lib/color.js +134 -0
  169. package/dist/lib/palette.d.ts +84 -0
  170. package/dist/lib/palette.d.ts.map +1 -0
  171. package/dist/lib/palette.js +193 -0
  172. package/dist/lib/scroll-lock.d.ts +19 -0
  173. package/dist/lib/scroll-lock.d.ts.map +1 -0
  174. package/dist/lib/scroll-lock.js +33 -0
  175. package/dist/patterns/app-shell.d.ts +36 -0
  176. package/dist/patterns/app-shell.d.ts.map +1 -0
  177. package/dist/patterns/app-shell.js +14 -0
  178. package/dist/patterns/auth-template.d.ts +36 -0
  179. package/dist/patterns/auth-template.d.ts.map +1 -0
  180. package/dist/patterns/auth-template.js +40 -0
  181. package/dist/patterns/detail-template.d.ts +52 -0
  182. package/dist/patterns/detail-template.d.ts.map +1 -0
  183. package/dist/patterns/detail-template.js +11 -0
  184. package/dist/patterns/index.d.ts +18 -0
  185. package/dist/patterns/index.d.ts.map +1 -0
  186. package/dist/patterns/index.js +17 -0
  187. package/dist/patterns/list-template.d.ts +32 -0
  188. package/dist/patterns/list-template.d.ts.map +1 -0
  189. package/dist/patterns/list-template.js +8 -0
  190. package/dist/patterns/overview-template.d.ts +26 -0
  191. package/dist/patterns/overview-template.d.ts.map +1 -0
  192. package/dist/patterns/overview-template.js +8 -0
  193. package/dist/patterns/public-template.d.ts +28 -0
  194. package/dist/patterns/public-template.d.ts.map +1 -0
  195. package/dist/patterns/public-template.js +7 -0
  196. package/dist/patterns/settings-template.d.ts +50 -0
  197. package/dist/patterns/settings-template.d.ts.map +1 -0
  198. package/dist/patterns/settings-template.js +33 -0
  199. package/dist/patterns/shared.d.ts +40 -0
  200. package/dist/patterns/shared.d.ts.map +1 -0
  201. package/dist/patterns/shared.js +29 -0
  202. package/dist/patterns/wizard-template.d.ts +28 -0
  203. package/dist/patterns/wizard-template.d.ts.map +1 -0
  204. package/dist/patterns/wizard-template.js +15 -0
  205. package/dist/styles.css +5 -0
  206. package/dist/theme.css +812 -0
  207. package/package.json +87 -0
package/dist/theme.css ADDED
@@ -0,0 +1,812 @@
1
+ /* ==============================================================
2
+ tamga-ui · TEMA KATMANI
3
+
4
+ Token'lar burada yaşar: renk rampası, semantik renkler, tip skalası,
5
+ ölçü, şekil ve motion. Sınıflar kit.css'te.
6
+
7
+ KULLANIM — tüketici kendi CSS'inde şu sırayı kurar:
8
+
9
+ @import "tailwindcss";
10
+ @import "tamga-ui/styles.css";
11
+ :root { --color-accent: #d6336c; } ← markanın tamamı
12
+
13
+ Bu dosya Tailwind v4 gerektirir (@theme direktifi kullanıyor).
14
+ kit.css gerektirmez — o saf CSS.
15
+
16
+ KURALLAR (guard'larla zorlanır):
17
+ · her token HEM :root HEM .dark içinde (check-token-parity)
18
+ · bileşen token'a adıyla erişir, ham hex yazmaz (check-hardcoded-colors)
19
+ · motion yalnız token üzerinden (check-motion-tokens)
20
+ ============================================================== */
21
+
22
+ @custom-variant dark (&:is(.dark *));
23
+
24
+ /* ============================================================
25
+ TOKEN KATMANI — kitin tek renk, ölçü ve hareket kaynağı.
26
+
27
+ KALICI (mekanizma, tartışmaya kapalı)
28
+ · token isimleri + @theme inline köprüsü
29
+ · her token HEM :root HEM .dark içinde (parite CI'da denetlenir)
30
+ · motion yalnız token üzerinden — ham süre ve eğri yasak
31
+ · yükselme tek formülden gelir: 1px kenar + N px sert offset, bulanıklık yok
32
+
33
+ DEĞİŞTİRİLEBİLİR (ürünün kararı)
34
+ · rampanın DEĞERLERİ. Bir ürün kendi CSS girişinde :root ve .dark blokları
35
+ yazarak markasını verir. Token'ın ADI kitin, DEĞERİ ürünündür.
36
+
37
+ Buradaki bir değeri değiştirmeden önce kitin ilgili karar belgesini güncelle —
38
+ sıra hep aynı: önce doküman, sonra değer.
39
+ ============================================================ */
40
+
41
+ /* tamga:sabit-olcek — temadan bağımsız: marka rampası, kırılma noktası,
42
+ hareket eğrileri ve süreler. Gece de gündüz de aynı. */
43
+ @theme {
44
+ /* Raw brand ramp. Nothing consumes it directly: the semantic tokens below are
45
+ the interface, and a component reaching for --color-brand-500 is skipping the
46
+ layer that makes theming work. Kept in step with the accent so that if anyone
47
+ ever does reach for it they get this product's blue, not the placeholder v2
48
+ shipped with.
49
+ TR: Ham marka rampası. Hiçbir şey doğrudan tüketmiyor: arayüz aşağıdaki anlamsal
50
+ token'lar, ve --color-brand-500'e uzanan bir bileşen temalandırmayı çalıştıran
51
+ katmanı atlıyor. */
52
+ --color-brand-50: #ecedf3;
53
+ /* Raw ramp, second step.
54
+ TR: Ham rampa, ikinci adım. */
55
+ --color-brand-100: #d6e2f5;
56
+ --color-brand-400: #53a4fa; /* = dark --primary TR: = koyu --primary */
57
+ --color-brand-500: #2069c9; /* = light --primary TR: = açık --primary */
58
+ --color-brand-600: #12245c; /* = the base under the face TR: = yüzün altındaki taban */
59
+
60
+ --breakpoint-xs: 30rem;
61
+
62
+ /* Motion (docs/13-design-soul §1) — theme-invariant, defined once here and read through the
63
+ ease/duration custom properties below. Components never write raw curves/durations (§10).
64
+ (Spelled out rather than written with a wildcard: Tailwind scans this file for class
65
+ candidates and read the glob form as an arbitrary utility, warning on every build.) */
66
+ --ease-instrument: cubic-bezier(0.22, 1, 0.36, 1); /* THE signature: everything that enters or moves TR: İMZA: giren ya da hareket eden her şey */
67
+ --ease-press: cubic-bezier(0.22, 1, 0.36, 1); /* the same curve: a press is not a different physics TR: aynı eğri: basmak farklı bir fizik değil */
68
+ /* --ease-settle removed (13 §1): the only curve with overshoot, and nothing in this
69
+ product bounces. An overshoot placed anywhere leaks everywhere. */
70
+ --ease-breath: ease-in-out; /* the two loops: beacon and skeleton TR: iki döngü: işaret ve iskelet */
71
+
72
+ --duration-instant: 100ms; /* press, hover, focus: every control (13 §1 --duration-press) TR: basma, üzerine gelme, odak: her kontrol (13 §1 --duration-press) */
73
+ --duration-quick: 160ms; /* colour and tone shifts TR: renk ve ton geçişleri */
74
+ --duration-base: 240ms; /* panels, popovers, toasts, value changes TR: paneller, balonlar, bildirimler, değer değişimleri */
75
+ --duration-slow: 340ms; /* route-level reveals TR: rota düzeyinde açılışlar */
76
+ /* Loops — long by design, the only things allowed past --duration-slow */
77
+ --duration-breath: 1100ms; /* skeleton TR: iskelet */
78
+ --duration-beacon: 1800ms; /* the live mark. 2400ms read as heavy on an instrument. TR: canlı işaret. 2400ms bir göstergede ağır okunuyordu. */
79
+ }
80
+
81
+ /* İŞARETÇİ YORUMU KENDİNDEN BAŞKA BİR İŞARETÇİNİN ADINI TAŞIMAZ. İlk hâli
82
+ burada koyu bloğun adını da anıyordu; ayrıştırıcı "koyu" işaretçisini
83
+ ararken bu yorumu buluyor ve AÇIK bloğu koyu sanıyordu. Parite kapısı da
84
+ bu yüzden açık bloğu kendisiyle karşılaştırıp sessizce geçiyordu.
85
+ tamga:tema-acik */
86
+ :root {
87
+ --radius: 6px; /* 13 §5: instrument sharpness, a knowing DNA §12 deviation (ADR pending) TR: 13 §5: gösterge keskinliği, DNA §12'den bilerek yapılan bir sapma (ADR bekliyor) */
88
+
89
+ /* Elevation — hard, blurless, offset shadows (docs/13-design-soul §2). Blur only on the
90
+ overlay's ambient second layer. Parity-checked in both :root and .dark (docs/03).
91
+ Every formula carries the SAME two layers in every theme (bottom shadow + inset top rim) so the
92
+ structure is parallel — light just holds the rim transparent; dark's rim is the load-bearing
93
+ "night edge" (§2). Equal layer counts also guarantee smooth box-shadow interpolation on press. */
94
+ --shadow-color: #d2cec8; /* = --color-edge: the offset IS the edge colour (13 Yasa 1). Darkened from #d9d6d1, which measured ΔL* 9.8 against the page, under this gate's floor of 10. TR: = --color-edge: kaydırmanın kendisi kenarın rengidir (13 Yasa 1). #d9d6d1'den koyulaştırıldı; sayfaya karşı ΔL* 9.8 ölçülmüştü, bu kapının 10 tabanının altında. */
95
+ --shadow-rim: transparent; /* no rim in either theme; see .dark TR: iki temada da çerçeve yok; bkz. .dark */
96
+ --shadow-ambient: rgb(38 34 26 / 0.32); /* scrim/overlay drop, warm ink TR: katman gölgesi, sıcak mürekkep */
97
+ --shadow-raised: 2px 2px 0 0 var(--shadow-color); /* diagonal, blurless (13 Yasa 1) TR: çapraz, bulanıksız (13 Yasa 1) */
98
+ --shadow-hover: 3px 3px 0 0 var(--shadow-color);
99
+ --shadow-pressed: 0 0 0 0 var(--shadow-color);
100
+ --shadow-overlay: 6px 6px 0 0 var(--shadow-color); /* the overlay plane: 6px, past anything the page can reach TR: katman düzlemi: 6px, sayfanın ulaşabileceği her şeyin ötesinde */
101
+ --shadow-seated-pressed: inset 0 0 0 0 transparent; /* seated never lifts, so it has nothing to collapse (13 §2) TR: oturmuş olan hiç kalkmaz, yani çökecek bir şeyi yok (13 §2) */
102
+
103
+ --background: #f5f2ec; /* warm paper TR: sıcak kâğıt */
104
+ --foreground: #26221a;
105
+ --card: #fdfcfa;
106
+ --card-foreground: #26221a;
107
+ --popover: #fdfcfa;
108
+ --popover-foreground: #26221a;
109
+
110
+ --primary: #2069c9; /* the FACE: L* 45, carries white ink at 5.22:1 (13 §2) TR: YÜZ: L* 45, beyaz mürekkebi 5.22:1 ile taşıyor (13 §2) */
111
+ --primary-foreground: #fdfcfa;
112
+ --secondary: #eceae6;
113
+ --secondary-foreground: #453f34;
114
+ --muted: #eceae6;
115
+ --muted-foreground: #6f695b; /* = --color-ink-faint: the same colour in the other name family, moved in step (contrast gate) TR: = --color-ink-faint: öteki ad ailesindeki aynı renk, onunla birlikte taşındı (kontrast kapısı) */
116
+ --accent: #ecedf3; /* selected-row wash TR: seçili satır yıkaması */
117
+ --accent-foreground: #12245c;
118
+ --destructive: #b3341f;
119
+ --destructive-foreground: #fdfcfa;
120
+ --success: #0a7a5f; /* healthy AND resolved share one green (13 Yasa 3) TR: sağlıklı VE çözüldü tek bir yeşili paylaşıyor (13 Yasa 3) */
121
+ --success-foreground: #fdfcfa;
122
+ --warning: #8a5a0b;
123
+ --warning-foreground: #fdfcfa;
124
+ --beacon: #12245c; /* ⚠️ no separate signature colour; see note below TR: ⚠️ ayrı bir imza rengi yok; aşağıdaki nota bakın */
125
+ --beacon-foreground: #fdfcfa;
126
+
127
+ --border: #e2ded6; /* the single rule colour TR: tek çizgi rengi */
128
+ /* Instrument scale marks (13 §4). NOT a border: a gauge's ticks are how the dial is READ, so they
129
+ answer to a FLOOR (be visible on every surface the dial can sit on), never to the border band's
130
+ deliberate softness. Kept warm-taupe in family, several steps darker than --border. */
131
+ --tick: #bdb8ae; /* scale marks answer to a FLOOR, not to the border's softness: they must read on card, page AND muted (13 §4) TR: ölçek işaretleri kenarın yumuşaklığına değil bir TABANA cevap verir: kartta, sayfada VE soluk zeminde okunmalı (13 §4) */
132
+ --input: #d2cec8; /* = --shadow-color. Yasa 1: the edge and the offset are one colour TR: = --shadow-color. Yasa 1: kenar ile kaydırma tek renktir */
133
+ --ring: #12245c;
134
+
135
+ /* Categorical series: for data that is NOT a status (regions, plans, series).
136
+ Deliberately QUIETER than the status palette: C* 26 against status's 36–65, so a
137
+ chart can never out-shout an event. Hues avoid critical's red (40°) and
138
+ resolved's green (169°) — the two carrying the strongest meaning, and the two a
139
+ reader would most easily mistake on a line. Measured: 22 ΔE between neighbours,
140
+ 20 ΔE to the nearest status colour.
141
+ TR: Kategorik seriler: durum OLMAYAN veri için (bölgeler, planlar, seriler). Durum
142
+ paletinden bilerek daha SESSİZ: durumun 36–65'ine karşı C* 26, yani bir grafik bir
143
+ olayın sesini asla bastıramıyor. */
144
+ --chart-1: #887c4f;
145
+ --chart-2: #32888a;
146
+ --chart-3: #4782a5;
147
+ --chart-4: #7f76a2;
148
+ --chart-5: #a36c84;
149
+ }
150
+
151
+ /* tamga:tema-koyu */
152
+ .dark {
153
+ /* Night field station — warm charcoal, not cold navy. */
154
+ /* Elevation (docs/13-design-soul §2 "night edge"): a darkening bottom shadow can't read on a
155
+ near-black ground (measured ceiling ΔL* ~8 vs light's ~16-20), so dark pushes --shadow-color to
156
+ near-black for max bottom separation AND adds the load-bearing cue — a 1px warm-white inset TOP
157
+ rim (light catches the raised top edge at night). Same two-layer formulas as light; on press the
158
+ rim goes transparent → the surface reads pressed flat (1:1 with light's bottom-out). */
159
+ --shadow-color: #363e6e;
160
+ --shadow-rim: transparent; /* the edge colour carries dark on its own — no rim needed */
161
+ --shadow-ambient: rgb(6 6 22 / 0.62);
162
+ --shadow-raised: 2px 2px 0 0 var(--shadow-color); /* diagonal, blurless (13 Yasa 1) */
163
+ --shadow-hover: 3px 3px 0 0 var(--shadow-color);
164
+ --shadow-pressed: 0 0 0 0 var(--shadow-color);
165
+ --shadow-overlay: 6px 6px 0 0 var(--shadow-color); /* the overlay plane: 6px, past anything the page can reach */
166
+ --shadow-seated-pressed: inset 0 0 0 0 transparent;
167
+
168
+ --background: #0f1127;
169
+ --foreground: #efeef4;
170
+ --card: #131832;
171
+ --card-foreground: #efeef4;
172
+ --popover: #131832;
173
+ --popover-foreground: #efeef4;
174
+
175
+ --primary: #53a4fa; /* face flips bright: white ink caps the fill at L* 47 on a dark ground */
176
+ --primary-foreground: #12245c; /* navy ink on the bright face — 5.62:1 */
177
+ --secondary: #1c2241;
178
+ --secondary-foreground: #d4d4df;
179
+ --muted: #1c2241;
180
+ --muted-foreground: #9494a8;
181
+ --accent: #0f2458;
182
+ --accent-foreground: #86a7f3;
183
+ --destructive: #ff9478;
184
+ --destructive-foreground: #0f1127;
185
+ --success: #4fd4ac;
186
+ --success-foreground: #0f1127;
187
+ --warning: #e8ab3c;
188
+ --warning-foreground: #0f1127;
189
+ --beacon: #86a7f3;
190
+ --beacon-foreground: #0f1127;
191
+
192
+ --border: #262d54;
193
+ --tick: #3f4880; /* same floor, measured against the darkest dial surface */
194
+ --input: #363e6e;
195
+ --ring: #86a7f3;
196
+
197
+ --chart-1: #ada072;
198
+ --chart-2: #5badaf;
199
+ --chart-3: #6ea7cc;
200
+ --chart-4: #a49ac9;
201
+ --chart-5: #ca90a9;
202
+ }
203
+
204
+ /* Köprü: tema ailesinin adlarını kitin `--color-*` ad alanına bağlıyor. Bir
205
+ token'ın Tailwind utility'si üretip üretmediği buradan geçip geçmediğine
206
+ bağlı, o yüzden işaretli.
207
+ tamga:kopru */
208
+ @theme inline {
209
+ --color-background: var(--background);
210
+ --color-foreground: var(--foreground);
211
+ --color-card: var(--card);
212
+ --color-card-foreground: var(--card-foreground);
213
+ --color-popover: var(--popover);
214
+ --color-popover-foreground: var(--popover-foreground);
215
+ --color-primary: var(--primary);
216
+ --color-primary-foreground: var(--primary-foreground);
217
+ --color-secondary: var(--secondary);
218
+ --color-secondary-foreground: var(--secondary-foreground);
219
+ --color-muted: var(--muted);
220
+ --color-muted-foreground: var(--muted-foreground);
221
+ --color-accent: var(--accent);
222
+ --color-accent-foreground: var(--accent-foreground);
223
+ --color-destructive: var(--destructive);
224
+ --color-destructive-foreground: var(--destructive-foreground);
225
+ --color-success: var(--success);
226
+ --color-success-foreground: var(--success-foreground);
227
+ --color-warning: var(--warning);
228
+ --color-warning-foreground: var(--warning-foreground);
229
+ --color-beacon: var(--beacon);
230
+ --color-beacon-foreground: var(--beacon-foreground);
231
+ --color-border: var(--border);
232
+ --color-tick: var(--tick);
233
+ --color-input: var(--input);
234
+ --color-ring: var(--ring);
235
+
236
+ --color-chart-1: var(--chart-1);
237
+ /* Teal, the second series. Far enough from resolved's green that a line is
238
+ never mistaken for a status. */
239
+ --color-chart-2: var(--chart-2);
240
+ /* Blue, the third series. */
241
+ --color-chart-3: var(--chart-3);
242
+ /* Violet, the fourth series. */
243
+ --color-chart-4: var(--chart-4);
244
+ /* Rose, the fifth and last. Beyond five the eye stops telling series apart
245
+ and a legend stops helping. */
246
+ --color-chart-5: var(--chart-5);
247
+
248
+ /* Typographic lock (docs/13-design-soul §6) — DECISION CHANGED 2026-08-16 (Berika).
249
+ The product runs on the SYSTEM UI stack. Outfit and JetBrains Mono were the earlier lock, but
250
+ the prototype everyone judged the design against had a broken variable chain and was silently
251
+ rendering system UI the whole time — that is the typography the design was actually approved
252
+ with, so it is the typography that ships.
253
+ Written out as an explicit value rather than left to a fallback: a stack you can read is a
254
+ stack you can change. Reverting is these three lines. */
255
+ --font-sans: -apple-system, "system-ui", "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
256
+ /* Measure — how long a line is allowed to get before the eye loses the start
257
+ of the next one. A typographic decision, so it lives with the tokens rather
258
+ than as an invented number in a className (13 §6). */
259
+ --measure-tight: 36ch; /* a note under a control */
260
+ --measure: 54ch; /* body copy in a card */
261
+ --measure-wide: 70ch; /* documentation prose */
262
+
263
+ --font-display: -apple-system, "system-ui", "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* headings are the same face, heavier — never a separate display cut (13 §6) */
264
+ /* Mono is the same face too — this is what the prototype did, and it is the shape the design was
265
+ approved in. The cost is real and worth stating: digits are no longer tabular by default, so a
266
+ column of numbers stops aligning on its own. `tabular-nums` is still available where a column
267
+ needs it. */
268
+ --font-mono: -apple-system, "system-ui", "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
269
+
270
+ /* Shape rhythm (docs/13-design-soul §5), base --radius = 0.75rem. Kept as a single-knob
271
+ calc scale: sm = 0.5rem and lg = 1rem land exactly on §5; md stays a shadcn-compat step. */
272
+ --radius-sm: calc(var(--radius) - 4px); /* 0.5rem — badges, tags, inline chips (§5) */
273
+ --radius-md: calc(var(--radius) - 2px); /* 0.625rem — shadcn default step */
274
+ --radius-lg: calc(var(--radius) + 4px); /* 1rem — cards, panels (§5) */
275
+ --radius-xl: calc(var(--radius) + 8px); /* 1.25rem — large surfaces */
276
+ --radius-full: 9999px; /* avatars and the live dot ONLY (§5) */
277
+ }
278
+
279
+ @layer base {
280
+ * {
281
+ border-color: var(--border);
282
+ outline-color: var(--ring);
283
+ }
284
+ body {
285
+ background-color: var(--background);
286
+ color: var(--foreground);
287
+ }
288
+ /* GEÇİCİ (Faz 2): headings in the display cut. Which face, which tracking — undecided. */
289
+ h1,
290
+ h2,
291
+ h3 {
292
+ font-family: var(--font-display);
293
+ letter-spacing: -0.01em;
294
+ }
295
+
296
+ /* Skeleton breath — an opacity breath, never a shimmer sweep (13 §8, §10).
297
+ Deep and quick on purpose: it started shallow and slow, which was right in
298
+ principle and useless in practice — at a glance you could not tell a loading
299
+ panel from a settled one, and that is its only job. */
300
+ @keyframes skeleton-breath {
301
+ 0%,
302
+ 100% {
303
+ opacity: 0.78;
304
+ }
305
+ 50% {
306
+ opacity: 0.06;
307
+ }
308
+ }
309
+ .animate-skeleton-breath {
310
+ animation: skeleton-breath var(--duration-breath) var(--ease-breath) infinite;
311
+ animation-delay: var(--skeleton-delay, 0ms);
312
+ }
313
+
314
+ /* The live mark. Brightness only — never a transform, or it starts competing
315
+ with the mascot's channel and Yasa 4 stops being enforceable (13 §3). */
316
+ @keyframes beacon-breath {
317
+ 0%,
318
+ 100% {
319
+ opacity: 1;
320
+ }
321
+ 50% {
322
+ opacity: 0.25;
323
+ }
324
+ }
325
+ .animate-beacon-breath {
326
+ animation: beacon-breath var(--duration-beacon) var(--ease-breath) infinite;
327
+ }
328
+
329
+ /* Decorative motion goes static under reduced motion. MECHANISM — keep in every art direction.
330
+ A stopped skeleton must still READ as a placeholder, so it parks near the middle of the
331
+ breath rather than at either end; an empty box is worse than no skeleton. */
332
+ @media (prefers-reduced-motion: reduce) {
333
+ .animate-skeleton-breath {
334
+ animation: none;
335
+ opacity: 0.42;
336
+ }
337
+ .animate-beacon-breath {
338
+ animation: none;
339
+ }
340
+ }
341
+ }
342
+
343
+ /* ============================================================
344
+ Press choreography (docs/13-design-soul §2) — THE single source for every raised interactive
345
+ surface (buttons, clickable cards). Apply the `press-surface` class; never re-implement it per
346
+ component (no second copy). Decorative, non-clickable surfaces must NOT use it (Law 2).
347
+ No transition-all — the property list is explicit.
348
+ ============================================================ */
349
+ .press-surface {
350
+ transform: translateY(0);
351
+ box-shadow: var(--shadow-raised);
352
+ outline: 2px solid transparent;
353
+ outline-offset: 2px;
354
+ transition-property: transform, box-shadow, border-color, outline-color, background-color, color;
355
+ transition-duration: var(--duration-quick);
356
+ transition-timing-function: var(--ease-instrument);
357
+ }
358
+ /* The working surface: one card that holds a whole screen (13 §4b).
359
+ The chrome around it — rail, header, ground — is all --card with no dividing
360
+ line, so it reads as one continuous frame. This is the only thing on top of
361
+ that frame, which is why it takes the CONTROL radius rather than the card
362
+ radius: at this size a softer corner makes the whole screen look like a
363
+ widget, and the sharper one keeps it in the same family as the buttons
364
+ inside it.
365
+ NOT a motion rule: this sat inside the reduced-motion query, so the surface
366
+ had no ground, no edge and no radius for anyone who had not turned reduced
367
+ motion on. */
368
+ .app-surface {
369
+ background: var(--background);
370
+ border: 1px solid var(--border);
371
+ border-radius: var(--radius-sm);
372
+ }
373
+
374
+ @media (prefers-reduced-motion: reduce) {
375
+ /* Functional feedback (lift, press travel, focus ring) stays — just shortened (13 §11). */
376
+ .press-surface {
377
+ transition-duration: var(--duration-instant);
378
+ }
379
+ }
380
+ .press-surface:hover:not(:disabled):not([aria-disabled="true"]):not([data-loading="true"]) {
381
+ transform: translate(-1px, -1px);
382
+ box-shadow: var(--shadow-hover);
383
+ /* Hover is carried by HEIGHT alone (13 §2). The inherited rule also turned the
384
+ border to the signature colour; that was dropped deliberately. One event
385
+ should produce one signal, and in this system an accent border already means
386
+ "selected or focused" — spending it on "the pointer is here" would blunt it. */
387
+ }
388
+ /* 1:1 on BOTH axes — the offset is diagonal (13 Yasa 1), so the travel has to be too, or the
389
+ surface lands beside its own shadow instead of on it. Measured in-browser: a vertical-only
390
+ press against a 2px 2px offset left the button 2px to the left of where it bottomed out.
391
+ If this scale ever changes, keep the press translate EQUAL to --shadow-raised's offset on
392
+ both x and y. */
393
+ .press-surface:active:not(:disabled):not([aria-disabled="true"]):not([data-loading="true"]) {
394
+ transform: translate(2px, 2px);
395
+ box-shadow: var(--shadow-pressed);
396
+ transition-duration: var(--duration-instant);
397
+ transition-timing-function: var(--ease-press);
398
+ }
399
+ .press-surface:focus-visible {
400
+ /* 2px beacon ring @2px offset; box-shadow + transform untouched — focus NEVER flattens (13 §2). */
401
+ outline-color: var(--beacon);
402
+ }
403
+ .press-surface:disabled,
404
+ .press-surface[aria-disabled="true"] {
405
+ transform: translateY(0);
406
+ box-shadow: none;
407
+ border-color: color-mix(in oklab, var(--border) 50%, transparent);
408
+ }
409
+ .press-surface[data-loading="true"] {
410
+ transform: translateY(0); /* travel locked */
411
+ box-shadow: var(--shadow-raised);
412
+ }
413
+
414
+ /* ============================================================
415
+ Surfaces (docs/13 §5) — the raised panel, defined once.
416
+
417
+ §5 is explicit and was not being followed: surfaces take --radius-card (6px), the edge is 1px in
418
+ the SHADOW colour (Yasa 1: the edge and the offset are one colour), and emphasis comes from a
419
+ hard diagonal offset. shadcn's `rounded-xl border shadow-sm` broke all three — `shadow-sm` is a
420
+ BLURRED shadow, which Yasa 1 forbids outright, and a blurred shadow is exactly what makes a
421
+ neobrutalist surface read as a generic SaaS card.
422
+
423
+ Role aliases, so call sites read by ROLE rather than by size (§5):
424
+ ============================================================ */
425
+ /* tamga:sabit-rol — rol takma adları ve yapısal ölçüler. Temaya bağlı değil. */
426
+ :root {
427
+ --radius-ctl: var(--radius-md); /* 4px: button, input, chip, segment TR: 4px: düğme, girdi, çip, segment */
428
+ --radius-card: var(--radius); /* 6px: card, overlay, panel TR: 6px: kart, katman, panel */
429
+
430
+ /* §5's structural rhythm. `--gutter` is the vertical line every heading, label, row and cell
431
+ starts on; it existed in the decision and nowhere in the code, so each screen was picking its
432
+ own px-6 / px-8 and the left edge wandered from page to page.
433
+ TR: §5'in yapısal ritmi. `--gutter` her başlığın, etiketin, satırın ve hücrenin
434
+ üstünde başladığı dikey çizgi; kararda vardı ama kodda hiçbir yerde yoktu, o yüzden
435
+ her ekran kendi px-6 / px-8'ini seçiyor ve sol kenar sayfadan sayfaya kayıyordu. */
436
+ --gutter: 24px;
437
+ --row: 56px; /* list row TR: liste satırı */
438
+ --row-sm: 48px; /* dense row TR: sık satır */
439
+ --control: 40px; /* every control's height (§5) TR: her kontrolün yüksekliği (§5) */
440
+ }
441
+
442
+ /* The one left line every page shares. */
443
+ .gutter {
444
+ padding-left: var(--gutter);
445
+ padding-right: var(--gutter);
446
+ }
447
+
448
+ /* A raised panel. Same grammar as .press-surface but with no choreography: it is not pressable, so
449
+ it never lifts and never presses (Law 2). */
450
+ .card-surface {
451
+ background: var(--card);
452
+ border: 1px solid var(--shadow-color);
453
+ border-radius: var(--radius-card);
454
+ box-shadow: var(--shadow-raised);
455
+ }
456
+
457
+ /* A seated well: content that sits IN the page rather than on it — filter bars, table headers,
458
+ sub-panels. No offset, ever. */
459
+ .sunk-surface {
460
+ background: var(--muted);
461
+ border: 1px solid var(--shadow-color);
462
+ border-radius: var(--radius-card);
463
+ }
464
+
465
+ /* Rayın kendi fiziği artık `kit.css`'te `.tamga-rail-link` olarak yaşıyor ve
466
+ `--color-nav-*` okuyor. Burada duran `.rail-link` bloğu ile onu besleyen
467
+ sekiz `--sidebar-*` token'ı SİLİNDİ: hiçbir bileşen onlara dokunmuyordu, ve
468
+ ölü bir token yalnız yer kaplamıyor, yanlış da söylüyor. Token sayfası
469
+ `--sidebar-primary` için kırmızı bir 1.08 basıyordu; hiçbir yerde
470
+ kullanılmayan bir rengin kontrast uyarısı, gerçek uyarıların arasında
471
+ gürültüdür. */
472
+
473
+ @media (prefers-reduced-motion: reduce) {
474
+ .rail-link {
475
+ transition-duration: var(--duration-instant);
476
+ }
477
+ }
478
+
479
+ /* ============================================================
480
+ Seated choreography (docs/13-design-soul §2) — THE single source for controls that sit IN a track
481
+ (tabs trigger, switch, checkbox, radio, segmented). Sibling of .press-surface, SAME grammar
482
+ (beacon focus ring, beacon hover warm, same tokens, same reduced-motion) — but the seated physics:
483
+ flat at rest, presses INTO the track on active (inset mirror of the raised bottom-out). No translate,
484
+ no scale. Apply the `seated-surface` class + a `border border-transparent` (so the warm shows).
485
+ Never re-implement it per component; decorative surfaces must NOT use it (Law 2).
486
+ ============================================================ */
487
+ .seated-surface {
488
+ position: relative; /* anchors the ::after tint overlay */
489
+ box-shadow: inset 0 0 0 0 var(--shadow-color); /* flat, but transitionable to the inset press */
490
+ outline: 2px solid transparent;
491
+ outline-offset: 2px;
492
+ transition-property: box-shadow, border-color, outline-color, color;
493
+ transition-duration: var(--duration-quick);
494
+ transition-timing-function: var(--ease-instrument);
495
+ }
496
+ /* The beacon "light" LAYERS over the control's own background via a solid-color ::after overlay —
497
+ it never replaces the state (a checked switch keeps --primary; an active tab keeps --background).
498
+ Solid color, NOT a gradient (§10). This also sidesteps the specificity clash with the component's
499
+ data-[state]:bg-* utility entirely — it's a different element and a different property. */
500
+ .seated-surface::after {
501
+ content: "";
502
+ position: absolute;
503
+ inset: 0;
504
+ border-radius: inherit;
505
+ pointer-events: none;
506
+ background-color: transparent;
507
+ transition: background-color var(--duration-quick) var(--ease-instrument);
508
+ }
509
+ @media (prefers-reduced-motion: reduce) {
510
+ /* functional feedback kept, shortened (13 §11) */
511
+ .seated-surface,
512
+ .seated-surface::after {
513
+ transition-duration: var(--duration-instant);
514
+ }
515
+ }
516
+ .seated-surface:hover:not(:disabled):not([aria-disabled="true"]) {
517
+ /* seated answers by FILLING, not by recolouring its edge (13 §2) */
518
+ }
519
+ .seated-surface:hover:not(:disabled):not([aria-disabled="true"])::after {
520
+ background-color: var(--accent);
521
+ }
522
+ .seated-surface:active:not(:disabled):not([aria-disabled="true"]) {
523
+ box-shadow: var(--shadow-seated-pressed); /* presses INTO the track — inset mirror of raised */
524
+ transition-duration: var(--duration-instant);
525
+ transition-timing-function: var(--ease-press);
526
+ }
527
+ .seated-surface:focus-visible {
528
+ outline-color: var(--beacon); /* SAME 2px beacon ring as raised — the shared grammar */
529
+ }
530
+ .seated-surface:disabled,
531
+ .seated-surface[aria-disabled="true"] {
532
+ box-shadow: none;
533
+ border-color: color-mix(in oklab, var(--border) 50%, transparent);
534
+ }
535
+
536
+ /* ==============================================================
537
+ TASLAK tokens (src/taslak) — here rather than in taslak.css because Tailwind generates utilities
538
+ only for the entry that imports it, and the draft needs `bg-shell`, `text-ink`, `text-body`.
539
+ Names are additive: v5 speaks --background/--card and Tailwind's own text scale, so nothing is
540
+ overwritten. `static` because a token reached only through var() in a TSX inline style is
541
+ invisible to the tree-shaker. Dark overrides and the tamga-* classes stay in taslak.css.
542
+ ============================================================== */
543
+ /* Kitin kendi ad ailesi (--color-page, --color-ink …). Koyu karşılıkları
544
+ kit.css'te, ayrı bir dosyada: tam olarak bir parite kapısı gerektiren şey.
545
+ tamga:kit-acik */
546
+ @theme static {
547
+
548
+
549
+ /* 1 · neutral ramp — cooled off, one step per layer */
550
+ /* The ground everything sits on. The rail and the band share it: what divides
551
+ them is a 1px line, never a fill.
552
+ TR: Her şeyin üstünde durduğu zemin. Ray ve şerit de aynı zemini kullanıyor: onları
553
+ ayıran şey 1px'lik bir çizgi, asla bir dolgu. */
554
+ --color-page: #f5f2ec;
555
+ /* A raised surface: cards, overlays, popovers. It is barely lighter than the
556
+ page on purpose; the edge does the lifting.
557
+ TR: Yükseltilmiş yüzey: kartlar, katmanlar, balonlar. Sayfadan bilerek çok az açık;
558
+ yükseltmeyi kenar yapıyor. */
559
+ --color-shell: #fdfcfa;
560
+ /* A row under the pointer, and a selected row's neutral wash. Same value as
561
+ sunk, different job.
562
+ TR: İmlecin altındaki satır, ve seçili satırın nötr yıkaması. Gömülü ile aynı değer,
563
+ farklı iş. */
564
+ --color-hover: #eceae6;
565
+ /* The strip above a table: counters, page-size, summary lines. It is the
566
+ page, separated by a line.
567
+ TR: Tablonun üstündeki şerit: sayaçlar, sayfa boyu, özet satırları. Sayfanın
568
+ kendisi, bir çizgiyle ayrılmış. */
569
+ --color-band: #f5f2ec;
570
+ /* The navigation rail. Also the page: a sidebar that fills itself becomes a
571
+ second surface competing with the content.
572
+ TR: Gezinme rayı. O da sayfa: kendini dolduran bir kenar çubuğu, içerikle yarışan
573
+ ikinci bir yüzeye dönüşüyor. */
574
+ --color-rail: #f5f2ec;
575
+ /* Content that sits IN the page rather than on it: filter bars, table
576
+ headers, code blocks, sub-panels.
577
+ TR: Sayfanın üstünde değil İÇİNDE duran içerik: filtre çubukları, tablo başlıkları,
578
+ kod blokları, alt paneller. */
579
+ --color-sunk: #eceae6;
580
+ /* the single rule colour: dividers and card edges
581
+ TR: tek çizgi rengi: ayraçlar ve kart kenarları */
582
+ --color-line: #e2ded6;
583
+ /* Darkened from #d9d6d1 after v5's contrast gate measured it at ΔL* 9.8 against
584
+ the page, just under the floor of 10 where a raised surface stops reading as
585
+ raised. check-token-contrast now measures it here too, and reproduces that
586
+ same 9.8, which is how we know the two gates share one arithmetic.
587
+ TR: #d9d6d1'den koyulaştırıldı: v5'in kontrast kapısı sayfaya karşı ΔL* 9.8
588
+ ölçmüştü, yükseltilmiş bir yüzeyin yükseltilmiş okunmayı bıraktığı 10 tabanının
589
+ hemen altında. check-token-contrast artık burada da ölçüyor ve aynı 9.8'i üretiyor;
590
+ iki kapının tek bir aritmetiği paylaştığını böyle biliyoruz. */
591
+ --color-edge: #d2cec8;
592
+ /* neutral fill under a chart: area body, sparkline wash
593
+ TR: grafiğin altındaki nötr dolgu: alan gövdesi, kıvılcım çizgisi yıkaması */
594
+ --color-chart-fill: #eceae6;
595
+ /* Lightened text, and it answers to AA like any other text. Was #716b5d, which
596
+ measured 4.41 against --color-sunk and --color-hover, under the 4.5 floor, so
597
+ secondary text on a filter bar, a table header or a hovered row was failing
598
+ while the same colour passed on the page. Nobody saw it: it fails by 0.09.
599
+ Darkened one step to clear 4.5 on every surface it can land on (4.54 on sunk,
600
+ 4.89 on the page, 5.32 on a card). check-token-contrast measures it now.
601
+ TR: Açılmış metin, ve her metin gibi AA'ya cevap veriyor. #716b5d'ydi; --color-sunk
602
+ ve --color-hover'a karşı 4.41 ölçüldü, 4.5 tabanının altında, yani bir filtre
603
+ çubuğundaki ya da tablo başlığındaki ikincil metin, aynı renk sayfada geçerken orada
604
+ kalıyordu. */
605
+ --color-ink-faint: #6f695b;
606
+ /* The second weight: labels, secondary rows, anything that supports the
607
+ heading without competing with it.
608
+ TR: İkinci ağırlık: etiketler, ikincil satırlar, başlıkla yarışmadan onu destekleyen
609
+ her şey. */
610
+ --color-ink-soft: #453f34;
611
+ /* The heaviest weight: headings, table values, anything the eye should land
612
+ on first.
613
+ TR: En ağır ağırlık: başlıklar, tablo değerleri, gözün ilk konması gereken her şey. */
614
+ --color-ink: #26221a;
615
+
616
+ /* 2 · accent — interaction only */
617
+ /* A face on a base, never a fill with a shadow. #12245c is L* 16 — our body
618
+ text is L* 27 and our heading ink is L* 13, so as a fill it was a text
619
+ colour, and every product primary worth comparing sits at L* 46–62. A
620
+ near-black face leaves no room for a base under it, which is why the offset
621
+ kept having to escape upward. The navy moved to the base, and the face
622
+ sits at L* 45 carrying white ink: 29 ΔL* between the two layers. */
623
+ --color-accent: #2069c9; /* primary fill TR: birincil dolgu */
624
+ --color-accent-hover: #005ab5; /* darkens, not lightens; white ink needs it TR: açılmaz, koyulaşır; beyaz mürekkep bunu istiyor */
625
+ /* The pressed face. It keeps going in the same direction as hover: darker in
626
+ light, brighter in dark.
627
+ TR: Basılı yüz. Üzerine gelmeyle aynı yönde devam ediyor: açıkta daha koyu, koyuda
628
+ daha parlak. */
629
+ --color-accent-active: #004c9b;
630
+ --color-accent-ink: #fdfcfa; /* white ink on the fill, 5.22:1 TR: dolgunun üstünde beyaz mürekkep, 5.22:1 */
631
+ --color-accent-line: #12245c; /* link text, focus ring, thin marks TR: bağlantı metni, odak halkası, ince işaretler */
632
+ --color-accent-bg: #ecedf3; /* selected row ground TR: seçili satırın zemini */
633
+ /* The base the face sits on, and the primary's edge. This is where the brand
634
+ navy belongs: dark, saturated, and doing the job a shadow is supposed to do
635
+ instead of pretending to be a fill.
636
+ TR: Yüzün üstüne oturduğu taban, ve birincilin kenarı. Marka lacivertinin yeri
637
+ burası: koyu, doygun, ve bir dolgu taklidi yapmak yerine bir gölgenin yapması
638
+ gereken işi yapıyor. */
639
+ --color-accent-shadow: #12245c;
640
+
641
+ /* 3 · status — healthy green, silenced neutral */
642
+ /* Something is broken and someone has to act. The only red in the system, and
643
+ it never decorates.
644
+ TR: Bir şey bozuldu ve birinin harekete geçmesi gerekiyor. Sistemdeki tek kırmızı,
645
+ ve asla süslemiyor. */
646
+ --color-critical: #b3341f;
647
+ /* The wash behind a critical chip or row. A tint, not a fill: it carries no
648
+ text of its own.
649
+ TR: Kritik bir çipin ya da satırın arkasındaki yıkama. Bir dolgu değil bir ton:
650
+ kendi metnini taşımıyor. */
651
+ --color-critical-bg: #fbeae4;
652
+ /* Not broken yet, but heading there. A threshold crossed, a queue growing, a
653
+ stock running low.
654
+ TR: Henüz bozulmadı ama o yöne gidiyor. Aşılan bir eşik, büyüyen bir kuyruk, azalan
655
+ bir stok. */
656
+ --color-warn: #8a5a0b;
657
+ /* The wash behind a warning chip or row.
658
+ TR: Uyarı çipinin ya da satırının arkasındaki yıkama. */
659
+ --color-warn-bg: #fbf1dd;
660
+ /* Healthy, and also resolved. One green for both, because a reader should
661
+ not have to learn two.
662
+ TR: Sağlıklı, ve aynı zamanda çözüldü. İkisi için tek yeşil, çünkü okuyanın iki renk
663
+ öğrenmesi gerekmemeli. */
664
+ --color-resolved: #0a7a5f;
665
+ /* The wash behind a healthy or resolved chip.
666
+ TR: Sağlıklı ya da çözülmüş bir çipin arkasındaki yıkama. */
667
+ --color-resolved-bg: #e3f3ec;
668
+ /* Was #716b5d, the same value as ink-faint, and it failed on the one ground it
669
+ is documented against: silent on chart-fill measured 4.41:1, under AA. It
670
+ passed on the card (5.17:1), which is why it went unnoticed: the healthy
671
+ and paused chips are the only place the pair actually meets. Darkened to
672
+ clear the wash (5.02:1) while staying clearly the muted tone. It no longer
673
+ tracks ink-faint, which is correct: they are different roles.
674
+ TR: #716b5d'ydi, ink-faint ile aynı değer, ve belgelendiği tek zeminde kalıyordu:
675
+ chart-fill üstünde 4.41:1, AA'nın altında. Kartta geçiyordu (5.17:1), fark
676
+ edilmemesinin sebebi de bu. */
677
+ --color-silent: #696256;
678
+
679
+ /* Instrument scale marks: the progress dial's ticks. NOT --color-edge: a tick is
680
+ READ, so it answers to a floor (visible on card, page AND the sunk wash), never
681
+ to the rule line's deliberate softness. On --color-sunk the edge measured ΔL* 7.0
682
+ against a floor of 12.
683
+ TR: Gösterge ölçek işaretleri: ilerleme kadranının çentikleri. --color-edge DEĞİL:
684
+ bir çentik OKUNUR, yani çizginin bilerek seçilmiş yumuşaklığına değil bir tabana
685
+ cevap verir (kartta, sayfada VE gömülü yıkamada görünecek). */
686
+ --color-tick: #bdb8ae;
687
+
688
+ /* Categorical series: data that is NOT a status (regions, plans, series).
689
+ Quieter than the status palette on purpose: C* 26 against status's 36–65, so a
690
+ chart can never out-shout an event. Hues avoid critical's red and resolved's
691
+ green, the two a reader would most easily misread on a line.
692
+ TR: Kategorik seriler: durum OLMAYAN veri (bölgeler, planlar, seriler). Durum
693
+ paletinden bilerek daha sessiz: durumun 36–65'ine karşı C* 26, yani bir grafik bir
694
+ olayın sesini asla bastıramıyor. */
695
+ --color-chart-1: #887c4f;
696
+ /* Teal, the second series. Far enough from resolved's green that a line is
697
+ never mistaken for a status.
698
+ TR: Deniz mavisi, ikinci seri. Çözüldü yeşilinden, bir çizginin durum sanılmayacağı
699
+ kadar uzak. */
700
+ --color-chart-2: #32888a;
701
+ /* Blue, the third series.
702
+ TR: Mavi, üçüncü seri. */
703
+ --color-chart-3: #4782a5;
704
+ /* Violet, the fourth series.
705
+ TR: Mor, dördüncü seri. */
706
+ --color-chart-4: #7f76a2;
707
+ /* Rose, the fifth and last. Beyond five the eye stops telling series apart
708
+ and a legend stops helping.
709
+ TR: Gül, beşinci ve sonuncu. Beşten sonra göz serileri ayırmayı bırakıyor ve bir
710
+ gösterge artık yardım etmiyor. */
711
+ --color-chart-5: #a36c84;
712
+
713
+ /* rail navigation */
714
+ /* An idle rail label is TEXT, so it answers to AA. Was #8a857a: 3.29 against the
715
+ rail, while dark's counterpart sat at 5.42, and the asymmetry was the tell that
716
+ light had never been measured. Now L* 46, the same band as --color-ink-faint,
717
+ which is what a faint label should be.
718
+ TR: Boştaki bir ray etiketi METİNDİR, yani AA'ya cevap verir. #8a857a'ydı: raya
719
+ karşı 3.29, koyudaki karşılığı 5.42'de dururken. Bu asimetri, açığın hiç
720
+ ölçülmediğinin işaretiydi. */
721
+ --color-nav-idle: #726d62;
722
+ /* A rail item under the pointer. Darker than idle in light, brighter in
723
+ dark: the label steps toward the reader.
724
+ TR: İmlecin altındaki ray öğesi. Açıkta boştakinden koyu, koyuda daha parlak: etiket
725
+ okuyana doğru bir adım atıyor. */
726
+ --color-nav-hover: #4a4438;
727
+ /* The wash behind a hovered rail item. The current item takes an outline
728
+ instead, never this fill.
729
+ TR: Üzerine gelinen ray öğesinin arkasındaki yıkama. Bulunulan öğe bunun yerine bir
730
+ dış çizgi alıyor, asla bu dolguyu. */
731
+ --color-nav-hover-bg: #eae6dd;
732
+
733
+ /* overlay plane: dropdowns, popovers, dialogs, toasts
734
+ TR: katman düzlemi: açılır listeler, balonlar, diyaloglar, bildirimler */
735
+ --color-scrim: rgba(38, 34, 26, 0.32);
736
+
737
+ /* ---------------------------------------------------------------- *
738
+ * Type scale. Ten steps, and nothing outside them.
739
+ *
740
+ * The kit ran on 19 hand-written sizes across 272 places, including
741
+ * 12.5px, 13.5px and 14.5px — half pixels, which no screen renders
742
+ * cleanly and which nobody chose on purpose. They existed because
743
+ * each one was typed at the moment it was needed, so the answer to
744
+ * "how big is body text?" was "somewhere between 12 and 14".
745
+ *
746
+ * Each step has ONE job. Pick by role, never by how it looks in the
747
+ * spot you happen to be in.
748
+ * ---------------------------------------------------------------- */
749
+ --text-micro: 10px; /* axis ticks, scale ends, the smallest label TR: eksen çentikleri, ölçek uçları, en küçük etiket */
750
+ --text-caption: 11px; /* dense mono identifiers, chip text TR: sık eşaralıklı kimlikler, çip metni */
751
+ --text-small: 12px; /* meta, secondary, table sub-lines TR: üstveri, ikincil satırlar, tablo alt satırları */
752
+ --text-body: 13px; /* THE default: rows, cells, body copy TR: VARSAYILAN: satırlar, hücreler, gövde metni */
753
+ --text-control: 14px; /* inputs, textareas, larger body TR: girdiler, metin alanları, daha büyük gövde */
754
+ --text-subhead: 15px; /* card and section titles TR: kart ve bölüm başlıkları */
755
+ --text-title: 18px; /* page titles TR: sayfa başlıkları */
756
+ /* The small display step: a card's hero number, a score.
757
+ TR: Küçük gösterim adımı: bir kartın öne çıkan sayısı, bir puan. */
758
+ --text-display-sm: 24px;
759
+ --text-display: 30px; /* KPI numbers TR: KPI sayıları */
760
+ /* The largest step, and the rarest. One per screen at most.
761
+ TR: En büyük adım, ve en nadiri. Ekran başına en fazla bir tane. */
762
+ --text-display-lg: 40px;
763
+
764
+ /* Measure — how long a line of text is allowed to get before the eye loses
765
+ the start of the next one. Three steps, and nothing outside them; the kit
766
+ ran on ten hand-written `ch` values across 31 places, which is the type
767
+ scale's disease in a second coat. */
768
+ --measure-tight: 36ch; /* a note under a control TR: bir kontrolün altındaki not */
769
+ --measure: 54ch; /* body copy in a card TR: kart içindeki gövde metni */
770
+ --measure-wide: 70ch; /* documentation prose TR: doküman metni */
771
+
772
+ /* ---------------------------------------------------------------- *
773
+ * Shape. One knob, and everything derives from it.
774
+ *
775
+ * Written as a calc scale rather than two loose numbers so "make the
776
+ * product a little softer" stays a one-line edit — v5 inherits the
777
+ * same single-knob structure, and matching it means the values port
778
+ * without redesigning anything.
779
+ *
780
+ * The VALUE is a deliberate departure. v5 carries --radius: 12px with
781
+ * a note pointing at the brand DNA's "soft corners"; this product went
782
+ * the other way on purpose. It is an instrument read at 3am, and a
783
+ * dense table of rows reads faster with corners that stop rather than
784
+ * curve. Recorded as a knowing deviation, not an oversight — the same
785
+ * way v5 records its own amber beacon as one.
786
+ * ---------------------------------------------------------------- */
787
+
788
+ /* aliases kept so call sites read by ROLE rather than by size */
789
+
790
+ /* ---------------------------------------------------------------- *
791
+ * Motion. Durations and curves are tokens for exactly the reason
792
+ * colours are: written inline they drift. Before this block existed
793
+ * the kit held 16 hand-written values doing four jobs, and they had
794
+ * already scattered — a toast appeared in 200ms, a progress bar moved
795
+ * in 240ms, a route revealed in 340ms. Nobody could point at a line
796
+ * and call it wrong; it just felt uneven.
797
+ *
798
+ * --press is its own step and the smallest on purpose: a control that
799
+ * answers a click in 100ms feels mechanical, which is the whole point
800
+ * of a hard-offset button. Anything slower reads as lag.
801
+ * ---------------------------------------------------------------- */
802
+ --duration-press: 100ms; /* hover, press, focus: every control TR: üzerine gelme, basma, odak: her kontrol */
803
+
804
+ --ease-standard: cubic-bezier(0.22, 1, 0.36, 1); /* everything that enters or moves TR: giren ya da hareket eden her şey */
805
+
806
+ /* Loops. Long by design, and the only things allowed past --duration-slow.
807
+ `--duration-spin` and `--ease-linear` lived here for the old CSS `.tamga-spinner`, a rotating
808
+ ring. The kit's spinner is three marching bars (ui/spinner.tsx) — nothing in this product
809
+ rotates any more, so both went with it.
810
+ TR: Döngüler. Bilerek uzun, ve --duration-slow'u geçmesine izin verilen tek şeyler. */
811
+ --duration-bar: 900ms;
812
+ }