diff --git a/src/components/icons/IconCheck.vue b/src/components/icons/IconCheck.vue
new file mode 100644
index 0000000..f39048c
--- /dev/null
+++ b/src/components/icons/IconCheck.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconCopy.vue b/src/components/icons/IconCopy.vue
new file mode 100644
index 0000000..8225f94
--- /dev/null
+++ b/src/components/icons/IconCopy.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconEmptyState.vue b/src/components/icons/IconEmptyState.vue
new file mode 100644
index 0000000..70b4bbc
--- /dev/null
+++ b/src/components/icons/IconEmptyState.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconExport.vue b/src/components/icons/IconExport.vue
new file mode 100644
index 0000000..60518b9
--- /dev/null
+++ b/src/components/icons/IconExport.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconHeart.vue b/src/components/icons/IconHeart.vue
new file mode 100644
index 0000000..b0e03da
--- /dev/null
+++ b/src/components/icons/IconHeart.vue
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconImport.vue b/src/components/icons/IconImport.vue
new file mode 100644
index 0000000..94d8cce
--- /dev/null
+++ b/src/components/icons/IconImport.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconMenu.vue b/src/components/icons/IconMenu.vue
new file mode 100644
index 0000000..5d64ad0
--- /dev/null
+++ b/src/components/icons/IconMenu.vue
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconMore.vue b/src/components/icons/IconMore.vue
new file mode 100644
index 0000000..8d39d1d
--- /dev/null
+++ b/src/components/icons/IconMore.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconPlus.vue b/src/components/icons/IconPlus.vue
new file mode 100644
index 0000000..ebc6077
--- /dev/null
+++ b/src/components/icons/IconPlus.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconPresetType.vue b/src/components/icons/IconPresetType.vue
index cf7f9da..ce09f29 100644
--- a/src/components/icons/IconPresetType.vue
+++ b/src/components/icons/IconPresetType.vue
@@ -1,53 +1,53 @@
-
@@ -62,93 +62,158 @@ defineProps<{
diff --git a/src/components/icons/IconSearch.vue b/src/components/icons/IconSearch.vue
new file mode 100644
index 0000000..afcf8ec
--- /dev/null
+++ b/src/components/icons/IconSearch.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconShare.vue b/src/components/icons/IconShare.vue
new file mode 100644
index 0000000..8a32834
--- /dev/null
+++ b/src/components/icons/IconShare.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconSort.vue b/src/components/icons/IconSort.vue
new file mode 100644
index 0000000..6f682b7
--- /dev/null
+++ b/src/components/icons/IconSort.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
diff --git a/src/components/icons/IconTheme.vue b/src/components/icons/IconTheme.vue
index 0d8d26e..71a78c3 100644
--- a/src/components/icons/IconTheme.vue
+++ b/src/components/icons/IconTheme.vue
@@ -1,52 +1,37 @@
-
-
+
+
-
-
-
@@ -55,99 +40,112 @@ defineProps<{
position: relative;
width: 1.25rem;
height: 1.25rem;
- display: flex;
- align-items: center;
- justify-content: center;
+ display: grid;
+ place-items: center;
}
-.moon-glow {
+svg,
+.theme-glow {
position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%) scale(0.5);
- width: 200%;
- height: 200%;
- border-radius: 50%;
- background: radial-gradient(closest-side, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%);
- opacity: 0;
- transition: all 0.4s ease;
- z-index: 0;
- pointer-events: none;
-}
-
-.icon-theme-container:hover .moon-glow.is-active {
- opacity: 1;
- transform: translate(-50%, -50%) scale(1);
+ inset: 0;
}
svg {
- position: absolute;
- width: 100%;
- height: 100%;
- transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
- z-index: 1;
+ overflow: visible;
+ transition: transform 0.55s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.35s ease;
}
-.icon-sun {
+.theme-sun {
opacity: 1;
- transform: rotate(0) scale(1);
+ transform: rotate(0deg) scale(1);
}
-.icon-sun.is-hidden {
+.theme-moon {
opacity: 0;
- transform: rotate(90deg) scale(0.5);
+ transform: rotate(-80deg) scale(0.55);
}
-.icon-moon {
+.theme-glow {
+ border-radius: 50%;
opacity: 0;
- transform: rotate(-90deg) scale(0.5);
+ transform: scale(0.5);
+ background: radial-gradient(circle, color-mix(in srgb, currentColor 24%, transparent) 0%, transparent 72%);
+ transition: opacity 0.35s ease, transform 0.45s ease;
+ pointer-events: none;
}
-.icon-moon.is-visible {
- opacity: 1;
- transform: rotate(0) scale(1);
-}
-
-/* Star styles */
-.star {
+.sun-core,
+.sun-ray,
+.moon-core,
+.moon-rim,
+.moon-ring {
+ stroke: currentColor;
+ fill: currentColor;
transform-origin: center;
- opacity: 0;
- transition: opacity 0.3s ease;
+ transition: transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.3s ease;
}
-.icon-moon.is-visible .star {
+.sun-core,
+.moon-core {
+ stroke-width: 2;
+ fill: none;
+}
+
+.moon-rim {
+ stroke-width: 2;
+ opacity: 0;
+ fill: none;
+}
+
+.moon-ring {
+ opacity: 0;
+}
+
+.icon-theme-container:hover .theme-glow {
+ opacity: 1;
+ transform: scale(1);
+}
+
+.icon-theme-container:hover .theme-sun {
+ transform: rotate(45deg) scale(1.08);
+}
+
+.icon-theme-container:hover .sun-ray {
+ transform: scaleX(1.08);
+}
+
+.icon-theme-container.is-dark .theme-sun {
+ opacity: 0;
+ transform: rotate(90deg) scale(0.45);
+}
+
+.icon-theme-container.is-dark .theme-moon {
+ opacity: 1;
+ transform: rotate(0deg) scale(1);
+}
+
+.icon-theme-container.is-dark .moon-rim {
+ opacity: 0.26;
+}
+
+.icon-theme-container.is-dark .moon-ring {
opacity: 1;
}
-/* Hover effects */
-.icon-theme-container:hover .icon-sun:not(.is-hidden) {
- animation: spin 4s linear infinite;
+.icon-theme-container:hover .theme-moon {
+ transform: rotate(-6deg) scale(1.04);
}
-.icon-theme-container:hover .icon-moon.is-visible {
- animation: swing 2.5s ease-in-out infinite;
+.icon-theme-container:hover .ring-1 {
+ animation: twinkle 1.4s ease-in-out infinite;
}
-.icon-theme-container:hover .star-1 {
- animation: twinkle 1.5s infinite ease-in-out;
-}
-
-.icon-theme-container:hover .star-2 {
- animation: twinkle 2s infinite ease-in-out 0.2s;
-}
-
-@keyframes spin {
- from { transform: rotate(0); }
- to { transform: rotate(360deg); }
-}
-
-@keyframes swing {
- 0%, 100% { transform: rotate(0) scale(1); }
- 50% { transform: rotate(-10deg) scale(1.05); }
+.icon-theme-container:hover .ring-2 {
+ animation: twinkle 1.8s ease-in-out infinite 0.15s;
}
@keyframes twinkle {
- 0%, 100% { opacity: 0.5; transform: scale(0.8); }
- 50% { opacity: 1; transform: scale(1.2); }
+ 0%, 100% { transform: scale(0.85); opacity: 0.45; }
+ 50% { transform: scale(1.25); opacity: 1; }
}
diff --git a/src/components/icons/IconTrash.vue b/src/components/icons/IconTrash.vue
new file mode 100644
index 0000000..495fca9
--- /dev/null
+++ b/src/components/icons/IconTrash.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/preset/PresetList.vue b/src/components/preset/PresetList.vue
index 6a01189..e8b3a91 100644
--- a/src/components/preset/PresetList.vue
+++ b/src/components/preset/PresetList.vue
@@ -4,6 +4,14 @@ import type { ExtendedPreset, PresetType } from '../../types';
import IconPresetType from '../icons/IconPresetType.vue';
import IconArrowLeft from '../icons/IconArrowLeft.vue';
import IconArrowRight from '../icons/IconArrowRight.vue';
+import IconHeart from '../icons/IconHeart.vue';
+import IconCheck from '../icons/IconCheck.vue';
+import IconCopy from '../icons/IconCopy.vue';
+import IconMore from '../icons/IconMore.vue';
+import IconShare from '../icons/IconShare.vue';
+import IconEditor from '../icons/IconEditor.vue';
+import IconTrash from '../icons/IconTrash.vue';
+import IconEmptyState from '../icons/IconEmptyState.vue';
const props = defineProps<{
presets: ExtendedPreset[];
@@ -187,8 +195,8 @@ function formatDate(dateStr: string) {
-
-
📭
+
@@ -234,53 +242,30 @@ function formatDate(dateStr: string) {
{{ preset.name }}
-