[feat] main layout 수정
parent
0890457b99
commit
8e1cc981fa
|
|
@ -30,6 +30,7 @@
|
||||||
"typescript": "~5.9.3",
|
"typescript": "~5.9.3",
|
||||||
"typescript-eslint": "^8.56.1",
|
"typescript-eslint": "^8.56.1",
|
||||||
"vite": "^7.3.1",
|
"vite": "^7.3.1",
|
||||||
|
"vite-plugin-svgr": "^5.0.0",
|
||||||
"vite-tsconfig-paths": "^6.1.1"
|
"vite-tsconfig-paths": "^6.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1023,6 +1024,29 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@rollup/pluginutils": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/estree": "^1.0.0",
|
||||||
|
"estree-walker": "^2.0.2",
|
||||||
|
"picomatch": "^4.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"rollup": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.59.0",
|
"version": "4.59.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
|
||||||
|
|
@ -1373,6 +1397,231 @@
|
||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-remove-jsx-attribute": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-svg-dynamic-title": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-svg-em-dimensions": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-transform-react-native-svg": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-transform-svg-component": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-preset": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@svgr/babel-plugin-add-jsx-attribute": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-remove-jsx-attribute": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-svg-dynamic-title": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-svg-em-dimensions": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-transform-react-native-svg": "8.1.0",
|
||||||
|
"@svgr/babel-plugin-transform-svg-component": "8.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/core": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/core": "^7.21.3",
|
||||||
|
"@svgr/babel-preset": "8.1.0",
|
||||||
|
"camelcase": "^6.2.0",
|
||||||
|
"cosmiconfig": "^8.1.3",
|
||||||
|
"snake-case": "^3.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/hast-util-to-babel-ast": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.21.3",
|
||||||
|
"entities": "^4.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/plugin-jsx": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/core": "^7.21.3",
|
||||||
|
"@svgr/babel-preset": "8.1.0",
|
||||||
|
"@svgr/hast-util-to-babel-ast": "8.0.0",
|
||||||
|
"svg-parser": "^2.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@svgr/core": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tailwindcss/node": {
|
"node_modules/@tailwindcss/node": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz",
|
||||||
|
|
@ -2505,6 +2754,19 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/camelcase": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001779",
|
"version": "1.0.30001779",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001779.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001779.tgz",
|
||||||
|
|
@ -2602,6 +2864,33 @@
|
||||||
"url": "https://opencollective.com/express"
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cosmiconfig": {
|
||||||
|
"version": "8.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
|
||||||
|
"integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"import-fresh": "^3.3.0",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"parse-json": "^5.2.0",
|
||||||
|
"path-type": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/d-fischer"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": ">=4.9.5"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
|
@ -2668,6 +2957,17 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dot-case": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"no-case": "^3.0.4",
|
||||||
|
"tslib": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dunder-proto": {
|
"node_modules/dunder-proto": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
|
|
@ -2703,6 +3003,29 @@
|
||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/entities": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/error-ex": {
|
||||||
|
"version": "1.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
|
||||||
|
"integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-arrayish": "^0.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/es-define-property": {
|
"node_modules/es-define-property": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
|
|
@ -2987,6 +3310,13 @@
|
||||||
"node": ">=4.0"
|
"node": ">=4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/estree-walker": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/esutils": {
|
"node_modules/esutils": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||||
|
|
@ -3349,6 +3679,13 @@
|
||||||
"node": ">=0.8.19"
|
"node": ">=0.8.19"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-arrayish": {
|
||||||
|
"version": "0.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||||
|
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/is-extglob": {
|
"node_modules/is-extglob": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
|
@ -3429,6 +3766,13 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/json-parse-even-better-errors": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/json-schema-traverse": {
|
"node_modules/json-schema-traverse": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||||
|
|
@ -3480,6 +3824,13 @@
|
||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lines-and-columns": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||||
|
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/locate-path": {
|
"node_modules/locate-path": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||||
|
|
@ -3503,6 +3854,16 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/lower-case": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||||
|
|
@ -3599,6 +3960,17 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/no-case": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"lower-case": "^2.0.2",
|
||||||
|
"tslib": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-releases": {
|
"node_modules/node-releases": {
|
||||||
"version": "2.0.36",
|
"version": "2.0.36",
|
||||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz",
|
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz",
|
||||||
|
|
@ -3669,6 +4041,25 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/parse-json": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/code-frame": "^7.0.0",
|
||||||
|
"error-ex": "^1.3.1",
|
||||||
|
"json-parse-even-better-errors": "^2.3.0",
|
||||||
|
"lines-and-columns": "^1.1.6"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-exists": {
|
"node_modules/path-exists": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
|
|
@ -3689,6 +4080,16 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/path-type": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
|
|
@ -3933,6 +4334,17 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/snake-case": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"dot-case": "^3.0.4",
|
||||||
|
"tslib": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
|
|
@ -3969,6 +4381,13 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/svg-parser": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/tailwindcss": {
|
"node_modules/tailwindcss": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz",
|
||||||
|
|
@ -4041,6 +4460,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "0BSD"
|
||||||
|
},
|
||||||
"node_modules/type-check": {
|
"node_modules/type-check": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
|
|
@ -4215,6 +4641,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vite-plugin-svgr": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-CZFWDtbWSLnF6C+uv8u7E5Ao6UVQYBpJrS6212XsEod/Lm4ErhOoFc01/po4ie5hqvMCr5KYrlMrSGQQEtMtBg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@rollup/pluginutils": "^5.2.0",
|
||||||
|
"@svgr/core": "^8.1.0",
|
||||||
|
"@svgr/plugin-jsx": "^8.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vite": ">=3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vite-tsconfig-paths": {
|
"node_modules/vite-tsconfig-paths": {
|
||||||
"version": "6.1.1",
|
"version": "6.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-6.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-6.1.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
"typescript": "~5.9.3",
|
"typescript": "~5.9.3",
|
||||||
"typescript-eslint": "^8.56.1",
|
"typescript-eslint": "^8.56.1",
|
||||||
"vite": "^7.3.1",
|
"vite": "^7.3.1",
|
||||||
|
"vite-plugin-svgr": "^5.0.0",
|
||||||
"vite-tsconfig-paths": "^6.1.1"
|
"vite-tsconfig-paths": "^6.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,244 @@
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
|
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css');
|
||||||
|
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
:root {
|
/* ─── Design Tokens ───────────────────────────────────────────────── */
|
||||||
--Color-Neutral-90: #151515;
|
@theme {
|
||||||
--Color-Neutral-80: #303030;
|
/* Navy ─ 950(darkest) · 900 · 800 · 50(lightest)
|
||||||
--Color-Neutral-70: #606060;
|
짙은 네이비 계열. 본문 텍스트, 다크 섹션 배경, 그라디언트 끝 */
|
||||||
--Color-Neutral-60: #808080;
|
--color-navy-950: #021341;
|
||||||
--Color-Neutral-40: #DADBDE;
|
--color-navy-900: #0A1128;
|
||||||
--Color-Neutral-30: #EAEBEF;
|
--color-navy-800: #1A2B5E;
|
||||||
--Color-Neutral-20: #F0F1F4;
|
--color-navy-50: #F4F6FB;
|
||||||
--Color-Neutral-10: #F7F8FA;
|
|
||||||
--Color-Neutral-00: #FFF;
|
/* Violet ─ 700(deep) · 500(accent)
|
||||||
--Color-Negative: #E71C3B;
|
퍼플 계열. 그라디언트 시작(700), 활성 상태·아이콘(500) */
|
||||||
--Color-Negative-Hover: #C21630;
|
--color-violet-700: #4F1DA1;
|
||||||
--Color-B: #4880EF;
|
--color-violet-500: #6C5CE7;
|
||||||
--Color-B-Hover: #3568C5;
|
/* Marketing accents (CTA / Process / Hero blobs — shared with DEMO) */
|
||||||
|
--color-marketing-cream: #fff3eb;
|
||||||
--font-family-primary: 'Pretendard', system-ui, sans-serif;
|
--color-marketing-lilac: #e4cfff;
|
||||||
--font-family-display: 'Playfair Display', serif;
|
--color-marketing-ice: #f5f9ff;
|
||||||
--font-family-inter: 'Inter', sans-serif;
|
--color-lavender-100: #f3e8ff;
|
||||||
|
--color-lavender-200: #e9d4ff;
|
||||||
|
--color-lavender-300: #d8b4fe;
|
||||||
|
--color-violet-hover: #af90ff;
|
||||||
|
/* Hero radial + blob tints */
|
||||||
|
--color-hero-wash-start: #e0e7ff;
|
||||||
|
--color-hero-wash-mid: #faf5ff;
|
||||||
|
--color-hero-wash-end: #fdf2f8;
|
||||||
|
--color-marketing-blush: #fbcfe8;
|
||||||
|
|
||||||
|
/* Neutral ─ 90(darkest) · 80 · 70 · 60 · 40 · 30 · 20 · 10 · 00(white) */
|
||||||
|
--color-neutral-90: #151515;
|
||||||
|
--color-neutral-80: #303030;
|
||||||
|
--color-neutral-70: #606060;
|
||||||
|
--color-neutral-60: #808080;
|
||||||
|
--color-neutral-40: #DADBDE;
|
||||||
|
--color-neutral-30: #EAEBEF;
|
||||||
|
--color-neutral-20: #F0F1F4;
|
||||||
|
--color-neutral-10: #F7F8FA;
|
||||||
|
--color-neutral-00: #FFFFFF;
|
||||||
|
|
||||||
|
/* Status ─ {critical | warning | good | info} × {bg | text | border | dot}
|
||||||
|
파스텔 시맨틱 팔레트. 원색(빨강·초록) 사용 금지 */
|
||||||
|
--color-status-critical-bg: #FFF0F0;
|
||||||
|
--color-status-critical-text: #7C3A4B;
|
||||||
|
--color-status-critical-border: #F5D5DC;
|
||||||
|
--color-status-critical-dot: #D4889A;
|
||||||
|
|
||||||
|
--color-status-warning-bg: #FFF6ED;
|
||||||
|
--color-status-warning-text: #7C5C3A;
|
||||||
|
--color-status-warning-border: #F5E0C5;
|
||||||
|
--color-status-warning-dot: #D4A872;
|
||||||
|
|
||||||
|
--color-status-good-bg: #F3F0FF;
|
||||||
|
--color-status-good-text: #4A3A7C;
|
||||||
|
--color-status-good-border: #D5CDF5;
|
||||||
|
--color-status-good-dot: #9B8AD4;
|
||||||
|
|
||||||
|
--color-status-info-bg: #EFF0FF;
|
||||||
|
--color-status-info-text: #3A3F7C;
|
||||||
|
--color-status-info-border: #C5CBF5;
|
||||||
|
--color-status-info-dot: #7A84D4;
|
||||||
|
|
||||||
|
/* Typography */
|
||||||
|
--font-sans: "Pretendard Variable", "Pretendard", ui-sans-serif, system-ui, sans-serif;
|
||||||
|
--font-serif: "Playfair Display", ui-serif, Georgia, Cambria, serif;
|
||||||
|
--font-inter: "Inter", ui-sans-serif, system-ui, sans-serif;
|
||||||
|
|
||||||
|
/* Animation */
|
||||||
|
--animate-blob: blob 7s infinite;
|
||||||
|
--animate-blob-large: blob-large 25s infinite ease-in-out;
|
||||||
|
--animate-fade-in-up: fade-in-up 0.6s ease-out both;
|
||||||
|
--animate-fade-in-left: fade-in-left 0.6s ease-out both;
|
||||||
|
--animate-fade-in-right: fade-in-right 0.6s ease-out both;
|
||||||
|
--animate-fade-in-scale: fade-in-scale 0.8s ease-out both;
|
||||||
}
|
}
|
||||||
|
|
||||||
html,
|
/* ─── Keyframes ───────────────────────────────────────────────────── */
|
||||||
body {
|
@keyframes blob {
|
||||||
font-family: var(--font-family-inter);
|
0% { transform: translate(0, 0) scale(1); }
|
||||||
font-style: normal;
|
33% { transform: translate(30px, -50px) scale(1.1); }
|
||||||
line-height: normal;
|
66% { transform: translate(-20px, 20px) scale(0.9); }
|
||||||
min-height: 100dvh;
|
100% { transform: translate(0, 0) scale(1); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes blob-large {
|
||||||
|
0% { transform: translate(0, 0) scale(1); }
|
||||||
|
33% { transform: translate(8vw, -8vh) scale(1.1); }
|
||||||
|
66% { transform: translate(-8vw, 8vh) scale(0.9); }
|
||||||
|
100% { transform: translate(0, 0) scale(1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fade + slide-up: replaces framer-motion entrance (opacity 0→1, y 20→0) */
|
||||||
|
@keyframes fade-in-up {
|
||||||
|
from { opacity: 0; transform: translateY(20px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fade + slide-left/right: whileInView x:-20→0 / x:20→0 */
|
||||||
|
@keyframes fade-in-left {
|
||||||
|
from { opacity: 0; transform: translateX(-20px); }
|
||||||
|
to { opacity: 1; transform: translateX(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-right {
|
||||||
|
from { opacity: 0; transform: translateX(20px); }
|
||||||
|
to { opacity: 1; transform: translateX(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in-scale {
|
||||||
|
from { opacity: 0; transform: scale(0.95); }
|
||||||
|
to { opacity: 1; transform: scale(1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── Animation Delays ────────────────────────────────────────────── */
|
||||||
|
/* UI entrance stagger (short) */
|
||||||
|
.animation-delay-100 { animation-delay: 0.1s; }
|
||||||
|
.animation-delay-200 { animation-delay: 0.2s; }
|
||||||
|
.animation-delay-300 { animation-delay: 0.3s; }
|
||||||
|
.animation-delay-400 { animation-delay: 0.4s; }
|
||||||
|
.animation-delay-500 { animation-delay: 0.5s; }
|
||||||
|
|
||||||
|
/* Blob float delays (long) */
|
||||||
|
.animation-delay-2000 { animation-delay: 2s; }
|
||||||
|
.animation-delay-4000 { animation-delay: 4s; }
|
||||||
|
.animation-delay-7000 { animation-delay: 7s; }
|
||||||
|
.animation-delay-14000 { animation-delay: 14s; }
|
||||||
|
|
||||||
|
/* ─── Utility Classes ─────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
/* 라이트 섹션 헤딩 그라디언트 텍스트 */
|
||||||
|
.text-gradient {
|
||||||
|
background: linear-gradient(to right, var(--color-navy-900), #3b5998);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 반투명 글래스 카드 — 랜딩 섹션 */
|
||||||
|
.glass-card {
|
||||||
|
@apply bg-white/70 backdrop-blur-xl border border-white/40 rounded-2xl;
|
||||||
|
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 다크 섹션 위 화이트 카드 사선 그림자 */
|
||||||
|
.card-shadow { box-shadow: 3px 4px 12px rgba(0, 0, 0, 0.06); }
|
||||||
|
.card-shadow:hover { box-shadow: 4px 6px 16px rgba(0, 0, 0, 0.09); }
|
||||||
|
|
||||||
|
/* 브랜드 그라디언트 Primary 버튼 */
|
||||||
|
.btn-primary {
|
||||||
|
@apply bg-gradient-to-r from-violet-700 to-navy-950 text-white rounded-full font-medium transition-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── Typography Scale ────────────────────────────────────────────── */
|
||||||
|
/* Display */
|
||||||
|
.display-72 { font-family: var(--font-serif); font-size: 72px; font-weight: 700; line-height: 1.1; letter-spacing: -1.44px; }
|
||||||
|
.display-48 { font-family: var(--font-serif); font-size: 48px; font-weight: 700; line-height: 1.1; letter-spacing: -0.96px; }
|
||||||
|
.display-36 { font-family: var(--font-serif); font-size: 36px; font-weight: 700; line-height: 1.15; letter-spacing: -0.72px; }
|
||||||
|
|
||||||
|
/* Headline */
|
||||||
|
.headline-30 { font-family: var(--font-serif); font-size: 30px; font-weight: 700; line-height: 1.2; letter-spacing: -0.6px; }
|
||||||
|
.headline-24 { font-family: var(--font-serif); font-size: 24px; font-weight: 700; line-height: 1.3; letter-spacing: -0.48px; }
|
||||||
|
.headline-20 { font-family: var(--font-serif); font-size: 20px; font-weight: 700; line-height: 1.4; letter-spacing: -0.4px; }
|
||||||
|
|
||||||
|
/* Title */
|
||||||
|
.title-20 { font-family: var(--font-sans); font-size: 20px; font-weight: 700; line-height: 1.4; letter-spacing: -0.4px; }
|
||||||
|
.title-18 { font-family: var(--font-sans); font-size: 18px; font-weight: 700; line-height: 1.4; letter-spacing: -0.36px; }
|
||||||
|
.title-18-semibold { font-family: var(--font-sans); font-size: 18px; font-weight: 600; line-height: 1.4; letter-spacing: -0.36px; }
|
||||||
|
.title-16 { font-family: var(--font-sans); font-size: 16px; font-weight: 600; line-height: 1.4; letter-spacing: -0.32px; }
|
||||||
|
.title-14 { font-family: var(--font-sans); font-size: 14px; font-weight: 600; line-height: 1.4; letter-spacing: -0.28px; }
|
||||||
|
|
||||||
|
/* Body */
|
||||||
|
.body-20 { font-family: var(--font-sans); font-size: 20px; font-weight: 400; line-height: 1.6; letter-spacing: -0.4px; }
|
||||||
|
.body-20-medium { font-family: var(--font-sans); font-size: 20px; font-weight: 500; line-height: 1.4; letter-spacing: -0.4px; }
|
||||||
|
.body-18 { font-family: var(--font-sans); font-size: 18px; font-weight: 400; line-height: 1.6; letter-spacing: -0.36px; }
|
||||||
|
.body-16 { font-family: var(--font-sans); font-size: 16px; font-weight: 400; line-height: 1.5; letter-spacing: -0.32px; }
|
||||||
|
.body-16-medium { font-family: var(--font-sans); font-size: 16px; font-weight: 500; line-height: 1.5; letter-spacing: -0.32px; }
|
||||||
|
.body-14 { font-family: var(--font-sans); font-size: 14px; font-weight: 400; line-height: 1.5; letter-spacing: -0.28px; }
|
||||||
|
.body-14-medium { font-family: var(--font-sans); font-size: 14px; font-weight: 500; line-height: 1.5; letter-spacing: -0.28px; }
|
||||||
|
|
||||||
|
/* Label */
|
||||||
|
.label-12 { font-family: var(--font-sans); font-size: 12px; font-weight: 500; line-height: 1.4; letter-spacing: -0.24px; }
|
||||||
|
.label-12-semibold { font-family: var(--font-sans); font-size: 12px; font-weight: 600; line-height: 1.4; letter-spacing: -0.24px; }
|
||||||
|
|
||||||
|
/* Responsive body: 18px → 20px at md (text-lg / text-xl) */
|
||||||
|
.body-18-md-20 {
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.625;
|
||||||
|
letter-spacing: -0.36px;
|
||||||
|
font-size: 1.125rem;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.body-18-md-20 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
letter-spacing: -0.4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive sans title: 18px → 20px at md (module card titles 등) */
|
||||||
|
.title-18-md-20 {
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.4;
|
||||||
|
letter-spacing: -0.36px;
|
||||||
|
font-size: 1.125rem;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.title-18-md-20 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
letter-spacing: -0.4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive list body: 14px → 16px at md */
|
||||||
|
.body-14-md-16 {
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.625;
|
||||||
|
letter-spacing: -0.28px;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.body-14-md-16 {
|
||||||
|
font-size: 1rem;
|
||||||
|
letter-spacing: -0.32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── Base ────────────────────────────────────────────────────────── */
|
||||||
|
@layer base {
|
||||||
|
html, body {
|
||||||
|
@apply font-sans text-neutral-80 bg-neutral-10 antialiased;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: normal;
|
||||||
|
min-height: 100dvh;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
@apply font-serif text-navy-900;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 요소가 뷰포트에 진입하면 inView = true 로 바뀌는 훅.
|
||||||
|
* framer-motion의 whileInView({ once: true }) 와 동일한 동작.
|
||||||
|
*/
|
||||||
|
export function useInView<T extends HTMLElement = HTMLElement>(
|
||||||
|
options?: IntersectionObserverInit,
|
||||||
|
) {
|
||||||
|
const ref = useRef<T>(null);
|
||||||
|
const [inView, setInView] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const el = ref.current;
|
||||||
|
if (!el) return;
|
||||||
|
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
([entry]) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
setInView(true);
|
||||||
|
observer.disconnect(); // once: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ threshold: 0.15, ...options },
|
||||||
|
);
|
||||||
|
|
||||||
|
observer.observe(el);
|
||||||
|
return () => observer.disconnect();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { ref, inView };
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 지정한 경로로 이동하면서 페이지 상단으로 smooth 스크롤합니다.
|
||||||
|
* 로고 클릭 등 "홈으로 돌아가기 + 스크롤 초기화" 패턴에 사용합니다.
|
||||||
|
*/
|
||||||
|
export function useScrollToTop(path = "/") {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
return (e: React.MouseEvent<HTMLAnchorElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
navigate(path);
|
||||||
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,22 +1,48 @@
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { useScrollToTop } from "@/hooks/useScrollToTop";
|
||||||
|
|
||||||
|
const LINKS = [
|
||||||
|
{ label: "Privacy Policy", href: "/privacy" },
|
||||||
|
{ label: "Terms of Service", href: "/terms" },
|
||||||
|
];
|
||||||
|
|
||||||
export function Footer() {
|
export function Footer() {
|
||||||
return (
|
const handleLogoClick = useScrollToTop();
|
||||||
<footer className="flex w-full items-center justify-between px-[316px] py-[48px]">
|
|
||||||
<div
|
|
||||||
className="text-[#0A1128] text-[30px] not-italic font-bold leading-[32px] tracking-[-0.6px]"
|
|
||||||
>
|
|
||||||
CLINICAD
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
return (
|
||||||
className="text-[#62748E] font-inter text-sm font-normal leading-5"
|
<footer className="bg-white border-t border-slate-100 py-12 px-6">
|
||||||
>
|
<div className="max-w-7xl mx-auto flex flex-col md:flex-row items-center justify-between gap-6">
|
||||||
© 2026 CLINICAD. All rights reserved. Infinite Marketing for Premium Medical Business & Marketing Agency
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex items-center gap-6">
|
{/* 로고 */}
|
||||||
<span className="text-[#62748E] font-inter text-sm font-normal leading-5">Privacy Policy</span>
|
<a
|
||||||
<span className="text-[#62748E] font-inter text-sm font-normal leading-5">Terms of Service</span>
|
href="/"
|
||||||
</div>
|
onClick={handleLogoClick}
|
||||||
</footer>
|
className="font-serif text-3xl font-black tracking-[0.05em] bg-gradient-to-r from-violet-700 to-navy-950 bg-clip-text text-transparent"
|
||||||
);
|
>
|
||||||
|
INFINITH
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{/* 카피라이트 */}
|
||||||
|
<p className="body-14 text-neutral-60 text-center md:text-left">
|
||||||
|
© {new Date().getFullYear()} CLINICAD. All rights reserved.{" "}
|
||||||
|
<br className="md:hidden" />
|
||||||
|
Infinite Marketing for Premium Medical Business & Marketing Agency
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* 링크 */}
|
||||||
|
<nav className="flex items-center gap-6">
|
||||||
|
{LINKS.map(({ label, href }) => (
|
||||||
|
<Link
|
||||||
|
key={label}
|
||||||
|
to={href}
|
||||||
|
className="body-14-medium text-neutral-60 hover:text-navy-900 transition-colors"
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1,42 +1,51 @@
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { useScrollToTop } from "@/hooks/useScrollToTop";
|
||||||
|
|
||||||
const MENUS = [
|
const MENUS = [
|
||||||
{ name: "Solution", href: "/" },
|
{ label: "Solution", href: "/#solution" },
|
||||||
{ name: "Modules", href: "/" },
|
{ label: "Modules", href: "/#modules" },
|
||||||
{ name: "Use Cases", href: "/" },
|
{ label: "Use Cases", href: "/#use-cases" },
|
||||||
]
|
];
|
||||||
|
|
||||||
export function GNB() {
|
export function GNB() {
|
||||||
return (
|
const handleLogoClick = useScrollToTop();
|
||||||
<nav className="w-full h-14 flex items-center justify-between px-[316px]" style={{ background: "var(--Color-Neutral-00)" }}>
|
|
||||||
|
|
||||||
{/* 로고 */}
|
return (
|
||||||
<span
|
<nav className="fixed top-0 left-0 right-0 z-50 h-20 bg-white/70 backdrop-blur-lg border-b border-white/20">
|
||||||
onClick={() => window.location.href = "/"}
|
<div className="max-w-7xl mx-auto px-6 h-full flex items-center justify-between">
|
||||||
className="text-[32px] font-bold leading-[32px] tracking-[-0.6px] ml-6 cursor-pointer"
|
|
||||||
style={{ color: "#0A1128", fontFamily: "var(--font-family-display)" }}
|
|
||||||
>
|
|
||||||
CLINAD
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{/* 메뉴 */}
|
{/* 로고 */}
|
||||||
<ul className="flex items-center gap-8">
|
<a
|
||||||
{MENUS.map(({ name }, index) => (
|
href="/"
|
||||||
<li
|
onClick={handleLogoClick}
|
||||||
key={index}
|
className="font-serif text-3xl font-black tracking-[0.05em] bg-gradient-to-r from-violet-700 to-navy-950 bg-clip-text text-transparent"
|
||||||
className="text-sm font-medium leading-5 cursor-pointer whitespace-nowrap"
|
>
|
||||||
style={{ color: "var(--Color-Neutral-70)", fontFamily: "var(--font-family-inter)" }}
|
INFINITH
|
||||||
>
|
</a>
|
||||||
{name}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{/* 로그인 버튼 */}
|
{/* 메뉴 — md 이상만 표시 */}
|
||||||
<button
|
<ul className="hidden md:flex items-center gap-8">
|
||||||
onClick={() => window.location.href = "/login"}
|
{MENUS.map(({ label, href }) => (
|
||||||
className="flex items-center justify-center w-[85px] h-[40px] shadow rounded-[99px] mr-6 bg-gradient-to-r from-[#4F1DA1] to-[#021341] text-white text-sm font-medium leading-5 cursor-pointer"
|
<li key={label}>
|
||||||
>
|
<a
|
||||||
Login
|
href={href}
|
||||||
</button>
|
className="body-14-medium text-neutral-70 hover:text-navy-900 transition-colors"
|
||||||
</nav>
|
>
|
||||||
)
|
{label}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{/* 로그인 버튼 */}
|
||||||
|
<Link
|
||||||
|
to="/login"
|
||||||
|
className="body-14-medium px-6 py-2.5 text-white rounded-full shadow-sm hover:shadow-md hover:opacity-90 transition-all bg-gradient-to-r from-violet-700 to-navy-950"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,18 @@
|
||||||
import { Outlet } from "react-router-dom";
|
import { Outlet } from "react-router-dom";
|
||||||
import { GNB } from "@/layouts/GNB";
|
import { GNB } from "@/layouts/GNB";
|
||||||
import { Footer } from "@/layouts/Footer";
|
import { Footer } from "@/layouts/Footer";
|
||||||
|
import { PageNavigator } from "@/layouts/PageNavigator";
|
||||||
|
|
||||||
export default function MainLayout() {
|
export default function MainLayout() {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col min-h-screen">
|
<div className="flex flex-col min-h-screen bg-neutral-10">
|
||||||
<header className="flex-none"><GNB /></header>
|
<GNB />
|
||||||
<main className="flex-grow"><Outlet /></main>
|
{/* fixed GNB(h-20) 높이만큼 상단 여백 확보 */}
|
||||||
<footer className="flex-none"><Footer /></footer>
|
<main className="flex-grow pt-20">
|
||||||
</div>
|
<Outlet />
|
||||||
)
|
</main>
|
||||||
|
<Footer />
|
||||||
|
<PageNavigator />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
|
import ChevronLeftIcon from "@/assets/home/chevron-left.svg?react";
|
||||||
|
import ChevronRightIcon from "@/assets/home/chevron-right.svg?react";
|
||||||
|
|
||||||
|
const PAGE_FLOW = [
|
||||||
|
{ path: "/", label: "홈" },
|
||||||
|
{ path: "/report", label: "마케팅 분석" },
|
||||||
|
{ path: "/plan", label: "콘텐츠 기획" },
|
||||||
|
{ path: "/studio", label: "콘텐츠 제작" },
|
||||||
|
{ path: "/channels", label: "채널 연결" },
|
||||||
|
{ path: "/distribute", label: "콘텐츠 배포" },
|
||||||
|
{ path: "/performance", label: "성과 관리" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function PageNavigator() {
|
||||||
|
const location = useLocation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const currentIndex = PAGE_FLOW.findIndex((p) => p.path === location.pathname);
|
||||||
|
if (currentIndex === -1) return null;
|
||||||
|
|
||||||
|
const prev = currentIndex > 0 ? PAGE_FLOW[currentIndex - 1] : null;
|
||||||
|
const next = currentIndex < PAGE_FLOW.length - 1 ? PAGE_FLOW[currentIndex + 1] : null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-no-print
|
||||||
|
className="fixed bottom-6 left-1/2 -translate-x-1/2 z-50 flex items-center gap-1 bg-white/90 backdrop-blur-xl border border-slate-200 rounded-full px-2 py-2 shadow-[0_4px_20px_rgba(0,0,0,0.08)]"
|
||||||
|
>
|
||||||
|
{/* 이전 페이지 */}
|
||||||
|
<button
|
||||||
|
onClick={() => prev && navigate(prev.path)}
|
||||||
|
disabled={!prev}
|
||||||
|
aria-label={prev ? `이전: ${prev.label}` : "이전 페이지 없음"}
|
||||||
|
className="body-14-medium flex items-center gap-2 px-3 py-2 rounded-full text-neutral-70 transition-all hover:bg-neutral-20 hover:text-navy-900 disabled:opacity-30 disabled:cursor-not-allowed cursor-pointer"
|
||||||
|
>
|
||||||
|
<ChevronLeftIcon aria-hidden="true" />
|
||||||
|
{prev && <span className="hidden sm:inline">{prev.label}</span>}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* 페이지 인디케이터 */}
|
||||||
|
<div className="flex items-center gap-2 px-2">
|
||||||
|
{PAGE_FLOW.map((page, i) => (
|
||||||
|
<button
|
||||||
|
key={page.path}
|
||||||
|
onClick={() => navigate(page.path)}
|
||||||
|
title={page.label}
|
||||||
|
aria-label={page.label}
|
||||||
|
className={`rounded-full transition-all cursor-pointer ${
|
||||||
|
i === currentIndex
|
||||||
|
? "w-6 h-2 bg-navy-900"
|
||||||
|
: "w-2 h-2 bg-neutral-40 hover:bg-neutral-60"
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 다음 페이지 */}
|
||||||
|
<button
|
||||||
|
onClick={() => next && navigate(next.path)}
|
||||||
|
disabled={!next}
|
||||||
|
aria-label={next ? `다음: ${next.label}` : "다음 페이지 없음"}
|
||||||
|
className="body-14-medium flex items-center gap-2 px-3 py-2 rounded-full text-neutral-70 transition-all hover:bg-neutral-20 hover:text-navy-900 disabled:opacity-30 disabled:cursor-not-allowed cursor-pointer"
|
||||||
|
>
|
||||||
|
{next && <span className="hidden sm:inline">{next.label}</span>}
|
||||||
|
<ChevronRightIcon aria-hidden="true" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
/// <reference types="vite/client" />
|
||||||
|
/// <reference types="vite-plugin-svgr/client" />
|
||||||
|
|
@ -2,8 +2,9 @@ import { defineConfig } from 'vite'
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react'
|
||||||
import tailwindcss from '@tailwindcss/vite'
|
import tailwindcss from '@tailwindcss/vite'
|
||||||
import tsconfigPaths from 'vite-tsconfig-paths'
|
import tsconfigPaths from 'vite-tsconfig-paths'
|
||||||
|
import svgr from 'vite-plugin-svgr'
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react(), tsconfigPaths(), tailwindcss()],
|
plugins: [react(), tsconfigPaths(), tailwindcss(), svgr()],
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue