diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs index a7f8260..98100e9 100644 --- a/frontend/.eslintrc.cjs +++ b/frontend/.eslintrc.cjs @@ -1,7 +1,13 @@ module.exports = { root: true, env: { browser: true, es2020: true }, - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react-hooks/recommended', 'prettier', 'plugin:storybook/recommended'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react-hooks/recommended', + 'prettier', + 'plugin:storybook/recommended', + ], ignorePatterns: ['dist', '.eslintrc.cjs'], parser: '@typescript-eslint/parser', plugins: ['react-refresh'], diff --git a/frontend/.prettierrc b/frontend/.prettierrc index db33ef4..37d422b 100644 --- a/frontend/.prettierrc +++ b/frontend/.prettierrc @@ -11,5 +11,6 @@ "singleQuote": true, "tabWidth": 2, "trailingComma": "es5", - "useTabs": false + "useTabs": false, + "plugins": ["prettier-plugin-tailwindcss"] } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9f7479b..f8f9d2e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -29,11 +29,15 @@ "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.1", "@vitejs/plugin-react-swc": "^3.5.0", + "autoprefixer": "^10.4.20", "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", "eslint-plugin-storybook": "^0.8.0", - "prettier": "3.3.3", + "postcss": "^8.4.41", + "prettier": "^3.3.3", + "prettier-plugin-tailwindcss": "^0.6.6", "storybook": "^8.2.9", "tailwindcss": "^3.4.10", "typescript": "^5.2.2", @@ -5236,6 +5240,44 @@ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -6322,6 +6364,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-plugin-react-hooks": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", @@ -6963,6 +7018,20 @@ "node": ">= 0.6" } }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -8402,6 +8471,16 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/npm-run-path": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", @@ -9050,6 +9129,85 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-plugin-tailwindcss": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.6.tgz", + "integrity": "sha512-OPva5S7WAsPLEsOuOWXATi13QrCKACCiIonFgIR6V4lYv4QLp++UXVhZSzRbZxXGimkQtQT86CC6fQqTOybGng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "@ianvs/prettier-plugin-sort-imports": "*", + "@prettier/plugin-pug": "*", + "@shopify/prettier-plugin-liquid": "*", + "@trivago/prettier-plugin-sort-imports": "*", + "@zackad/prettier-plugin-twig-melody": "*", + "prettier": "^3.0", + "prettier-plugin-astro": "*", + "prettier-plugin-css-order": "*", + "prettier-plugin-import-sort": "*", + "prettier-plugin-jsdoc": "*", + "prettier-plugin-marko": "*", + "prettier-plugin-multiline-arrays": "*", + "prettier-plugin-organize-attributes": "*", + "prettier-plugin-organize-imports": "*", + "prettier-plugin-sort-imports": "*", + "prettier-plugin-style-order": "*", + "prettier-plugin-svelte": "*" + }, + "peerDependenciesMeta": { + "@ianvs/prettier-plugin-sort-imports": { + "optional": true + }, + "@prettier/plugin-pug": { + "optional": true + }, + "@shopify/prettier-plugin-liquid": { + "optional": true + }, + "@trivago/prettier-plugin-sort-imports": { + "optional": true + }, + "@zackad/prettier-plugin-twig-melody": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-css-order": { + "optional": true + }, + "prettier-plugin-import-sort": { + "optional": true + }, + "prettier-plugin-jsdoc": { + "optional": true + }, + "prettier-plugin-marko": { + "optional": true + }, + "prettier-plugin-multiline-arrays": { + "optional": true + }, + "prettier-plugin-organize-attributes": { + "optional": true + }, + "prettier-plugin-organize-imports": { + "optional": true + }, + "prettier-plugin-sort-imports": { + "optional": true + }, + "prettier-plugin-style-order": { + "optional": true + }, + "prettier-plugin-svelte": { + "optional": true + } + } + }, "node_modules/pretty-format": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index 58fbb89..83c3f64 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -35,11 +35,15 @@ "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.1", "@vitejs/plugin-react-swc": "^3.5.0", + "autoprefixer": "^10.4.20", "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", "eslint-plugin-storybook": "^0.8.0", - "prettier": "3.3.3", + "postcss": "^8.4.41", + "prettier": "^3.3.3", + "prettier-plugin-tailwindcss": "^0.6.6", "storybook": "^8.2.9", "tailwindcss": "^3.4.10", "typescript": "^5.2.2", diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/frontend/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/frontend/src/App.css b/frontend/src/App.css deleted file mode 100644 index e69de29..0000000 diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 68767f0..a99e427 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,5 +1,4 @@ import { RouterProvider } from 'react-router-dom'; -import './App.css'; import router from './router'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; diff --git a/frontend/src/index.css b/frontend/src/index.css index 6119ad9..5d36893 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,68 +1,65 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; +@tailwind base; +@tailwind components; +@tailwind utilities; + +@font-face { + font-family: 'Pretendard Variable'; + font-weight: 45 920; + font-style: normal; + font-display: fallback; + src: url('./assets/fonts/PretendardVariable.woff2') format('woff2-variations'); +} + +.large-title { + font-size: 36px; + font-weight: 700; + line-height: 1.2; +} + +.small-title { + font-size: 32px; + font-weight: 700; + line-height: 1.2; +} + +.heading { + font-size: 24px; + font-weight: 700; + line-height: 1.2; +} + +.subheading { + font-size: 20px; + font-weight: 700; + line-height: 1.2; +} + +.body { + font-size: 16px; font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + line-height: 1.4; } -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; +.body-strong { + font-size: 16px; + font-weight: 700; + line-height: 1.4; } -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; +.body-small { + font-size: 14px; + font-weight: 400; + line-height: 1.4; } -h1 { - font-size: 3.2em; - line-height: 1.1; +.body-small-strong { + font-size: 14px; + font-weight: 700; + line-height: 1.4; } -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } +.caption { + font-size: 12px; + font-weight: 400; + line-height: 1.4; } diff --git a/frontend/src/router/index.tsx b/frontend/src/router/index.tsx index eddae7a..54ab4b1 100644 --- a/frontend/src/router/index.tsx +++ b/frontend/src/router/index.tsx @@ -7,6 +7,7 @@ const router = createBrowserRouter([ children: [ { index: true, + element:
index
, }, ], }, diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js new file mode 100644 index 0000000..d0a0fba --- /dev/null +++ b/frontend/tailwind.config.js @@ -0,0 +1,47 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], + theme: { + colors: { + transparent: 'transparent', + current: 'currentColor', + black: '#000', + white: '#fff', + gray: { + 50: '#fafafa', + 100: '#f5f5f5', + 200: '#e6e6e6', + 300: '#d9d9d9', + 400: '#b3b3b3', + 500: '#757575', + 600: '#444444', + 700: '#383838', + 800: '#2c2c2c', + 900: '#1e1e1e', + 1000: '#111111', + }, + primary: '#1177ff', + }, + + fontFamily: { + sans: [ + 'Pretendard Variable', + 'Pretendard', + '-apple-system', + 'BlinkMacSystemFont', + 'system-ui', + 'Roboto', + 'Helvetica Neue', + 'Segoe UI', + 'Apple SD Gothic Neo', + 'Noto Sans KR', + 'Malgun Gothic', + 'Apple Color Emoji', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'sans-serif', + ], + }, + }, + plugins: [], +};