diff --git a/apps/admin/src/assets/images/create-show.png b/apps/admin/src/assets/images/create-show.png
deleted file mode 100644
index 6ee8b0c0..00000000
Binary files a/apps/admin/src/assets/images/create-show.png and /dev/null differ
diff --git a/apps/admin/src/assets/images/entrance-notification.png b/apps/admin/src/assets/images/entrance-notification.png
deleted file mode 100644
index 1ec063d3..00000000
Binary files a/apps/admin/src/assets/images/entrance-notification.png and /dev/null differ
diff --git a/apps/admin/src/assets/images/key-visual.png b/apps/admin/src/assets/images/key-visual.png
deleted file mode 100644
index e8a2dc88..00000000
Binary files a/apps/admin/src/assets/images/key-visual.png and /dev/null differ
diff --git a/apps/admin/src/assets/images/light.png b/apps/admin/src/assets/images/light.png
deleted file mode 100644
index 54299407..00000000
Binary files a/apps/admin/src/assets/images/light.png and /dev/null differ
diff --git a/apps/admin/src/assets/images/manage-entrance.png b/apps/admin/src/assets/images/manage-entrance.png
deleted file mode 100644
index 64a87316..00000000
Binary files a/apps/admin/src/assets/images/manage-entrance.png and /dev/null differ
diff --git a/apps/admin/src/assets/images/mobile-admin-preview.png b/apps/admin/src/assets/images/mobile-admin-preview.png
deleted file mode 100644
index 80aa5f15..00000000
Binary files a/apps/admin/src/assets/images/mobile-admin-preview.png and /dev/null differ
diff --git a/apps/admin/src/assets/images/mobile-ticket-preview.png b/apps/admin/src/assets/images/mobile-ticket-preview.png
deleted file mode 100644
index 4f2f5938..00000000
Binary files a/apps/admin/src/assets/images/mobile-ticket-preview.png and /dev/null differ
diff --git a/apps/admin/src/assets/images/more-information-light.png b/apps/admin/src/assets/images/more-information-light.png
deleted file mode 100644
index 56059edd..00000000
Binary files a/apps/admin/src/assets/images/more-information-light.png and /dev/null differ
diff --git a/apps/admin/src/assets/images/pc-admin-preview.png b/apps/admin/src/assets/images/pc-admin-preview.png
deleted file mode 100644
index de28f62f..00000000
Binary files a/apps/admin/src/assets/images/pc-admin-preview.png and /dev/null differ
diff --git a/apps/admin/src/assets/images/pc-ticket-preview.png b/apps/admin/src/assets/images/pc-ticket-preview.png
deleted file mode 100644
index 93bc0a51..00000000
Binary files a/apps/admin/src/assets/images/pc-ticket-preview.png and /dev/null differ
diff --git a/apps/admin/src/assets/images/show-info.png b/apps/admin/src/assets/images/show-info.png
deleted file mode 100644
index 64504205..00000000
Binary files a/apps/admin/src/assets/images/show-info.png and /dev/null differ
diff --git a/apps/admin/src/assets/images/ticket-purchase.png b/apps/admin/src/assets/images/ticket-purchase.png
deleted file mode 100644
index e9218329..00000000
Binary files a/apps/admin/src/assets/images/ticket-purchase.png and /dev/null differ
diff --git a/apps/admin/src/assets/landing-v2/arrow.svg b/apps/admin/src/assets/landing-v2/arrow.svg
new file mode 100644
index 00000000..82ecc5e2
--- /dev/null
+++ b/apps/admin/src/assets/landing-v2/arrow.svg
@@ -0,0 +1,3 @@
+
diff --git a/apps/admin/src/assets/landing-v2/entry-asis.png b/apps/admin/src/assets/landing-v2/entry-asis.png
new file mode 100644
index 00000000..ee26fbad
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/entry-asis.png differ
diff --git a/apps/admin/src/assets/landing-v2/entry-tobe.png b/apps/admin/src/assets/landing-v2/entry-tobe.png
new file mode 100644
index 00000000..d169f523
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/entry-tobe.png differ
diff --git a/apps/admin/src/assets/landing-v2/hero-1.png b/apps/admin/src/assets/landing-v2/hero-1.png
new file mode 100644
index 00000000..bf5c3035
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/hero-1.png differ
diff --git a/apps/admin/src/assets/landing-v2/hero-2.png b/apps/admin/src/assets/landing-v2/hero-2.png
new file mode 100644
index 00000000..e3c3d5a1
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/hero-2.png differ
diff --git a/apps/admin/src/assets/landing-v2/hero-3.png b/apps/admin/src/assets/landing-v2/hero-3.png
new file mode 100644
index 00000000..052f281d
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/hero-3.png differ
diff --git a/apps/admin/src/assets/landing-v2/hero-4.png b/apps/admin/src/assets/landing-v2/hero-4.png
new file mode 100644
index 00000000..208ba721
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/hero-4.png differ
diff --git a/apps/admin/src/assets/landing-v2/hero-5.png b/apps/admin/src/assets/landing-v2/hero-5.png
new file mode 100644
index 00000000..e69cf512
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/hero-5.png differ
diff --git a/apps/admin/src/assets/landing-v2/hero-logo.svg b/apps/admin/src/assets/landing-v2/hero-logo.svg
new file mode 100644
index 00000000..3fb23394
--- /dev/null
+++ b/apps/admin/src/assets/landing-v2/hero-logo.svg
@@ -0,0 +1,7 @@
+
diff --git a/apps/admin/src/assets/landing-v2/light.svg b/apps/admin/src/assets/landing-v2/light.svg
new file mode 100644
index 00000000..d1685fb3
--- /dev/null
+++ b/apps/admin/src/assets/landing-v2/light.svg
@@ -0,0 +1,52 @@
+
diff --git a/apps/admin/src/assets/landing-v2/notify-asis.png b/apps/admin/src/assets/landing-v2/notify-asis.png
new file mode 100644
index 00000000..cbe61780
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/notify-asis.png differ
diff --git a/apps/admin/src/assets/landing-v2/notify-tobe.png b/apps/admin/src/assets/landing-v2/notify-tobe.png
new file mode 100644
index 00000000..773aa492
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/notify-tobe.png differ
diff --git a/apps/admin/src/assets/landing-v2/payment.png b/apps/admin/src/assets/landing-v2/payment.png
new file mode 100644
index 00000000..b9022f48
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/payment.png differ
diff --git a/apps/admin/src/assets/landing-v2/problem-1.png b/apps/admin/src/assets/landing-v2/problem-1.png
new file mode 100644
index 00000000..7a153fa4
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-1.png differ
diff --git a/apps/admin/src/assets/landing-v2/problem-2.png b/apps/admin/src/assets/landing-v2/problem-2.png
new file mode 100644
index 00000000..06b91c95
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-2.png differ
diff --git a/apps/admin/src/assets/landing-v2/problem-3.png b/apps/admin/src/assets/landing-v2/problem-3.png
new file mode 100644
index 00000000..bfa678f4
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-3.png differ
diff --git a/apps/admin/src/assets/landing-v2/problem-4.png b/apps/admin/src/assets/landing-v2/problem-4.png
new file mode 100644
index 00000000..2d610e9e
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-4.png differ
diff --git a/apps/admin/src/assets/landing-v2/problem-5.png b/apps/admin/src/assets/landing-v2/problem-5.png
new file mode 100644
index 00000000..80b53ccb
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-5.png differ
diff --git a/apps/admin/src/assets/landing-v2/problem-6.png b/apps/admin/src/assets/landing-v2/problem-6.png
new file mode 100644
index 00000000..8df3af66
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-6.png differ
diff --git a/apps/admin/src/assets/landing-v2/promo-1.png b/apps/admin/src/assets/landing-v2/promo-1.png
new file mode 100644
index 00000000..364a5665
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/promo-1.png differ
diff --git a/apps/admin/src/assets/landing-v2/promo-2.png b/apps/admin/src/assets/landing-v2/promo-2.png
new file mode 100644
index 00000000..6668fade
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/promo-2.png differ
diff --git a/apps/admin/src/assets/landing-v2/sales-asis.png b/apps/admin/src/assets/landing-v2/sales-asis.png
new file mode 100644
index 00000000..db85cca9
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/sales-asis.png differ
diff --git a/apps/admin/src/assets/landing-v2/sales-tobe.png b/apps/admin/src/assets/landing-v2/sales-tobe.png
new file mode 100644
index 00000000..1bc3282d
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/sales-tobe.png differ
diff --git a/apps/admin/src/assets/landing-v2/stats-asis.png b/apps/admin/src/assets/landing-v2/stats-asis.png
new file mode 100644
index 00000000..55106205
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/stats-asis.png differ
diff --git a/apps/admin/src/assets/landing-v2/stats-tobe.png b/apps/admin/src/assets/landing-v2/stats-tobe.png
new file mode 100644
index 00000000..beaf49f2
Binary files /dev/null and b/apps/admin/src/assets/landing-v2/stats-tobe.png differ
diff --git a/apps/admin/src/pages/Landing/LandingPage.styles.ts b/apps/admin/src/pages/Landing/LandingPage.styles.ts
index 65d1bb7b..1d9b02be 100644
--- a/apps/admin/src/pages/Landing/LandingPage.styles.ts
+++ b/apps/admin/src/pages/Landing/LandingPage.styles.ts
@@ -1,17 +1,13 @@
-import { mq_lg } from '@boolti/ui';
import styled from '@emotion/styled';
import { m } from 'framer-motion';
const Container = styled(m.div)`
overflow: hidden;
min-height: 100vh;
- padding-top: 48px;
+
&::-webkit-scrollbar {
display: none;
}
- ${mq_lg} {
- padding-top: 68px;
- }
`;
const FooterContainer = styled.div`
diff --git a/apps/admin/src/pages/Landing/atoms/visibleSectionAtom.ts b/apps/admin/src/pages/Landing/atoms/visibleSectionAtom.ts
index de8b8fd8..0789a2e0 100644
--- a/apps/admin/src/pages/Landing/atoms/visibleSectionAtom.ts
+++ b/apps/admin/src/pages/Landing/atoms/visibleSectionAtom.ts
@@ -2,9 +2,14 @@ import { atom, useSetAtom } from 'jotai';
import { useEffect } from 'react';
import { useInView } from 'react-intersection-observer';
-type VisibleSection = 'key-visal' | 'organizer' | 'user';
+type VisibleSection =
+ | 'hero'
+ | 'problem'
+ | 'solution-features'
+ | 'solution-highlight'
+ | 'how-to-use';
-export const visibleSectionAtom = atom('key-visal');
+export const visibleSectionAtom = atom('hero');
export const useVisibleSectionAtom = (section: VisibleSection) => {
const { ref, inView, entry } = useInView({ threshold: 0.2 });
diff --git a/apps/admin/src/pages/Landing/components/FeatureCard/FeatureCard.styles.ts b/apps/admin/src/pages/Landing/components/FeatureCard/FeatureCard.styles.ts
new file mode 100644
index 00000000..e0d2fd2a
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/FeatureCard/FeatureCard.styles.ts
@@ -0,0 +1,157 @@
+import { mq_lg } from '@boolti/ui';
+import styled from '@emotion/styled';
+
+import { LANDING_COLORS, mq_desktop } from '../../constants';
+
+const Card = styled.article`
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ width: 100%;
+`;
+
+const TextArea = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 16px;
+ padding: 0 24px 24px;
+
+ ${mq_lg} {
+ gap: 20px;
+ padding: 0 0 32px;
+ }
+
+ ${mq_desktop} {
+ gap: 24px;
+ padding: 0 0 40px;
+ }
+`;
+
+const Chip = styled.div`
+ display: inline-flex;
+ align-items: center;
+ padding: 8px 14px;
+ border-radius: 200px;
+ background-color: ${LANDING_COLORS.chipBg};
+ color: ${LANDING_COLORS.chipText};
+ font-family: Pretendard, sans-serif;
+ font-weight: 600;
+ font-size: 16px;
+ line-height: 1.3;
+ letter-spacing: -0.02em;
+
+ ${mq_lg} {
+ font-size: 18px;
+ }
+
+ ${mq_desktop} {
+ padding: 10px 16px;
+ font-size: 24px;
+ }
+`;
+
+const TitleBlock = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
+ text-align: center;
+`;
+
+const Title = styled.h3`
+ font-family: Pretendard, sans-serif;
+ font-weight: 600;
+ font-size: 20px;
+ line-height: 1.35;
+ letter-spacing: -0.02em;
+ white-space: pre-line;
+ color: #000000;
+ margin: 0;
+
+ ${mq_lg} {
+ font-size: 24px;
+ }
+
+ ${mq_desktop} {
+ font-size: 32px;
+ }
+`;
+
+const Description = styled.p`
+ font-family: Pretendard, sans-serif;
+ font-weight: 400;
+ font-size: 14px;
+ line-height: 1.5;
+ letter-spacing: -0.02em;
+ white-space: pre-line;
+ color: #a2a5b4;
+ margin: 0;
+
+ ${mq_lg} {
+ font-size: 18px;
+ }
+
+ ${mq_desktop} {
+ font-size: 24px;
+ }
+`;
+
+const Media = styled.div`
+ position: relative;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 12px;
+ width: 100%;
+ padding: 16px;
+ border: 1px solid ${LANDING_COLORS.cardBorder};
+ border-radius: 16px;
+ background-color: #ffffff;
+
+ ${mq_desktop} {
+ padding: 32px;
+ gap: 24px;
+ }
+`;
+
+const MediaImage = styled.img`
+ width: 100%;
+ height: auto;
+ object-fit: cover;
+ border-radius: 8px;
+`;
+
+const MediaArrow = styled.div`
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 32px;
+ height: 32px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ svg,
+ img {
+ width: 100%;
+ height: 100%;
+ }
+
+ ${mq_desktop} {
+ width: 48px;
+ height: 48px;
+ }
+`;
+
+export default {
+ Card,
+ TextArea,
+ Chip,
+ TitleBlock,
+ Title,
+ Description,
+ Media,
+ MediaImage,
+ MediaArrow,
+};
diff --git a/apps/admin/src/pages/Landing/components/FeatureCard/index.tsx b/apps/admin/src/pages/Landing/components/FeatureCard/index.tsx
new file mode 100644
index 00000000..3044dacf
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/FeatureCard/index.tsx
@@ -0,0 +1,49 @@
+import { ReactNode } from 'react';
+
+import arrowSvg from '~/assets/landing-v2/arrow.svg';
+
+import Styled from './FeatureCard.styles';
+
+interface FeatureCardProps {
+ chip: string;
+ title: string;
+ description: string;
+ asisSrc?: string;
+ tobeSrc?: string;
+ media?: ReactNode;
+ className?: string;
+}
+
+const FeatureCard = ({
+ chip,
+ title,
+ description,
+ asisSrc,
+ tobeSrc,
+ media,
+ className,
+}: FeatureCardProps) => {
+ return (
+
+
+ {chip}
+
+ {title}
+ {description}
+
+
+ {media ??
+ (asisSrc && tobeSrc ? (
+
+
+
+
+
+
+
+ ) : null)}
+
+ );
+};
+
+export default FeatureCard;
diff --git a/apps/admin/src/pages/Landing/components/FeatureItem/FeatureItem.styles.ts b/apps/admin/src/pages/Landing/components/FeatureItem/FeatureItem.styles.ts
deleted file mode 100644
index 0bd6ca0d..00000000
--- a/apps/admin/src/pages/Landing/components/FeatureItem/FeatureItem.styles.ts
+++ /dev/null
@@ -1,134 +0,0 @@
-import { mq_lg, mq_md } from '@boolti/ui';
-import styled from '@emotion/styled';
-
-const Container = styled.div<{ position: 'left' | 'right' }>`
- display: flex;
- flex-wrap: wrap;
- justify-content: center;
- align-items: center;
- padding: 80px 0 40px;
- flex-direction: column;
-
- ${mq_lg} {
- max-width: ${({ theme }) => theme.breakpoint.desktop};
- margin: 0 auto;
- padding: 110px 20px 0;
- justify-content: space-between;
- flex-direction: ${({ position }) => (position === 'left' ? 'row' : 'row-reverse')};
- }
- ${mq_md} {
- flex-direction: column;
- align-items: ${({ position }) => (position === 'left' ? 'flex-start' : 'flex-end')};
- max-width: ${({ theme }) => theme.breakpoint.tablet};
- }
-`;
-
-const Circle = styled.div`
- z-index: 0;
- width: 70px;
- height: 70px;
- border-radius: 100%;
- background-color: ${({ theme }) => theme.palette.primary.o1};
- opacity: 0.15;
- filter: blur(10px);
- position: absolute;
- top: -125%;
- left: -75%;
-
- ${mq_lg} {
- width: 120px;
- height: 120px;
- top: -150%;
- }
-`;
-
-const TextContainer = styled.div`
- text-align: center;
-
- ${mq_lg} {
- flex: 0 0 auto;
- text-align: left;
- }
-`;
-
-const CategoryText = styled.span`
- z-index: 1;
- display: inline-block;
- position: relative;
- ${({ theme }) => theme.typo.b1};
- font-weight: bold;
- color: ${({ theme }) => theme.palette.primary.o1};
-
- ${mq_lg} {
- ${({ theme }) => theme.typo.h2};
- font-size: 20px;
- line-height: 24px;
- }
-`;
-
-const Title = styled.h3`
- position: relative;
- z-index: 1;
- ${({ theme }) => theme.typo.point.p4};
- color: ${({ theme }) => theme.palette.grey.g90};
- margin: 6px 0;
- white-space: pre-wrap;
-
- ${mq_lg} {
- font-size: 32px;
- margin: 12px 0 20px;
- line-height: 52px;
- }
-
- ${mq_md} {
- margin: 12px 0 6px;
- }
-`;
-
-const Description = styled.p`
- ${({ theme }) => theme.typo.b1};
- color: ${({ theme }) => theme.palette.grey.g60};
- white-space: pre-wrap;
-
- ${mq_lg} {
- font-size: 20px;
- line-height: 32px;
- }
-`;
-
-const Image = styled.img<{
- maxWidth: [number, number, number];
- padding: [number, number];
- position: 'left' | 'right';
-}>`
- width: calc(100% - 40px);
- max-width: ${({ maxWidth }) => maxWidth[0]}px;
- margin-top: 40px;
- padding: ${({ padding }) => padding[0]}px ${({ padding }) => padding[1]}px;
-
- ${mq_md} {
- margin-top: 40px !important;
- margin-${({ position }) => position}: auto;
- max-width: ${({ maxWidth }) => maxWidth[1]}px !important;
- }
-
- ${mq_lg} {
- min-width: 0;
- min-height: 0;
- overflow: hidden;
- flex: 1 1 auto;
- width: auto;
- max-width: ${({ maxWidth }) => maxWidth[2]}px;
- margin-top: 0;
- }
-`;
-
-export default {
- Container,
- Circle,
- CategoryText,
- TextContainer,
- Title,
- Description,
- Image,
-};
diff --git a/apps/admin/src/pages/Landing/components/FeatureItem/index.tsx b/apps/admin/src/pages/Landing/components/FeatureItem/index.tsx
deleted file mode 100644
index 157f02aa..00000000
--- a/apps/admin/src/pages/Landing/components/FeatureItem/index.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import Styled from './FeatureItem.styles';
-
-interface Props {
- category: string;
- title: string;
- description: string;
- position: 'left' | 'right';
- imageSrc: string;
- maxWidth: [number, number, number];
- imagePadding?: [number, number];
-}
-
-const FeatureItem = ({
- category,
- title,
- description,
- position,
- imageSrc,
- maxWidth,
- imagePadding = [0, 0],
-}: Props) => {
- return (
-
-
-
- {category}
-
-
- {title}
- {description}
-
-
-
- );
-};
-
-export default FeatureItem;
diff --git a/apps/admin/src/pages/Landing/components/Header/Header.styles.ts b/apps/admin/src/pages/Landing/components/Header/Header.styles.ts
index 57492b8b..4eec972e 100644
--- a/apps/admin/src/pages/Landing/components/Header/Header.styles.ts
+++ b/apps/admin/src/pages/Landing/components/Header/Header.styles.ts
@@ -1,22 +1,21 @@
-import { Button as _Button, mq_lg } from '@boolti/ui';
+import { mq_lg } from '@boolti/ui';
import styled from '@emotion/styled';
import { m } from 'framer-motion';
import { Link } from 'react-router-dom';
+import { LANDING_COLORS } from '../../constants';
+
const Header = styled.header`
position: fixed;
- z-index: 2;
+ z-index: 10;
top: 0;
left: 0;
width: 100%;
- border-bottom: 1px solid;
- border-color: ${({ theme }) => `${theme.palette.grey.g50}${theme.palette.opacity[30]}`};
- background: ${({ theme }) => `${theme.palette.grey.g60}${theme.palette.opacity[40]}`};
- backdrop-filter: blur(40px);
+ border-bottom: 1px solid ${LANDING_COLORS.headerBorder};
+ background: ${LANDING_COLORS.headerGlass};
+ backdrop-filter: blur(80px);
+ -webkit-backdrop-filter: blur(80px);
padding: 0 20px;
- ${mq_lg} {
- padding: 0 20px;
- }
`;
const HeaderContaienr = styled(m.div)`
@@ -26,10 +25,10 @@ const HeaderContaienr = styled(m.div)`
align-items: center;
justify-content: space-between;
max-width: ${({ theme }) => theme.breakpoint.desktop};
- height: 48px;
+ height: 56px;
+
${mq_lg} {
- padding: 0 20px;
- height: 68px;
+ height: 72px;
}
`;
@@ -37,7 +36,8 @@ const BooltiIcon = styled.button`
width: 55.5px;
height: 21px;
cursor: pointer;
- z-index: 1;
+ display: flex;
+ align-items: center;
${mq_lg} {
width: 74px;
@@ -49,95 +49,79 @@ const BooltiIcon = styled.button`
}
`;
-const MobileButton = styled.button`
- width: 40px;
- height: 40px;
+const Nav = styled.div`
display: flex;
align-items: center;
- justify-content: flex-end;
- cursor: pointer;
-
- & > svg {
- color: white;
- width: 24px;
- height: 24px;
- }
+ gap: 12px;
${mq_lg} {
- display: none;
+ gap: 24px;
}
`;
-const MobileMenu = styled(m.div)`
- display: flex;
- flex-direction: column;
- overflow: hidden;
- margin-top: auto;
- width: 100%;
+const TextButton = styled.button`
+ display: none;
+ font-family: Pretendard, sans-serif;
+ font-weight: 600;
+ font-size: 16px;
+ line-height: 1.3;
+ color: #ffffff;
+ padding: 8px 12px;
+ cursor: pointer;
${mq_lg} {
- display: none;
+ display: inline-flex;
}
`;
-const DesktopMenu = styled.div`
- display: none;
+const PrimaryButton = styled(Link)`
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 8px 14px;
+ border-radius: 12px;
+ background-color: ${LANDING_COLORS.primaryCta};
+ color: #ffffff;
+ font-family: Pretendard, sans-serif;
+ font-weight: 500;
+ font-size: 14px;
+ line-height: 1.3;
+ text-decoration: none;
+ cursor: pointer;
+
${mq_lg} {
- flex: 1;
- padding-left: 48px;
- display: flex;
+ padding: 10px 18px;
+ font-size: 16px;
}
`;
-const InternalLink = styled(Link)`
- display: flex;
- align-items: center;
- ${({ theme }) => theme.typo.b1};
- color: ${({ theme }) => theme.palette.grey.w};
+const AuthTextButton = styled.button`
+ font-family: Pretendard, sans-serif;
+ font-weight: 600;
+ font-size: 14px;
+ line-height: 1.3;
+ color: #ffffff;
+ padding: 8px 12px;
cursor: pointer;
- padding: 12px 0;
${mq_lg} {
- ${({ theme }) => theme.typo.sh1};
- padding: 0 18px;
+ font-size: 16px;
}
`;
const DropDownContainer = styled.div`
- margin-left: auto;
-
.icon-wrapper > svg {
- color: ${({ theme }) => theme.palette.grey.w};
+ color: #ffffff;
}
`;
-const AuthButton = styled.button`
- ${({ theme }) => theme.typo.sh1};
- cursor: pointer;
-
- padding: 0 18px;
- color: ${({ theme }) => theme.palette.grey.w};
- &:last-child {
- margin-left: auto;
- }
-`;
-
-const MobileAuthButton = styled(_Button)`
- display: flex;
- cursor: pointer;
- width: 100%;
- margin: 12px 0 20px;
-`;
-
export default {
Header,
- DesktopMenu,
HeaderContaienr,
BooltiIcon,
- MobileButton,
- MobileMenu,
- InternalLink,
- MobileAuthButton,
+ Nav,
+ TextButton,
+ PrimaryButton,
+ AuthTextButton,
DropDownContainer,
- AuthButton,
};
diff --git a/apps/admin/src/pages/Landing/components/Header/index.tsx b/apps/admin/src/pages/Landing/components/Header/index.tsx
index 0ca540a3..69dea86b 100644
--- a/apps/admin/src/pages/Landing/components/Header/index.tsx
+++ b/apps/admin/src/pages/Landing/components/Header/index.tsx
@@ -1,143 +1,68 @@
import { queryKeys, useLogout, useQueryClient, useUserProfile } from '@boolti/api';
-import { BooltiDark, CloseIcon, MenuIcon } from '@boolti/icon';
+import { BooltiDark } from '@boolti/icon';
import { useTheme } from '@emotion/react';
-import { useAtomValue } from 'jotai';
-import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import ProfileDropdown from '~/components/ProfileDropdown';
import { PATH } from '~/constants/routes';
import { useDeviceWidth } from '~/hooks/useDeviceWidth';
-import { useScrollDirection } from '~/hooks/useScrollDirection';
-
import { useAuthAtom } from '~/atoms/useAuthAtom';
import { openStoreLink } from '~/utils/link';
-import { Tab } from '..';
-import { visibleSectionAtom } from '../../atoms/visibleSectionAtom';
+
import Styled from './Header.styles';
const Header = () => {
const { isLogin, removeToken } = useAuthAtom();
- const currentVisibleSection = useAtomValue(visibleSectionAtom);
- const scrollDirection = useScrollDirection();
- const visible = currentVisibleSection === 'key-visal' || scrollDirection === 'up';
-
- const deviceWidth = useDeviceWidth();
const theme = useTheme();
+ const deviceWidth = useDeviceWidth();
const isMobile = deviceWidth < parseInt(theme.breakpoint.mobile, 10);
- const logoutMutation = useLogout();
const navigate = useNavigate();
const queryClient = useQueryClient();
-
- const [isExpanded, setIsExpanded] = useState(false);
+ const logoutMutation = useLogout();
const { data } = useUserProfile({ enabled: isLogin() });
const { imgPath } = data ?? {};
- const onClickAuthButton = async () => {
+ const handleAppExplore = () => {
+ if (isMobile) {
+ openStoreLink();
+ return;
+ }
+ navigate(PATH.QR);
+ };
+
+ const handleAuth = async () => {
if (isLogin()) {
await logoutMutation.mutateAsync();
-
removeToken();
queryClient.removeQueries({ ...queryKeys.user.summary });
-
return;
}
-
navigate(PATH.LOGIN);
};
return (
-
+
scrollTo({ top: 0, behavior: 'smooth' })}>
-
-
- {
- if (isMobile) {
- openStoreLink();
- return;
- }
- navigate(PATH.QR);
- }}
- >
- 앱 바로가기
-
- 공연 준비하기
+
+
+ 앱 둘러보기
+
{isLogin() ? (
) : (
- 로그인
+
+ 로그인
+
)}
-
-
- {/** 모바일용 */}
- {
- setIsExpanded((prev) => !prev);
- }}
- >
- {isExpanded ? : }
-
+ 시작하기
+
-
- {
- if (isMobile) {
- openStoreLink();
- return;
- }
- navigate(PATH.QR);
- }}
- >
- 앱 바로가기
-
- 공연 준비하기
-
- {isLogin() ? '로그아웃' : '로그인'}
-
-
-
- {!isMobile && }
);
};
diff --git a/apps/admin/src/pages/Landing/components/Hero/Hero.styles.ts b/apps/admin/src/pages/Landing/components/Hero/Hero.styles.ts
new file mode 100644
index 00000000..a827f0e3
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/Hero/Hero.styles.ts
@@ -0,0 +1,152 @@
+import { mq_lg } from '@boolti/ui';
+import styled from '@emotion/styled';
+
+import { LANDING_COLORS, mq_desktop } from '../../constants';
+
+const Section = styled.section`
+ display: flex;
+ flex-direction: column;
+ align-self: stretch;
+ padding: 104px 20px 32px;
+ background: ${LANDING_COLORS.heroGradient};
+
+ ${mq_lg} {
+ padding: 140px 24px 24px;
+ }
+
+ ${mq_desktop} {
+ padding: 140px 32px 48px;
+ }
+`;
+
+const Container = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ gap: 32px;
+ width: 100%;
+ max-width: 1200px;
+ margin: 0 auto;
+
+ ${mq_desktop} {
+ gap: 43px;
+ }
+`;
+
+const TextBlock = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
+ text-align: center;
+`;
+
+const Eyebrow = styled.span`
+ font-family: Pretendard, sans-serif;
+ font-weight: 400;
+ font-size: 18px;
+ line-height: 1.3;
+ letter-spacing: -0.04em;
+ color: #a2a5b4;
+
+ ${mq_lg} {
+ font-size: 22px;
+ }
+
+ ${mq_desktop} {
+ font-size: 26px;
+ }
+`;
+
+const Title = styled.h1`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
+ font-family: Pretendard, sans-serif;
+ font-weight: 600;
+ font-size: 28px;
+ line-height: 1.45;
+ letter-spacing: -0.02em;
+ color: #ffffff;
+ margin: 0;
+
+ ${mq_lg} {
+ font-size: 34px;
+ }
+
+ ${mq_desktop} {
+ font-size: 42px;
+ }
+`;
+
+const TitleRow = styled.span`
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+`;
+
+const LogoMark = styled.span`
+ display: inline-flex;
+ align-items: center;
+ height: 1em;
+
+ svg,
+ img {
+ height: 1em;
+ width: auto;
+ }
+`;
+
+const ImageRow = styled.div`
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 12px;
+ padding: 16px 4px;
+ overflow-x: auto;
+ scrollbar-width: none;
+
+ &::-webkit-scrollbar {
+ display: none;
+ }
+
+ ${mq_desktop} {
+ gap: 16px;
+ padding: 24px 8px;
+ justify-content: center;
+ }
+`;
+
+const ImageCard = styled.img`
+ flex-shrink: 0;
+ width: 200px;
+ height: 268px;
+ border-radius: 16px;
+ object-fit: cover;
+ background-color: #2a2a3d;
+ user-select: none;
+
+ ${mq_lg} {
+ width: 240px;
+ height: 322px;
+ }
+
+ ${mq_desktop} {
+ width: 280px;
+ height: 376px;
+ }
+`;
+
+export default {
+ Section,
+ Container,
+ TextBlock,
+ Eyebrow,
+ Title,
+ TitleRow,
+ LogoMark,
+ ImageRow,
+ ImageCard,
+};
diff --git a/apps/admin/src/pages/Landing/components/Hero/index.tsx b/apps/admin/src/pages/Landing/components/Hero/index.tsx
new file mode 100644
index 00000000..0a2cd782
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/Hero/index.tsx
@@ -0,0 +1,42 @@
+import heroLogo from '~/assets/landing-v2/hero-logo.svg';
+import hero1 from '~/assets/landing-v2/hero-1.png';
+import hero2 from '~/assets/landing-v2/hero-2.png';
+import hero3 from '~/assets/landing-v2/hero-3.png';
+import hero4 from '~/assets/landing-v2/hero-4.png';
+import hero5 from '~/assets/landing-v2/hero-5.png';
+
+import { LANDING_COPY } from '../../constants';
+import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom';
+import Styled from './Hero.styles';
+
+const HERO_IMAGES = [hero1, hero2, hero3, hero4, hero5];
+
+const Hero = () => {
+ const { ref } = useVisibleSectionAtom('hero');
+
+ return (
+
+
+
+ {LANDING_COPY.hero.eyebrow}
+
+ {LANDING_COPY.hero.titleLead}
+
+ {LANDING_COPY.hero.titleTrail}
+
+
+
+
+
+
+
+ {HERO_IMAGES.map((src, index) => (
+
+ ))}
+
+
+
+ );
+};
+
+export default Hero;
diff --git a/apps/admin/src/pages/Landing/components/HowToUse/HowToUse.styles.ts b/apps/admin/src/pages/Landing/components/HowToUse/HowToUse.styles.ts
new file mode 100644
index 00000000..512d8c1f
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/HowToUse/HowToUse.styles.ts
@@ -0,0 +1,138 @@
+import { mq_lg } from '@boolti/ui';
+import styled from '@emotion/styled';
+import { Link } from 'react-router-dom';
+
+import { LANDING_COLORS, mq_desktop } from '../../constants';
+
+const Section = styled.section`
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ align-self: stretch;
+ gap: 40px;
+ padding: 80px 20px;
+ background-color: #000000;
+ overflow: hidden;
+
+ ${mq_lg} {
+ gap: 48px;
+ padding: 96px 32px;
+ }
+
+ ${mq_desktop} {
+ gap: 56px;
+ padding: 120px 32px;
+ }
+`;
+
+const Light = styled.img`
+ position: absolute;
+ top: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 100%;
+ max-width: 1200px;
+ height: auto;
+ pointer-events: none;
+ opacity: 0.6;
+ z-index: 1;
+`;
+
+const Title = styled.h2`
+ position: relative;
+ z-index: 2;
+ text-align: center;
+ font-family: Pretendard, sans-serif;
+ font-weight: 600;
+ font-size: 24px;
+ line-height: 1.45;
+ letter-spacing: -0.02em;
+ color: #ffffff;
+ white-space: pre-line;
+ margin: 0;
+
+ ${mq_lg} {
+ font-size: 32px;
+ }
+
+ ${mq_desktop} {
+ font-size: 40px;
+ }
+`;
+
+const BtnWrap = styled.div`
+ position: relative;
+ z-index: 2;
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ width: 100%;
+ max-width: 360px;
+
+ ${mq_lg} {
+ flex-direction: row;
+ width: auto;
+ max-width: none;
+ gap: 16px;
+ }
+`;
+
+const baseButton = `
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+ padding: 16px 24px;
+ border-radius: 12px;
+ font-family: Pretendard, sans-serif;
+ font-size: 16px;
+ line-height: 1.3;
+ letter-spacing: -0.02em;
+ cursor: pointer;
+ text-decoration: none;
+ border: 0;
+`;
+
+const PrimaryButton = styled(Link)`
+ ${baseButton}
+ background-color: ${LANDING_COLORS.primaryCta};
+ color: #ffffff;
+ font-weight: 500;
+ box-shadow: 0 8px 24px rgba(255, 104, 39, 0.3);
+
+ ${mq_lg} {
+ padding: 18px 28px;
+ font-size: 18px;
+ }
+
+ ${mq_desktop} {
+ padding: 20px 32px;
+ font-size: 24px;
+ }
+`;
+
+const SecondaryButton = styled.button`
+ ${baseButton}
+ background-color: ${LANDING_COLORS.darkButton};
+ color: ${LANDING_COLORS.darkButtonText};
+ font-weight: 400;
+
+ ${mq_lg} {
+ padding: 18px 28px;
+ font-size: 18px;
+ }
+
+ ${mq_desktop} {
+ padding: 20px 32px;
+ font-size: 24px;
+ }
+`;
+
+export default {
+ Section,
+ Light,
+ Title,
+ BtnWrap,
+ PrimaryButton,
+ SecondaryButton,
+};
diff --git a/apps/admin/src/pages/Landing/components/HowToUse/index.tsx b/apps/admin/src/pages/Landing/components/HowToUse/index.tsx
new file mode 100644
index 00000000..8b0bacdc
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/HowToUse/index.tsx
@@ -0,0 +1,44 @@
+import { useTheme } from '@emotion/react';
+import { useNavigate } from 'react-router-dom';
+
+import lightSvg from '~/assets/landing-v2/light.svg';
+import { PATH } from '~/constants/routes';
+import { useDeviceWidth } from '~/hooks/useDeviceWidth';
+import { openStoreLink } from '~/utils/link';
+
+import { LANDING_COPY } from '../../constants';
+import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom';
+import Styled from './HowToUse.styles';
+
+const HowToUse = () => {
+ const { ref } = useVisibleSectionAtom('how-to-use');
+ const theme = useTheme();
+ const deviceWidth = useDeviceWidth();
+ const navigate = useNavigate();
+ const isMobile = deviceWidth < parseInt(theme.breakpoint.mobile, 10);
+
+ const handleSecondary = () => {
+ if (isMobile) {
+ openStoreLink();
+ return;
+ }
+ navigate(PATH.QR);
+ };
+
+ return (
+
+
+ {LANDING_COPY.howToUse.title}
+
+
+ {LANDING_COPY.howToUse.secondaryCta}
+
+
+ {LANDING_COPY.howToUse.primaryCta}
+
+
+
+ );
+};
+
+export default HowToUse;
diff --git a/apps/admin/src/pages/Landing/components/KeyVisual/KeyVisual.styles.tsx b/apps/admin/src/pages/Landing/components/KeyVisual/KeyVisual.styles.tsx
deleted file mode 100644
index fd176679..00000000
--- a/apps/admin/src/pages/Landing/components/KeyVisual/KeyVisual.styles.tsx
+++ /dev/null
@@ -1,195 +0,0 @@
-import { mq_lg } from '@boolti/ui';
-import styled from '@emotion/styled';
-import { m } from 'framer-motion';
-
-import keyVisualImg from '~/assets/images/key-visual.png';
-
-const Container = styled.section`
- position: relative;
- text-align: center;
- width: 100%;
- margin-top: -49px;
- padding-top: 49px;
- height: 740px;
- background: #070708 url('${keyVisualImg}');
- background-position: bottom center;
- background-repeat: no-repeat;
- background-size: cover;
- ${mq_lg} {
- margin-top: -69px;
- padding-top: 69px;
- height: 1200px;
- }
- &::before,
- &::after {
- z-index: 0;
- content: '';
- position: absolute;
- top: 0;
- width: 20%;
- height: 100%;
- background: linear-gradient(
- 90deg,
- #020205 45.03%,
- rgba(2, 2, 5, 0.81) 81.17%,
- rgba(2, 2, 5, 0) 100%
- );
- filter: blur(27.700000762939453px);
- }
- &::before {
- left: 0;
- margin-left: -5%;
- }
- &::after {
- right: 0;
- margin-right: -5%;
- transform: rotate(180deg);
- }
-`;
-
-const Title = styled.h1`
- z-index: 1;
- display: flex;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- ${({ theme }) => theme.typo.h2};
- color: ${({ theme }) => theme.palette.grey.g00};
- margin-top: 100px;
-
- & svg {
- margin-top: 16px;
- width: 104px;
- height: 37px;
- display: inline-block;
- color: ${({ theme }) => theme.palette.grey.g00};
-
- path {
- fill: ${({ theme }) => theme.palette.grey.g00};
- }
- }
-
- ${mq_lg} {
- font-size: 48px;
- line-height: normal;
- margin-top: 246px;
-
- & svg {
- margin-top: 40px;
- width: 259px;
- height: 98px;
- }
- }
-`;
-
-const Description = styled(m.span)`
- z-index: 1;
- display: inline-block;
- position: relative;
- white-space: pre-wrap;
- word-break: keep-all;
- ${({ theme }) => theme.typo.b4};
- color: ${({ theme }) => theme.palette.grey.g00};
- margin-top: 170px;
- padding: 0 60px;
-
- & > b {
- font-weight: bold;
- }
-
- &::before,
- &::after {
- content: '';
- position: absolute;
- top: 50%;
- left: 50%;
- width: calc(100% - 60px);
- max-width: 456px;
- height: 48px;
- border-radius: 100%;
- border: 0.2px solid rgba(255, 255, 255, 0.4);
- }
- &::before {
- transform: translate3d(-50%, -50%, 0) rotate(1.6deg);
- }
- &::after {
- transform: translate3d(-50%, -50%, 0) rotate(6.4deg);
- }
-
- ${mq_lg} {
- width: calc(100% - 80px);
- max-width: 1010px;
- margin-top: 400px;
- ${({ theme }) => theme.typo.b4};
- font-size: 28px;
- line-height: 48px;
- letter-spacing: -0.64px;
-
- &::before,
- &::after {
- height: 128px;
- max-width: 1010px;
- border-width: 1px;
- }
- }
-`;
-
-const FloatingUnion = styled.div<{ position: 'left' | 'right' }>`
- position: absolute;
- ${({ position }) => {
- switch (position) {
- case 'left': {
- return `
- top: -30px;
- left: 10px;
- width: 40px;
- height: 40px;
- transform: roate(24deg);
-
- ${mq_lg} {
- top: -30%;
- left: -36px;
- width: 96px;
- height: 96px;
- }
- `;
- }
- case 'right': {
- return `
- top: 20%;
- right: 10px;
- width: 42px;
- height: 42px;
- transform: rotate(-50deg);
-
- ${mq_lg} {
- top: 30%;
- right: -46px;
- width: 114px;
- height: 114px;
- }
- `;
- }
- }
- }}
-`;
-
-export const MobileBreak = styled.br`
- ${mq_lg} {
- display: none;
- }
-`;
-
-export const Hidden = styled.div`
- height: 0;
- opacity: 0;
-`;
-
-export default {
- Container,
- Title,
- Description,
- MobileBreak,
- Hidden,
- FloatingUnion,
-};
diff --git a/apps/admin/src/pages/Landing/components/KeyVisual/index.tsx b/apps/admin/src/pages/Landing/components/KeyVisual/index.tsx
deleted file mode 100644
index 558a94f4..00000000
--- a/apps/admin/src/pages/Landing/components/KeyVisual/index.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-import { BooltiDark } from '@boolti/icon';
-import { useAnimation, useInView } from 'framer-motion';
-import { useEffect, useRef } from 'react';
-
-import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom';
-import Styled from './KeyVisual.styles';
-
-const Union = () => {
- return (
-
- );
-};
-
-const KeyVisual = () => {
- const { ref: sectionRef } = useVisibleSectionAtom('key-visal');
- const hiddenElementRef = useRef(null);
- const isInView = useInView(hiddenElementRef, { amount: 'all' });
- const animation = useAnimation();
-
- useEffect(() => {
- if (isInView) {
- animation.start('visible');
- }
- }, [isInView, animation]);
-
- return (
-
-
- 핫한 공연 예매의 시작
-
-
-
- <>음악을 사랑하는 모두가, 공연을 즐기고 싶은 모두가{'\n'}>
- <>더 쉽게 공연을 주최하고 관람할 수 있도록!{'\n'}>
- <>
-
- 지금 불티에서 당신의 공연을 시작해 보세요
- >
-
-
-
-
-
-
-
-
-
- );
-};
-
-export default KeyVisual;
diff --git a/apps/admin/src/pages/Landing/components/MoreInformation/MoreInformation.styles.ts b/apps/admin/src/pages/Landing/components/MoreInformation/MoreInformation.styles.ts
deleted file mode 100644
index 2c1492f9..00000000
--- a/apps/admin/src/pages/Landing/components/MoreInformation/MoreInformation.styles.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { mq_lg } from '@boolti/ui';
-import styled from '@emotion/styled';
-import { Link } from 'react-router-dom';
-
-import lightImg from '~/assets/images/more-information-light.png';
-
-export const Container = styled.section`
- position: relative;
- display: flex;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- width: 100%;
- padding: 80px 0;
- background-color: ${({ theme }) => theme.palette.grey.b};
- ${mq_lg} {
- height: 400px;
- }
-`;
-
-const BackgroundLight = styled.div`
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-image: url('${lightImg}');
- background-position: top center;
- background-repeat: no-repeat;
- background-size: cover;
-`;
-
-const Text = styled.p`
- z-index: 1;
-
- white-space: pre-wrap;
- text-align: center;
- ${({ theme }) => theme.typo.sh2};
- color: ${({ theme }) => theme.palette.grey.w};
-
- ${mq_lg} {
- font-size: 32px;
- font-weight: bold;
- line-height: 60px;
- }
-`;
-
-const Button = styled(Link)`
- z-index: 1;
- cursor: pointer;
- border-radius: 4px;
- margin-top: 16px;
- padding: 9px 16px;
- ${({ theme }) => theme.typo.sh1};
- color: ${({ theme }) => theme.palette.grey.w};
- background-color: ${({ theme }) => theme.palette.primary.o1};
- ${mq_lg} {
- padding: 13px 20px;
- margin-top: 28px;
- }
-`;
-
-export default {
- Container,
- BackgroundLight,
- Text,
- Button,
-};
diff --git a/apps/admin/src/pages/Landing/components/MoreInformation/index.tsx b/apps/admin/src/pages/Landing/components/MoreInformation/index.tsx
deleted file mode 100644
index 23244b62..00000000
--- a/apps/admin/src/pages/Landing/components/MoreInformation/index.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import Styled from './MoreInformation.styles';
-
-const MoerInformation = () => {
- const moreInfoPageLink = 'https://www.notion.so/boolti/Boolti-6de303e8cc0242ea8b3930ce33032aa2';
-
- return (
-
-
- 더욱 자세한 불티 이용 방법이{'\n'}궁금하시다면?
- 이용 방법 보러 가기
-
- );
-};
-
-export default MoerInformation;
diff --git a/apps/admin/src/pages/Landing/components/OrganizerSection/OrganizerSection.styles.ts b/apps/admin/src/pages/Landing/components/OrganizerSection/OrganizerSection.styles.ts
deleted file mode 100644
index 189fb534..00000000
--- a/apps/admin/src/pages/Landing/components/OrganizerSection/OrganizerSection.styles.ts
+++ /dev/null
@@ -1,128 +0,0 @@
-import { mq_lg } from '@boolti/ui';
-import styled from '@emotion/styled';
-import { Link } from 'react-router-dom';
-
-import lightImg from '~/assets/images/light.png';
-
-const Section = styled.section`
- width: 100%;
-`;
-
-const Container = styled.div`
- position: relative;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- background-color: #ff5b15;
- padding-top: 80px;
-
- &::after {
- position: absolute;
- bottom: 0;
- width: calc(100% - 80px);
- height: 40px;
- content: '';
- opacity: 0.25;
- background: linear-gradient(180deg, rgba(255, 92, 22, 0) 9.57%, #ff5d17 90.96%);
- }
-
- ${mq_lg} {
- padding-top: 128px;
-
- &::after {
- width: calc(100% - 160px);
- height: 160px;
- }
- }
-`;
-
-const BackgroundLight = styled.div`
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-image: url('${lightImg}');
- background-position: top center;
- background-repeat: no-repeat;
- background-size: cover;
-`;
-
-const Title = styled.h2`
- text-align: center;
- white-space: pre-wrap;
- color: ${({ theme }) => theme.palette.grey.w};
- ${({ theme }) => theme.typo.point.p4};
-
- ${mq_lg} {
- white-space: normal;
- font-size: 32px;
- line-height: 38px;
- }
-`;
-
-const Description = styled.p`
- text-align: center;
- color: #ffc7ae;
- ${({ theme }) => theme.typo.b1};
- white-space: pre-wrap;
- margin-top: 6px;
-
- ${mq_lg} {
- white-space: normal;
- margin-top: 8px;
- font-size: 20px;
- line-height: 32px;
- }
-`;
-
-const Button = styled(Link)`
- z-index: 1;
- cursor: pointer;
- padding: 9px 16px;
- border-radius: 4px;
- margin-top: 12px;
- background-color: #ffe9e0;
- color: ${({ theme }) => theme.palette.primary.o1};
- ${({ theme }) => theme.typo.sh1};
-
- ${mq_lg} {
- padding: 13px 20px;
- margin-top: 24px;
- }
-`;
-
-const PcAdminPreviewImage = styled.img`
- display: none;
- ${mq_lg} {
- display: block;
- width: calc(100% - 160px);
- max-width: 1080px;
- height: auto;
- border-radius: 32px 32px 0px 0px;
- margin-top: 80px;
- }
-`;
-
-const MobileAdminPrevieImage = styled.img`
- margin-top: 32px;
- max-width: 320px;
- height: auto;
- width: calc(100% - 168px);
- border-radius: 12px 12px 0px 0px;
- ${mq_lg} {
- display: none;
- }
-`;
-
-export default {
- Section,
- BackgroundLight,
- Container,
- Title,
- Description,
- Button,
- PcAdminPreviewImage,
- MobileAdminPrevieImage,
-};
diff --git a/apps/admin/src/pages/Landing/components/OrganizerSection/index.tsx b/apps/admin/src/pages/Landing/components/OrganizerSection/index.tsx
deleted file mode 100644
index e3cb7665..00000000
--- a/apps/admin/src/pages/Landing/components/OrganizerSection/index.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import createShowImg from '~/assets/images/create-show.png';
-import manageEnteranceImg from '~/assets/images/manage-entrance.png';
-import mobileAdminPreviewImg from '~/assets/images/mobile-admin-preview.png';
-import pcAdminPreviewImg from '~/assets/images/pc-admin-preview.png';
-import { PATH } from '~/constants/routes';
-
-import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom';
-import FeatureItem from '../FeatureItem';
-import Styled from './OrganizerSection.styles';
-
-const OrganizerSection = () => {
- const { ref: sectionRef } = useVisibleSectionAtom('organizer');
- return (
-
-
-
- 누구보다 바쁜{'\n'}주최자를 위한 웹
-
- 공연을 등록하고 방문자 명단과{'\n'}
- 정산된 수익을 한눈에 확인해 보세요
-
- 공연 준비하기
-
-
-
-
-
-
- );
-};
-
-export default OrganizerSection;
diff --git a/apps/admin/src/pages/Landing/components/Problem/Problem.styles.ts b/apps/admin/src/pages/Landing/components/Problem/Problem.styles.ts
new file mode 100644
index 00000000..f8608ce5
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/Problem/Problem.styles.ts
@@ -0,0 +1,85 @@
+import { mq_lg } from '@boolti/ui';
+import styled from '@emotion/styled';
+
+import { mq_desktop } from '../../constants';
+
+const Section = styled.section`
+ position: relative;
+ width: 100%;
+ min-height: 360px;
+ background-color: #020206;
+ overflow: hidden;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ ${mq_lg} {
+ min-height: 480px;
+ }
+
+ ${mq_desktop} {
+ height: 631px;
+ }
+`;
+
+const Title = styled.h2`
+ position: relative;
+ z-index: 2;
+ text-align: center;
+ font-family: Pretendard, sans-serif;
+ font-weight: 600;
+ font-size: 24px;
+ line-height: 1.45;
+ letter-spacing: -0.02em;
+ color: #ffffff;
+ white-space: pre-line;
+ padding: 0 24px;
+ margin: 0;
+
+ ${mq_lg} {
+ font-size: 32px;
+ }
+
+ ${mq_desktop} {
+ font-size: 40px;
+ padding: 0;
+ }
+`;
+
+const FloatingLayer = styled.div`
+ position: absolute;
+ top: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 1200px;
+ height: 100%;
+ display: none;
+ pointer-events: none;
+
+ ${mq_desktop} {
+ display: block;
+ }
+`;
+
+const FloatingLogo = styled.img<{
+ top: number;
+ left: number;
+ width: number;
+ height: number;
+}>`
+ position: absolute;
+ top: ${({ top }) => top}px;
+ left: ${({ left }) => left}px;
+ width: ${({ width }) => width}px;
+ height: ${({ height }) => height}px;
+ object-fit: contain;
+ opacity: 0.55;
+ user-select: none;
+`;
+
+export default {
+ Section,
+ Title,
+ FloatingLayer,
+ FloatingLogo,
+};
diff --git a/apps/admin/src/pages/Landing/components/Problem/index.tsx b/apps/admin/src/pages/Landing/components/Problem/index.tsx
new file mode 100644
index 00000000..00a20169
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/Problem/index.tsx
@@ -0,0 +1,37 @@
+import problem1 from '~/assets/landing-v2/problem-1.png';
+import problem2 from '~/assets/landing-v2/problem-2.png';
+import problem3 from '~/assets/landing-v2/problem-3.png';
+import problem4 from '~/assets/landing-v2/problem-4.png';
+import problem5 from '~/assets/landing-v2/problem-5.png';
+import problem6 from '~/assets/landing-v2/problem-6.png';
+
+import { LANDING_COPY } from '../../constants';
+import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom';
+import Styled from './Problem.styles';
+
+// Figma Desktop 1200px 절대 좌표
+const FLOATING_LOGOS = [
+ { src: problem1, top: 164, left: 178, width: 291.64, height: 70.84 },
+ { src: problem2, top: 440, left: 681, width: 291.64, height: 70.84 },
+ { src: problem3, top: 370, left: 73.39, width: 287.24, height: 88.1 },
+ { src: problem4, top: 55, left: 96, width: 260.97, height: 78.2 },
+ { src: problem5, top: 126, left: 779.03, width: 317.95, height: 92.37 },
+ { src: problem6, top: 325, left: 877.83, width: 240.59, height: 96.6 },
+] as const;
+
+const Problem = () => {
+ const { ref } = useVisibleSectionAtom('problem');
+
+ return (
+
+
+ {FLOATING_LOGOS.map(({ src, ...pos }, index) => (
+
+ ))}
+
+ {LANDING_COPY.problem.title}
+
+ );
+};
+
+export default Problem;
diff --git a/apps/admin/src/pages/Landing/components/SolutionFeatures/SolutionFeatures.styles.ts b/apps/admin/src/pages/Landing/components/SolutionFeatures/SolutionFeatures.styles.ts
new file mode 100644
index 00000000..2b601da1
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/SolutionFeatures/SolutionFeatures.styles.ts
@@ -0,0 +1,97 @@
+import { mq_lg } from '@boolti/ui';
+import styled from '@emotion/styled';
+
+import { mq_desktop } from '../../constants';
+
+const Section = styled.section`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ align-self: stretch;
+ gap: 48px;
+ padding: 80px 20px;
+ background-color: #ffffff;
+
+ ${mq_lg} {
+ gap: 56px;
+ padding: 96px 32px;
+ }
+
+ ${mq_desktop} {
+ gap: 64px;
+ padding: 100px 80px;
+ }
+`;
+
+const Heading = styled.header`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 10px;
+ text-align: center;
+`;
+
+const Eyebrow = styled.span`
+ font-family: Pretendard, sans-serif;
+ font-weight: 400;
+ font-size: 18px;
+ line-height: 1.3;
+ letter-spacing: -0.04em;
+ color: #a2a5b4;
+
+ ${mq_lg} {
+ font-size: 22px;
+ }
+
+ ${mq_desktop} {
+ font-size: 26px;
+ }
+`;
+
+const TitleRow = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+ font-family: Pretendard, sans-serif;
+ font-weight: 600;
+ font-size: 24px;
+ line-height: 1.35;
+ letter-spacing: -0.02em;
+ color: #000000;
+
+ ${mq_lg} {
+ flex-direction: row;
+ gap: 12px;
+ font-size: 34px;
+ }
+
+ ${mq_desktop} {
+ font-size: 40px;
+ }
+`;
+
+const CardList = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 56px;
+ width: 100%;
+ max-width: 1200px;
+ margin: 0 auto;
+
+ ${mq_lg} {
+ gap: 88px;
+ }
+
+ ${mq_desktop} {
+ gap: 112px;
+ }
+`;
+
+export default {
+ Section,
+ Heading,
+ Eyebrow,
+ TitleRow,
+ CardList,
+};
diff --git a/apps/admin/src/pages/Landing/components/SolutionFeatures/index.tsx b/apps/admin/src/pages/Landing/components/SolutionFeatures/index.tsx
new file mode 100644
index 00000000..5f557995
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/SolutionFeatures/index.tsx
@@ -0,0 +1,50 @@
+import entryAsis from '~/assets/landing-v2/entry-asis.png';
+import entryTobe from '~/assets/landing-v2/entry-tobe.png';
+import notifyAsis from '~/assets/landing-v2/notify-asis.png';
+import notifyTobe from '~/assets/landing-v2/notify-tobe.png';
+import salesAsis from '~/assets/landing-v2/sales-asis.png';
+import salesTobe from '~/assets/landing-v2/sales-tobe.png';
+import statsAsis from '~/assets/landing-v2/stats-asis.png';
+import statsTobe from '~/assets/landing-v2/stats-tobe.png';
+
+import { LANDING_COPY } from '../../constants';
+import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom';
+import FeatureCard from '../FeatureCard';
+import Styled from './SolutionFeatures.styles';
+
+const FEATURE_MEDIA = [
+ { asis: salesAsis, tobe: salesTobe },
+ { asis: notifyAsis, tobe: notifyTobe },
+ { asis: entryAsis, tobe: entryTobe },
+ { asis: statsAsis, tobe: statsTobe },
+];
+
+const SolutionFeatures = () => {
+ const { ref } = useVisibleSectionAtom('solution-features');
+
+ return (
+
+
+ {LANDING_COPY.solutionFeatures.eyebrow}
+
+ {LANDING_COPY.solutionFeatures.titleLead}
+ {LANDING_COPY.solutionFeatures.titleTrail}
+
+
+
+ {LANDING_COPY.solutionFeatures.items.map((item, index) => (
+
+ ))}
+
+
+ );
+};
+
+export default SolutionFeatures;
diff --git a/apps/admin/src/pages/Landing/components/SolutionHighlight/SolutionHighlight.styles.ts b/apps/admin/src/pages/Landing/components/SolutionHighlight/SolutionHighlight.styles.ts
new file mode 100644
index 00000000..c05d2769
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/SolutionHighlight/SolutionHighlight.styles.ts
@@ -0,0 +1,272 @@
+import { mq_lg } from '@boolti/ui';
+import styled from '@emotion/styled';
+
+import { LANDING_COLORS, mq_desktop } from '../../constants';
+
+const Section = styled.section`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ align-self: stretch;
+ gap: 40px;
+ padding: 80px 0;
+ background-color: ${LANDING_COLORS.solutionLightBg};
+
+ ${mq_lg} {
+ gap: 56px;
+ padding: 96px 0;
+ }
+
+ ${mq_desktop} {
+ gap: 64px;
+ padding: 100px 0;
+ }
+`;
+
+const Title = styled.h2`
+ text-align: center;
+ font-family: Pretendard, sans-serif;
+ font-weight: 600;
+ font-size: 24px;
+ line-height: 1.35;
+ letter-spacing: -0.02em;
+ color: #000000;
+ white-space: pre-line;
+ padding: 0 20px;
+ margin: 0;
+
+ ${mq_lg} {
+ font-size: 34px;
+ }
+
+ ${mq_desktop} {
+ font-size: 40px;
+ padding: 0;
+ }
+`;
+
+const ScrollArea = styled.div`
+ display: flex;
+ flex-direction: row;
+ gap: 16px;
+ overflow-x: auto;
+ width: 100%;
+ padding: 0 20px;
+ scrollbar-width: none;
+
+ &::-webkit-scrollbar {
+ display: none;
+ }
+
+ ${mq_lg} {
+ gap: 16px;
+ padding: 0 32px;
+ justify-content: center;
+ }
+
+ ${mq_desktop} {
+ padding: 0 80px;
+ }
+`;
+
+const Card = styled.div<{ variant: 'light' | 'dark' }>`
+ flex-shrink: 0;
+ width: 320px;
+ display: flex;
+ flex-direction: column;
+ border-radius: 16px;
+ overflow: hidden;
+ border: ${({ variant }) =>
+ variant === 'dark' ? 'none' : `1px solid ${LANDING_COLORS.cardBorder}`};
+ background-color: ${({ variant }) =>
+ variant === 'dark' ? LANDING_COLORS.darkCardBg : '#FFFFFF'};
+
+ ${mq_lg} {
+ flex-direction: row;
+ width: 560px;
+ height: 420px;
+ }
+
+ ${mq_desktop} {
+ width: 620px;
+ height: 480px;
+ }
+`;
+
+const TextCard = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 16px;
+ padding: 32px;
+ background-color: #ffffff;
+
+ ${mq_lg} {
+ flex: 0 0 55%;
+ gap: 24px;
+ padding: 48px 40px;
+ }
+
+ ${mq_desktop} {
+ gap: 28px;
+ padding: 60px 52px;
+ }
+`;
+
+const Chip = styled.span`
+ display: inline-flex;
+ padding: 8px 16px;
+ border-radius: 200px;
+ background-color: ${LANDING_COLORS.chipBg};
+ color: ${LANDING_COLORS.chipText};
+ font-family: Pretendard, sans-serif;
+ font-weight: 600;
+ font-size: 16px;
+ line-height: 1.3;
+
+ ${mq_lg} {
+ font-size: 18px;
+ }
+
+ ${mq_desktop} {
+ font-size: 24px;
+ padding: 10px 16px;
+ }
+`;
+
+const CardTitle = styled.h3`
+ font-family: Pretendard, sans-serif;
+ font-weight: 600;
+ font-size: 24px;
+ line-height: 1.35;
+ letter-spacing: -0.02em;
+ white-space: pre-line;
+ color: #000000;
+ margin: 0;
+
+ ${mq_lg} {
+ font-size: 28px;
+ }
+
+ ${mq_desktop} {
+ font-size: 32px;
+ }
+`;
+
+const CardDescription = styled.p`
+ font-family: Pretendard, sans-serif;
+ font-weight: 400;
+ font-size: 16px;
+ line-height: 1.5;
+ color: #a2a5b4;
+ margin: 0;
+
+ ${mq_lg} {
+ font-size: 20px;
+ }
+
+ ${mq_desktop} {
+ font-size: 24px;
+ }
+`;
+
+const ImgCard = styled.div<{ variant: 'light' | 'dark' }>`
+ position: relative;
+ flex: 1;
+ min-height: 260px;
+ overflow: hidden;
+ background: ${({ variant }) =>
+ variant === 'dark' ? LANDING_COLORS.paymentGradient : LANDING_COLORS.promoGradient};
+
+ ${mq_lg} {
+ min-height: 0;
+ }
+`;
+
+const PromoStack = styled.div`
+ position: relative;
+ width: 100%;
+ height: 100%;
+ min-height: 260px;
+`;
+
+const PromoImage = styled.img<{ offset: 'back' | 'front' }>`
+ position: absolute;
+ width: 55%;
+ max-width: 180px;
+ height: auto;
+ border-radius: 20px;
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.15);
+
+ ${({ offset }) =>
+ offset === 'back'
+ ? `
+ bottom: -20%;
+ left: 8%;
+ transform: rotate(-10deg);
+ z-index: 1;
+ `
+ : `
+ bottom: -32%;
+ right: 0%;
+ transform: rotate(6deg);
+ z-index: 2;
+ `}
+
+ ${mq_lg} {
+ max-width: 200px;
+
+ ${({ offset }) =>
+ offset === 'back'
+ ? `
+ bottom: -15%;
+ left: 8%;
+ `
+ : `
+ bottom: -28%;
+ right: -5%;
+ `}
+ }
+`;
+
+const PaymentWrap = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: flex-end;
+ width: 100%;
+ height: 100%;
+ min-height: 260px;
+ padding-top: 24px;
+
+ ${mq_lg} {
+ padding-top: 40px;
+ }
+`;
+
+const PaymentImage = styled.img`
+ width: 70%;
+ max-width: 260px;
+ height: auto;
+ border-radius: 28px;
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.2);
+
+ ${mq_desktop} {
+ max-width: 320px;
+ }
+`;
+
+export default {
+ Section,
+ Title,
+ ScrollArea,
+ Card,
+ TextCard,
+ Chip,
+ CardTitle,
+ CardDescription,
+ ImgCard,
+ PromoStack,
+ PromoImage,
+ PaymentWrap,
+ PaymentImage,
+};
diff --git a/apps/admin/src/pages/Landing/components/SolutionHighlight/index.tsx b/apps/admin/src/pages/Landing/components/SolutionHighlight/index.tsx
new file mode 100644
index 00000000..53932a54
--- /dev/null
+++ b/apps/admin/src/pages/Landing/components/SolutionHighlight/index.tsx
@@ -0,0 +1,41 @@
+import payment from '~/assets/landing-v2/payment.png';
+import promo1 from '~/assets/landing-v2/promo-1.png';
+import promo2 from '~/assets/landing-v2/promo-2.png';
+
+import { LANDING_COPY } from '../../constants';
+import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom';
+import Styled from './SolutionHighlight.styles';
+
+const HIGHLIGHT_MEDIA = [
+
+
+
+ ,
+
+
+ ,
+];
+
+const SolutionHighlight = () => {
+ const { ref } = useVisibleSectionAtom('solution-highlight');
+
+ return (
+
+ {LANDING_COPY.solutionHighlight.title}
+
+ {LANDING_COPY.solutionHighlight.items.map((item, index) => (
+
+
+ {item.chip}
+ {item.title}
+ {item.description}
+
+ {HIGHLIGHT_MEDIA[index]}
+
+ ))}
+
+
+ );
+};
+
+export default SolutionHighlight;
diff --git a/apps/admin/src/pages/Landing/components/Tab/Tab.styles.ts b/apps/admin/src/pages/Landing/components/Tab/Tab.styles.ts
deleted file mode 100644
index 31c58dba..00000000
--- a/apps/admin/src/pages/Landing/components/Tab/Tab.styles.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { mq_lg } from '@boolti/ui';
-import styled from '@emotion/styled';
-import { m } from 'framer-motion';
-
-const Container = styled(m.div)`
- display: flex;
- justify-content: center;
- align-items: center;
- height: 48px;
- width: 100%;
- ${mq_lg} {
- height: 64px;
- }
-`;
-
-const List = styled.div`
- display: flex;
- align-items: flex-end;
- width: 100%;
- height: 100%;
- max-width: ${({ theme }) => theme.breakpoint.desktop};
-`;
-
-const Button = styled.button<{ isActive?: boolean }>`
- cursor: pointer;
- box-sizing: border-box;
- padding: 12px 0;
- ${({ theme }) => theme.typo.sh1};
- color: ${({ theme }) => theme.palette.grey.g00};
-
- &:not(:first-of-type) {
- margin-left: 20px;
- }
-
- border-bottom: 2px solid
- ${({ isActive, theme }) => (isActive ? theme.palette.primary.o1 : 'transparent')};
-
- ${mq_lg} {
- padding: 12px 0 16px 0;
- }
-`;
-
-export default { Container, Button, List };
diff --git a/apps/admin/src/pages/Landing/components/Tab/index.tsx b/apps/admin/src/pages/Landing/components/Tab/index.tsx
deleted file mode 100644
index b6079d7e..00000000
--- a/apps/admin/src/pages/Landing/components/Tab/index.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { useAtom } from 'jotai';
-
-import { visibleSectionAtom } from '../../atoms/visibleSectionAtom';
-import Styled from './Tab.styles';
-
-const items = [
- { key: 'organizer', children: '주최자용 웹' },
- { key: 'user', children: '방문자용 앱' },
-] as const;
-
-const Tab = () => {
- const [currentVisibleSection, setCurrentVisibleSection] = useAtom(visibleSectionAtom);
- return (
-
-
- {items.map((item) => (
- {
- const element = document.getElementById(item.key);
- if (element) {
- setCurrentVisibleSection(item.key);
- const top = window.scrollY + element.getBoundingClientRect().top - 60;
- setTimeout(() => {
- window.scrollTo({ top, behavior: 'smooth' });
- }, 0);
- }
- }}
- >
- {item.children}
-
- ))}
-
-
- );
-};
-
-export default Tab;
diff --git a/apps/admin/src/pages/Landing/components/UserSection/UserSection.styles.ts b/apps/admin/src/pages/Landing/components/UserSection/UserSection.styles.ts
deleted file mode 100644
index 3682e9bb..00000000
--- a/apps/admin/src/pages/Landing/components/UserSection/UserSection.styles.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { Button as _Button, mq_lg } from '@boolti/ui';
-import styled from '@emotion/styled';
-
-const Section = styled.section`
- width: 100%;
-`;
-
-const Container = styled.div`
- position: relative;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- background-color: ${({ theme }) => theme.palette.mobile.grey.g95};
- padding-top: 80px;
-
- ${mq_lg} {
- padding-top: 128px;
- }
-`;
-
-const Title = styled.h2`
- text-align: center;
- white-space: pre-wrap;
- color: ${({ theme }) => theme.palette.grey.w};
- ${({ theme }) => theme.typo.point.p4};
-
- ${mq_lg} {
- white-space: normal;
- font-size: 32px;
- line-height: 38px;
- }
-`;
-
-const Description = styled.p`
- text-align: center;
- color: ${({ theme }) => theme.palette.grey.g30};
- ${({ theme }) => theme.typo.b1};
- white-space: pre-wrap;
- margin-top: 6px;
-
- ${mq_lg} {
- white-space: normal;
- margin-top: 8px;
- font-size: 20px;
- line-height: 32px;
- }
-`;
-
-const Button = styled(_Button)`
- cursor: pointer;
- margin-top: 12px;
-
- ${mq_lg} {
- margin-top: 24px;
- }
-`;
-
-const TicketPreviewImage = styled.img`
- display: none;
- ${mq_lg} {
- display: block;
- width: calc(100% - 160px);
- max-width: 1080px;
- margin-top: 80px;
- }
-`;
-
-const MobileTicketPreviewImage = styled.img`
- margin-top: 32px;
- width: calc(100% - 60px);
- display: block;
- ${mq_lg} {
- display: none;
- }
-`;
-
-export default {
- Section,
- Container,
- Title,
- Description,
- Button,
- TicketPreviewImage,
- MobileTicketPreviewImage,
-};
diff --git a/apps/admin/src/pages/Landing/components/UserSection/index.tsx b/apps/admin/src/pages/Landing/components/UserSection/index.tsx
deleted file mode 100644
index 56a02c88..00000000
--- a/apps/admin/src/pages/Landing/components/UserSection/index.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-import { useTheme } from '@emotion/react';
-import { useNavigate } from 'react-router-dom';
-
-import entranceNotificationImg from '~/assets/images/entrance-notification.png';
-import mobileTicketPreivewImg from '~/assets/images/mobile-ticket-preview.png';
-import pcTicketPreviewImg from '~/assets/images/pc-ticket-preview.png';
-import showInfoImg from '~/assets/images/show-info.png';
-import ticketPurchaseImg from '~/assets/images/ticket-purchase.png';
-import { PATH } from '~/constants/routes';
-import { useDeviceWidth } from '~/hooks/useDeviceWidth';
-
-import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom';
-import FeatureItem from '../FeatureItem';
-import Styled from './UserSection.styles';
-import { openStoreLink } from '~/utils/link';
-
-const UserSection = () => {
- const { ref: sectionRef } = useVisibleSectionAtom('user');
- const navigate = useNavigate();
- const deviceWidth = useDeviceWidth();
- const theme = useTheme();
- const isMobile = deviceWidth < parseInt(theme.breakpoint.mobile, 10);
- return (
-
-
- 빠른 입장을 원하는{'\n'}방문자를 위한 앱
-
- 번거로운 티켓 찾기는 이제 그만!{'\n'}앱에서 바로 티켓을 제시해 보세요
-
- {
- if (isMobile) {
- openStoreLink();
- return;
- }
- navigate(PATH.QR);
- }}
- >
- 앱 바로가기
-
-
-
-
-
-
-
-
- );
-};
-
-export default UserSection;
diff --git a/apps/admin/src/pages/Landing/components/index.ts b/apps/admin/src/pages/Landing/components/index.ts
index 5e8762d8..e5e1049c 100644
--- a/apps/admin/src/pages/Landing/components/index.ts
+++ b/apps/admin/src/pages/Landing/components/index.ts
@@ -1,8 +1,9 @@
+import FeatureCard from './FeatureCard';
import Header from './Header';
-import KeyVisual from './KeyVisual';
-import MoreInformation from './MoreInformation';
-import OrganizerSection from './OrganizerSection';
-import Tab from './Tab';
-import UserSection from './UserSection';
+import Hero from './Hero';
+import HowToUse from './HowToUse';
+import Problem from './Problem';
+import SolutionFeatures from './SolutionFeatures';
+import SolutionHighlight from './SolutionHighlight';
-export { Header, KeyVisual, MoreInformation, OrganizerSection, Tab, UserSection };
+export { FeatureCard, Header, Hero, HowToUse, Problem, SolutionFeatures, SolutionHighlight };
diff --git a/apps/admin/src/pages/Landing/constants.ts b/apps/admin/src/pages/Landing/constants.ts
new file mode 100644
index 00000000..7755fb08
--- /dev/null
+++ b/apps/admin/src/pages/Landing/constants.ts
@@ -0,0 +1,78 @@
+export const mq_desktop = '@media (min-width: 1120px)';
+
+export const LANDING_COLORS = {
+ heroGradient: 'linear-gradient(180deg, #131343 0%, #020206 100%)',
+ heroBottom: '#020206',
+ solutionLightBg: '#ECEFF3',
+ chipBg: 'rgba(255, 207, 186, 0.5)',
+ chipText: '#FF6827',
+ primaryCta: '#FF6827',
+ darkButton: '#282B33',
+ darkButtonText: '#A2A5B4',
+ darkCardBg: '#A2A5B4',
+ headerGlass: 'rgba(111, 116, 133, 0.4)',
+ headerBorder: 'rgba(136, 141, 157, 0.3)',
+ cardBorder: '#D8DBE5',
+ promoGradient: 'linear-gradient(180deg, #FFE6DF 0%, #F3F5F9 100%)',
+ paymentGradient: 'linear-gradient(180deg, #E9EBFE 0%, #F3F5F9 100%)',
+} as const;
+
+export const LANDING_COPY = {
+ hero: {
+ eyebrow: '공연 등록 · 판매 · 입장 관리까지',
+ titleLead: '소규모 공연을 위한',
+ titleTrail: '올인원 플랫폼,',
+ },
+ problem: {
+ title: '공연 준비,\n아직도 수작업으로 하시나요?',
+ },
+ solutionFeatures: {
+ eyebrow: '공연 등록부터 정산까지',
+ titleLead: '번거로운 일은',
+ titleTrail: '불티에서 한 번에 해결!',
+ items: [
+ {
+ chip: '티켓 판매',
+ title: '입금/환불 걱정 끝',
+ description: '입금 확인부터 환불 처리까지,\n번거로웠던 모든 과정을 자동으로 처리',
+ },
+ {
+ chip: '관람안내',
+ title: '놓칠 걱정 없는 자동 알림 시스템',
+ description: '일일이 문자를 보내지 않아도\n자동 알림으로 관객이 공연을 놓치지 않게',
+ },
+ {
+ chip: '입장 관리',
+ title: '입장은 QR로 빠르게',
+ description: '번거로운 발권이나 확인 절차 없이\nQR 스캔만으로 대기 없는 입장 가능',
+ },
+ {
+ chip: '실시간 현황',
+ title: '실시간 현황을 한눈에',
+ description: '티켓 판매 현황, 실제 입장 관객 수 등\n주요 정보를 모니터링하고 빠르게 대응',
+ },
+ ],
+ },
+ solutionHighlight: {
+ title: '링크 하나로 가볍게\n다양한 결제 수단으로 편리하게',
+ items: [
+ {
+ chip: '공연 홍보',
+ title: '링크 하나로\n홍보 끝!',
+ description: '일일이 정보를 첨부할 필요 없이, 링크만 공유하면 공연 홍보 완료',
+ variant: 'light' as const,
+ },
+ {
+ chip: '결제/발권',
+ title: '다양한 결제 수단 지원',
+ description: '번거로운 입금 대조 과정 없이 실시간으로 티켓 발권 가능',
+ variant: 'dark' as const,
+ },
+ ],
+ },
+ howToUse: {
+ title: '불티와 함께 온전히,\n공연과 무대에 집중해 보세요',
+ primaryCta: '3분만에 끝나는 공연 등록 →',
+ secondaryCta: '앱 둘러보기',
+ },
+} as const;
diff --git a/apps/admin/src/pages/Landing/index.tsx b/apps/admin/src/pages/Landing/index.tsx
index 39bf3c64..98ba59b0 100644
--- a/apps/admin/src/pages/Landing/index.tsx
+++ b/apps/admin/src/pages/Landing/index.tsx
@@ -1,31 +1,36 @@
import { Footer } from '@boolti/ui';
-
-import { Header, KeyVisual, MoreInformation, OrganizerSection, UserSection } from './components';
-import Styled from './LandingPage.styles';
import { usePopup } from '@boolti/api';
+
import usePopupDialog from '~/hooks/usePopupDialog';
+import {
+ Header,
+ Hero,
+ HowToUse,
+ Problem,
+ SolutionFeatures,
+ SolutionHighlight,
+} from './components';
+import Styled from './LandingPage.styles';
+
const LandingPage = () => {
const { data: popupData } = usePopup('HOME');
usePopupDialog(popupData);
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
);
};