diff --git a/package.json b/package.json index 5faa2bd..d4c2432 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ ] }, "dependencies": { + "@vanilla-extract/css": "^1.18.0", + "@vanilla-extract/vite-plugin": "^5.1.4", "eslint-import-resolver-typescript": "^4.4.4", "react": "^19.2.0", "react-dom": "^19.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2f1fd97..9d1eab9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,12 @@ importers: .: dependencies: + '@vanilla-extract/css': + specifier: ^1.18.0 + version: 1.18.0 + '@vanilla-extract/vite-plugin': + specifier: ^5.1.4 + version: 5.1.4(@types/node@24.10.4)(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.2))(yaml@2.8.2) eslint-import-resolver-typescript: specifier: ^4.4.4 version: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.2) @@ -145,6 +151,10 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -166,6 +176,12 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/runtime@7.28.4': resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} engines: {node: '>=6.9.0'} @@ -191,6 +207,9 @@ packages: '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@emotion/hash@0.9.2': + resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} + '@esbuild/aix-ppc64@0.27.2': resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} engines: {node: '>=18'} @@ -1034,6 +1053,26 @@ packages: cpu: [x64] os: [win32] + '@vanilla-extract/babel-plugin-debug-ids@1.2.2': + resolution: {integrity: sha512-MeDWGICAF9zA/OZLOKwhoRlsUW+fiMwnfuOAqFVohL31Agj7Q/RBWAYweqjHLgFBCsdnr6XIfwjJnmb2znEWxw==} + + '@vanilla-extract/compiler@0.3.4': + resolution: {integrity: sha512-W9HXf9EAccpE1vEIATvSoBVj/bQnmHfYHfDJjUN8dcOHW6oMcnoGTqweDM9I66BHqlNH4d0IsaeZKSViOv7K4w==} + + '@vanilla-extract/css@1.18.0': + resolution: {integrity: sha512-/p0dwOjr0o8gE5BRQ5O9P0u/2DjUd6Zfga2JGmE4KaY7ZITWMszTzk4x4CPlM5cKkRr2ZGzbE6XkuPNfp9shSQ==} + + '@vanilla-extract/integration@8.0.7': + resolution: {integrity: sha512-ILob4F9cEHXpbWAVt3Y2iaQJpqYq/c/5TJC8Fz58C2XmX3QW2Y589krvViiyJhQfydCGK3EbwPQhVFjQaBeKfg==} + + '@vanilla-extract/private@1.0.9': + resolution: {integrity: sha512-gT2jbfZuaaCLrAxwXbRgIhGhcXbRZCG3v4TTUnjw0EJ7ArdBRxkq4msNJkbuRkCgfIK5ATmprB5t9ljvLeFDEA==} + + '@vanilla-extract/vite-plugin@5.1.4': + resolution: {integrity: sha512-fTYNKUK3n4ApkUf2FEcO7mpqNKEHf9kDGg8DXlkqHtPxgwPhjuaajmDfQCSBsNgnA2SLI+CB5EO6kLQuKsw2Rw==} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + '@vitejs/plugin-react-swc@4.2.2': resolution: {integrity: sha512-x+rE6tsxq/gxrEJN3Nv3dIV60lFflPj94c90b+NNo6n1QV1QQUTLoL0MpaOVasUZ0zqVBn7ead1B5ecx1JAGfA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1191,6 +1230,10 @@ packages: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -1255,6 +1298,9 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -1293,6 +1339,11 @@ packages: css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + csso@5.0.5: resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} @@ -1329,6 +1380,14 @@ packages: supports-color: optional: true + dedent@1.7.1: + resolution: {integrity: sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} @@ -1336,6 +1395,9 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deep-object-diff@1.1.9: + resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -1444,6 +1506,9 @@ packages: resolution: {integrity: sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==} engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -1625,6 +1690,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + eval@0.1.8: + resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==} + engines: {node: '>= 0.8'} + eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} @@ -1947,6 +2016,9 @@ packages: resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} engines: {node: 20 || >=22} + javascript-stringify@2.1.0: + resolution: {integrity: sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2024,6 +2096,9 @@ packages: lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.2.4: resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} engines: {node: 20 || >=22} @@ -2048,6 +2123,9 @@ packages: mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + media-query-parser@2.0.2: + resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -2078,6 +2156,12 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + mlly@1.8.0: + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + + modern-ahocorasick@1.1.0: + resolution: {integrity: sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2193,6 +2277,9 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pathval@2.0.1: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} @@ -2213,6 +2300,9 @@ packages: engines: {node: '>=0.10'} hasBin: true + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -2302,6 +2392,9 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + require-like@0.1.2: + resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -2587,6 +2680,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -2615,6 +2711,11 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + vite-plugin-svgr@4.5.0: resolution: {integrity: sha512-W+uoSpmVkSmNOGPSsDCWVW/DDAyv+9fap9AZXBvWiQqrboJ08j2vh0tFxTD/LjwqwAd3yYSVJgm54S/1GhbdnA==} peerDependencies: @@ -2803,6 +2904,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-plugin-utils@7.27.1': {} + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} @@ -2818,6 +2921,11 @@ snapshots: dependencies: '@babel/types': 7.28.5 + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/runtime@7.28.4': {} '@babel/template@7.27.2': @@ -2859,6 +2967,8 @@ snapshots: tslib: 2.8.1 optional: true + '@emotion/hash@0.9.2': {} + '@esbuild/aix-ppc64@0.27.2': optional: true @@ -3598,6 +3708,88 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true + '@vanilla-extract/babel-plugin-debug-ids@1.2.2': + dependencies: + '@babel/core': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@vanilla-extract/compiler@0.3.4(@types/node@24.10.4)(yaml@2.8.2)': + dependencies: + '@vanilla-extract/css': 1.18.0 + '@vanilla-extract/integration': 8.0.7 + vite: 7.3.0(@types/node@24.10.4)(yaml@2.8.2) + vite-node: 3.2.4(@types/node@24.10.4)(yaml@2.8.2) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + '@vanilla-extract/css@1.18.0': + dependencies: + '@emotion/hash': 0.9.2 + '@vanilla-extract/private': 1.0.9 + css-what: 6.2.2 + cssesc: 3.0.0 + csstype: 3.2.3 + dedent: 1.7.1 + deep-object-diff: 1.1.9 + deepmerge: 4.3.1 + lru-cache: 10.4.3 + media-query-parser: 2.0.2 + modern-ahocorasick: 1.1.0 + picocolors: 1.1.1 + transitivePeerDependencies: + - babel-plugin-macros + + '@vanilla-extract/integration@8.0.7': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + '@vanilla-extract/babel-plugin-debug-ids': 1.2.2 + '@vanilla-extract/css': 1.18.0 + dedent: 1.7.1 + esbuild: 0.27.2 + eval: 0.1.8 + find-up: 5.0.0 + javascript-stringify: 2.1.0 + mlly: 1.8.0 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + '@vanilla-extract/private@1.0.9': {} + + '@vanilla-extract/vite-plugin@5.1.4(@types/node@24.10.4)(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.2))(yaml@2.8.2)': + dependencies: + '@vanilla-extract/compiler': 0.3.4(@types/node@24.10.4)(yaml@2.8.2) + '@vanilla-extract/integration': 8.0.7 + vite: 7.3.0(@types/node@24.10.4)(yaml@2.8.2) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + '@vitejs/plugin-react-swc@4.2.2(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.2))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.47 @@ -3785,6 +3977,8 @@ snapshots: dependencies: run-applescript: 7.1.0 + cac@6.7.14: {} + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -3846,6 +4040,8 @@ snapshots: concat-map@0.0.1: {} + confbox@0.1.8: {} + convert-source-map@2.0.0: {} cookie@1.1.1: {} @@ -3887,6 +4083,8 @@ snapshots: css.escape@1.5.1: {} + cssesc@3.0.0: {} + csso@5.0.5: dependencies: css-tree: 2.2.1 @@ -3919,10 +4117,14 @@ snapshots: dependencies: ms: 2.1.3 + dedent@1.7.1: {} + deep-eql@5.0.2: {} deep-is@0.1.4: {} + deep-object-diff@1.1.9: {} + deepmerge@4.3.1: {} default-browser-id@5.0.1: {} @@ -4089,6 +4291,8 @@ snapshots: iterator.prototype: 1.1.5 safe-array-concat: 1.1.3 + es-module-lexer@1.7.0: {} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -4346,6 +4550,11 @@ snapshots: esutils@2.0.3: {} + eval@0.1.8: + dependencies: + '@types/node': 24.10.4 + require-like: 0.1.2 + eventemitter3@5.0.1: {} fast-deep-equal@3.1.3: {} @@ -4659,6 +4868,8 @@ snapshots: dependencies: '@isaacs/cliui': 8.0.2 + javascript-stringify@2.1.0: {} + js-tokens@4.0.0: {} js-yaml@4.1.1: @@ -4742,6 +4953,8 @@ snapshots: dependencies: tslib: 2.8.1 + lru-cache@10.4.3: {} + lru-cache@11.2.4: {} lru-cache@5.1.1: @@ -4760,6 +4973,10 @@ snapshots: mdn-data@2.0.30: {} + media-query-parser@2.0.2: + dependencies: + '@babel/runtime': 7.28.4 + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -4785,6 +5002,15 @@ snapshots: minipass@7.1.2: {} + mlly@1.8.0: + dependencies: + acorn: 8.15.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.1 + + modern-ahocorasick@1.1.0: {} + ms@2.1.3: {} nano-spawn@2.0.0: {} @@ -4908,6 +5134,8 @@ snapshots: path-type@4.0.0: {} + pathe@2.0.3: {} + pathval@2.0.1: {} picocolors@1.1.1: {} @@ -4918,6 +5146,12 @@ snapshots: pidtree@0.6.0: {} + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.0 + pathe: 2.0.3 + possible-typed-array-names@1.1.0: {} postcss@8.5.6: @@ -5025,6 +5259,8 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + require-like@0.1.2: {} + resolve-from@4.0.0: {} resolve-pkg-maps@1.0.0: {} @@ -5405,6 +5641,8 @@ snapshots: typescript@5.9.3: {} + ufo@1.6.1: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -5459,6 +5697,27 @@ snapshots: dependencies: react: 19.2.3 + vite-node@3.2.4(@types/node@24.10.4)(yaml@2.8.2): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.3.0(@types/node@24.10.4)(yaml@2.8.2) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vite-plugin-svgr@4.5.0(rollup@4.55.1)(typescript@5.9.3)(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.2)): dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.55.1) diff --git a/src/app/App.tsx b/src/app/App.tsx index d8a6add..965d875 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,12 +1,13 @@ import { RouterProvider } from "react-router-dom"; +import ThemeProvider from "./providers"; import { router } from "./routes/app-router"; const App = () => { return ( - <> + - + ); }; diff --git a/src/app/main.tsx b/src/app/main.tsx index 9c72744..6af872b 100644 --- a/src/app/main.tsx +++ b/src/app/main.tsx @@ -3,6 +3,8 @@ import { createRoot } from "react-dom/client"; import App from "@app/App"; +import "@app/styles/global.css"; + const rootEl = document.getElementById("root"); if (!rootEl) throw new Error('Root element "#root" not found'); diff --git a/src/app/providers/.gitkeep b/src/app/providers/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/providers/index.ts b/src/app/providers/index.ts new file mode 100644 index 0000000..f5ffff0 --- /dev/null +++ b/src/app/providers/index.ts @@ -0,0 +1 @@ +export { default } from "./theme-provider"; \ No newline at end of file diff --git a/src/app/providers/theme-provider.tsx b/src/app/providers/theme-provider.tsx new file mode 100644 index 0000000..43ee46f --- /dev/null +++ b/src/app/providers/theme-provider.tsx @@ -0,0 +1,19 @@ +import { type ReactNode } from "react"; + +import { themeClass } from "../styles"; + +const ThemeProvider = ({ + theme, + className, + children, +}: { + children: ReactNode; + theme?: string; + className?: string; +}) => { + return ( +
{children}
+ ); +}; + +export default ThemeProvider; diff --git a/src/app/styles/.gitkeep b/src/app/styles/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/styles/global.css.ts b/src/app/styles/global.css.ts new file mode 100644 index 0000000..1da2c47 --- /dev/null +++ b/src/app/styles/global.css.ts @@ -0,0 +1,46 @@ +import "./reset.css.ts"; + +import { globalStyle, globalFontFace } from "@vanilla-extract/css"; + +import PretendardWoff2 from "@shared/assets/fonts/PretendardVariable.woff2"; + +import { themeVars } from "./theme.css"; + +globalFontFace("Pretendard", { + src: `url(${PretendardWoff2}) format("woff2")`, + fontWeight: "100 900", + fontStyle: "normal", + fontDisplay: "swap", +}); + +globalStyle("html, body", { + fontFamily: "Pretendard", +}); + +globalStyle(":root", { + textRendering: "optimizeLegibility", +}); + +globalStyle("html", { + fontSize: "62.5%", +}); + +globalStyle("html, body, #root", { + height: "100%", + backgroundColor: themeVars.color.white, + color: themeVars.color.black, +}); + +globalStyle("a", { + color: "inherit", + textDecoration: "none", +}); + +globalStyle("button", { + cursor: "pointer", + border: "none", + padding: 0, + background: "none", +}); + +globalStyle("img, svg, button", { userSelect: "none" }); diff --git a/src/app/styles/index.ts b/src/app/styles/index.ts new file mode 100644 index 0000000..0afedd2 --- /dev/null +++ b/src/app/styles/index.ts @@ -0,0 +1 @@ +export * from "./theme.css"; diff --git a/src/app/styles/reset.css.ts b/src/app/styles/reset.css.ts new file mode 100644 index 0000000..f4e84d6 --- /dev/null +++ b/src/app/styles/reset.css.ts @@ -0,0 +1,59 @@ +import { globalStyle } from "@vanilla-extract/css"; + +globalStyle("*, *::before, *::after", { + boxSizing: "border-box", + margin: "0", + padding: "0", +}); + +globalStyle("html:focus-within", { + scrollBehavior: "smooth", +}); + +globalStyle("body", { + minHeight: "100dvh", +}); + +globalStyle("h1, h2, h3, h4, h5, h6", { + fontSize: "inherit", + fontWeight: "inherit", +}); + +globalStyle("table", { + textIndent: "0", + borderColor: "inherit", + borderCollapse: "collapse", +}); + +globalStyle("button, select", { + textTransform: "none", +}); + +globalStyle("ol, ul, menu", { + listStyle: "none", +}); + +globalStyle("textarea", { + resize: "none", +}); + +globalStyle(":disabled", { + cursor: "default", +}); + +globalStyle("img, picture", { + maxWidth: "100%", + height: "auto", + display: "block", +}); + +globalStyle("input", { + appearance: "none", + background: "transparent", + border: "none", + outline: "none", +}); + +globalStyle("input, button, textarea, select", { + fontFamily: "inherit", +}); diff --git a/src/app/styles/theme.css.ts b/src/app/styles/theme.css.ts new file mode 100644 index 0000000..92c7c38 --- /dev/null +++ b/src/app/styles/theme.css.ts @@ -0,0 +1,15 @@ +import { createTheme } from "@vanilla-extract/css"; + +import { fontStyles } from "@/shared/styles/font-style.css"; +import { color } from "@/shared/styles/tokens/color.css"; + +// 테마 토큰 정의 +const tokens = { + color: color, + fontStyles: fontStyles, +}; + +// color와 fontStyle 테마로 생성 +const [themeClass, themeVars] = createTheme(tokens); + +export { themeClass, themeVars, tokens }; diff --git a/src/pages/home/home-page.css.ts b/src/pages/home/home-page.css.ts index e69de29..f56b8a2 100644 --- a/src/pages/home/home-page.css.ts +++ b/src/pages/home/home-page.css.ts @@ -0,0 +1,11 @@ +import { style } from "@vanilla-extract/css"; + +import { themeVars } from "@/app/styles"; + +export const appContainer = style({ + display: "flex", + flexDirection: "column", + color: themeVars.color.blue300, + backgroundColor: themeVars.color.blue500, + ...themeVars.fontStyles.title_b_28, +}); diff --git a/src/pages/home/home-page.tsx b/src/pages/home/home-page.tsx index 0be0346..fab5b74 100644 --- a/src/pages/home/home-page.tsx +++ b/src/pages/home/home-page.tsx @@ -1,11 +1,14 @@ import Heart from "@icons/heart.svg?react"; import KERORO from "@images/comfit_web_status.jpg"; +import { appContainer } from "./home-page.css"; + const HomePage = () => { return ( -
-

Welcome to the Home Page

- Keroro +
+

프리텐다드

+

카카오로 시작하기

+ Keroro
); diff --git a/src/shared/assets/fonts/PretendardVariable.woff2 b/src/shared/assets/fonts/PretendardVariable.woff2 new file mode 100644 index 0000000..49c54b5 Binary files /dev/null and b/src/shared/assets/fonts/PretendardVariable.woff2 differ diff --git a/src/shared/styles/.gitkeep b/src/shared/styles/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/shared/styles/font-style.css.ts b/src/shared/styles/font-style.css.ts new file mode 100644 index 0000000..1009c96 --- /dev/null +++ b/src/shared/styles/font-style.css.ts @@ -0,0 +1,141 @@ +import { typography } from "./tokens/typography.css"; + +export const fontStyles = { + // display + display_b_56: { + fontSize: typography.fontSize[56], + fontWeight: typography.fontWeight.bold, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + display_b_40: { + fontSize: typography.fontSize[40], + fontWeight: typography.fontWeight.bold, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + + // title + title_b_36: { + fontSize: typography.fontSize[36], + fontWeight: typography.fontWeight.bold, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + title_b_28: { + fontSize: typography.fontSize[28], + fontWeight: typography.fontWeight.bold, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + title_m_28: { + fontSize: typography.fontSize[28], + fontWeight: typography.fontWeight.medium, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + title_b_24: { + fontSize: typography.fontSize[24], + fontWeight: typography.fontWeight.bold, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + title_m_24: { + fontSize: typography.fontSize[24], + fontWeight: typography.fontWeight.medium, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + + // heading + hding_b_22: { + fontSize: typography.fontSize[22], + fontWeight: typography.fontWeight.bold, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + hding_m_22: { + fontSize: typography.fontSize[22], + fontWeight: typography.fontWeight.medium, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + hding_b_20: { + fontSize: typography.fontSize[20], + fontWeight: typography.fontWeight.bold, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + hding_m_20: { + fontSize: typography.fontSize[20], + fontWeight: typography.fontWeight.medium, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + + // headline + hline_b_18: { + fontSize: typography.fontSize[18], + fontWeight: typography.fontWeight.bold, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + hline_m_18: { + fontSize: typography.fontSize[18], + fontWeight: typography.fontWeight.medium, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + + // body + body_b_16: { + fontSize: typography.fontSize[16], + fontWeight: typography.fontWeight.bold, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + body_m_16: { + fontSize: typography.fontSize[16], + fontWeight: typography.fontWeight.medium, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + body_r_16: { + fontSize: typography.fontSize[16], + fontWeight: typography.fontWeight.regular, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + body_b_14: { + fontSize: typography.fontSize[14], + fontWeight: typography.fontWeight.bold, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + body_m_14: { + fontSize: typography.fontSize[14], + fontWeight: typography.fontWeight.medium, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + body_r_14: { + fontSize: typography.fontSize[14], + fontWeight: typography.fontWeight.regular, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + + // caption + cap_b_12: { + fontSize: typography.fontSize[12], + fontWeight: typography.fontWeight.bold, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, + cap_m_12: { + fontSize: typography.fontSize[12], + fontWeight: typography.fontWeight.medium, + lineHeight: typography.lineHeight.normal, + letterSpacing: typography.letterSpacing.normal, + }, +} as const; diff --git a/src/shared/styles/tokens/.gitkeep b/src/shared/styles/tokens/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/shared/styles/tokens/color.css.ts b/src/shared/styles/tokens/color.css.ts new file mode 100644 index 0000000..28f5340 --- /dev/null +++ b/src/shared/styles/tokens/color.css.ts @@ -0,0 +1,37 @@ +export const color = { + // Gray scale + gray100: "#F1F3F7", + gray200: "#E1E5EB", + gray300: "#CBCFD7", + gray400: "#A6A9B0", + gray500: "#70757C", + gray600: "#5A5C63", + gray700: "#37383C", + gray800: "#212225", + gray900: "#171719", + + // Normal (기본 콘텐츠 컬러) + normal: "#70737C38", + + // Primary scale + blue100: "#F0F4FF", + blue200: "#DCE4FF", + blue300: "#C8D6FF", + blue400: "#A0B7FF", + blue500: "#7899FF", + blue600: "#5A81FA", + + // Sub Green scale + green100: "#EBF8DA", + green200: "#CDEE9F", + green300: "#BDED78", + + // Sub Purple scale + purple100: "#FCF0FF", + purple200: "#EDCCF8", + purple300: "#E196F7", + + // White / Black + white: "#FFFFFF", + black: "#000000", +} as const; diff --git a/src/shared/styles/tokens/typography.css.ts b/src/shared/styles/tokens/typography.css.ts new file mode 100644 index 0000000..a639f92 --- /dev/null +++ b/src/shared/styles/tokens/typography.css.ts @@ -0,0 +1,27 @@ +export const typography = { + fontSize: { + 12: "1.2rem", + 14: "1.4rem", + 16: "1.6rem", + 18: "1.8rem", + 20: "2rem", + 22: "2.2rem", + 24: "2.4rem", + 28: "2.8rem", + 36: "3.6rem", + 40: "4rem", + 56: "5.6rem", + }, + fontWeight: { + regular: "400", + medium: "500", + bold: "700", + }, + lineHeight: { + normal: "150%", + }, + + letterSpacing: { + normal: "-0.01em", + }, +} as const; diff --git a/vite.config.ts b/vite.config.ts index 994c048..2aae6c9 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,27 +2,31 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react-swc"; import svgr from "vite-plugin-svgr"; import path from "path"; +import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin"; // https://vite.dev/config/ export default defineConfig({ - plugins: [react(), + plugins: [ + react(), + vanillaExtractPlugin(), svgr({ svgrOptions: { plugins: ["@svgr/plugin-svgo", "@svgr/plugin-jsx"], - svgoConfig: { + svgoConfig: { plugins: [ { name: "preset-default", params: { overrides: { removeViewBox: false, - } - } - } - ] + }, + }, + }, + ], }, - } - })], + }, + }), + ], resolve: { alias: { "@": path.resolve(__dirname, "./src"),