ciderui 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.
- package/README.md +106 -0
- package/js/carousel.js +77 -0
- package/js/combobox.js +125 -0
- package/js/command.js +91 -0
- package/js/context-menu.js +49 -0
- package/js/dialog.js +18 -0
- package/js/dropdown-menu.js +39 -0
- package/js/otp.js +92 -0
- package/js/popover.js +35 -0
- package/js/select.js +56 -0
- package/js/sheet.js +17 -0
- package/js/tabs.js +34 -0
- package/js/toast.js +60 -0
- package/js/toggle.js +26 -0
- package/package.json +53 -0
- package/src/css/ciderui.cdn.css +11 -0
- package/src/css/ciderui.css +324 -0
- package/src/css/components/accordion.css +31 -0
- package/src/css/components/alert.css +18 -0
- package/src/css/components/aspect-ratio.css +7 -0
- package/src/css/components/avatar.css +17 -0
- package/src/css/components/badge.css +20 -0
- package/src/css/components/breadcrumb.css +16 -0
- package/src/css/components/button-group.css +20 -0
- package/src/css/components/button.css +59 -0
- package/src/css/components/card.css +37 -0
- package/src/css/components/carousel.css +60 -0
- package/src/css/components/checkbox.css +16 -0
- package/src/css/components/collapsible.css +25 -0
- package/src/css/components/combobox.css +69 -0
- package/src/css/components/command.css +64 -0
- package/src/css/components/context-menu.css +28 -0
- package/src/css/components/dialog.css +23 -0
- package/src/css/components/drawer.css +69 -0
- package/src/css/components/dropdown-menu.css +28 -0
- package/src/css/components/empty.css +12 -0
- package/src/css/components/field.css +7 -0
- package/src/css/components/file-tree.css +53 -0
- package/src/css/components/form-controls.css +57 -0
- package/src/css/components/form.css +15 -0
- package/src/css/components/hover-card.css +25 -0
- package/src/css/components/input-group.css +48 -0
- package/src/css/components/input-otp.css +22 -0
- package/src/css/components/item.css +43 -0
- package/src/css/components/kbd.css +7 -0
- package/src/css/components/label.css +4 -0
- package/src/css/components/pagination.css +15 -0
- package/src/css/components/popover.css +19 -0
- package/src/css/components/progress.css +18 -0
- package/src/css/components/radio.css +13 -0
- package/src/css/components/scroll-area.css +24 -0
- package/src/css/components/separator.css +19 -0
- package/src/css/components/sheet.css +46 -0
- package/src/css/components/sidebar.css +32 -0
- package/src/css/components/skeleton.css +9 -0
- package/src/css/components/slider.css +48 -0
- package/src/css/components/spinner.css +12 -0
- package/src/css/components/switch.css +28 -0
- package/src/css/components/table.css +39 -0
- package/src/css/components/tabs.css +44 -0
- package/src/css/components/theme-switcher.css +17 -0
- package/src/css/components/toast.css +22 -0
- package/src/css/components/toggle.css +34 -0
- package/src/css/components/tooltip.css +66 -0
- package/src/css/components/typography.css +84 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/* ========== INPUT GROUP ========== */
|
|
2
|
+
.input-group {
|
|
3
|
+
@apply relative;
|
|
4
|
+
& .input-group-icon {
|
|
5
|
+
@apply absolute top-1/2 -translate-y-1/2 pointer-events-none text-muted-foreground;
|
|
6
|
+
& svg { @apply size-4; }
|
|
7
|
+
}
|
|
8
|
+
& .input-group-icon-left {
|
|
9
|
+
@apply left-3;
|
|
10
|
+
}
|
|
11
|
+
& .input-group-icon-right {
|
|
12
|
+
@apply right-3;
|
|
13
|
+
}
|
|
14
|
+
& .input-group-text {
|
|
15
|
+
@apply absolute top-1/2 -translate-y-1/2 pointer-events-none text-muted-foreground text-[13px];
|
|
16
|
+
}
|
|
17
|
+
& .input-group-text-left {
|
|
18
|
+
@apply left-3;
|
|
19
|
+
}
|
|
20
|
+
& .input-group-text-right {
|
|
21
|
+
@apply right-3;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
.input-group-attached {
|
|
25
|
+
@apply flex items-stretch;
|
|
26
|
+
& .input-group-addon {
|
|
27
|
+
@apply flex items-center border px-3 text-[13px] text-muted-foreground;
|
|
28
|
+
background: var(--muted);
|
|
29
|
+
}
|
|
30
|
+
& .input-group-addon:first-child {
|
|
31
|
+
@apply rounded-l-xl border-r-0;
|
|
32
|
+
}
|
|
33
|
+
& .input-group-addon:last-child {
|
|
34
|
+
@apply rounded-r-xl border-l-0;
|
|
35
|
+
}
|
|
36
|
+
& .input, & input {
|
|
37
|
+
@apply flex-1;
|
|
38
|
+
}
|
|
39
|
+
& .input:not(:first-child):not(:last-child), & input:not(:first-child):not(:last-child) {
|
|
40
|
+
@apply rounded-none;
|
|
41
|
+
}
|
|
42
|
+
& .input:first-child, & input:first-child {
|
|
43
|
+
@apply rounded-r-none;
|
|
44
|
+
}
|
|
45
|
+
& .input:last-child, & input:last-child {
|
|
46
|
+
@apply rounded-l-none;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* ========== INPUT OTP ========== */
|
|
2
|
+
.input-otp {
|
|
3
|
+
@apply flex items-center gap-2;
|
|
4
|
+
}
|
|
5
|
+
.input-otp-slot {
|
|
6
|
+
@apply flex size-12 items-center justify-center rounded-[12px] border text-[17px] font-medium text-foreground;
|
|
7
|
+
border-color: var(--input-border);
|
|
8
|
+
background: var(--surface-1);
|
|
9
|
+
caret-color: transparent;
|
|
10
|
+
transition: border-color 0.2s var(--apple-ease);
|
|
11
|
+
&:focus-within, &[data-active] {
|
|
12
|
+
border-color: var(--primary);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
.input-otp-separator {
|
|
16
|
+
@apply flex items-center text-muted-foreground;
|
|
17
|
+
& span { @apply mx-0.5 text-xl; }
|
|
18
|
+
}
|
|
19
|
+
.input-otp[data-error] .input-otp-slot {
|
|
20
|
+
border-color: var(--destructive);
|
|
21
|
+
color: var(--destructive);
|
|
22
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* ========== ITEM ========== */
|
|
2
|
+
.item {
|
|
3
|
+
@apply flex items-center gap-4 rounded-2xl p-4 text-[13px];
|
|
4
|
+
transition: background-color 0.15s var(--apple-ease);
|
|
5
|
+
& .item-icon {
|
|
6
|
+
@apply flex size-9 shrink-0 items-center justify-center rounded-[10px] text-muted-foreground;
|
|
7
|
+
background: var(--surface-3);
|
|
8
|
+
& svg { @apply size-4; }
|
|
9
|
+
}
|
|
10
|
+
& .item-avatar {
|
|
11
|
+
@apply size-10 shrink-0 rounded-full object-cover;
|
|
12
|
+
}
|
|
13
|
+
& .item-content {
|
|
14
|
+
@apply flex flex-1 flex-col gap-0.5;
|
|
15
|
+
& h3 { @apply text-sm font-medium leading-snug; }
|
|
16
|
+
& p { @apply text-[13px] text-muted-foreground; }
|
|
17
|
+
}
|
|
18
|
+
& .item-action {
|
|
19
|
+
@apply flex items-center gap-2 text-muted-foreground;
|
|
20
|
+
& svg { @apply size-4; }
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
.item-outline {
|
|
24
|
+
box-shadow: var(--float-ring);
|
|
25
|
+
}
|
|
26
|
+
.item-muted {
|
|
27
|
+
background: var(--surface-1);
|
|
28
|
+
}
|
|
29
|
+
a.item, button.item {
|
|
30
|
+
@apply cursor-pointer;
|
|
31
|
+
&:hover { background: var(--surface-2); }
|
|
32
|
+
&:focus-visible { outline: 3px solid oklch(from var(--primary) l c h / 0.3); outline-offset: -3px; }
|
|
33
|
+
}
|
|
34
|
+
.item-group {
|
|
35
|
+
@apply flex flex-col rounded-2xl bg-card;
|
|
36
|
+
box-shadow: var(--shadow-sm), var(--panel-ring);
|
|
37
|
+
& .item { @apply rounded-none; }
|
|
38
|
+
& .item:first-child { @apply rounded-t-2xl; }
|
|
39
|
+
& .item:last-child { @apply rounded-b-2xl; }
|
|
40
|
+
& .item + .item {
|
|
41
|
+
border-top: 1px solid var(--surface-3);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/* ========== KBD ========== */
|
|
2
|
+
.kbd {
|
|
3
|
+
@apply inline-flex h-5 min-w-5 items-center justify-center rounded-[5px] px-1.5 text-[11px] font-medium text-muted-foreground;
|
|
4
|
+
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
|
|
5
|
+
background: var(--surface-3);
|
|
6
|
+
box-shadow: 0 1px 0 var(--panel-border), var(--float-ring);
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* ========== PAGINATION ========== */
|
|
2
|
+
.pagination {
|
|
3
|
+
@apply flex items-center gap-0.5;
|
|
4
|
+
}
|
|
5
|
+
.pagination-item {
|
|
6
|
+
@apply inline-flex h-9 min-w-9 items-center justify-center rounded-[10px] text-[13px] font-medium text-muted-foreground cursor-pointer;
|
|
7
|
+
transition: all 0.2s var(--apple-ease);
|
|
8
|
+
&:hover { background: var(--surface-3); }
|
|
9
|
+
&:focus-visible { outline: 3px solid oklch(from var(--primary) l c h / 0.3); outline-offset: 2px; }
|
|
10
|
+
&[data-active] {
|
|
11
|
+
@apply bg-primary text-primary-foreground;
|
|
12
|
+
box-shadow: var(--shadow-sm);
|
|
13
|
+
}
|
|
14
|
+
&:disabled { @apply pointer-events-none opacity-50; }
|
|
15
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* ========== POPOVER ========== */
|
|
2
|
+
.popover {
|
|
3
|
+
@apply relative inline-block;
|
|
4
|
+
}
|
|
5
|
+
.popover-content {
|
|
6
|
+
@apply absolute z-50 mt-2 min-w-[220px] rounded-2xl p-4;
|
|
7
|
+
display: none;
|
|
8
|
+
background: var(--glass-bg-opaque);
|
|
9
|
+
backdrop-filter: var(--glass-blur);
|
|
10
|
+
-webkit-backdrop-filter: var(--glass-blur);
|
|
11
|
+
box-shadow: var(--shadow-lg), var(--float-ring);
|
|
12
|
+
animation: slideUp 0.2s var(--apple-spring);
|
|
13
|
+
&[data-open] { display: block; }
|
|
14
|
+
}
|
|
15
|
+
.popover-top {
|
|
16
|
+
& .popover-content {
|
|
17
|
+
@apply bottom-full top-auto mb-2 mt-0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* ========== PROGRESS ========== */
|
|
2
|
+
.progress {
|
|
3
|
+
@apply h-1.5 w-full overflow-hidden rounded-full;
|
|
4
|
+
background: var(--surface-4);
|
|
5
|
+
& .progress-bar {
|
|
6
|
+
@apply h-full rounded-full bg-primary;
|
|
7
|
+
transition: width 0.5s var(--apple-spring);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
.progress-sm {
|
|
11
|
+
@apply h-1;
|
|
12
|
+
}
|
|
13
|
+
.progress-indeterminate {
|
|
14
|
+
& .progress-bar {
|
|
15
|
+
@apply w-1/3;
|
|
16
|
+
animation: indeterminate 1.5s ease-in-out infinite;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* ========== RADIO ========== */
|
|
2
|
+
.radio {
|
|
3
|
+
@apply appearance-none size-[18px] shrink-0 rounded-full border bg-card cursor-pointer;
|
|
4
|
+
border-color: var(--input-border);
|
|
5
|
+
transition: all 0.2s var(--apple-ease);
|
|
6
|
+
&:checked {
|
|
7
|
+
border-color: var(--primary);
|
|
8
|
+
border-width: 5px;
|
|
9
|
+
}
|
|
10
|
+
&:hover:not(:focus-visible):not(:checked) { border-color: var(--input-border-hover); }
|
|
11
|
+
&:focus-visible { box-shadow: 0 0 0 4px oklch(from var(--primary) l c h / 0.15); }
|
|
12
|
+
&:disabled { @apply cursor-not-allowed opacity-50; }
|
|
13
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* ========== SCROLL AREA ========== */
|
|
2
|
+
.scroll-area {
|
|
3
|
+
overflow: auto;
|
|
4
|
+
&::-webkit-scrollbar {
|
|
5
|
+
width: 7px;
|
|
6
|
+
height: 7px;
|
|
7
|
+
}
|
|
8
|
+
&::-webkit-scrollbar-track {
|
|
9
|
+
background: transparent;
|
|
10
|
+
}
|
|
11
|
+
&::-webkit-scrollbar-thumb {
|
|
12
|
+
border-radius: 9999px;
|
|
13
|
+
background: var(--surface-6);
|
|
14
|
+
border: 1px solid transparent;
|
|
15
|
+
background-clip: content-box;
|
|
16
|
+
&:hover { background: var(--surface-7); background-clip: content-box; }
|
|
17
|
+
}
|
|
18
|
+
scrollbar-width: thin;
|
|
19
|
+
scrollbar-color: var(--surface-6) transparent;
|
|
20
|
+
}
|
|
21
|
+
.scroll-area-horizontal {
|
|
22
|
+
overflow-x: auto;
|
|
23
|
+
overflow-y: hidden;
|
|
24
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* ========== SEPARATOR ========== */
|
|
2
|
+
.separator {
|
|
3
|
+
@apply shrink-0;
|
|
4
|
+
background: var(--panel-border);
|
|
5
|
+
}
|
|
6
|
+
.separator:not(.separator-vertical) {
|
|
7
|
+
@apply h-px w-full;
|
|
8
|
+
}
|
|
9
|
+
.separator-vertical {
|
|
10
|
+
@apply w-px self-stretch;
|
|
11
|
+
}
|
|
12
|
+
.separator-label {
|
|
13
|
+
@apply flex items-center gap-3 text-xs text-muted-foreground;
|
|
14
|
+
&::before, &::after {
|
|
15
|
+
content: "";
|
|
16
|
+
@apply h-px flex-1;
|
|
17
|
+
background: var(--panel-border);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/* ========== SHEET ========== */
|
|
2
|
+
dialog.sheet,
|
|
3
|
+
.sheet {
|
|
4
|
+
@apply fixed m-0 h-full bg-card text-card-foreground;
|
|
5
|
+
max-height: 100vh;
|
|
6
|
+
max-width: min(420px, 85vw);
|
|
7
|
+
box-shadow: var(--shadow-xl);
|
|
8
|
+
&::backdrop {
|
|
9
|
+
background: var(--backdrop-bg);
|
|
10
|
+
backdrop-filter: var(--glass-blur);
|
|
11
|
+
-webkit-backdrop-filter: var(--glass-blur);
|
|
12
|
+
}
|
|
13
|
+
&[open] { animation: sheetSlideIn 0.35s var(--apple-spring); }
|
|
14
|
+
/* Right (default) */
|
|
15
|
+
&:not(.sheet-left) {
|
|
16
|
+
@apply right-0 top-0;
|
|
17
|
+
border-left: 1px solid var(--panel-border);
|
|
18
|
+
&[open] { animation-name: sheetSlideInRight; }
|
|
19
|
+
}
|
|
20
|
+
/* Left */
|
|
21
|
+
&.sheet-left {
|
|
22
|
+
@apply left-0 top-0;
|
|
23
|
+
border-right: 1px solid var(--panel-border);
|
|
24
|
+
&[open] { animation-name: sheetSlideInLeft; }
|
|
25
|
+
}
|
|
26
|
+
& > header {
|
|
27
|
+
@apply px-6 py-5;
|
|
28
|
+
border-bottom: 1px solid var(--panel-border);
|
|
29
|
+
& h2 { @apply text-[20px] font-semibold tracking-tight text-foreground; }
|
|
30
|
+
& p { @apply mt-1 text-[13px] text-muted-foreground; }
|
|
31
|
+
}
|
|
32
|
+
& > section {
|
|
33
|
+
@apply overflow-y-auto px-6 py-5;
|
|
34
|
+
}
|
|
35
|
+
& > footer {
|
|
36
|
+
@apply px-6 py-4;
|
|
37
|
+
border-top: 1px solid var(--panel-border);
|
|
38
|
+
}
|
|
39
|
+
& .sheet-close {
|
|
40
|
+
@apply absolute right-4 top-4 rounded-full p-1.5 text-muted-foreground cursor-pointer;
|
|
41
|
+
transition: all 0.2s var(--apple-ease);
|
|
42
|
+
&:hover { @apply text-foreground bg-accent; }
|
|
43
|
+
&:focus-visible { outline: 3px solid oklch(from var(--primary) l c h / 0.3); outline-offset: 2px; }
|
|
44
|
+
& svg { @apply size-4; }
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* ========== SIDEBAR ========== */
|
|
2
|
+
.sidebar {
|
|
3
|
+
@apply fixed left-0 top-0 flex h-full w-[260px] flex-col;
|
|
4
|
+
background: var(--glass-bg);
|
|
5
|
+
backdrop-filter: var(--glass-blur);
|
|
6
|
+
-webkit-backdrop-filter: var(--glass-blur);
|
|
7
|
+
border-right: 1px solid var(--panel-border);
|
|
8
|
+
& .sidebar-header {
|
|
9
|
+
@apply flex items-center gap-2.5 px-5 py-4;
|
|
10
|
+
border-bottom: 1px solid var(--panel-border);
|
|
11
|
+
& h2 { @apply text-[13px] font-semibold tracking-tight; }
|
|
12
|
+
}
|
|
13
|
+
& .sidebar-content {
|
|
14
|
+
@apply flex-1 overflow-y-auto px-3 py-3;
|
|
15
|
+
}
|
|
16
|
+
& .sidebar-section {
|
|
17
|
+
@apply mb-4;
|
|
18
|
+
& h3 { @apply mb-1 px-2 text-[11px] font-semibold text-muted-foreground; }
|
|
19
|
+
}
|
|
20
|
+
& .sidebar-item {
|
|
21
|
+
@apply flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-[13px] text-foreground/70 cursor-pointer;
|
|
22
|
+
transition: all 0.15s var(--apple-ease);
|
|
23
|
+
& svg { @apply size-4 text-muted-foreground; }
|
|
24
|
+
&:hover { background: var(--surface-3); @apply text-foreground; }
|
|
25
|
+
&:focus-visible { outline: 3px solid oklch(from var(--primary) l c h / 0.3); outline-offset: -3px; }
|
|
26
|
+
&[data-active] { background: var(--surface-4); @apply text-foreground font-medium; }
|
|
27
|
+
}
|
|
28
|
+
& .sidebar-footer {
|
|
29
|
+
@apply px-5 py-4;
|
|
30
|
+
border-top: 1px solid var(--panel-border);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/* ========== SLIDER ========== */
|
|
2
|
+
.slider {
|
|
3
|
+
@apply w-full cursor-pointer appearance-none rounded-full;
|
|
4
|
+
height: 4px;
|
|
5
|
+
background: var(--surface-5);
|
|
6
|
+
accent-color: var(--primary);
|
|
7
|
+
&::-webkit-slider-thumb {
|
|
8
|
+
@apply appearance-none rounded-full bg-white;
|
|
9
|
+
width: 22px;
|
|
10
|
+
height: 22px;
|
|
11
|
+
box-shadow: 0 1px 4px oklch(0 0 0 / 0.15), 0 0 0 1px oklch(0 0 0 / 0.04);
|
|
12
|
+
transition: box-shadow 0.2s var(--apple-ease), transform 0.2s var(--apple-ease);
|
|
13
|
+
}
|
|
14
|
+
&::-webkit-slider-thumb:hover {
|
|
15
|
+
box-shadow: 0 2px 8px oklch(0 0 0 / 0.2), 0 0 0 1px oklch(0 0 0 / 0.04);
|
|
16
|
+
transform: scale(1.05);
|
|
17
|
+
}
|
|
18
|
+
&::-webkit-slider-thumb:active {
|
|
19
|
+
box-shadow: 0 1px 3px oklch(0 0 0 / 0.2), 0 0 0 1px oklch(0 0 0 / 0.04);
|
|
20
|
+
transform: scale(0.95);
|
|
21
|
+
}
|
|
22
|
+
&::-moz-range-thumb {
|
|
23
|
+
@apply rounded-full bg-white;
|
|
24
|
+
width: 22px;
|
|
25
|
+
height: 22px;
|
|
26
|
+
border: none;
|
|
27
|
+
box-shadow: 0 1px 4px oklch(0 0 0 / 0.15), 0 0 0 1px oklch(0 0 0 / 0.04);
|
|
28
|
+
transition: box-shadow 0.2s var(--apple-ease), transform 0.2s var(--apple-ease);
|
|
29
|
+
}
|
|
30
|
+
&::-moz-range-thumb:hover {
|
|
31
|
+
box-shadow: 0 2px 8px oklch(0 0 0 / 0.2), 0 0 0 1px oklch(0 0 0 / 0.04);
|
|
32
|
+
transform: scale(1.05);
|
|
33
|
+
}
|
|
34
|
+
&::-moz-range-thumb:active {
|
|
35
|
+
box-shadow: 0 1px 3px oklch(0 0 0 / 0.2), 0 0 0 1px oklch(0 0 0 / 0.04);
|
|
36
|
+
transform: scale(0.95);
|
|
37
|
+
}
|
|
38
|
+
&:focus-visible {
|
|
39
|
+
outline: none;
|
|
40
|
+
&::-webkit-slider-thumb {
|
|
41
|
+
box-shadow: 0 0 0 4px oklch(from var(--primary) l c h / 0.15), 0 1px 4px oklch(0 0 0 / 0.15), 0 0 0 1px oklch(0 0 0 / 0.04);
|
|
42
|
+
}
|
|
43
|
+
&::-moz-range-thumb {
|
|
44
|
+
box-shadow: 0 0 0 4px oklch(from var(--primary) l c h / 0.15), 0 1px 4px oklch(0 0 0 / 0.15), 0 0 0 1px oklch(0 0 0 / 0.04);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
&:disabled { @apply cursor-not-allowed opacity-50; }
|
|
48
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* ========== SPINNER ========== */
|
|
2
|
+
.spinner {
|
|
3
|
+
@apply inline-block size-5;
|
|
4
|
+
border-radius: 50%;
|
|
5
|
+
color: var(--muted-foreground);
|
|
6
|
+
background: conic-gradient(transparent 150deg, currentColor);
|
|
7
|
+
-webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 2px), #000 0);
|
|
8
|
+
mask: radial-gradient(farthest-side, #0000 calc(100% - 2px), #000 0);
|
|
9
|
+
animation: spin 1s linear infinite;
|
|
10
|
+
}
|
|
11
|
+
.spinner-sm { @apply size-4; }
|
|
12
|
+
.spinner-lg { @apply size-8; }
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* ========== SWITCH ========== */
|
|
2
|
+
.switch {
|
|
3
|
+
@apply appearance-none relative shrink-0 rounded-full cursor-pointer;
|
|
4
|
+
width: 51px;
|
|
5
|
+
height: 31px;
|
|
6
|
+
background: oklch(0.862 0.007 286.02);
|
|
7
|
+
transition: background-color 0.25s var(--apple-ease);
|
|
8
|
+
&::after {
|
|
9
|
+
content: "";
|
|
10
|
+
@apply absolute rounded-full bg-white;
|
|
11
|
+
top: 2px;
|
|
12
|
+
left: 2px;
|
|
13
|
+
width: 27px;
|
|
14
|
+
height: 27px;
|
|
15
|
+
box-shadow: 0 2px 4px oklch(0 0 0 / 0.15), 0 1px 2px oklch(0 0 0 / 0.1);
|
|
16
|
+
transition: transform 0.25s var(--apple-spring);
|
|
17
|
+
}
|
|
18
|
+
&:checked {
|
|
19
|
+
background: var(--primary);
|
|
20
|
+
&::after { transform: translateX(20px); }
|
|
21
|
+
}
|
|
22
|
+
&:focus-visible { box-shadow: 0 0 0 4px oklch(from var(--primary) l c h / 0.15); }
|
|
23
|
+
&:disabled { @apply cursor-not-allowed opacity-50; }
|
|
24
|
+
&:is(.dark *) {
|
|
25
|
+
background: oklch(0.350 0.004 285.99);
|
|
26
|
+
&:checked { background: var(--primary); }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/* ========== TABLE ========== */
|
|
2
|
+
.table {
|
|
3
|
+
@apply overflow-x-auto rounded-2xl bg-card;
|
|
4
|
+
box-shadow: var(--shadow-sm), var(--panel-ring);
|
|
5
|
+
& table {
|
|
6
|
+
@apply w-full text-left text-[13px];
|
|
7
|
+
}
|
|
8
|
+
& thead tr {
|
|
9
|
+
border-bottom: 1px solid var(--panel-border);
|
|
10
|
+
background: var(--surface-1);
|
|
11
|
+
}
|
|
12
|
+
& th {
|
|
13
|
+
@apply px-4 py-3 text-xs font-semibold text-muted-foreground;
|
|
14
|
+
}
|
|
15
|
+
& tbody {
|
|
16
|
+
& tr + tr {
|
|
17
|
+
border-top: 1px solid var(--surface-3);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
& td {
|
|
21
|
+
@apply px-4 py-3;
|
|
22
|
+
}
|
|
23
|
+
& tbody tr {
|
|
24
|
+
transition: background-color 0.15s var(--apple-ease);
|
|
25
|
+
&:hover {
|
|
26
|
+
background: var(--surface-1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
& tfoot tr {
|
|
30
|
+
border-top: 1px solid var(--panel-border);
|
|
31
|
+
background: var(--surface-1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
.table-striped {
|
|
35
|
+
& tbody tr:hover { background: inherit; }
|
|
36
|
+
& tbody tr:nth-child(even) {
|
|
37
|
+
background: var(--surface-1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/* ========== TABS ========== */
|
|
2
|
+
.tabs {
|
|
3
|
+
/* wrapper */
|
|
4
|
+
}
|
|
5
|
+
.tabs-list {
|
|
6
|
+
@apply flex;
|
|
7
|
+
border-bottom: 1px solid var(--panel-border);
|
|
8
|
+
}
|
|
9
|
+
.tabs-trigger {
|
|
10
|
+
@apply relative px-4 py-2.5 text-[13px] font-medium text-muted-foreground cursor-pointer;
|
|
11
|
+
transition: color 0.2s var(--apple-ease);
|
|
12
|
+
&:hover { @apply text-foreground; }
|
|
13
|
+
&:focus-visible { outline: 3px solid oklch(from var(--primary) l c h / 0.3); outline-offset: -3px; }
|
|
14
|
+
&[data-active] {
|
|
15
|
+
color: var(--primary);
|
|
16
|
+
&::after {
|
|
17
|
+
content: "";
|
|
18
|
+
@apply absolute bottom-0 left-0 h-0.5 w-full;
|
|
19
|
+
border-radius: 1px 1px 0 0;
|
|
20
|
+
background: var(--primary);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
.tabs-content {
|
|
25
|
+
@apply py-4;
|
|
26
|
+
&:not([data-active]) { @apply hidden; }
|
|
27
|
+
}
|
|
28
|
+
/* Pill variant — Apple segmented control */
|
|
29
|
+
.tabs-pill {
|
|
30
|
+
& .tabs-list {
|
|
31
|
+
@apply inline-flex rounded-[10px] border-0 p-1;
|
|
32
|
+
background: var(--surface-4);
|
|
33
|
+
}
|
|
34
|
+
& .tabs-trigger {
|
|
35
|
+
@apply rounded-[7px] px-3.5 py-1.5 text-[13px];
|
|
36
|
+
transition: all 0.2s var(--apple-spring);
|
|
37
|
+
&[data-active] {
|
|
38
|
+
@apply text-foreground;
|
|
39
|
+
background: var(--card);
|
|
40
|
+
box-shadow: var(--shadow-sm);
|
|
41
|
+
&::after { display: none; }
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* ========== THEME SWITCHER ========== */
|
|
2
|
+
.theme-switcher {
|
|
3
|
+
@apply inline-flex items-center rounded-[10px] p-0.5;
|
|
4
|
+
background: var(--surface-4);
|
|
5
|
+
& button {
|
|
6
|
+
@apply flex size-8 items-center justify-center rounded-[7px] text-muted-foreground cursor-pointer;
|
|
7
|
+
transition: all 0.2s var(--apple-spring);
|
|
8
|
+
& svg { @apply size-4; }
|
|
9
|
+
&:hover { @apply text-foreground; }
|
|
10
|
+
&:focus-visible { outline: 3px solid oklch(from var(--primary) l c h / 0.3); outline-offset: 2px; }
|
|
11
|
+
&[data-active] {
|
|
12
|
+
@apply text-foreground;
|
|
13
|
+
background: var(--card);
|
|
14
|
+
box-shadow: var(--shadow-sm);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* ========== TOAST ========== */
|
|
2
|
+
.toast {
|
|
3
|
+
@apply flex w-[360px] items-start gap-3 rounded-2xl p-4;
|
|
4
|
+
background: var(--glass-bg-opaque);
|
|
5
|
+
backdrop-filter: var(--glass-blur);
|
|
6
|
+
-webkit-backdrop-filter: var(--glass-blur);
|
|
7
|
+
box-shadow: var(--shadow-lg), var(--float-ring);
|
|
8
|
+
animation: slideUp 0.3s var(--apple-spring);
|
|
9
|
+
& svg:first-child { @apply mt-0.5 size-5 shrink-0; }
|
|
10
|
+
& .toast-title { @apply text-[13px] font-semibold text-foreground; }
|
|
11
|
+
& .toast-message { @apply mt-0.5 text-[13px] text-muted-foreground; }
|
|
12
|
+
& .toast-close {
|
|
13
|
+
@apply shrink-0 text-muted-foreground cursor-pointer;
|
|
14
|
+
transition: color 0.15s var(--apple-ease);
|
|
15
|
+
&:hover { @apply text-foreground; }
|
|
16
|
+
&:focus-visible { outline: 3px solid oklch(from var(--primary) l c h / 0.3); outline-offset: 2px; border-radius: 4px; }
|
|
17
|
+
& svg { @apply size-4; }
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
.toast-container {
|
|
21
|
+
@apply fixed bottom-4 right-4 z-[100] flex flex-col gap-2.5;
|
|
22
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* ========== TOGGLE ========== */
|
|
2
|
+
.toggle {
|
|
3
|
+
@apply inline-flex size-9 items-center justify-center rounded-[8px] text-muted-foreground cursor-pointer;
|
|
4
|
+
transition: all 0.2s var(--apple-ease);
|
|
5
|
+
&:focus-visible { outline: 3px solid oklch(from var(--primary) l c h / 0.3); outline-offset: 2px; }
|
|
6
|
+
&:hover {
|
|
7
|
+
@apply text-foreground;
|
|
8
|
+
background: var(--surface-3);
|
|
9
|
+
}
|
|
10
|
+
&:active { transform: scale(var(--apple-press-scale)); }
|
|
11
|
+
&[data-active], &[aria-pressed="true"] {
|
|
12
|
+
@apply text-foreground;
|
|
13
|
+
background: var(--surface-4);
|
|
14
|
+
}
|
|
15
|
+
&:disabled, &[disabled] { @apply pointer-events-none opacity-50; }
|
|
16
|
+
& svg { @apply size-4; }
|
|
17
|
+
}
|
|
18
|
+
.toggle-sm { @apply size-8; & svg { @apply size-3.5; } }
|
|
19
|
+
.toggle-lg { @apply size-10; & svg { @apply size-5; } }
|
|
20
|
+
.toggle-outline {
|
|
21
|
+
box-shadow: inset 0 0 0 1px var(--border-solid);
|
|
22
|
+
&[data-active], &[aria-pressed="true"] {
|
|
23
|
+
@apply text-primary;
|
|
24
|
+
background: oklch(from var(--primary) l c h / 0.06);
|
|
25
|
+
box-shadow: inset 0 0 0 1px oklch(from var(--primary) l c h / 0.2);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
.toggle-group {
|
|
29
|
+
@apply inline-flex items-center gap-0.5 rounded-[10px] p-0.5;
|
|
30
|
+
background: var(--surface-3);
|
|
31
|
+
& .toggle {
|
|
32
|
+
@apply rounded-[7px];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* ========== TOOLTIP ========== */
|
|
2
|
+
.tooltip {
|
|
3
|
+
@apply relative inline-block;
|
|
4
|
+
}
|
|
5
|
+
.tooltip-content {
|
|
6
|
+
@apply pointer-events-none absolute bottom-full left-1/2 mb-2 -translate-x-1/2 whitespace-nowrap rounded-lg px-3 py-1.5 text-xs font-medium;
|
|
7
|
+
--tooltip-bg: oklch(0.200 0.004 285.99);
|
|
8
|
+
--tooltip-fg: white;
|
|
9
|
+
background: var(--tooltip-bg);
|
|
10
|
+
color: var(--tooltip-fg);
|
|
11
|
+
box-shadow: var(--shadow-md);
|
|
12
|
+
opacity: 0;
|
|
13
|
+
transform: translateX(-50%) translateY(2px);
|
|
14
|
+
transition: opacity 0.15s var(--apple-ease), transform 0.15s var(--apple-ease);
|
|
15
|
+
.tooltip:hover > & {
|
|
16
|
+
opacity: 1;
|
|
17
|
+
transform: translateX(-50%) translateY(0);
|
|
18
|
+
}
|
|
19
|
+
&::after {
|
|
20
|
+
content: "";
|
|
21
|
+
@apply absolute left-1/2 top-full -translate-x-1/2;
|
|
22
|
+
border: 4px solid transparent;
|
|
23
|
+
border-top-color: var(--tooltip-bg);
|
|
24
|
+
}
|
|
25
|
+
&:is(.dark *) {
|
|
26
|
+
--tooltip-bg: oklch(0.940 0.003 285.66);
|
|
27
|
+
--tooltip-fg: oklch(0.200 0.004 285.99);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
.tooltip-bottom {
|
|
31
|
+
& .tooltip-content {
|
|
32
|
+
@apply bottom-auto top-full mb-0 mt-2;
|
|
33
|
+
transform: translateX(-50%) translateY(-2px);
|
|
34
|
+
.tooltip:hover > & { transform: translateX(-50%) translateY(0); }
|
|
35
|
+
&::after {
|
|
36
|
+
@apply top-auto bottom-full;
|
|
37
|
+
border-top-color: transparent;
|
|
38
|
+
border-bottom-color: var(--tooltip-bg);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.tooltip-right {
|
|
44
|
+
& .tooltip-content {
|
|
45
|
+
@apply bottom-auto left-full top-1/2 mb-0 ml-2 -translate-y-1/2 translate-x-0;
|
|
46
|
+
transform: translateY(-50%) translateX(-2px);
|
|
47
|
+
.tooltip:hover > & { transform: translateY(-50%) translateX(0); }
|
|
48
|
+
&::after {
|
|
49
|
+
@apply left-auto right-full top-1/2 -translate-y-1/2;
|
|
50
|
+
border-top-color: transparent;
|
|
51
|
+
border-right-color: var(--tooltip-bg);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
.tooltip-left {
|
|
56
|
+
& .tooltip-content {
|
|
57
|
+
@apply bottom-auto right-full left-auto top-1/2 mb-0 mr-2 -translate-y-1/2 translate-x-0;
|
|
58
|
+
transform: translateY(-50%) translateX(2px);
|
|
59
|
+
.tooltip:hover > & { transform: translateY(-50%) translateX(0); }
|
|
60
|
+
&::after {
|
|
61
|
+
@apply right-auto left-full top-1/2 -translate-y-1/2;
|
|
62
|
+
border-top-color: transparent;
|
|
63
|
+
border-left-color: var(--tooltip-bg);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|