@kashi-ui/css 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/base.css CHANGED
@@ -14,6 +14,9 @@
14
14
  font-size: var(--k-text-md);
15
15
  line-height: var(--k-leading-normal);
16
16
  -webkit-font-smoothing: antialiased;
17
+ text-rendering: optimizeLegibility;
18
+ /* نوار اسکرول هم‌رنگ تم */
19
+ scrollbar-color: var(--k-border-primary) transparent;
17
20
  -moz-osx-font-smoothing: grayscale;
18
21
  /* کشیده‌نویسی و اتصال درست حروف فارسی */
19
22
  font-feature-settings: "kern", "liga", "calt";
@@ -71,6 +74,9 @@
71
74
  }
72
75
  }
73
76
 
77
+ /* متن پاراگراف‌ها بدون تک‌کلمهٔ تنها در خط آخر */
78
+ :where(p, li, figcaption) { text-wrap: pretty; }
79
+
74
80
  /* ارقام لاتین در کنار متن فارسی: tabular برای جدول‌ها و اعداد */
75
81
  .k-tabular { font-variant-numeric: tabular-nums; }
76
82
 
@@ -26,7 +26,7 @@
26
26
  background: var(--_bg);
27
27
  color: var(--k-text-tertiary);
28
28
  font-size: var(--k-text-sm);
29
- box-shadow: var(--k-shadow-xs);
29
+ box-shadow: var(--k-shadow-xs), var(--k-highlight);
30
30
  }
31
31
 
32
32
  .k-alert--brand { --_accent: var(--k-text-brand); }
@@ -15,7 +15,7 @@
15
15
  gap: var(--k-space-1);
16
16
  padding-block: 0.125rem;
17
17
  padding-inline: var(--_px);
18
- border: 1px solid color-mix(in srgb, var(--_fg) 24%, transparent);
18
+ border: 1px solid color-mix(in srgb, var(--_fg) 20%, transparent);
19
19
  border-radius: var(--k-badge-radius, var(--k-radius-full));
20
20
  background: var(--_bg);
21
21
  color: var(--_fg);
@@ -11,8 +11,8 @@
11
11
  --_h: var(--k-btn-height-md, calc(2.5rem * var(--k-density)));
12
12
  --_px: var(--k-btn-padding-md, calc(0.875rem * var(--k-density)));
13
13
  --_fs: var(--k-text-sm);
14
- --_bg: var(--k-bg-primary);
15
- --_bg-hover: var(--k-bg-hover);
14
+ --_bg: var(--k-btn-secondary-bg, var(--k-bg-elevated));
15
+ --_bg-hover: color-mix(in srgb, var(--_bg), var(--k-text-primary) 5%);
16
16
  --_fg: var(--k-text-secondary);
17
17
  --_fg-hover: var(--k-text-primary);
18
18
  --_border: var(--k-border-primary);
@@ -81,7 +81,7 @@
81
81
  content: "";
82
82
  position: absolute;
83
83
  inset: 1px;
84
- border: 1px solid rgb(255 255 255 / 0.12);
84
+ border: 1px solid rgb(255 255 255 / var(--k-btn-highlight, 0.14));
85
85
  border-radius: inherit;
86
86
  mask: linear-gradient(to bottom, #000, transparent);
87
87
  pointer-events: none;
@@ -89,6 +89,7 @@
89
89
  .k-btn:is(.k-btn--primary, .k-btn--danger):is(:disabled, [aria-disabled="true"]:not([aria-busy="true"]))::before { display: none; }
90
90
  .k-btn--tertiary {
91
91
  --_bg: transparent;
92
+ --_bg-hover: var(--k-bg-hover);
92
93
  --_border: transparent;
93
94
  --_shadow: none;
94
95
  }
@@ -106,8 +107,8 @@
106
107
  .k-btn--danger {
107
108
  --_bg: var(--k-bg-error);
108
109
  --_bg-hover: var(--k-bg-error-hover);
109
- --_fg: var(--k-text-on-brand);
110
- --_fg-hover: var(--k-text-on-brand);
110
+ --_fg: var(--k-text-on-error);
111
+ --_fg-hover: var(--k-text-on-error);
111
112
  --_border: transparent;
112
113
  --_shadow: var(--k-shadow-xs), var(--k-shadow-skeuomorphic);
113
114
  --_ring: var(--k-ring-error);
@@ -115,7 +116,6 @@
115
116
  .k-btn--danger-secondary {
116
117
  --_fg: var(--k-text-error);
117
118
  --_fg-hover: var(--k-text-error);
118
- --_bg-hover: var(--k-bg-error-subtle);
119
119
  --_ring: var(--k-ring-error);
120
120
  }
121
121
 
@@ -124,7 +124,7 @@
124
124
  border: 1px solid var(--k-border-secondary);
125
125
  border-radius: var(--k-radius-xl);
126
126
  background: var(--k-calendar-bg, var(--k-bg-elevated));
127
- box-shadow: var(--k-shadow-xl);
127
+ box-shadow: var(--k-shadow-xl), var(--k-highlight);
128
128
  animation: k-pop-in var(--k-duration-fast) var(--k-ease-standard);
129
129
  }
130
130
  @keyframes k-pop-in { from { opacity: 0; translate: 0 -4px; } }
@@ -20,7 +20,7 @@
20
20
  border-radius: var(--k-card-radius, var(--k-radius-xl));
21
21
  background: var(--k-card-bg, var(--k-bg-elevated));
22
22
  color: var(--k-text-primary);
23
- box-shadow: var(--k-card-shadow, var(--k-shadow-xs));
23
+ box-shadow: var(--k-card-shadow, var(--k-shadow-xs)), var(--k-highlight);
24
24
  overflow: clip;
25
25
  }
26
26
 
@@ -57,7 +57,7 @@
57
57
 
58
58
  .k-card__media { display: block; inline-size: 100%; object-fit: cover; }
59
59
 
60
- .k-card--flat { box-shadow: none; }
60
+ .k-card--flat { box-shadow: var(--k-highlight); }
61
61
 
62
62
  .k-card--interactive {
63
63
  position: relative;
@@ -65,7 +65,7 @@
65
65
  border-color var(--k-duration-fast) var(--k-ease-standard),
66
66
  box-shadow var(--k-duration-normal) var(--k-ease-standard);
67
67
  }
68
- .k-card--interactive:hover { border-color: var(--k-border-primary); box-shadow: var(--k-shadow-md); }
68
+ .k-card--interactive:hover { border-color: var(--k-border-primary); box-shadow: var(--k-shadow-md), var(--k-highlight); }
69
69
  .k-card--interactive:has(:focus-visible) { box-shadow: var(--k-shadow-md), var(--k-ring-brand); }
70
70
  /* لینک اصلی کل کارت را قابل‌کلیک می‌کند ولی فقط یک توقف Tab دارد */
71
71
  .k-card--interactive :is(a, button).k-card__link::after { content: ""; position: absolute; inset: 0; }
@@ -23,8 +23,9 @@
23
23
  margin: 0;
24
24
  border: 1px solid var(--_border);
25
25
  border-radius: var(--k-checkbox-radius, calc(0.3125rem * var(--k-radius-factor)));
26
- background: var(--k-bg-primary);
26
+ background: var(--k-bg-elevated);
27
27
  color: var(--k-text-on-brand);
28
+ box-shadow: var(--k-shadow-xs);
28
29
  cursor: pointer;
29
30
  transition:
30
31
  background-color var(--k-duration-fast) var(--k-ease-standard),
@@ -45,7 +46,7 @@
45
46
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M3 7h8'/%3E%3C/svg%3E");
46
47
  }
47
48
 
48
- .k-checkbox:hover { --_border: var(--k-border-brand); }
49
+ .k-checkbox:hover:not(:disabled) { --_border: var(--k-border-brand); box-shadow: 0 0 0 4px var(--k-bg-hover); }
49
50
 
50
51
  .k-checkbox:is(:checked, :indeterminate) {
51
52
  --_border: var(--k-bg-brand);
@@ -0,0 +1,74 @@
1
+ /* پنجرهٔ گفتگو — روی <dialog> بومی: تلهٔ فوکوس، Esc و غیرفعال شدن پس‌زمینه رایگان
2
+ * اندازه‌ها: k-dialog--sm | k-dialog--md (پیش‌فرض) | k-dialog--lg
3
+ *
4
+ * متغیرها: --k-dialog-width --k-dialog-radius --k-dialog-padding
5
+ */
6
+ .k-dialog {
7
+ --_p: var(--k-dialog-padding, var(--k-space-6));
8
+
9
+ inline-size: min(var(--k-dialog-width, 30rem), calc(100vw - 2rem));
10
+ max-block-size: calc(100dvh - 2rem);
11
+ margin: auto;
12
+ padding: 0;
13
+ border: 1px solid var(--k-border-secondary);
14
+ border-radius: var(--k-dialog-radius, var(--k-radius-2xl));
15
+ background: var(--k-bg-elevated);
16
+ color: var(--k-text-primary);
17
+ box-shadow: var(--k-shadow-2xl), var(--k-highlight);
18
+ overflow: auto;
19
+ }
20
+ .k-dialog--sm { --k-dialog-width: 24rem; }
21
+ .k-dialog--lg { --k-dialog-width: 42rem; }
22
+
23
+ .k-dialog::backdrop {
24
+ background: rgb(8 9 12 / 0.6);
25
+ backdrop-filter: blur(4px);
26
+ }
27
+ .k-dialog[open] { animation: k-dialog-in var(--k-duration-normal) var(--k-ease-emphasized); }
28
+ .k-dialog[open]::backdrop { animation: k-fade-in var(--k-duration-normal) var(--k-ease-standard); }
29
+ @keyframes k-dialog-in { from { opacity: 0; scale: 0.96; translate: 0 8px; } }
30
+ @keyframes k-fade-in { from { opacity: 0; } }
31
+
32
+ .k-dialog__header {
33
+ display: flex;
34
+ align-items: flex-start;
35
+ gap: var(--k-space-4);
36
+ padding: var(--_p) var(--_p) 0;
37
+ }
38
+ .k-dialog__icon {
39
+ display: grid;
40
+ place-items: center;
41
+ flex-shrink: 0;
42
+ inline-size: 3rem;
43
+ block-size: 3rem;
44
+ border-radius: 50%;
45
+ background: var(--k-bg-brand-subtle);
46
+ color: var(--k-text-brand);
47
+ box-shadow: 0 0 0 8px color-mix(in srgb, var(--k-bg-brand-subtle) 50%, transparent);
48
+ }
49
+ .k-dialog__icon svg { inline-size: 1.5rem; block-size: 1.5rem; }
50
+ .k-dialog--danger .k-dialog__icon { background: var(--k-bg-error-subtle); color: var(--k-text-error); box-shadow: 0 0 0 8px color-mix(in srgb, var(--k-bg-error-subtle) 50%, transparent); }
51
+ .k-dialog__heading { flex: 1; display: grid; gap: var(--k-space-1); padding-block-start: var(--k-space-1); }
52
+ .k-dialog__title { margin: 0; font-size: var(--k-text-lg); font-weight: var(--k-weight-semibold); line-height: var(--k-leading-tight); }
53
+ .k-dialog__description { margin: 0; color: var(--k-text-tertiary); font-size: var(--k-text-sm); line-height: var(--k-leading-normal); }
54
+ .k-dialog__close { margin-block: -0.25rem; margin-inline-end: -0.5rem; }
55
+ .k-dialog__body { padding: var(--k-space-5) var(--_p) 0; }
56
+ .k-dialog__footer {
57
+ display: flex;
58
+ flex-wrap: wrap;
59
+ justify-content: flex-end;
60
+ gap: var(--k-space-3);
61
+ padding: var(--k-space-6) var(--_p) var(--_p);
62
+ }
63
+ .k-dialog__footer--block > * { flex: 1; }
64
+
65
+ /* قفل اسکرول صفحه هنگام باز بودن */
66
+ html:has(.k-dialog[open]) { overflow: hidden; }
67
+
68
+ @media (max-width: 30rem) {
69
+ .k-dialog__footer { flex-direction: column-reverse; }
70
+ .k-dialog__footer > * { inline-size: 100%; }
71
+ }
72
+ @media (forced-colors: active) {
73
+ .k-dialog { border-color: CanvasText; }
74
+ }
@@ -23,11 +23,16 @@
23
23
  color: var(--k-text-primary);
24
24
  box-shadow: var(--k-shadow-xs);
25
25
  cursor: text;
26
+ font-size: var(--k-text-md);
26
27
  transition:
27
28
  border-color var(--k-duration-fast) var(--k-ease-standard),
28
29
  box-shadow var(--k-duration-fast) var(--k-ease-standard);
29
30
  }
30
31
 
32
+ .k-input:hover:not(:focus-within, :has(:disabled, [aria-invalid="true"])) {
33
+ --_border: var(--k-input-border-hover, var(--k-text-quaternary));
34
+ }
35
+
31
36
  .k-input:focus-within {
32
37
  --_border: var(--k-border-brand);
33
38
  box-shadow: var(--k-shadow-xs), var(--_ring);
@@ -59,6 +64,17 @@
59
64
  font: inherit;
60
65
  font-size: var(--k-text-md);
61
66
  }
67
+ /* ارقام هم‌عرض تا عدد هنگام تایپ جابه‌جا نشود */
68
+ .k-input__control:is([inputmode="numeric"], [inputmode="tel"], [inputmode="decimal"]) {
69
+ font-variant-numeric: tabular-nums;
70
+ letter-spacing: 0.02em;
71
+ }
72
+
73
+ /* iOS هنگام فوکوس روی فیلدی با متن کوچک‌تر از ۱۶ پیکسل کل صفحه را بزرگ می‌کند */
74
+ @supports (-webkit-touch-callout: none) {
75
+ .k-input__control { font-size: max(16px, 1em); }
76
+ }
77
+
62
78
  .k-input__control::placeholder { color: var(--k-text-tertiary); opacity: 1; }
63
79
  .k-input__control:disabled { color: var(--k-text-quaternary); cursor: not-allowed; }
64
80
 
@@ -93,5 +109,9 @@
93
109
 
94
110
  @media (forced-colors: active) {
95
111
  .k-input { border-color: FieldText; }
96
- .k-input:focus-within { outline-color: Highlight; }
112
+ .k-input:hover:not(:focus-within, :has(:disabled, [aria-invalid="true"])) {
113
+ --_border: var(--k-input-border-hover, var(--k-text-quaternary));
114
+ }
115
+
116
+ .k-input:focus-within { outline-color: Highlight; }
97
117
  }
@@ -0,0 +1,81 @@
1
+ /* رادیو — روی <input type="radio"> بومی؛ برای گروه از <fieldset class="k-radio-group"> استفاده کنید
2
+ * <fieldset class="k-radio-group">
3
+ * <legend class="k-label">روش ارسال</legend>
4
+ * <label class="k-check"><input type="radio" name="ship" class="k-radio"><span class="k-check__text">…</span></label>
5
+ * </fieldset>
6
+ * کارت‌های قابل‌انتخاب: k-radio-group--cards
7
+ *
8
+ * متغیرها: --k-radio-size
9
+ */
10
+ .k-radio {
11
+ --_s: var(--k-radio-size, 1.125rem);
12
+ --_border: var(--k-border-input);
13
+
14
+ appearance: none;
15
+ display: inline-grid;
16
+ place-content: center;
17
+ flex-shrink: 0;
18
+ inline-size: var(--_s);
19
+ block-size: var(--_s);
20
+ margin: 0;
21
+ border: 1px solid var(--_border);
22
+ border-radius: 50%;
23
+ background: var(--k-bg-elevated);
24
+ box-shadow: var(--k-shadow-xs);
25
+ cursor: pointer;
26
+ transition: border-color var(--k-duration-fast), background-color var(--k-duration-fast), box-shadow var(--k-duration-fast);
27
+ }
28
+ .k-radio::before {
29
+ content: "";
30
+ inline-size: calc(var(--_s) * 0.4);
31
+ block-size: calc(var(--_s) * 0.4);
32
+ border-radius: 50%;
33
+ background: var(--k-text-on-brand);
34
+ scale: 0;
35
+ transition: scale var(--k-duration-fast) var(--k-ease-emphasized);
36
+ }
37
+ .k-radio:hover:not(:disabled) { --_border: var(--k-border-brand); box-shadow: 0 0 0 4px var(--k-bg-hover); }
38
+ .k-radio:checked { --_border: var(--k-bg-brand); background: var(--k-bg-brand); }
39
+ .k-radio:checked::before { scale: 1; }
40
+ .k-radio:focus-visible { outline: 2px solid transparent; box-shadow: var(--k-ring-brand); }
41
+ .k-radio[aria-invalid="true"] { --_border: var(--k-border-error); }
42
+ .k-radio:disabled { --_border: var(--k-border-secondary); background: var(--k-bg-tertiary); cursor: not-allowed; }
43
+ .k-radio:disabled::before { background: var(--k-text-quaternary); }
44
+
45
+ .k-check > .k-radio { margin-block-start: calc((1.25rem - var(--_s)) / 2); }
46
+
47
+ .k-radio-group {
48
+ display: grid;
49
+ gap: var(--k-space-3);
50
+ min-inline-size: 0;
51
+ margin: 0;
52
+ padding: 0;
53
+ border: 0;
54
+ }
55
+ .k-radio-group > legend { padding: 0; margin-block-end: var(--k-space-3); }
56
+ .k-radio-group--inline { display: flex; flex-wrap: wrap; gap: var(--k-space-3) var(--k-space-6); }
57
+
58
+ /* کارت‌های قابل‌انتخاب (مثل انتخاب پلن یا روش ارسال) */
59
+ .k-radio-group--cards .k-check {
60
+ display: flex;
61
+ padding: var(--k-space-4);
62
+ border: 1px solid var(--k-border-secondary);
63
+ border-radius: var(--k-radius-lg);
64
+ background: var(--k-bg-elevated);
65
+ box-shadow: var(--k-shadow-xs), var(--k-highlight);
66
+ transition: border-color var(--k-duration-fast), box-shadow var(--k-duration-fast);
67
+ }
68
+ .k-radio-group--cards .k-check:hover { border-color: var(--k-border-primary); }
69
+ .k-radio-group--cards .k-check:has(:checked) {
70
+ border-color: var(--k-border-brand);
71
+ box-shadow: 0 0 0 1px var(--k-border-brand), var(--k-shadow-xs);
72
+ }
73
+ .k-radio-group--cards .k-check:has(:focus-visible) { box-shadow: var(--k-ring-brand); }
74
+ .k-radio-group--cards .k-check:has(:focus-visible) .k-radio { box-shadow: none; }
75
+ .k-radio-group--cards .k-check__text { flex: 1; }
76
+
77
+ @media (forced-colors: active) {
78
+ .k-radio { appearance: auto; }
79
+ .k-radio::before { display: none; }
80
+ .k-radio-group--cards .k-check:has(:checked) { outline: 2px solid Highlight; }
81
+ }
@@ -0,0 +1,56 @@
1
+ /* انتخاب از فهرست — <select> بومی با ظاهر کاشی (دسترس‌پذیر و سازگار با گوشی)
2
+ * <div class="k-select"><select class="k-select__control">…</select></div>
3
+ * اندازه‌ها: k-select--sm | k-select--lg — خطا: aria-invalid="true"
4
+ */
5
+ .k-select {
6
+ --_h: var(--k-input-height-md, calc(2.75rem * var(--k-density)));
7
+ position: relative;
8
+ display: flex;
9
+ }
10
+ .k-select--sm { --_h: var(--k-input-height-sm, calc(2.5rem * var(--k-density))); }
11
+ .k-select--lg { --_h: var(--k-input-height-lg, calc(3rem * var(--k-density))); }
12
+
13
+ .k-select__control {
14
+ appearance: none;
15
+ flex: 1;
16
+ min-inline-size: 0;
17
+ block-size: var(--_h);
18
+ padding-inline: calc(0.875rem * var(--k-density)) 2.5rem;
19
+ border: 1px solid var(--k-input-border, var(--k-border-input));
20
+ border-radius: var(--k-input-radius, var(--k-radius-md));
21
+ background: var(--k-input-bg, var(--k-bg-primary));
22
+ color: var(--k-text-primary);
23
+ box-shadow: var(--k-shadow-xs);
24
+ font: inherit;
25
+ font-size: var(--k-text-md);
26
+ cursor: pointer;
27
+ transition: border-color var(--k-duration-fast), box-shadow var(--k-duration-fast);
28
+ }
29
+ .k-select__control:hover:not(:disabled, :focus) { border-color: var(--k-text-quaternary); }
30
+ .k-select__control:focus-visible { outline: 2px solid transparent; border-color: var(--k-border-brand); box-shadow: var(--k-shadow-xs), var(--k-ring-brand); }
31
+ .k-select__control[aria-invalid="true"] { border-color: var(--k-border-error); }
32
+ .k-select__control[aria-invalid="true"]:focus-visible { box-shadow: var(--k-ring-error); }
33
+ .k-select__control:disabled { background: var(--k-bg-secondary); border-color: var(--k-border-secondary); color: var(--k-text-quaternary); box-shadow: none; cursor: not-allowed; }
34
+ .k-select__control:has(option[value=""]:checked) { color: var(--k-text-tertiary); }
35
+ .k-select__control option { background: var(--k-bg-elevated); color: var(--k-text-primary); }
36
+
37
+ /* فلش در انتهای فیلد */
38
+ .k-select::after {
39
+ content: "";
40
+ position: absolute;
41
+ inset-block: 0;
42
+ inset-inline-end: 0.875rem;
43
+ inline-size: 1.125rem;
44
+ margin-block: auto;
45
+ block-size: 1.125rem;
46
+ background: var(--k-text-tertiary);
47
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 8 4 4 4-4'/%3E%3C/svg%3E") center / contain no-repeat;
48
+ pointer-events: none;
49
+ }
50
+
51
+ @supports (-webkit-touch-callout: none) {
52
+ .k-select__control { font-size: max(16px, 1em); }
53
+ }
54
+ @media (forced-colors: active) {
55
+ .k-select::after { background: CanvasText; }
56
+ }
@@ -26,6 +26,7 @@
26
26
  border-radius: var(--k-radius-full);
27
27
  background: var(--_track);
28
28
  cursor: pointer;
29
+ box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.12);
29
30
  transition:
30
31
  background-color var(--k-duration-normal) var(--k-ease-standard),
31
32
  box-shadow var(--k-duration-fast) var(--k-ease-standard);
@@ -37,7 +38,7 @@
37
38
  block-size: calc(var(--_h) - var(--_pad) * 2);
38
39
  border-radius: var(--k-radius-full);
39
40
  background: var(--k-switch-thumb, #fff);
40
- box-shadow: var(--k-shadow-sm);
41
+ box-shadow: 0 1px 3px rgb(10 13 18 / 0.2), 0 1px 2px rgb(10 13 18 / 0.12);
41
42
  transition: margin-inline-start var(--k-duration-normal) var(--k-ease-emphasized);
42
43
  }
43
44
 
@@ -0,0 +1,77 @@
1
+ /* زبانه‌ها (Tabs) — ساختار ARIA را کامپوننت React می‌سازد
2
+ * گونه‌ها: k-tabs--line (پیش‌فرض) | k-tabs--pill | k-tabs--segmented — تمام‌عرض: k-tabs--block
3
+ */
4
+ .k-tabs { display: grid; gap: var(--k-space-4); }
5
+
6
+ .k-tabs__list {
7
+ position: relative;
8
+ display: flex;
9
+ gap: var(--k-space-1);
10
+ overflow-x: auto;
11
+ scrollbar-width: none;
12
+ }
13
+
14
+ .k-tabs__tab {
15
+ position: relative;
16
+ display: inline-flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+ gap: var(--k-space-2);
20
+ min-block-size: calc(2.5rem * var(--k-density));
21
+ padding-inline: var(--k-space-3);
22
+ border: 0;
23
+ border-radius: var(--k-radius-md);
24
+ background: transparent;
25
+ color: var(--k-text-tertiary);
26
+ font: inherit;
27
+ font-size: var(--k-text-sm);
28
+ font-weight: var(--k-weight-semibold);
29
+ white-space: nowrap;
30
+ cursor: pointer;
31
+ transition: color var(--k-duration-fast), background-color var(--k-duration-fast);
32
+ }
33
+ .k-tabs__tab:hover { color: var(--k-text-primary); }
34
+ .k-tabs__tab[aria-selected="true"] { color: var(--k-text-primary); }
35
+ .k-tabs__tab:focus-visible { outline: 2px solid transparent; box-shadow: var(--k-ring-brand); }
36
+ .k-tabs__tab:disabled { color: var(--k-text-quaternary); cursor: not-allowed; }
37
+ .k-tabs__tab .k-badge { font-size: var(--k-text-xs); padding-block: 0; }
38
+
39
+ .k-tabs__panel:focus-visible { outline: 2px solid var(--k-border-brand); outline-offset: 4px; border-radius: var(--k-radius-sm); }
40
+
41
+ /* خطی: خط زیر زبانهٔ فعال */
42
+ .k-tabs--line .k-tabs__list { border-block-end: 1px solid var(--k-border-secondary); gap: var(--k-space-4); }
43
+ .k-tabs--line .k-tabs__tab { padding-inline: var(--k-space-1); border-radius: 0; }
44
+ .k-tabs--line .k-tabs__tab:focus-visible { border-radius: var(--k-radius-sm); }
45
+ .k-tabs--line .k-tabs__tab[aria-selected="true"]::after {
46
+ content: "";
47
+ position: absolute;
48
+ inset-inline: 0;
49
+ inset-block-end: -1px;
50
+ block-size: 2px;
51
+ border-radius: 2px;
52
+ background: var(--k-border-brand);
53
+ }
54
+
55
+ /* قرصی */
56
+ .k-tabs--pill .k-tabs__tab:hover { background: var(--k-bg-hover); }
57
+ .k-tabs--pill .k-tabs__tab[aria-selected="true"] { background: var(--k-bg-brand-subtle); color: var(--k-text-brand); }
58
+
59
+ /* چندبخشی: مثل کنترل iOS */
60
+ .k-tabs--segmented .k-tabs__list {
61
+ inline-size: fit-content;
62
+ padding: 3px;
63
+ border: 1px solid var(--k-border-secondary);
64
+ border-radius: calc(var(--k-radius-md) + 3px);
65
+ background: var(--k-bg-secondary);
66
+ }
67
+ .k-tabs--segmented .k-tabs__tab { min-block-size: calc(2.25rem * var(--k-density)); }
68
+ .k-tabs--segmented .k-tabs__tab[aria-selected="true"] {
69
+ background: var(--k-bg-elevated);
70
+ box-shadow: var(--k-shadow-sm), var(--k-highlight);
71
+ }
72
+ .k-tabs--block .k-tabs__list { inline-size: auto; }
73
+ .k-tabs--block .k-tabs__tab { flex: 1; }
74
+
75
+ @media (forced-colors: active) {
76
+ .k-tabs__tab[aria-selected="true"] { outline: 2px solid Highlight; }
77
+ }
@@ -0,0 +1,76 @@
1
+ /* اعلان کوتاه (Toast) — محل نمایش را کامپوننت <Toaster> می‌سازد
2
+ * رنگ‌ها: neutral | success | error | warning | info
3
+ */
4
+ .k-toaster {
5
+ position: fixed;
6
+ inset-block-end: var(--k-space-6);
7
+ inset-inline-end: var(--k-space-6);
8
+ z-index: var(--k-z-toast);
9
+ display: grid;
10
+ gap: var(--k-space-3);
11
+ inline-size: min(24rem, calc(100vw - 2rem));
12
+ margin: 0;
13
+ padding: 0;
14
+ list-style: none;
15
+ pointer-events: none;
16
+ }
17
+ .k-toaster--top { inset-block: var(--k-space-6) auto; }
18
+ @media (max-width: 30rem) {
19
+ .k-toaster { inset-inline: var(--k-space-4); inset-block-end: var(--k-space-4); inline-size: auto; }
20
+ }
21
+
22
+ .k-toast {
23
+ --_accent: var(--k-text-tertiary);
24
+
25
+ position: relative;
26
+ display: flex;
27
+ align-items: flex-start;
28
+ gap: var(--k-space-3);
29
+ padding: var(--k-space-4);
30
+ border: 1px solid var(--k-border-secondary);
31
+ border-radius: var(--k-radius-xl);
32
+ background: var(--k-bg-elevated);
33
+ color: var(--k-text-primary);
34
+ box-shadow: var(--k-shadow-lg), var(--k-highlight);
35
+ pointer-events: auto;
36
+ animation: k-toast-in var(--k-duration-slow) var(--k-ease-emphasized);
37
+ overflow: hidden;
38
+ }
39
+ .k-toast[data-state="closing"] { animation: k-toast-out var(--k-duration-normal) var(--k-ease-standard) forwards; }
40
+ @keyframes k-toast-in { from { opacity: 0; translate: 0 12px; scale: 0.97; } }
41
+ @keyframes k-toast-out { to { opacity: 0; translate: 0 8px; scale: 0.97; } }
42
+
43
+ .k-toast--success { --_accent: var(--k-text-success); }
44
+ .k-toast--error { --_accent: var(--k-text-error); }
45
+ .k-toast--warning { --_accent: var(--k-text-warning); }
46
+ .k-toast--info { --_accent: var(--k-text-info); }
47
+
48
+ .k-toast__icon { flex-shrink: 0; inline-size: 1.25rem; block-size: 1.25rem; margin-block-start: 0.125rem; color: var(--_accent); }
49
+ .k-toast__icon svg { inline-size: 100%; block-size: 100%; }
50
+ .k-toast__content { flex: 1; display: grid; gap: 0.125rem; min-inline-size: 0; font-size: var(--k-text-sm); }
51
+ .k-toast__title { margin: 0; font-weight: var(--k-weight-semibold); }
52
+ .k-toast__description { margin: 0; color: var(--k-text-tertiary); }
53
+ .k-toast__action { margin-block-start: var(--k-space-2); justify-self: start; }
54
+ .k-toast__close { margin-block: -0.375rem; margin-inline-end: -0.375rem; }
55
+
56
+ /* نوار زمان باقی‌مانده */
57
+ .k-toast__progress {
58
+ position: absolute;
59
+ inset-inline: 0;
60
+ inset-block-end: 0;
61
+ block-size: 2px;
62
+ background: var(--_accent);
63
+ opacity: 0.6;
64
+ transform-origin: var(--_origin, right);
65
+ animation: k-toast-progress linear forwards;
66
+ }
67
+ [dir="ltr"] .k-toast__progress { --_origin: left; }
68
+ .k-toast:is(:hover, :focus-within) .k-toast__progress { animation-play-state: paused; }
69
+ @keyframes k-toast-progress { to { scale: 0 1; } }
70
+
71
+ @media (prefers-reduced-motion: reduce) {
72
+ .k-toast__progress { display: none; }
73
+ }
74
+ @media (forced-colors: active) {
75
+ .k-toast { border-color: CanvasText; }
76
+ }
@@ -0,0 +1,48 @@
1
+ /* راهنمای کوتاه (Tooltip) — با hover و فوکوس، بسته شدن با Esc (WCAG 1.4.13)
2
+ * فقط برای توضیح تکمیلی؛ اطلاعات ضروری را در tooltip پنهان نکنید.
3
+ */
4
+ .k-tooltip-anchor { position: relative; display: inline-flex; }
5
+
6
+ .k-tooltip {
7
+ position: absolute;
8
+ inset-block-end: calc(100% + 8px);
9
+ inset-inline-start: 50%;
10
+ z-index: var(--k-z-dropdown);
11
+ inline-size: max-content;
12
+ max-inline-size: 16rem;
13
+ padding: var(--k-space-1_5) var(--k-space-3);
14
+ border-radius: var(--k-radius-md);
15
+ background: var(--k-tooltip-bg, var(--k-text-primary));
16
+ color: var(--k-tooltip-fg, var(--k-bg-primary));
17
+ box-shadow: var(--k-shadow-lg);
18
+ font-size: var(--k-text-xs);
19
+ font-weight: var(--k-weight-medium);
20
+ line-height: 1.6;
21
+ text-align: center;
22
+ translate: 50% 0;
23
+ pointer-events: auto;
24
+ animation: k-tip-in var(--k-duration-fast) var(--k-ease-standard);
25
+ }
26
+ [dir="ltr"] .k-tooltip { translate: -50% 0; }
27
+ .k-tooltip[hidden] { display: none; }
28
+ .k-tooltip--bottom { inset-block: calc(100% + 8px) auto; }
29
+
30
+ /* پیکان */
31
+ .k-tooltip::after {
32
+ content: "";
33
+ position: absolute;
34
+ inset-block-start: 100%;
35
+ inset-inline-start: 50%;
36
+ translate: 50% 0;
37
+ border: 5px solid transparent;
38
+ border-block-start-color: var(--k-tooltip-bg, var(--k-text-primary));
39
+ }
40
+ [dir="ltr"] .k-tooltip::after { translate: -50% 0; }
41
+ .k-tooltip--bottom::after { inset-block: auto 100%; border-block-start-color: transparent; border-block-end-color: var(--k-tooltip-bg, var(--k-text-primary)); }
42
+ @keyframes k-tip-in { from { opacity: 0; translate: 50% 3px; } }
43
+ [dir="ltr"] .k-tooltip { animation-name: k-tip-in-ltr; }
44
+ @keyframes k-tip-in-ltr { from { opacity: 0; translate: -50% 3px; } }
45
+
46
+ @media (forced-colors: active) {
47
+ .k-tooltip { border: 1px solid CanvasText; }
48
+ }