diff --git a/package.json b/package.json
index e240b8f..6af7af0 100644
--- a/package.json
+++ b/package.json
@@ -15,17 +15,19 @@
"cors": "latest",
"dotenv": "latest",
"express": "latest",
+ "gsap": "^3.15.0",
"jsonwebtoken": "latest",
+ "lucide-vue-next": "latest",
+ "motion-v": "^1.10.3",
+ "multer": "latest",
+ "mysql2": "latest",
"vite": "latest",
"vue": "latest",
- "vue-router": "latest",
- "lucide-vue-next": "latest",
- "multer": "latest",
- "mysql2": "latest"
+ "vue-router": "latest"
},
"devDependencies": {
- "tailwindcss": "^3.4.17",
+ "autoprefixer": "latest",
"postcss": "latest",
- "autoprefixer": "latest"
+ "tailwindcss": "^3.4.17"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index bfcb2fe..5951a75 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -23,12 +23,18 @@ importers:
express:
specifier: latest
version: 5.2.1
+ gsap:
+ specifier: ^3.15.0
+ version: 3.15.0
jsonwebtoken:
specifier: latest
version: 9.0.3
lucide-vue-next:
specifier: latest
version: 1.0.0(vue@3.5.34)
+ motion-v:
+ specifier: ^1.10.3
+ version: 1.10.3(@vueuse/core@14.3.0(vue@3.5.34))(vue@3.5.34)
multer:
specifier: latest
version: 2.1.1
@@ -235,6 +241,9 @@ packages:
'@types/node@25.7.0':
resolution: {integrity: sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg==}
+ '@types/web-bluetooth@0.0.21':
+ resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
+
'@vitejs/plugin-vue@6.0.6':
resolution: {integrity: sha512-u9HHgfrq3AjXlysn0eINFnWQOJQLO9WN6VprZ8FXl7A2bYisv3Hui9Ij+7QZ41F/WYWarHjwBbXtD7dKg3uxbg==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -289,6 +298,19 @@ packages:
'@vue/shared@3.5.34':
resolution: {integrity: sha512-24uqU4OIiX29ryC3MeWid/Xf2fa2EFRUVLb77nRhk+UrTVrh/XiGtFAFmJBAtBRbjwNdsPRP+jj/OL27Eg1NDA==}
+ '@vueuse/core@14.3.0':
+ resolution: {integrity: sha512-aHfz47g0ZhMtTVHmIzMVpJy8ePhhOy68GY5bv110+5DVtZ+W7BsOx+m61UNQqfrWyPztIHIanWa3E2tib3NFIw==}
+ peerDependencies:
+ vue: ^3.5.0
+
+ '@vueuse/metadata@14.3.0':
+ resolution: {integrity: sha512-BwxmbAzwAVF50+MW57GXOUEV61nFBGnlBvrTqj49PqWJu3uw7hdu72ztXeZ33RdZtDY6kO+bfCAE1PCn88Tktw==}
+
+ '@vueuse/shared@14.3.0':
+ resolution: {integrity: sha512-bZpge9eSXwa4ToSiqJ7j6KRwhAsneMFoSz3LMWKQDkqimm3D/tbFlrklrs/IOqC8tEcYmXQZJ6N0UrjhBirVCg==}
+ peerDependencies:
+ vue: ^3.5.0
+
accepts@2.0.0:
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
engines: {node: '>= 0.6'}
@@ -554,6 +576,20 @@ packages:
fraction.js@5.3.4:
resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
+ framer-motion@12.39.0:
+ resolution: {integrity: sha512-+vnLfzrv0MzjLzNl+nvNvR7jdg3q4cxxjz/YvzfifHl0TREtL00cs1RoMTxs+1PzLiEqZGV6gYsBY0oEAYZ24w==}
+ peerDependencies:
+ '@emotion/is-prop-valid': '*'
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@emotion/is-prop-valid':
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+
fresh@2.0.0:
resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
engines: {node: '>= 0.8'}
@@ -589,6 +625,9 @@ packages:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
+ gsap@3.15.0:
+ resolution: {integrity: sha512-dMW4CWBTUK1AEEDeZc1g4xpPGIrSf9fJF960qbTZmN/QwZIWY5wgliS6JWl9/25fpTGJrMRtSjGtOmPnfjZB+A==}
+
has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
@@ -597,6 +636,9 @@ packages:
resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==}
engines: {node: '>= 0.4'}
+ hey-listen@1.0.8:
+ resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==}
+
hookable@5.5.3:
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
@@ -833,6 +875,18 @@ packages:
mlly@1.8.2:
resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==}
+ motion-dom@12.39.0:
+ resolution: {integrity: sha512-Xn7aAcGDhco/JZTXOub64UmaYn73C6J1Po7Fk+8EvkJsNGTqfhon6UJY53vJKXW5v5Zl8HrYsVxv6oPXeGoGLQ==}
+
+ motion-utils@12.39.0:
+ resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==}
+
+ motion-v@1.10.3:
+ resolution: {integrity: sha512-9Ewo/wwGv7FO3PqYJpllBF/Efc7tbeM1iinVrM73s0RUQrnXHwMZCaRX98u4lu0PQCrZghPPfCsQ14pWKIEbnQ==}
+ peerDependencies:
+ '@vueuse/core': '>=10.0.0'
+ vue: '>=3.0.0'
+
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
@@ -1398,6 +1452,8 @@ snapshots:
dependencies:
undici-types: 7.21.0
+ '@types/web-bluetooth@0.0.21': {}
+
'@vitejs/plugin-vue@6.0.6(vite@8.0.12(@types/node@25.7.0)(jiti@1.21.7)(yaml@2.9.0))(vue@3.5.34)':
dependencies:
'@rolldown/pluginutils': 1.0.0-rc.13
@@ -1481,6 +1537,19 @@ snapshots:
'@vue/shared@3.5.34': {}
+ '@vueuse/core@14.3.0(vue@3.5.34)':
+ dependencies:
+ '@types/web-bluetooth': 0.0.21
+ '@vueuse/metadata': 14.3.0
+ '@vueuse/shared': 14.3.0(vue@3.5.34)
+ vue: 3.5.34
+
+ '@vueuse/metadata@14.3.0': {}
+
+ '@vueuse/shared@14.3.0(vue@3.5.34)':
+ dependencies:
+ vue: 3.5.34
+
accepts@2.0.0:
dependencies:
mime-types: 3.0.2
@@ -1744,6 +1813,12 @@ snapshots:
fraction.js@5.3.4: {}
+ framer-motion@12.39.0:
+ dependencies:
+ motion-dom: 12.39.0
+ motion-utils: 12.39.0
+ tslib: 2.8.1
+
fresh@2.0.0: {}
fsevents@2.3.3:
@@ -1783,12 +1858,16 @@ snapshots:
gopd@1.2.0: {}
+ gsap@3.15.0: {}
+
has-symbols@1.1.0: {}
hasown@2.0.3:
dependencies:
function-bind: 1.1.2
+ hey-listen@1.0.8: {}
+
hookable@5.5.3: {}
http-errors@2.0.1:
@@ -1980,6 +2059,24 @@ snapshots:
pkg-types: 1.3.1
ufo: 1.6.4
+ motion-dom@12.39.0:
+ dependencies:
+ motion-utils: 12.39.0
+
+ motion-utils@12.39.0: {}
+
+ motion-v@1.10.3(@vueuse/core@14.3.0(vue@3.5.34))(vue@3.5.34):
+ dependencies:
+ '@vueuse/core': 14.3.0(vue@3.5.34)
+ framer-motion: 12.39.0
+ hey-listen: 1.0.8
+ motion-dom: 12.39.0
+ vue: 3.5.34
+ transitivePeerDependencies:
+ - '@emotion/is-prop-valid'
+ - react
+ - react-dom
+
ms@2.1.3: {}
muggle-string@0.4.1: {}
@@ -2323,8 +2420,7 @@ snapshots:
ts-interface-checker@0.1.13: {}
- tslib@2.8.1:
- optional: true
+ tslib@2.8.1: {}
type-is@1.6.18:
dependencies:
diff --git a/src/main.js b/src/main.js
index a3e3a30..088bca4 100644
--- a/src/main.js
+++ b/src/main.js
@@ -3,4 +3,8 @@ import App from "./App.vue"
import router from "./router"
import "./assets/main.css"
+if (localStorage.getItem("secondtech_theme") === "dark") {
+ document.documentElement.classList.add("dark")
+}
+
createApp(App).use(router).mount("#app")
diff --git a/src/vuebits/ShinyText/ShinyText.vue b/src/vuebits/ShinyText/ShinyText.vue
new file mode 100644
index 0000000..e7c0c30
--- /dev/null
+++ b/src/vuebits/ShinyText/ShinyText.vue
@@ -0,0 +1,135 @@
+
+
+
+
+ {{ text }}
+
+
diff --git a/src/vuebits/TextType/TextType.vue b/src/vuebits/TextType/TextType.vue
new file mode 100644
index 0000000..b0fc831
--- /dev/null
+++ b/src/vuebits/TextType/TextType.vue
@@ -0,0 +1,176 @@
+
+
+
+
+
+ {{ displayedText }}
+
+
+ {{ cursorCharacter }}
+
+
+