diff --git a/app/(main)/_components/FeedSection.tsx b/app/(main)/_components/FeedSection.tsx
new file mode 100644
index 0000000..e6df087
--- /dev/null
+++ b/app/(main)/_components/FeedSection.tsx
@@ -0,0 +1,25 @@
+import { FeedCard } from "@/entities/feed/ui/FeedCard";
+
+import { Container } from "@/shared/container/Container";
+
+import * as styles from "./feedSection.css";
+
+//TODO - 반응형해야함
+export const FeedSection = () => {
+ return (
+
+
+ 잡만리에서 지금 화제인 글
+ 실시간 좋아요 & 트렌드
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/app/(main)/_components/feedSection.css.ts b/app/(main)/_components/feedSection.css.ts
new file mode 100644
index 0000000..0e53512
--- /dev/null
+++ b/app/(main)/_components/feedSection.css.ts
@@ -0,0 +1,41 @@
+import { style } from "@vanilla-extract/css";
+
+export const header = style({
+ display: "flex",
+ flexDirection: "row",
+ justifyContent: "space-between",
+ alignItems: "center",
+ "@media": {
+ "screen and (max-width: 768px)": {
+ flexDirection: "column",
+ alignItems: "flex-start",
+ padding: "16px 0",
+ },
+ },
+});
+
+export const h2 = style({
+ fontSize: "24px",
+ fontWeight: 600,
+ "@media": {
+ "screen and (max-width: 768px)": {
+ margin: "4px 0",
+ },
+ },
+});
+
+export const span = style({
+ color: "gray",
+});
+
+export const cardGrid = style({
+ display: "grid",
+ gridTemplateColumns: "repeat(3, 1fr)",
+ gap: "1rem",
+ "@media": {
+ "screen and (max-width: 768px)": {
+ gridTemplateColumns: "repeat(2,1fr)",
+ gap: "0.5rem",
+ },
+ },
+});
diff --git a/app/(main)/page.tsx b/app/(main)/page.tsx
index 8e73f33..b7944e6 100644
--- a/app/(main)/page.tsx
+++ b/app/(main)/page.tsx
@@ -1,5 +1,14 @@
+import { Spacing } from "@/shared/ui/spacing";
+
import { CompanyListSection } from "./_components/CompanyListSection";
+import { FeedSection } from "./_components/FeedSection";
export default function Home() {
- return ;
+ return (
+ <>
+
+
+
+ >
+ );
}
diff --git a/package.json b/package.json
index 3cb83d7..2cf3324 100644
--- a/package.json
+++ b/package.json
@@ -25,9 +25,9 @@
"@vanilla-extract/vite-plugin": "^5.1.3",
"ky": "^1.14.1",
"lucide-react": "^0.555.0",
- "next": "15.5.7",
- "react": "^19.2.1",
- "react-dom": "^19.2.1"
+ "next": "15.5.9",
+ "react": "^19.2.2",
+ "react-dom": "^19.2.2"
},
"devDependencies": {
"@chromatic-com/storybook": "^4.1.3",
diff --git a/src/entities/feed/ui/FeedCard.tsx b/src/entities/feed/ui/FeedCard.tsx
new file mode 100644
index 0000000..fc6f75c
--- /dev/null
+++ b/src/entities/feed/ui/FeedCard.tsx
@@ -0,0 +1,13 @@
+import { FeedContent, FeedFooter, FeedHeader } from "@/entities/feed/ui";
+
+import * as styles from "./feedCard.css";
+
+export const FeedCard = () => {
+ return (
+
+
+
+
+
+ );
+};
diff --git a/src/entities/feed/ui/FeedContent.tsx b/src/entities/feed/ui/FeedContent.tsx
new file mode 100644
index 0000000..3af4b0a
--- /dev/null
+++ b/src/entities/feed/ui/FeedContent.tsx
@@ -0,0 +1,15 @@
+import { Badge } from "@/shared/ui/badge/Badge";
+
+import * as styles from "./feedContent.css";
+
+export const FeedContent = () => {
+ return (
+
+ 피드 내용
+
+ 태그1
+ 태그2
+
+
+ );
+};
diff --git a/src/entities/feed/ui/FeedFooter.tsx b/src/entities/feed/ui/FeedFooter.tsx
new file mode 100644
index 0000000..60c44a0
--- /dev/null
+++ b/src/entities/feed/ui/FeedFooter.tsx
@@ -0,0 +1,38 @@
+"use client";
+import { useState } from "react";
+
+import { Heart, MessageCircle } from "lucide-react";
+
+import * as styles from "./feedFooter.css";
+
+export const FeedFooter = () => {
+ const [isLiked, setIsLiked] = useState(false);
+ return (
+
+ );
+};
diff --git a/src/entities/feed/ui/FeedHeader.tsx b/src/entities/feed/ui/FeedHeader.tsx
new file mode 100644
index 0000000..45b6496
--- /dev/null
+++ b/src/entities/feed/ui/FeedHeader.tsx
@@ -0,0 +1,19 @@
+import { Badge } from "@/shared/ui/badge/Badge";
+
+import * as styles from "./feedHeader.css";
+
+export const FeedHeader = () => {
+ return (
+
+
+
피드 제목
+
+ 작성자
+ 날짜
+
+
+ );
+};
diff --git a/src/entities/feed/ui/feedCard.css.ts b/src/entities/feed/ui/feedCard.css.ts
new file mode 100644
index 0000000..4531599
--- /dev/null
+++ b/src/entities/feed/ui/feedCard.css.ts
@@ -0,0 +1,18 @@
+import { style } from "@vanilla-extract/css";
+
+export const cardContainer = style({
+ display: "flex",
+ flexDirection: "column",
+ gap: "12px",
+ padding: "24px",
+ border: "1px solid #E2E8F0",
+ borderRadius: "16px",
+ backgroundColor: "white",
+ boxShadow: "0 1px 3px rgba(0, 0, 0, 0.1)",
+ transition: "box-shadow 0.2s",
+ maxWidth: "350px",
+ width: "100%",
+ ":hover": {
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
+ },
+});
diff --git a/src/entities/feed/ui/feedContent.css.ts b/src/entities/feed/ui/feedContent.css.ts
new file mode 100644
index 0000000..3b895e3
--- /dev/null
+++ b/src/entities/feed/ui/feedContent.css.ts
@@ -0,0 +1,19 @@
+import { style } from "@vanilla-extract/css";
+
+export const contentContainer = style({
+ display: "flex",
+ flexDirection: "column",
+ gap: "12px",
+});
+
+export const contentBody = style({
+ fontSize: "16px",
+ lineHeight: "1.6",
+ margin: 0,
+});
+
+export const hashtagContainer = style({
+ display: "flex",
+ flexWrap: "wrap",
+ gap: "8px",
+});
diff --git a/src/entities/feed/ui/feedFooter.css.ts b/src/entities/feed/ui/feedFooter.css.ts
new file mode 100644
index 0000000..3b42713
--- /dev/null
+++ b/src/entities/feed/ui/feedFooter.css.ts
@@ -0,0 +1,77 @@
+import { style, keyframes } from "@vanilla-extract/css";
+
+const heartBeat = keyframes({
+ "0%": { transform: "scale(1)" },
+ "25%": { transform: "scale(1.2)" },
+ "50%": { transform: "scale(1.1)" },
+ "100%": { transform: "scale(1)" },
+});
+
+export const footerContainer = style({
+ display: "flex",
+ flexDirection: "column",
+ gap: "8px",
+ paddingTop: "16px",
+});
+
+export const statsContainer = style({
+ display: "flex",
+ gap: "8px",
+ alignItems: "center",
+ "@media": {
+ "screen and (max-width: 768px)": {
+ flexDirection: "column",
+ alignItems: "flex-start",
+ },
+ },
+});
+
+export const likeContainer = style({
+ display: "flex",
+ alignItems: "center",
+ gap: "4px",
+ padding: "0",
+ border: "none",
+ backgroundColor: "transparent",
+ fontSize: "14px",
+ color: "#64748B",
+});
+
+export const likeButton = style({
+ cursor: "pointer",
+});
+
+export const commentCount = style({
+ display: "flex",
+ alignItems: "center",
+ gap: "6px",
+ fontSize: "14px",
+ color: "#64748B",
+});
+
+export const messageContainer = style({
+ display: "flex",
+});
+
+export const messageButton = style({
+ padding: "10px 16px",
+ backgroundColor: "#F1F5F9",
+ color: "#64748B",
+ border: "none",
+ borderRadius: "8px",
+ fontSize: "14px",
+ fontWeight: 500,
+ cursor: "pointer",
+ ":hover": {
+ backgroundColor: "#E2E8F0",
+ },
+});
+
+export const heartIcon = style({
+ transition: "all 0.3s ease",
+ cursor: "pointer",
+});
+
+export const heartIconLiked = style({
+ animation: `${heartBeat} 0.4s ease`,
+});
diff --git a/src/entities/feed/ui/feedHeader.css.ts b/src/entities/feed/ui/feedHeader.css.ts
new file mode 100644
index 0000000..2d2e88e
--- /dev/null
+++ b/src/entities/feed/ui/feedHeader.css.ts
@@ -0,0 +1,33 @@
+import { style } from "@vanilla-extract/css";
+
+export const headerContainer = style({
+ display: "flex",
+ flexDirection: "column",
+ gap: "8px",
+});
+
+export const cardHeader = style({
+ display: "inline-flex",
+ flexDirection: "row",
+ gap: "8px",
+ alignItems: "center",
+});
+
+export const tagText = style({
+ color: "#64748B",
+ fontSize: "14px",
+});
+
+export const cardTitle = style({
+ fontSize: "24px",
+ fontWeight: 600,
+ margin: "4px 0",
+});
+
+export const cardMeta = style({
+ display: "flex",
+ flexDirection: "column",
+ gap: "4px",
+ fontSize: "14px",
+ color: "#94A3B8",
+});
diff --git a/src/entities/feed/ui/index.ts b/src/entities/feed/ui/index.ts
new file mode 100644
index 0000000..834f0a4
--- /dev/null
+++ b/src/entities/feed/ui/index.ts
@@ -0,0 +1,4 @@
+export { FeedContent } from "./FeedContent";
+export { FeedFooter } from "./FeedFooter";
+export { FeedHeader } from "./FeedHeader";
+export { FeedCard } from "./FeedCard";
diff --git a/src/shared/container/container.css.ts b/src/shared/container/container.css.ts
index dc49fd4..0f797ae 100644
--- a/src/shared/container/container.css.ts
+++ b/src/shared/container/container.css.ts
@@ -6,5 +6,5 @@ export const container = style({
backgroundColor: "#ffffff",
border: "1px solid rgba(0, 0, 0, 0.10)",
borderRadius: "24px",
- padding: "40px",
+ padding: "30px",
});
diff --git a/src/shared/ui/badge/Badge.tsx b/src/shared/ui/badge/Badge.tsx
new file mode 100644
index 0000000..3adef5c
--- /dev/null
+++ b/src/shared/ui/badge/Badge.tsx
@@ -0,0 +1,16 @@
+import { ReactNode } from "react";
+import { RecipeVariants } from "@vanilla-extract/recipes";
+
+import * as styles from "./badge.css";
+
+type BadgeVariants = NonNullable>;
+
+interface BadgeProps {
+ children: ReactNode;
+ variant?: BadgeVariants["variant"];
+ size?: BadgeVariants["size"];
+}
+
+export const Badge = ({ children, variant, size }: BadgeProps) => {
+ return {children};
+};
diff --git a/src/shared/ui/badge/badge.css.ts b/src/shared/ui/badge/badge.css.ts
new file mode 100644
index 0000000..6d05ebc
--- /dev/null
+++ b/src/shared/ui/badge/badge.css.ts
@@ -0,0 +1,56 @@
+import { recipe } from "@vanilla-extract/recipes";
+
+export const badge = recipe({
+ base: {
+ display: "inline-flex",
+ alignItems: "center",
+ justifyContent: "center",
+ fontWeight: 500,
+ borderRadius: "20px",
+ },
+
+ variants: {
+ variant: {
+ primary: {
+ backgroundColor: "#EEF2FF",
+ color: "#2362F0",
+ },
+ secondary: {
+ backgroundColor: "#F1F5F9",
+ color: "#64748B",
+ },
+ success: {
+ backgroundColor: "#DCFCE7",
+ color: "#16A34A",
+ },
+ warning: {
+ backgroundColor: "#FEF3C7",
+ color: "#D97706",
+ },
+ danger: {
+ backgroundColor: "#FEE2E2",
+ color: "#DC2626",
+ },
+ },
+
+ size: {
+ small: {
+ padding: "2px 6px",
+ fontSize: "12px",
+ },
+ medium: {
+ padding: "4px 8px",
+ fontSize: "14px",
+ },
+ large: {
+ padding: "6px 12px",
+ fontSize: "16px",
+ },
+ },
+ },
+
+ defaultVariants: {
+ variant: "primary",
+ size: "medium",
+ },
+});
diff --git a/src/shared/ui/spacing/Spacing.tsx b/src/shared/ui/spacing/Spacing.tsx
new file mode 100644
index 0000000..b4795d9
--- /dev/null
+++ b/src/shared/ui/spacing/Spacing.tsx
@@ -0,0 +1,12 @@
+import * as styles from "./spacing.css";
+
+interface SpacingProps {
+ direction?: "vertical" | "horizontal";
+ size?: number;
+}
+
+export const Spacing = ({ direction = "vertical", size = 16 }: SpacingProps) => {
+ const style = direction === "vertical" ? { height: `${size}px` } : { width: `${size}px` };
+
+ return ;
+};
diff --git a/src/shared/ui/spacing/index.ts b/src/shared/ui/spacing/index.ts
new file mode 100644
index 0000000..acec44b
--- /dev/null
+++ b/src/shared/ui/spacing/index.ts
@@ -0,0 +1 @@
+export { Spacing } from "./Spacing";
diff --git a/src/shared/ui/spacing/spacing.css.ts b/src/shared/ui/spacing/spacing.css.ts
new file mode 100644
index 0000000..9e94c74
--- /dev/null
+++ b/src/shared/ui/spacing/spacing.css.ts
@@ -0,0 +1,22 @@
+import { recipe } from "@vanilla-extract/recipes";
+
+export const spacing = recipe({
+ base: {
+ flexShrink: 0,
+ },
+
+ variants: {
+ direction: {
+ vertical: {
+ width: "100%",
+ },
+ horizontal: {
+ height: "100%",
+ },
+ },
+ },
+
+ defaultVariants: {
+ direction: "vertical",
+ },
+});
diff --git a/yarn.lock b/yarn.lock
index 34f1e81..429b685 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1102,10 +1102,10 @@ __metadata:
languageName: node
linkType: hard
-"@next/env@npm:15.5.7":
- version: 15.5.7
- resolution: "@next/env@npm:15.5.7"
- checksum: 10c0/f92d99e5fa3516c6b7699abafd9bd813f5c1889dd257ab098f1b71f93137f5e4f49792e22f6dddf8a59efcb134e8e84277c983ff88607b2a42aac651bfde78ea
+"@next/env@npm:15.5.9":
+ version: 15.5.9
+ resolution: "@next/env@npm:15.5.9"
+ checksum: 10c0/92c4e29d81a8e78c33c2da179648a4f478a9a6852966192e079007b19ec9955e72530d5ca7df55ea0efeccbf5b1c9d0efcaf80433e26af89c6478193e1d088f1
languageName: node
linkType: hard
@@ -4629,10 +4629,10 @@ __metadata:
globrex: "npm:^0.1.2"
ky: "npm:^1.14.1"
lucide-react: "npm:^0.555.0"
- next: "npm:15.5.7"
+ next: "npm:15.5.9"
prettier: "npm:^3.7.3"
- react: "npm:^19.2.1"
- react-dom: "npm:^19.2.1"
+ react: "npm:^19.2.2"
+ react-dom: "npm:^19.2.2"
rollup: "npm:^4.53.3"
storybook: "npm:^9.1.0"
typescript: "npm:^5"
@@ -5124,11 +5124,11 @@ __metadata:
languageName: node
linkType: hard
-"next@npm:15.5.7":
- version: 15.5.7
- resolution: "next@npm:15.5.7"
+"next@npm:15.5.9":
+ version: 15.5.9
+ resolution: "next@npm:15.5.9"
dependencies:
- "@next/env": "npm:15.5.7"
+ "@next/env": "npm:15.5.9"
"@next/swc-darwin-arm64": "npm:15.5.7"
"@next/swc-darwin-x64": "npm:15.5.7"
"@next/swc-linux-arm64-gnu": "npm:15.5.7"
@@ -5179,7 +5179,7 @@ __metadata:
optional: true
bin:
next: dist/bin/next
- checksum: 10c0/baf5b9f42416c478702b3894479b3d7862bc4abf18afe0e43b7fc7ed35567b8dc6cb76cd94906505bab9013cb8d0f3370cdc0451c01ec15ae5a638d37b5ba7c7
+ checksum: 10c0/6a120afbc45b96aa14debba6375602d6319093af4e3e8c648cf22b12ffb9db016c889df5e764cf5e0aa414ad60505db4e2095624a19f4b71316561076158651a
languageName: node
linkType: hard
@@ -5622,7 +5622,7 @@ __metadata:
languageName: node
linkType: hard
-"react-dom@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0, react-dom@npm:^19.2.1":
+"react-dom@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0, react-dom@npm:^19.2.2":
version: 19.2.3
resolution: "react-dom@npm:19.2.3"
dependencies:
@@ -5640,7 +5640,7 @@ __metadata:
languageName: node
linkType: hard
-"react@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0, react@npm:^19.2.1":
+"react@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0, react@npm:^19.2.2":
version: 19.2.3
resolution: "react@npm:19.2.3"
checksum: 10c0/094220b3ba3a76c1b668f972ace1dd15509b157aead1b40391d1c8e657e720c201d9719537375eff08f5e0514748c0319063392a6f000e31303aafc4471f1436