@mc-markets/ui 1.0.86 → 1.0.90

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 (76) hide show
  1. package/README.md +40 -141
  2. package/dist/404.html +22 -22
  3. package/dist/components/Breadcrumb/Breadcrumb.vue.d.ts +5 -13
  4. package/dist/components/Breadcrumb/Breadcrumb.vue.d.ts.map +1 -1
  5. package/dist/components/Breadcrumb/BreadcrumbSeparator.vue.d.ts +3 -0
  6. package/dist/components/Breadcrumb/BreadcrumbSeparator.vue.d.ts.map +1 -0
  7. package/dist/components/DatePicker/DatePicker.vue.d.ts +1 -1
  8. package/dist/components/DatePicker/DatePicker.vue.d.ts.map +1 -1
  9. package/dist/components/TabCard/TabCard.vue.d.ts.map +1 -1
  10. package/dist/components/Tag/Tag.vue.d.ts +2 -0
  11. package/dist/components/Tag/Tag.vue.d.ts.map +1 -1
  12. package/dist/index.cjs +1 -5
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.ts +1 -2
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.mjs +605 -661
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/style.css +1 -1
  19. package/package.json +1 -1
  20. package/packages/components/Alert/Alert.vue +139 -139
  21. package/packages/components/Banner/Banner.vue +299 -299
  22. package/packages/components/Breadcrumb/Breadcrumb.vue +113 -77
  23. package/packages/components/Breadcrumb/BreadcrumbSeparator.vue +31 -0
  24. package/packages/components/Button/Button.vue +17 -17
  25. package/packages/components/DatePicker/DatePicker.vue +85 -86
  26. package/packages/components/Dialog/Dialog.vue +61 -61
  27. package/packages/components/Empty/Empty.vue +74 -74
  28. package/packages/components/Form/Form.vue +30 -30
  29. package/packages/components/FormItem/FormItem.vue +19 -19
  30. package/packages/components/Icon/Icon.vue +210 -210
  31. package/packages/components/Input/Input.vue +15 -15
  32. package/packages/components/Message/Message.vue +503 -503
  33. package/packages/components/NotifiMessage/NotifiMessage.vue +293 -293
  34. package/packages/components/Notification/Notification.vue +19 -19
  35. package/packages/components/Option/Option.vue +13 -13
  36. package/packages/components/OptionGroup/OptionGroup.vue +13 -13
  37. package/packages/components/Pagination/Pagination.vue +61 -61
  38. package/packages/components/Radio/Radio.vue +67 -67
  39. package/packages/components/RadioButton/RadioButton.vue +110 -110
  40. package/packages/components/RadioGroup/RadioGroup.vue +155 -155
  41. package/packages/components/Select/Select.vue +22 -22
  42. package/packages/components/Switch/Switch.vue +47 -47
  43. package/packages/components/TabCard/TabCard.vue +107 -177
  44. package/packages/components/TabCard/TabCardItem.vue +105 -102
  45. package/packages/components/Table/Table.vue +17 -17
  46. package/packages/components/Table/TableColumn.vue +20 -20
  47. package/packages/components/Tabs/TabPane.vue +79 -79
  48. package/packages/components/Tabs/Tabs.vue +267 -267
  49. package/packages/components/Tag/Tag.vue +211 -164
  50. package/packages/components/Tooltip/Tooltip.vue +58 -58
  51. package/packages/hooks/useClassName.js +23 -23
  52. package/packages/styles/README.md +129 -129
  53. package/packages/styles/components/button.scss +121 -121
  54. package/packages/styles/components/checkbox.scss +18 -18
  55. package/packages/styles/components/dialog.scss +47 -47
  56. package/packages/styles/components/form.scss +18 -18
  57. package/packages/styles/components/input.scss +14 -14
  58. package/packages/styles/components/select.scss +62 -60
  59. package/packages/styles/components/table.scss +37 -37
  60. package/packages/styles/components/tabs.scss +76 -76
  61. package/packages/styles/components/tag.scss +142 -142
  62. package/packages/styles/font/iconfont.scss +363 -363
  63. package/packages/styles/index.scss +94 -94
  64. package/packages/styles/variables/border-mode.css +6 -6
  65. package/packages/styles/variables/color-modes-dark.css +143 -143
  66. package/packages/styles/variables/index.scss +5 -5
  67. package/packages/styles/variables/primitives-style.css +112 -112
  68. package/packages/styles/variables/radius-mode.css +14 -14
  69. package/packages/styles/variables/spacing-mode.css +20 -20
  70. package/packages/styles/variables/typography-desktop.css +40 -40
  71. package/packages/styles/variables/typography-mobile.css +40 -40
  72. package/packages/utils/classNames.js +23 -23
  73. package/packages/utils/styleUtils.js +105 -105
  74. package/dist/components/Breadcrumb/BreadcrumbItem.vue.d.ts +0 -17
  75. package/dist/components/Breadcrumb/BreadcrumbItem.vue.d.ts.map +0 -1
  76. package/packages/components/Breadcrumb/BreadcrumbItem.vue +0 -142
@@ -1,79 +1,79 @@
1
- <template>
2
- <div
3
- v-show="isActive"
4
- class="m-tab-pane"
5
- :class="{ 'is-active': isActive }"
6
- >
7
- <slot></slot>
8
- </div>
9
- </template>
10
-
11
- <script>
12
- import { inject, computed, onMounted, onUnmounted } from 'vue'
13
-
14
- export default {
15
- name: 'MTabPane',
16
- props: {
17
- label: {
18
- type: String,
19
- required: true
20
- },
21
- name: {
22
- type: [String, Number],
23
- default: ''
24
- },
25
- disabled: {
26
- type: Boolean,
27
- default: false
28
- },
29
- closable: {
30
- type: Boolean,
31
- default: false
32
- }
33
- },
34
- setup(props) {
35
- const tabsContext = inject('tabsContext')
36
-
37
- // 计算tab名称,如果没有提供name则使用label
38
- const tabName = computed(() => {
39
- return props.name || props.label
40
- })
41
-
42
- // 计算是否激活
43
- const isActive = computed(() => {
44
- return tabsContext.activeTab.value === tabName.value
45
- })
46
-
47
- // 组件挂载时注册tab
48
- onMounted(() => {
49
- const tabInfo = {
50
- label: props.label,
51
- name: tabName.value,
52
- disabled: props.disabled,
53
- closable: props.closable
54
- }
55
- tabsContext.registerTab(tabInfo)
56
- })
57
-
58
- // 组件卸载时注销tab
59
- onUnmounted(() => {
60
- tabsContext.unregisterTab(tabName.value)
61
- })
62
-
63
- return {
64
- isActive,
65
- tabName
66
- }
67
- }
68
- }
69
- </script>
70
-
71
- <style lang="scss" scoped>
72
- .m-tab-pane {
73
- display: none;
74
-
75
- &.is-active {
76
- display: block;
77
- }
78
- }
79
- </style>
1
+ <template>
2
+ <div
3
+ v-show="isActive"
4
+ class="m-tab-pane"
5
+ :class="{ 'is-active': isActive }"
6
+ >
7
+ <slot></slot>
8
+ </div>
9
+ </template>
10
+
11
+ <script>
12
+ import { inject, computed, onMounted, onUnmounted } from 'vue'
13
+
14
+ export default {
15
+ name: 'MTabPane',
16
+ props: {
17
+ label: {
18
+ type: String,
19
+ required: true
20
+ },
21
+ name: {
22
+ type: [String, Number],
23
+ default: ''
24
+ },
25
+ disabled: {
26
+ type: Boolean,
27
+ default: false
28
+ },
29
+ closable: {
30
+ type: Boolean,
31
+ default: false
32
+ }
33
+ },
34
+ setup(props) {
35
+ const tabsContext = inject('tabsContext')
36
+
37
+ // 计算tab名称,如果没有提供name则使用label
38
+ const tabName = computed(() => {
39
+ return props.name || props.label
40
+ })
41
+
42
+ // 计算是否激活
43
+ const isActive = computed(() => {
44
+ return tabsContext.activeTab.value === tabName.value
45
+ })
46
+
47
+ // 组件挂载时注册tab
48
+ onMounted(() => {
49
+ const tabInfo = {
50
+ label: props.label,
51
+ name: tabName.value,
52
+ disabled: props.disabled,
53
+ closable: props.closable
54
+ }
55
+ tabsContext.registerTab(tabInfo)
56
+ })
57
+
58
+ // 组件卸载时注销tab
59
+ onUnmounted(() => {
60
+ tabsContext.unregisterTab(tabName.value)
61
+ })
62
+
63
+ return {
64
+ isActive,
65
+ tabName
66
+ }
67
+ }
68
+ }
69
+ </script>
70
+
71
+ <style lang="scss" scoped>
72
+ .m-tab-pane {
73
+ display: none;
74
+
75
+ &.is-active {
76
+ display: block;
77
+ }
78
+ }
79
+ </style>
@@ -1,267 +1,267 @@
1
- <template>
2
- <div class="m-tabs" :class="{ 'style-solid': styleType === 'solid' }">
3
- <div class="m-tabs__header">
4
- <div class="m-tabs__nav" ref="navRef">
5
- <div
6
- v-for="(tab, index) in tabs"
7
- :key="tab.name"
8
- :class="[
9
- 'm-tabs__item',
10
- { 'is-active': activeTab === tab.name }
11
- ]"
12
- @click="handleTabClick(tab.name)"
13
- >
14
- {{ tab.label }}
15
- </div>
16
- <div
17
- v-if="styleType !== 'solid'"
18
- class="m-tabs__active-bar"
19
- :style="activeBarStyle"
20
- ></div>
21
- </div>
22
- </div>
23
- <div class="m-tabs__content">
24
- <slot></slot>
25
- </div>
26
- </div>
27
- </template>
28
-
29
- <script>
30
- import { ref, reactive, computed, onMounted, nextTick, provide, watch } from 'vue'
31
-
32
- export default {
33
- name: 'MTabs',
34
- props: {
35
- modelValue: {
36
- type: [String, Number],
37
- default: ''
38
- },
39
- closable: {
40
- type: Boolean,
41
- default: false
42
- },
43
- styleType: {
44
- type: String,
45
- default: 'default',
46
- validator: (value) => ['default', 'solid'].includes(value)
47
- }
48
- },
49
- emits: ['update:modelValue', 'tab-click', 'tab-remove', 'tab-change', 'tab-add', 'edit'],
50
- setup(props, { emit }) {
51
- const navRef = ref(null)
52
- const tabs = ref([])
53
- const activeTab = ref(props.modelValue)
54
-
55
- // 活动条样式
56
- const activeBarStyle = ref({ width: '0px', left: '0px' })
57
-
58
- // 更新活动条位置
59
- const updateActiveBarPosition = () => {
60
- nextTick(() => {
61
- if (!navRef.value || tabs.value.length === 0) {
62
- activeBarStyle.value = { width: '0px', left: '0px' }
63
- return
64
- }
65
-
66
- const activeTabName = activeTab.value
67
- if (!activeTabName) {
68
- activeBarStyle.value = { width: '0px', left: '0px' }
69
- return
70
- }
71
-
72
- const activeIndex = tabs.value.findIndex(tab => tab.name === activeTabName)
73
- if (activeIndex === -1) {
74
- activeBarStyle.value = { width: '0px', left: '0px' }
75
- return
76
- }
77
-
78
- const navItems = navRef.value.querySelectorAll('.m-tabs__item')
79
- const activeItem = navItems[activeIndex]
80
-
81
- if (!activeItem) {
82
- activeBarStyle.value = { width: '0px', left: '0px' }
83
- return
84
- }
85
-
86
- // 计算居中位置:tab中心位置 - 8px(16px宽度的一半)
87
- const centerLeft = activeItem.offsetLeft + (activeItem.offsetWidth / 2) - 8
88
-
89
- activeBarStyle.value = {
90
- width: '16px',
91
- left: `${centerLeft}px`
92
- }
93
- })
94
- }
95
-
96
- // 处理tab点击
97
- const handleTabClick = (tabName) => {
98
- if (tabName === activeTab.value) return
99
-
100
- const oldValue = activeTab.value
101
- activeTab.value = tabName
102
- emit('update:modelValue', tabName)
103
- emit('tab-click', tabName)
104
- emit('tab-change', tabName, oldValue)
105
- updateActiveBarPosition()
106
- }
107
-
108
- // 处理tab关闭
109
- const handleTabRemove = (tabName) => {
110
- emit('tab-remove', tabName)
111
- emit('edit', tabName, 'remove')
112
- }
113
-
114
- // 处理tab添加
115
- const handleTabAdd = () => {
116
- emit('tab-add')
117
- emit('edit', null, 'add')
118
- }
119
-
120
- // 注册tab
121
- const registerTab = (tab) => {
122
- const index = tabs.value.findIndex(t => t.name === tab.name)
123
- if (index === -1) {
124
- tabs.value.push(tab)
125
- } else {
126
- tabs.value[index] = tab
127
- }
128
- }
129
-
130
- // 注销tab
131
- const unregisterTab = (tabName) => {
132
- const index = tabs.value.findIndex(t => t.name === tabName)
133
- if (index > -1) {
134
- tabs.value.splice(index, 1)
135
- }
136
- }
137
-
138
- // 提供给子组件的方法
139
- provide('tabsContext', {
140
- activeTab,
141
- registerTab,
142
- unregisterTab,
143
- handleTabRemove,
144
- handleTabAdd
145
- })
146
-
147
- // 监听modelValue变化
148
- watch(() => props.modelValue, (newValue, oldValue) => {
149
- if (newValue !== activeTab.value) {
150
- activeTab.value = newValue
151
- emit('tab-change', newValue, oldValue)
152
- updateActiveBarPosition()
153
- }
154
- })
155
-
156
- // 监听tabs变化
157
- watch(tabs, () => {
158
- updateActiveBarPosition()
159
- }, { deep: true })
160
-
161
- // 初始化时设置默认active tab
162
- onMounted(() => {
163
- if (!activeTab.value && tabs.value.length > 0) {
164
- const firstTab = tabs.value[0]
165
- activeTab.value = firstTab.name
166
- emit('update:modelValue', activeTab.value)
167
- }
168
- updateActiveBarPosition()
169
- })
170
-
171
- return {
172
- navRef,
173
- tabs,
174
- activeTab,
175
- activeBarStyle,
176
- handleTabClick,
177
- handleTabRemove,
178
- handleTabAdd,
179
- registerTab,
180
- unregisterTab,
181
- updateActiveBarPosition
182
- }
183
- }
184
- }
185
- </script>
186
-
187
- <style lang="scss" scoped>
188
- .m-tabs {
189
- &__header {
190
- position: relative;
191
- }
192
-
193
- &__nav {
194
- position: relative;
195
- display: flex;
196
- border-bottom: 1px solid var(--border-primary);
197
- }
198
-
199
- &__item {
200
- position: relative;
201
- height: 24px;
202
- margin-right: 20px;
203
- margin-bottom: 6px;
204
- cursor: pointer;
205
- color: var(--text-tertiary);
206
- font-size: var(--font-size-text-base);
207
- transition: color 0.3s;
208
- user-select: none;
209
- font-weight: 600;
210
-
211
- &:hover {
212
- color: var(--text-brand);
213
- }
214
-
215
- &.is-active {
216
- color: var(--text-brand);
217
- }
218
-
219
- &:last-child {
220
- margin-right: 0;
221
- }
222
- }
223
-
224
- &__active-bar {
225
- position: absolute;
226
- bottom: 0;
227
- height: 3px;
228
- background-color: var(--text-brand);
229
- transition: all 0.3s;
230
- z-index: 1;
231
- }
232
-
233
- // solid 样式
234
- &.style-solid {
235
- .m-tabs__nav {
236
- border-bottom: none;
237
- background-color: var(--bg-tertiary-hover);
238
- border-radius: 8px;
239
- padding: 4px;
240
- }
241
-
242
- .m-tabs__item {
243
- height: 32px;
244
- margin-right: 0;
245
- margin-bottom: 0;
246
- padding: 0 16px;
247
- border-radius: 6px;
248
- display: flex;
249
- align-items: center;
250
- justify-content: center;
251
- background-color: transparent;
252
- transition: all 0.3s;
253
-
254
- &:hover {
255
- background-color: rgba(0, 0, 0, 0.05);
256
- }
257
-
258
- &.is-active {
259
- background-color: var(--bg-primary);
260
- color: var(--text-primary);
261
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
262
- }
263
- }
264
- }
265
- }
266
-
267
- </style>
1
+ <template>
2
+ <div class="m-tabs" :class="{ 'style-solid': styleType === 'solid' }">
3
+ <div class="m-tabs__header">
4
+ <div class="m-tabs__nav" ref="navRef">
5
+ <div
6
+ v-for="(tab, index) in tabs"
7
+ :key="tab.name"
8
+ :class="[
9
+ 'm-tabs__item',
10
+ { 'is-active': activeTab === tab.name }
11
+ ]"
12
+ @click="handleTabClick(tab.name)"
13
+ >
14
+ {{ tab.label }}
15
+ </div>
16
+ <div
17
+ v-if="styleType !== 'solid'"
18
+ class="m-tabs__active-bar"
19
+ :style="activeBarStyle"
20
+ ></div>
21
+ </div>
22
+ </div>
23
+ <div class="m-tabs__content">
24
+ <slot></slot>
25
+ </div>
26
+ </div>
27
+ </template>
28
+
29
+ <script>
30
+ import { ref, reactive, computed, onMounted, nextTick, provide, watch } from 'vue'
31
+
32
+ export default {
33
+ name: 'MTabs',
34
+ props: {
35
+ modelValue: {
36
+ type: [String, Number],
37
+ default: ''
38
+ },
39
+ closable: {
40
+ type: Boolean,
41
+ default: false
42
+ },
43
+ styleType: {
44
+ type: String,
45
+ default: 'default',
46
+ validator: (value) => ['default', 'solid'].includes(value)
47
+ }
48
+ },
49
+ emits: ['update:modelValue', 'tab-click', 'tab-remove', 'tab-change', 'tab-add', 'edit'],
50
+ setup(props, { emit }) {
51
+ const navRef = ref(null)
52
+ const tabs = ref([])
53
+ const activeTab = ref(props.modelValue)
54
+
55
+ // 活动条样式
56
+ const activeBarStyle = ref({ width: '0px', left: '0px' })
57
+
58
+ // 更新活动条位置
59
+ const updateActiveBarPosition = () => {
60
+ nextTick(() => {
61
+ if (!navRef.value || tabs.value.length === 0) {
62
+ activeBarStyle.value = { width: '0px', left: '0px' }
63
+ return
64
+ }
65
+
66
+ const activeTabName = activeTab.value
67
+ if (!activeTabName) {
68
+ activeBarStyle.value = { width: '0px', left: '0px' }
69
+ return
70
+ }
71
+
72
+ const activeIndex = tabs.value.findIndex(tab => tab.name === activeTabName)
73
+ if (activeIndex === -1) {
74
+ activeBarStyle.value = { width: '0px', left: '0px' }
75
+ return
76
+ }
77
+
78
+ const navItems = navRef.value.querySelectorAll('.m-tabs__item')
79
+ const activeItem = navItems[activeIndex]
80
+
81
+ if (!activeItem) {
82
+ activeBarStyle.value = { width: '0px', left: '0px' }
83
+ return
84
+ }
85
+
86
+ // 计算居中位置:tab中心位置 - 8px(16px宽度的一半)
87
+ const centerLeft = activeItem.offsetLeft + (activeItem.offsetWidth / 2) - 8
88
+
89
+ activeBarStyle.value = {
90
+ width: '16px',
91
+ left: `${centerLeft}px`
92
+ }
93
+ })
94
+ }
95
+
96
+ // 处理tab点击
97
+ const handleTabClick = (tabName) => {
98
+ if (tabName === activeTab.value) return
99
+
100
+ const oldValue = activeTab.value
101
+ activeTab.value = tabName
102
+ emit('update:modelValue', tabName)
103
+ emit('tab-click', tabName)
104
+ emit('tab-change', tabName, oldValue)
105
+ updateActiveBarPosition()
106
+ }
107
+
108
+ // 处理tab关闭
109
+ const handleTabRemove = (tabName) => {
110
+ emit('tab-remove', tabName)
111
+ emit('edit', tabName, 'remove')
112
+ }
113
+
114
+ // 处理tab添加
115
+ const handleTabAdd = () => {
116
+ emit('tab-add')
117
+ emit('edit', null, 'add')
118
+ }
119
+
120
+ // 注册tab
121
+ const registerTab = (tab) => {
122
+ const index = tabs.value.findIndex(t => t.name === tab.name)
123
+ if (index === -1) {
124
+ tabs.value.push(tab)
125
+ } else {
126
+ tabs.value[index] = tab
127
+ }
128
+ }
129
+
130
+ // 注销tab
131
+ const unregisterTab = (tabName) => {
132
+ const index = tabs.value.findIndex(t => t.name === tabName)
133
+ if (index > -1) {
134
+ tabs.value.splice(index, 1)
135
+ }
136
+ }
137
+
138
+ // 提供给子组件的方法
139
+ provide('tabsContext', {
140
+ activeTab,
141
+ registerTab,
142
+ unregisterTab,
143
+ handleTabRemove,
144
+ handleTabAdd
145
+ })
146
+
147
+ // 监听modelValue变化
148
+ watch(() => props.modelValue, (newValue, oldValue) => {
149
+ if (newValue !== activeTab.value) {
150
+ activeTab.value = newValue
151
+ emit('tab-change', newValue, oldValue)
152
+ updateActiveBarPosition()
153
+ }
154
+ })
155
+
156
+ // 监听tabs变化
157
+ watch(tabs, () => {
158
+ updateActiveBarPosition()
159
+ }, { deep: true })
160
+
161
+ // 初始化时设置默认active tab
162
+ onMounted(() => {
163
+ if (!activeTab.value && tabs.value.length > 0) {
164
+ const firstTab = tabs.value[0]
165
+ activeTab.value = firstTab.name
166
+ emit('update:modelValue', activeTab.value)
167
+ }
168
+ updateActiveBarPosition()
169
+ })
170
+
171
+ return {
172
+ navRef,
173
+ tabs,
174
+ activeTab,
175
+ activeBarStyle,
176
+ handleTabClick,
177
+ handleTabRemove,
178
+ handleTabAdd,
179
+ registerTab,
180
+ unregisterTab,
181
+ updateActiveBarPosition
182
+ }
183
+ }
184
+ }
185
+ </script>
186
+
187
+ <style lang="scss" scoped>
188
+ .m-tabs {
189
+ &__header {
190
+ position: relative;
191
+ }
192
+
193
+ &__nav {
194
+ position: relative;
195
+ display: flex;
196
+ border-bottom: 1px solid var(--border-primary);
197
+ }
198
+
199
+ &__item {
200
+ position: relative;
201
+ height: 24px;
202
+ margin-right: 20px;
203
+ margin-bottom: 6px;
204
+ cursor: pointer;
205
+ color: var(--text-tertiary);
206
+ font-size: var(--font-size-text-base);
207
+ transition: color 0.3s;
208
+ user-select: none;
209
+ font-weight: 600;
210
+
211
+ &:hover {
212
+ color: var(--text-brand);
213
+ }
214
+
215
+ &.is-active {
216
+ color: var(--text-brand);
217
+ }
218
+
219
+ &:last-child {
220
+ margin-right: 0;
221
+ }
222
+ }
223
+
224
+ &__active-bar {
225
+ position: absolute;
226
+ bottom: 0;
227
+ height: 3px;
228
+ background-color: var(--text-brand);
229
+ transition: all 0.3s;
230
+ z-index: 1;
231
+ }
232
+
233
+ // solid 样式
234
+ &.style-solid {
235
+ .m-tabs__nav {
236
+ border-bottom: none;
237
+ background-color: var(--bg-tertiary-hover);
238
+ border-radius: 8px;
239
+ padding: 4px;
240
+ }
241
+
242
+ .m-tabs__item {
243
+ height: 32px;
244
+ margin-right: 0;
245
+ margin-bottom: 0;
246
+ padding: 0 16px;
247
+ border-radius: 6px;
248
+ display: flex;
249
+ align-items: center;
250
+ justify-content: center;
251
+ background-color: transparent;
252
+ transition: all 0.3s;
253
+
254
+ &:hover {
255
+ background-color: rgba(0, 0, 0, 0.05);
256
+ }
257
+
258
+ &.is-active {
259
+ background-color: var(--bg-primary);
260
+ color: var(--text-primary);
261
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
262
+ }
263
+ }
264
+ }
265
+ }
266
+
267
+ </style>