diff --git a/next.config.js b/next.config.js
index a843cbee..da265d11 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,6 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
-}
+ images: {
+ domains: ['sprint-fe-project.s3.ap-northeast-2.amazonaws.com'],
+ },
+};
-module.exports = nextConfig
+module.exports = nextConfig;
diff --git a/pages/_app.tsx b/pages/_app.tsx
index 021681f4..ad0f0594 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -1,6 +1,12 @@
-import '@/styles/globals.css'
-import type { AppProps } from 'next/app'
+import GlobalLayout from '@/src/components/GlobalLayout';
+import '@/styles/reset.css';
+import '@/styles/globals.css';
+import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
- return
+ return (
+
+
+
+ );
}
diff --git a/pages/_document.tsx b/pages/_document.tsx
index 54e8bf3e..713078f7 100644
--- a/pages/_document.tsx
+++ b/pages/_document.tsx
@@ -1,13 +1,13 @@
-import { Html, Head, Main, NextScript } from 'next/document'
+import { Html, Head, Main, NextScript } from 'next/document';
export default function Document() {
return (
-
+
- )
+ );
}
diff --git a/pages/api/hello.ts b/pages/api/hello.ts
deleted file mode 100644
index f8bcc7e5..00000000
--- a/pages/api/hello.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
-import type { NextApiRequest, NextApiResponse } from 'next'
-
-type Data = {
- name: string
-}
-
-export default function handler(
- req: NextApiRequest,
- res: NextApiResponse
-) {
- res.status(200).json({ name: 'John Doe' })
-}
diff --git a/pages/boards/components/BestBoardCard.module.css b/pages/boards/components/BestBoardCard.module.css
new file mode 100644
index 00000000..169ff0d5
--- /dev/null
+++ b/pages/boards/components/BestBoardCard.module.css
@@ -0,0 +1,80 @@
+.bestBoardCardContainer {
+ border-radius: 8px;
+ background: var(--Secondary-50, #f9fafb);
+ padding: 0px 24px;
+ padding-bottom: 15px;
+
+ display: flex;
+ flex-direction: column;
+ gap: 18px;
+}
+
+.bestBoardBadge {
+ width: 102px;
+ height: 30px;
+ text-align: center;
+ padding: 2px 24px;
+ background: var(--Primary-100, #3692ff);
+ border-radius: 0px 0px 16px 16px;
+
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.bestText {
+ color: #fff;
+ font-size: 16px;
+ font-weight: 600;
+}
+
+.contentContainer {
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ flex-wrap: wrap;
+}
+
+.contentTitle {
+ color: var(--Secondary-800, #1f2937);
+ font-size: 20px;
+ font-weight: 600;
+ max-width: 256px;
+}
+
+.contentImgWrapper {
+ position: relative;
+ width: 72px;
+ height: 72px;
+
+ border-radius: 6px;
+ border: 1px solid var(--Secondary-200, #e5e7eb);
+ background: #fff;
+}
+
+.additionalInfo {
+ color: var(--Secondary-600, #4b5563);
+ font-size: 14px;
+ font-weight: 400;
+
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 8px;
+}
+
+.likeCountWrapper {
+ flex: 1;
+
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+/* tablet */
+@media screen and (max-width: 1199px) {
+ .contentTitle {
+ gap: 40px;
+ max-width: 180px;
+ }
+}
diff --git a/pages/boards/components/BestBoardCard.tsx b/pages/boards/components/BestBoardCard.tsx
new file mode 100644
index 00000000..555d7496
--- /dev/null
+++ b/pages/boards/components/BestBoardCard.tsx
@@ -0,0 +1,42 @@
+import Image from 'next/image';
+import styles from './BestBoardCard.module.css';
+import medalSvg from '@/src/assets/ic_medal.svg';
+import heardSvg from '@/src/assets/ic_heart.svg';
+import { Board } from '@/src/apis/boardTypes';
+
+interface BestBoardCardProps
+ extends Pick<
+ Board,
+ 'title' | 'image' | 'writer' | 'likeCount' | 'createdAt'
+ > {}
+
+export default function BestBoardCard({
+ title,
+ image,
+ writer,
+ likeCount,
+ createdAt,
+}: BestBoardCardProps) {
+ return (
+
+
+
+ Best
+
+
+
+
{writer.nickname}
+
+
+ {likeCount}
+
+
{new Date(createdAt).toLocaleDateString()}
+
+
+ );
+}
diff --git a/pages/boards/components/BestBoards.module.css b/pages/boards/components/BestBoards.module.css
new file mode 100644
index 00000000..9c335b01
--- /dev/null
+++ b/pages/boards/components/BestBoards.module.css
@@ -0,0 +1,43 @@
+.bestBoards {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 24px;
+
+ margin-bottom: 40px;
+}
+
+.title {
+ color: var(--Secondary-900, #111827);
+ font-size: 20px;
+ font-weight: 700;
+
+ padding: 24px 0;
+}
+
+/* tablet */
+@media screen and (max-width: 1199px) {
+ .bestBoards {
+ grid-template-columns: repeat(2, 1fr);
+ gap: 16px;
+ margin-bottom: 24px;
+ }
+
+ .bestBoards > *:nth-child(n + 3) {
+ display: none;
+ }
+}
+
+/* mobile */
+@media screen and (max-width: 767px) {
+ .bestBoards {
+ grid-template-columns: repeat(1, 1fr);
+ }
+
+ .title {
+ padding: 16px 0;
+ }
+
+ .bestBoards > *:nth-child(n + 2) {
+ display: none;
+ }
+}
diff --git a/pages/boards/components/BestBoards.tsx b/pages/boards/components/BestBoards.tsx
new file mode 100644
index 00000000..5a81735e
--- /dev/null
+++ b/pages/boards/components/BestBoards.tsx
@@ -0,0 +1,20 @@
+import { Board } from '@/src/apis/boardTypes';
+import BestBoardCard from './BestBoardCard';
+import styles from './BestBoards.module.css';
+
+interface BestBoardsProps {
+ boards: Board[];
+}
+
+export default function BestBoards({ boards }: BestBoardsProps) {
+ return (
+
+ 베스트 게시글
+
+ {boards.map((board) => (
+
+ ))}
+
+
+ );
+}
diff --git a/pages/boards/components/Boards.module.css b/pages/boards/components/Boards.module.css
new file mode 100644
index 00000000..fdc84945
--- /dev/null
+++ b/pages/boards/components/Boards.module.css
@@ -0,0 +1,46 @@
+.boardsHeader {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 24px;
+}
+
+.title {
+ color: var(--Secondary-800, #1f2937);
+ font-size: 20px;
+ font-weight: 700;
+}
+
+.searchBar {
+ padding: 9px 20px 9px 16px;
+ border-radius: 12px;
+ background: var(--Secondary-100, #f3f4f6);
+
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.searchData {
+ font-size: 16px;
+ font-weight: 400;
+ background: transparent;
+}
+
+.searchData::placeholder {
+ color: var(--Secondary-400, #9ca3af);
+}
+
+/* tablet */
+@media screen and (max-width: 1199px) {
+ .boardsHeader {
+ margin-bottom: 48px;
+ }
+}
+
+/* mobile */
+@media screen and (max-width: 767px) {
+ .boardsHeader {
+ margin-bottom: 16px;
+ }
+}
diff --git a/pages/boards/components/Boards.tsx b/pages/boards/components/Boards.tsx
new file mode 100644
index 00000000..1d4d8495
--- /dev/null
+++ b/pages/boards/components/Boards.tsx
@@ -0,0 +1,26 @@
+import Image from 'next/image';
+import Button from '@/src/components/Button';
+import styles from './Boards.module.css';
+import searchSvg from '@/src/assets/ic_search.svg';
+
+export default function Boards() {
+ return (
+
+ );
+}
diff --git a/pages/boards/index.tsx b/pages/boards/index.tsx
new file mode 100644
index 00000000..5e584f2c
--- /dev/null
+++ b/pages/boards/index.tsx
@@ -0,0 +1,33 @@
+import { GetStaticProps } from 'next';
+import BestBoards from './components/BestBoards';
+import { Board } from '@/src/apis/boardTypes';
+import { getBoards } from '@/src/apis/boardsApi';
+import Boards from './components/Boards';
+
+interface BoardsIndexProps {
+ boards: Board[];
+}
+
+export default function BoardsIndex({ boards }: BoardsIndexProps) {
+ return (
+
+
+
+
+ );
+}
+
+export const getStaticProps: GetStaticProps = async () => {
+ const { list } = await getBoards({
+ page: 1,
+ pageSize: 3,
+ orderBy: 'like',
+ });
+
+ return {
+ props: {
+ boards: list || [],
+ },
+ revalidate: 600, // Re-generate the page every 600 seconds (ISR)
+ };
+};
diff --git a/pages/index.tsx b/pages/index.tsx
index 02c4dee0..e53f8cde 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,114 +1,7 @@
-import Head from 'next/head'
-import Image from 'next/image'
-import { Inter } from 'next/font/google'
-import styles from '@/styles/Home.module.css'
-
-const inter = Inter({ subsets: ['latin'] })
-
export default function Home() {
return (
<>
-
- Create Next App
-
-
-
-
-
-
-
- Get started by editing
- pages/index.tsx
-
-
-
-
-
-
-
-
-
-
+ index
>
- )
+ );
}
diff --git a/public/next.svg b/public/next.svg
deleted file mode 100644
index 5174b28c..00000000
--- a/public/next.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/vercel.svg b/public/vercel.svg
deleted file mode 100644
index d2f84222..00000000
--- a/public/vercel.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/apis/boardTypes.ts b/src/apis/boardTypes.ts
new file mode 100644
index 00000000..e44f3fdf
--- /dev/null
+++ b/src/apis/boardTypes.ts
@@ -0,0 +1,27 @@
+export interface Writer {
+ id: number;
+ nickname: string;
+}
+
+export interface Board {
+ id: number;
+ title: string;
+ content: string;
+ image: string; // TODO image null 처리
+ likeCount: number;
+ createdAt: string;
+ updatedAt: string;
+ writer: Writer;
+}
+
+export interface GetBoardsResponse {
+ list: Board[];
+ totalCount: number;
+}
+
+export interface GetBoardsRequestParams {
+ page?: number;
+ pageSize?: number;
+ orderBy?: 'recent' | 'like';
+ keyword?: string;
+}
diff --git a/src/apis/boardsApi.ts b/src/apis/boardsApi.ts
new file mode 100644
index 00000000..d0b14090
--- /dev/null
+++ b/src/apis/boardsApi.ts
@@ -0,0 +1,39 @@
+import { Board, GetBoardsResponse, GetBoardsRequestParams } from './boardTypes';
+
+const BASE_URL = 'https://panda-market-api.vercel.app';
+
+async function fetchFromAPI(endpoint: string): Promise {
+ try {
+ const response = await fetch(endpoint);
+ if (!response.ok) {
+ throw new Error(
+ `HTTP error! Status: ${response.status} / response: ${response}`
+ );
+ }
+
+ return await response.json();
+ } catch (error) {
+ console.error('Failed to fetch data:', error);
+ throw error;
+ }
+}
+
+export async function getBoards({
+ page = 1,
+ pageSize = 10,
+ orderBy = 'recent',
+ keyword,
+}: GetBoardsRequestParams) {
+ const queryParams = new URLSearchParams({
+ page: page.toString(),
+ pageSize: pageSize.toString(),
+ orderBy,
+ });
+
+ if (keyword) {
+ queryParams.append('keyword', keyword);
+ }
+
+ const endpoint = `${BASE_URL}/articles?${queryParams.toString()}`;
+ return await fetchFromAPI(endpoint);
+}
diff --git a/src/assets/avatar.svg b/src/assets/avatar.svg
new file mode 100644
index 00000000..3136c4fa
--- /dev/null
+++ b/src/assets/avatar.svg
@@ -0,0 +1,24 @@
+
diff --git a/src/assets/ic_heart.svg b/src/assets/ic_heart.svg
new file mode 100644
index 00000000..2d4338bf
--- /dev/null
+++ b/src/assets/ic_heart.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/ic_medal.svg b/src/assets/ic_medal.svg
new file mode 100644
index 00000000..d650c401
--- /dev/null
+++ b/src/assets/ic_medal.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/assets/ic_search.svg b/src/assets/ic_search.svg
new file mode 100644
index 00000000..e8b451e4
--- /dev/null
+++ b/src/assets/ic_search.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/logo_lg.png b/src/assets/logo_lg.png
new file mode 100644
index 00000000..1fa247ed
Binary files /dev/null and b/src/assets/logo_lg.png differ
diff --git a/src/assets/logo_sm.png b/src/assets/logo_sm.png
new file mode 100644
index 00000000..c72c1788
Binary files /dev/null and b/src/assets/logo_sm.png differ
diff --git a/src/components/Button.module.css b/src/components/Button.module.css
new file mode 100644
index 00000000..f01db878
--- /dev/null
+++ b/src/components/Button.module.css
@@ -0,0 +1,12 @@
+.primaryButton {
+ border-radius: 8px;
+ background: var(--Primary-100, #3692ff);
+
+ color: #fff;
+ font-size: 16px;
+ font-weight: 600;
+
+ padding: 12px 23px;
+ width: 100%;
+ height: 100%;
+}
diff --git a/src/components/Button.tsx b/src/components/Button.tsx
new file mode 100644
index 00000000..56cd4dd6
--- /dev/null
+++ b/src/components/Button.tsx
@@ -0,0 +1,19 @@
+import { ButtonHTMLAttributes } from 'react';
+import styles from './Button.module.css';
+
+interface PrimaryButtonProps extends ButtonHTMLAttributes {
+ children: React.ReactNode;
+ className?: string;
+}
+
+export default function Button({
+ children,
+ className,
+ ...props
+}: PrimaryButtonProps) {
+ return (
+
+ );
+}
diff --git a/src/components/GlobalLayout.module.css b/src/components/GlobalLayout.module.css
new file mode 100644
index 00000000..2ccbc164
--- /dev/null
+++ b/src/components/GlobalLayout.module.css
@@ -0,0 +1,4 @@
+.main {
+ margin-top: 75px;
+ width: 100%;
+}
diff --git a/src/components/GlobalLayout.tsx b/src/components/GlobalLayout.tsx
new file mode 100644
index 00000000..f4ce9201
--- /dev/null
+++ b/src/components/GlobalLayout.tsx
@@ -0,0 +1,14 @@
+import { ReactNode } from 'react';
+import Header from './Header';
+import styles from './GlobalLayout.module.css';
+
+export default function GlobalLayout({ children }: { children: ReactNode }) {
+ return (
+ <>
+
+
+ {children}
+
+ >
+ );
+}
diff --git a/src/components/Header.module.css b/src/components/Header.module.css
new file mode 100644
index 00000000..49aa3e69
--- /dev/null
+++ b/src/components/Header.module.css
@@ -0,0 +1,56 @@
+.header {
+ z-index: 999;
+ position: fixed;
+ top: 0;
+ width: 100%;
+ border-bottom: 1px solid #dfdfdf;
+}
+
+.headerContainer {
+ padding: 10px 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ max-width: 1300px;
+ margin: auto;
+}
+
+.logoWrapper {
+ width: 153px;
+ height: 51px;
+ background-image: url('../assets/logo_lg.png');
+ background-size: contain;
+ background-repeat: no-repeat;
+ cursor: pointer;
+}
+
+.nav {
+ color: var(--Secondary-600, #4b5563);
+ text-align: center;
+ font-size: 18px;
+ font-weight: 700;
+ flex: 1;
+
+ display: flex;
+ gap: 30px;
+ margin-left: 30px;
+}
+
+.avatarWrapper {
+ position: relative;
+ width: 40px;
+ height: 40px;
+}
+
+/* mobile */
+@media screen and (max-width: 767px) {
+ .logoWrapper {
+ width: 81px;
+ height: 40px;
+ background-image: url('../assets/logo_sm.png');
+ }
+
+ .nav {
+ font-size: 16px;
+ }
+}
diff --git a/src/components/Header.tsx b/src/components/Header.tsx
new file mode 100644
index 00000000..1f5362ba
--- /dev/null
+++ b/src/components/Header.tsx
@@ -0,0 +1,25 @@
+import Link from 'next/link';
+import styles from './Header.module.css';
+import Image from 'next/image';
+import avatarSvg from '@/src/assets/avatar.svg';
+
+export default function Header() {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/styles/Home.module.css b/styles/Home.module.css
deleted file mode 100644
index 6676d2c6..00000000
--- a/styles/Home.module.css
+++ /dev/null
@@ -1,229 +0,0 @@
-.main {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- align-items: center;
- padding: 6rem;
- min-height: 100vh;
-}
-
-.description {
- display: inherit;
- justify-content: inherit;
- align-items: inherit;
- font-size: 0.85rem;
- max-width: var(--max-width);
- width: 100%;
- z-index: 2;
- font-family: var(--font-mono);
-}
-
-.description a {
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 0.5rem;
-}
-
-.description p {
- position: relative;
- margin: 0;
- padding: 1rem;
- background-color: rgba(var(--callout-rgb), 0.5);
- border: 1px solid rgba(var(--callout-border-rgb), 0.3);
- border-radius: var(--border-radius);
-}
-
-.code {
- font-weight: 700;
- font-family: var(--font-mono);
-}
-
-.grid {
- display: grid;
- grid-template-columns: repeat(4, minmax(25%, auto));
- max-width: 100%;
- width: var(--max-width);
-}
-
-.card {
- padding: 1rem 1.2rem;
- border-radius: var(--border-radius);
- background: rgba(var(--card-rgb), 0);
- border: 1px solid rgba(var(--card-border-rgb), 0);
- transition: background 200ms, border 200ms;
-}
-
-.card span {
- display: inline-block;
- transition: transform 200ms;
-}
-
-.card h2 {
- font-weight: 600;
- margin-bottom: 0.7rem;
-}
-
-.card p {
- margin: 0;
- opacity: 0.6;
- font-size: 0.9rem;
- line-height: 1.5;
- max-width: 30ch;
-}
-
-.center {
- display: flex;
- justify-content: center;
- align-items: center;
- position: relative;
- padding: 4rem 0;
-}
-
-.center::before {
- background: var(--secondary-glow);
- border-radius: 50%;
- width: 480px;
- height: 360px;
- margin-left: -400px;
-}
-
-.center::after {
- background: var(--primary-glow);
- width: 240px;
- height: 180px;
- z-index: -1;
-}
-
-.center::before,
-.center::after {
- content: '';
- left: 50%;
- position: absolute;
- filter: blur(45px);
- transform: translateZ(0);
-}
-
-.logo {
- position: relative;
-}
-/* Enable hover only on non-touch devices */
-@media (hover: hover) and (pointer: fine) {
- .card:hover {
- background: rgba(var(--card-rgb), 0.1);
- border: 1px solid rgba(var(--card-border-rgb), 0.15);
- }
-
- .card:hover span {
- transform: translateX(4px);
- }
-}
-
-@media (prefers-reduced-motion) {
- .card:hover span {
- transform: none;
- }
-}
-
-/* Mobile */
-@media (max-width: 700px) {
- .content {
- padding: 4rem;
- }
-
- .grid {
- grid-template-columns: 1fr;
- margin-bottom: 120px;
- max-width: 320px;
- text-align: center;
- }
-
- .card {
- padding: 1rem 2.5rem;
- }
-
- .card h2 {
- margin-bottom: 0.5rem;
- }
-
- .center {
- padding: 8rem 0 6rem;
- }
-
- .center::before {
- transform: none;
- height: 300px;
- }
-
- .description {
- font-size: 0.8rem;
- }
-
- .description a {
- padding: 1rem;
- }
-
- .description p,
- .description div {
- display: flex;
- justify-content: center;
- position: fixed;
- width: 100%;
- }
-
- .description p {
- align-items: center;
- inset: 0 0 auto;
- padding: 2rem 1rem 1.4rem;
- border-radius: 0;
- border: none;
- border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25);
- background: linear-gradient(
- to bottom,
- rgba(var(--background-start-rgb), 1),
- rgba(var(--callout-rgb), 0.5)
- );
- background-clip: padding-box;
- backdrop-filter: blur(24px);
- }
-
- .description div {
- align-items: flex-end;
- pointer-events: none;
- inset: auto 0 0;
- padding: 2rem;
- height: 200px;
- background: linear-gradient(
- to bottom,
- transparent 0%,
- rgb(var(--background-end-rgb)) 40%
- );
- z-index: 1;
- }
-}
-
-/* Tablet and Smaller Desktop */
-@media (min-width: 701px) and (max-width: 1120px) {
- .grid {
- grid-template-columns: repeat(2, 50%);
- }
-}
-
-@media (prefers-color-scheme: dark) {
- .vercelLogo {
- filter: invert(1);
- }
-
- .logo {
- filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70);
- }
-}
-
-@keyframes rotate {
- from {
- transform: rotate(360deg);
- }
- to {
- transform: rotate(0deg);
- }
-}
diff --git a/styles/globals.css b/styles/globals.css
index d4f491e1..14b366ae 100644
--- a/styles/globals.css
+++ b/styles/globals.css
@@ -1,107 +1,50 @@
-:root {
- --max-width: 1100px;
- --border-radius: 12px;
- --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono',
- 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro',
- 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace;
-
- --foreground-rgb: 0, 0, 0;
- --background-start-rgb: 214, 219, 220;
- --background-end-rgb: 255, 255, 255;
-
- --primary-glow: conic-gradient(
- from 180deg at 50% 50%,
- #16abff33 0deg,
- #0885ff33 55deg,
- #54d6ff33 120deg,
- #0071ff33 160deg,
- transparent 360deg
- );
- --secondary-glow: radial-gradient(
- rgba(255, 255, 255, 1),
- rgba(255, 255, 255, 0)
- );
+@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css');
- --tile-start-rgb: 239, 245, 249;
- --tile-end-rgb: 228, 232, 233;
- --tile-border: conic-gradient(
- #00000080,
- #00000040,
- #00000030,
- #00000020,
- #00000010,
- #00000010,
- #00000080
- );
-
- --callout-rgb: 238, 240, 241;
- --callout-border-rgb: 172, 175, 176;
- --card-rgb: 180, 185, 188;
- --card-border-rgb: 131, 134, 135;
+:root {
+ --Primary-300: #1251aa;
+ --Primary-200: #1967d6;
+ --Primary-100: #3692ff;
+ --main-bg-color: #cfe5ff;
+ --Secondary-900: #111827;
+ --Secondary-800: #1f2937;
+ --Secondary-700: #374151;
+ --Secondary-600: #4b5563;
+ --Secondary-500: #6b7280;
+ --Secondary-400: #9ca3af;
+ --Secondary-200: #e5e7eb;
+ --Secondary-100: #f3f4f6;
+ --Secondary-50: #f9fafb;
+ --error-red: #f74747;
+ --size-max-width: 1200px;
}
-@media (prefers-color-scheme: dark) {
- :root {
- --foreground-rgb: 255, 255, 255;
- --background-start-rgb: 0, 0, 0;
- --background-end-rgb: 0, 0, 0;
-
- --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0));
- --secondary-glow: linear-gradient(
- to bottom right,
- rgba(1, 65, 255, 0),
- rgba(1, 65, 255, 0),
- rgba(1, 65, 255, 0.3)
- );
-
- --tile-start-rgb: 2, 13, 46;
- --tile-end-rgb: 2, 5, 19;
- --tile-border: conic-gradient(
- #ffffff80,
- #ffffff40,
- #ffffff30,
- #ffffff20,
- #ffffff10,
- #ffffff10,
- #ffffff80
- );
-
- --callout-rgb: 20, 20, 20;
- --callout-border-rgb: 108, 108, 108;
- --card-rgb: 100, 100, 100;
- --card-border-rgb: 200, 200, 200;
- }
+* {
+ font-family: 'Pretendard', sans-serif;
}
-* {
- box-sizing: border-box;
- padding: 0;
- margin: 0;
+header {
+ background-color: #fff;
}
-html,
-body {
- max-width: 100vw;
- overflow-x: hidden;
+footer {
+ background-color: var(--Secondary-900);
}
-body {
- color: rgb(var(--foreground-rgb));
- background: linear-gradient(
- to bottom,
- transparent,
- rgb(var(--background-end-rgb))
- )
- rgb(var(--background-start-rgb));
+.max-container {
+ max-width: var(--size-max-width);
+ margin: auto;
}
-a {
- color: inherit;
- text-decoration: none;
+/* tablet */
+@media screen and (max-width: 1199px) {
+ .max-container {
+ max-width: 760px;
+ }
}
-@media (prefers-color-scheme: dark) {
- html {
- color-scheme: dark;
+/* mobile */
+@media screen and (max-width: 767px) {
+ .max-container {
+ max-width: 360px;
}
}
diff --git a/styles/reset.css b/styles/reset.css
new file mode 100644
index 00000000..68d34450
--- /dev/null
+++ b/styles/reset.css
@@ -0,0 +1,56 @@
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ color: inherit;
+ vertical-align: baseline;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ height: 100vh;
+ width: 100%;
+}
+
+a {
+ text-decoration: none;
+}
+
+ul {
+ list-style: none;
+ padding: 0;
+}
+
+button {
+ border: none;
+ outline: none;
+ cursor: pointer;
+}
+
+footer {
+ width: 100%;
+}
+
+input {
+ outline: none;
+ border: none;
+}
+
+input:focus {
+ outline: none;
+}
+
+input[type='submit'] {
+ cursor: pointer;
+ outline: none;
+}
+
+@media screen and (max-width: 767px) {
+ body {
+ height: 100%;
+ }
+}