[Feature/#140] 랜딩페이지 구현 및 로그인/대시보드 라우팅 안정화 - #164
Conversation
Made-with: Cursor
- 랜딩 섹션 로딩(Suspense) 분리로 초기 렌더 개선 - 요금제/플랫폼 선택 UI 디테일 정리 - '/' 접속 시 '/landing'으로 이동 - 미사용 에셋 제거 및 lockfile 동기화 Made-with: Cursor
- 헤더의 로그인/시작하기 버튼 제거 - 히어로 보조 CTA를 요금제 섹션 이동으로 변경 Made-with: Cursor
- 로그인/소셜 로그인 성공 후 '/dashboard'로 이동 - 대시보드/사이드바 경로를 '/dashboard'로 통일 - 개발 프록시에서 Origin 헤더 제거로 CORS 거부 방지 - dev 환경에서 API baseURL 미설정 허용 Made-with: Cursor
- LandingPage를 pages/landing으로 이동 - 라우터 import 경로 정리 Made-with: Cursor
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (10)
📝 WalkthroughWalkthrough루트 경로를 Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~35 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 38 minutes and 49 seconds.Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (4)
src/components/landing/LandingFooter.tsx (1)
29-31: 연도 하드코딩은 유지보수 포인트가 됩니다.Line 30은 런타임 연도로 계산해두면 매년 수정 이슈를 줄일 수 있어요.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/LandingFooter.tsx` around lines 29 - 31, In LandingFooter.tsx replace the hard-coded "© 2026" string with a runtime computed year by using JavaScript's Date().getFullYear() inside the LandingFooter component (keep the existing <p className="font-caption text-text-disabled"> element and its text structure), e.g., build the string dynamically when rendering so the footer shows "© {new Date().getFullYear()} WhereYouAd. All rights reserved." to avoid manual yearly updates.src/components/landing/GuidePlatform.tsx (1)
77-94: 드롭다운 트리거와 패널을 ARIA로 연결하면 더 좋습니다.
aria-expanded와 함께aria-controls+ 패널id를 연결하면 보조기기 탐색성이 더 좋아집니다.As per coding guidelines,
src/**:7. 접근성: 시맨틱 HTML, ARIA 속성 사용 확인.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/GuidePlatform.tsx` around lines 77 - 94, The button that toggles the dropdown (using setIsMenuOpen and aria-expanded={isMenuOpen}) should include an aria-controls attribute that references the panel element's id; add a stable unique id for the menu panel (e.g., "guide-platform-menu" or generated via React's useId/useRef) on the div that renders when isMenuOpen is true, and set aria-controls on the button to that id so assistive tech can associate the trigger (button with ChevronDown) with the panel; ensure the panel id matches exactly and remains stable across renders.src/components/landing/LandingGuide.tsx (1)
12-24: 페이지 렌더 타입을 판별 유니온으로 바꿔서 조합 오류를 컴파일 타임에 막아주세요.지금 구조는
useOverview/useTimeline/usePlatform/image/alt가 모두 선택값이라 잘못된 조합(예: 이미지 렌더인데alt누락)을 타입으로 막지 못합니다.리팩터링 예시
-type TGuidePage = { +type TGuidePageBase = { number: string; label: string; title: string; description: string; steps: TGuideStep[]; - image?: string; - alt?: string; reverse: boolean; - useOverview?: boolean; - useTimeline?: boolean; - usePlatform?: boolean; }; + +type TGuidePage = + | (TGuidePageBase & { kind: "overview" }) + | (TGuidePageBase & { kind: "timeline" }) + | (TGuidePageBase & { kind: "platform" }) + | (TGuidePageBase & { kind: "image"; image: string; alt: string }); @@ - {page.useOverview ? ( + {page.kind === "overview" ? ( <div className="p-0 bg-transparent"> <GuideOverviewChart /> </div> - ) : page.useTimeline ? ( + ) : page.kind === "timeline" ? ( <div className="p-0 bg-transparent"> <GuideTimeline /> </div> - ) : page.usePlatform ? ( + ) : page.kind === "platform" ? ( <div className="p-0 bg-transparent"> <GuidePlatform /> </div> ) : ( <img src={page.image} alt={page.alt}As per coding guidelines "src/: ... 4. 타입 안정성: TypeScript 타입의 명확성 확인." અને "src/: ... 7. 접근성: 시맨틱 HTML, ARIA 속성 사용 확인."
Also applies to: 143-159
src/components/landing/LandingFeatures.tsx (1)
15-20:TFeatureCardProps.delay는 현재 사용되지 않아 타입이 불필요하게 복잡합니다.
delay를 선언해두고 실제 데이터에서는Omit으로 제거하고 있어요. 카드 데이터 전용 타입으로 단순화하면 타입 의도가 더 명확해집니다.리팩터링 예시
-type TFeatureCardProps = { - delay: number; +type TFeatureCardProps = { title: string; description: string; Graphic: () => ReactNode; }; @@ - const featureCards: Omit<TFeatureCardProps, "delay">[] = [ + const featureCards: TFeatureCardProps[] = [As per coding guidelines "src/**: ... 4. 타입 안정성: TypeScript 타입의 명확성 확인."
Also applies to: 184-185
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/LandingFeatures.tsx` around lines 15 - 20, TFeatureCardProps currently declares an unused delay field which complicates types; remove delay from TFeatureCardProps and create a simplified Card data type (or use the existing card array type directly) so the data model matches usage, update any Omit<TFeatureCardProps, "delay"> usages to the new type, and adjust the FeatureCard/landing card data declarations and consumers in LandingFeatures.tsx (also address the duplicate issue around the other occurrence referenced at lines 184-185) so the props and card data types are consistent and minimal.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/dashboard/charts/TrafficChart.tsx`:
- Around line 205-227: The current useMemo block that computes apexOptions
ignores yAxisMax when it is 0 because it uses if (!yAxisMax); change that guard
to only exclude null/undefined (e.g., use if (yAxisMax == null) or if (yAxisMax
=== undefined || yAxisMax === null)) so a numeric 0 will still override the
y-axis max; update the logic inside the useMemo where yAxisMax, chartOptions,
and local yaxis are referenced (apexOptions, useMemo, yAxisMax, chartOptions,
yaxis) accordingly.
In `@src/components/landing/GuideOverviewChart.tsx`:
- Around line 96-99: The chart currently defines two series (variable series
with names "클릭수" and "예측 클릭수") but the legend rendering only shows one item;
update the chart legend configuration to display both series names to match the
series array. Locate the variable series and the chart options where legend
items/labels are set (references: series, and the legend option used around the
chart render), then adjust the legend to include both "클릭수" and "예측 클릭수" (or
derive labels from series.map(s => s.name)) and ensure legend.show (or
equivalent) remains true so the legend entries align with the two series. Ensure
no hardcoded single-label remains (remove or replace any single-entry legend
array).
In `@src/components/landing/GuidePlatform.tsx`:
- Around line 98-114: The toggle button currently only updates visual styles;
add an accessibility state by exposing selection via an ARIA attribute: update
the button rendered in the map (the element using togglePlatform(platform.id),
platform.id and isSelected) to include aria-pressed={isSelected} so assistive
technologies can read the toggle state; ensure the boolean comes from the same
isSelected variable used for styling and keep the existing sr-only label
unchanged.
In `@src/components/landing/GuideTimeline.tsx`:
- Around line 80-86: The icon-only navigation buttons in GuideTimeline (the
buttons rendering ChevronLeftIcon and ChevronRightIcon) lack accessible names
and explicit button types; update each icon-only <button> (both the left/right
chevrons and the similar buttons later in the file) to include type="button" and
a descriptive aria-label (e.g., aria-label="Previous week" / aria-label="Next
week" or context-appropriate labels) so screen readers convey their purpose
while preserving existing classes and handlers.
- Around line 90-97: The two clickable divs in the GuideTimeline component that
wrap SortIcon and FilterIcon are non-semantic and block keyboard access; change
those divs to semantic <button> elements (preserve the className styling, add
type="button", keep any onClick handlers) and add accessible labels (e.g.,
aria-label or visible text is fine) so the Sort and Filter controls are
keyboard-focusable and screen-reader friendly; update the elements that
currently render SortIcon and FilterIcon in GuideTimeline accordingly.
In `@src/components/landing/LandingFeatures.tsx`:
- Around line 77-109: The two decorative controls in LandingFeatures (the
gradient "AI로 요약하기" button with the animated motion.span and the "다운로드" button)
are non-interactive visual-only elements but are rendered as focusable
<button>s; change them to non-interactive elements or remove them from the
keyboard/AT tree: replace the decorative <button> elements with <div> or <span>
and add role="presentation" and aria-hidden="true", or if you must keep
<button>, set tabIndex={-1} and aria-hidden="true" (or disabled for semantic
controls) to prevent keyboard focus; apply the same fix for the similar controls
referenced at the other occurrence (the elements around symbols SparkleIcon and
the styled motion.span) so decorative UI is not tabbable.
In `@src/components/landing/LandingFooter.tsx`:
- Around line 14-25: The footer Link elements in LandingFooter.tsx currently use
placeholder hrefs ("#") so the core links don't navigate; update each Link (the
four Link elements rendering 회사소개, 이용약관, 개인정보처리방침, 고객센터) to point to the actual
internal routes or external URLs (e.g., Link to="/about" for 회사소개, to="/terms"
for 이용약관, to="/privacy" for 개인정보처리방침, and to="/support" or an external support
URL for 고객센터), ensuring you use the same Link component import
(react-router-dom) and preserve the existing className and accessibility (add
aria-labels if needed).
In `@src/components/landing/LandingPricing.tsx`:
- Around line 179-187: The CTA button in LandingPricing rendering (the button
using plan.buttonText and plan.featured) has no click handler; wire it to the
plan's action by using the plan's CTA field (e.g., plan.ctaUrl or
plan.ctaAction) — if plan.ctaUrl exists render the button as a link/navigation
(or add an onClick that calls a navigate function/router push or window.open for
external URLs), fall back to a provided plan.onClick callback when present, and
preserve the existing styling for plan.featured; also ensure the handler
respects target behavior (same tab vs new tab) and adds an aria-label for
accessibility.
In `@src/components/sidebar/Sidebar.tsx`:
- Around line 82-94: The dashboard active-check logic (used in the child loop
and in isParentActive) fails to treat "/dashboard/" as equal to "/dashboard";
normalize location.pathname and item/c.path comparisons by trimming trailing
slashes before comparing (e.g., derive a normalizedPath =
location.pathname.replace(/\/+$/, '') and compare normalizedPath ===
'/dashboard' or normalizedPath.startsWith(item.path.replace(/\/+$/, ''))), then
use those normalized comparisons in the existing functions/conditions
(references: isParentActive, the c.path === "/dashboard" equality check and the
location.pathname.startsWith(c.path) usage) so "/dashboard/" is correctly
treated as active.
---
Nitpick comments:
In `@src/components/landing/GuidePlatform.tsx`:
- Around line 77-94: The button that toggles the dropdown (using setIsMenuOpen
and aria-expanded={isMenuOpen}) should include an aria-controls attribute that
references the panel element's id; add a stable unique id for the menu panel
(e.g., "guide-platform-menu" or generated via React's useId/useRef) on the div
that renders when isMenuOpen is true, and set aria-controls on the button to
that id so assistive tech can associate the trigger (button with ChevronDown)
with the panel; ensure the panel id matches exactly and remains stable across
renders.
In `@src/components/landing/LandingFeatures.tsx`:
- Around line 15-20: TFeatureCardProps currently declares an unused delay field
which complicates types; remove delay from TFeatureCardProps and create a
simplified Card data type (or use the existing card array type directly) so the
data model matches usage, update any Omit<TFeatureCardProps, "delay"> usages to
the new type, and adjust the FeatureCard/landing card data declarations and
consumers in LandingFeatures.tsx (also address the duplicate issue around the
other occurrence referenced at lines 184-185) so the props and card data types
are consistent and minimal.
In `@src/components/landing/LandingFooter.tsx`:
- Around line 29-31: In LandingFooter.tsx replace the hard-coded "© 2026" string
with a runtime computed year by using JavaScript's Date().getFullYear() inside
the LandingFooter component (keep the existing <p className="font-caption
text-text-disabled"> element and its text structure), e.g., build the string
dynamically when rendering so the footer shows "© {new Date().getFullYear()}
WhereYouAd. All rights reserved." to avoid manual yearly updates.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 52f0c710-457c-4ef6-9b20-3218c3ff8500
⛔ Files ignored due to path filters (26)
package-lock.jsonis excluded by!**/package-lock.jsonand included by nonepackage.jsonis excluded by none and included by nonesrc/assets/icon/ai/sparkle.svgis excluded by!**/*.svgand included bysrc/**src/assets/icon/chevron/chervon-double-right.svgis excluded by!**/*.svgand included bysrc/**src/assets/icon/chevron/chervon-left.svgis excluded by!**/*.svgand included bysrc/**src/assets/icon/chevron/chevron-down.svgis excluded by!**/*.svgand included bysrc/**src/assets/icon/chevron/chevron-up.svgis excluded by!**/*.svgand included bysrc/**src/assets/icon/chevron/trend-down.svgis excluded by!**/*.svgand included bysrc/**src/assets/icon/chevron/trend-up.svgis excluded by!**/*.svgand included bysrc/**src/assets/icon/timeline/chevron-left.svgis excluded by!**/*.svgand included bysrc/**src/assets/icon/timeline/chevron-right.svgis excluded by!**/*.svgand included bysrc/**src/assets/icon/timeline/filter.svgis excluded by!**/*.svgand included bysrc/**src/assets/icon/timeline/kebab.svgis excluded by!**/*.svgand included bysrc/**src/assets/icon/timeline/sort.svgis excluded by!**/*.svgand included bysrc/**src/assets/logo/social-logo/plain/google_ads.pngis excluded by!**/*.pngand included bysrc/**src/assets/logo/social-logo/plain/meta.svgis excluded by!**/*.svgand included bysrc/**src/assets/logo/social-logo/wordmark/naver-wordmark.pngis excluded by!**/*.pngand included bysrc/**src/assets/logo/social-logo/wordmark/naver-wordmark.svgis excluded by!**/*.svgand included bysrc/**src/assets/mockup/iOS app dock.pngis excluded by!**/*.pngand included bysrc/**src/assets/mockup/iPad Air mockup.pngis excluded by!**/*.pngand included bysrc/**src/assets/mockup/laptop_mockup.pngis excluded by!**/*.pngand included bysrc/**src/assets/mockup/logo_test/logo_2.pngis excluded by!**/*.pngand included bysrc/**src/assets/mockup/optimized/mockup_test.jpgis excluded by!**/*.jpgand included bysrc/**src/assets/mockup/optimized/timeline_dashboard.jpgis excluded by!**/*.jpgand included bysrc/**tsconfig.app.jsonis excluded by none and included by nonevite.config.tsis excluded by none and included by none
📒 Files selected for processing (22)
src/components/dashboard/charts/TrafficChart.tsxsrc/components/landing/GuideOverviewChart.tsxsrc/components/landing/GuidePlatform.tsxsrc/components/landing/GuideTimeline.tsxsrc/components/landing/LandingBrandIdentity.tsxsrc/components/landing/LandingFAQ.tsxsrc/components/landing/LandingFeatures.tsxsrc/components/landing/LandingFooter.tsxsrc/components/landing/LandingGuide.tsxsrc/components/landing/LandingHeader.tsxsrc/components/landing/LandingHero.tsxsrc/components/landing/LandingPricing.tsxsrc/components/landing/LandingSectionHeader.tsxsrc/components/sidebar/Sidebar.tsxsrc/constants/sidebarNav.tssrc/index.csssrc/lib/axiosInstance.tssrc/pages/auth/Login.tsxsrc/pages/auth/RedirectPage.tsxsrc/pages/landing/LandingPage.tsxsrc/routes/MainRoutes.tsxsrc/routes/Router.tsx
CI의 pnpm --frozen-lockfile 설치 실패를 방지하기 위해 package.json 변경사항을 pnpm-lock.yaml에 반영합니다. Made-with: Cursor
- 미사용 패키지(lucide-react) 제거 - pnpm-lock.yaml / package-lock.json 동기화 Made-with: Cursor
📚 Storybook 배포 완료
|
- 데코용 폼 컨트롤을 비상호작용 요소로 변경해 포커스 제거 - 대시보드 메뉴 활성화 판정에서 trailing slash 처리 - 요금제 CTA 버튼에 회원가입/문의 동작 연결 - 차트 시리즈/범례 불일치 수정 Made-with: Cursor
- 프로 플랜 문의 CTA mailto를 whereyouadofficial@gmail.com으로 변경 Made-with: Cursor
- 초기 단계에 필요한 링크(이용약관/개인정보처리방침/고객센터)만 유지 Made-with: Cursor
- 고객센터를 mailto(whereyouadofficial@gmail.com)로 연결 - 약관/개인정보처리방침은 링크 준비 전까지 비활성 텍스트로 표시 Made-with: Cursor
- 이용약관/개인정보처리방침을 Notion 링크로 연결 - 고객센터 mailto 유지 Made-with: Cursor
jjjsun
left a comment
There was a problem hiding this comment.
P3: 랜딩헤더부분 높이랑 폰트크기 조금 더 키우면 더 잘보일것같습니다!
|
P4: 전체적인 구조가 깔끔하게 잘 정리된것같아요! 고생하셨어요! |
- 헤더 높이를 72px로 고정해 OS/브라우저별 차이를 최소화 - 히어로 높이 계산에 CSS 변수를 사용해 레이아웃 일관성 유지 Made-with: Cursor
- md 이상에서 헤더 높이를 80px로 상향 - 헤더 네비게이션 폰트 크기 15px → 16px Made-with: Cursor
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/components/landing/LandingPricing.tsx (1)
106-115: ⚡ Quick winCTA 분기 기준을 플랜
name문자열에서 분리해 주세요.지금은
"프로"텍스트에 비즈니스 로직이 묶여 있어 문구 변경/다국어 시 동작이 깨질 수 있습니다.ctaType/ctaHref같은 명시 필드를plans에 두고 분기하는 쪽이 안전합니다.제안 수정안
type TPlan = { name: string; + ctaType: "signup" | "mailto"; + ctaHref?: string; target: string; price: string; @@ { name: "프리", + ctaType: "signup", @@ { name: "스타터", + ctaType: "signup", @@ { name: "팀", + ctaType: "signup", @@ { name: "프로", + ctaType: "mailto", + ctaHref: "mailto:whereyouadofficial@gmail.com", @@ - function handleCta(planName: string) { - if (planName === "프로") { + function handleCta(plan: TPlan) { + if (plan.ctaType === "mailto" && plan.ctaHref) { const subject = encodeURIComponent("WhereYouAd 요금제 문의"); const body = encodeURIComponent("문의하실 내용을 입력해 주세요."); - window.location.href = `mailto:whereyouadofficial@gmail.com?subject=${subject}&body=${body}`; + window.location.href = `${plan.ctaHref}?subject=${subject}&body=${body}`; return; } @@ - onClick={() => handleCta(plan.name)} + onClick={() => handleCta(plan)}As per coding guidelines "2. 구조와 책임 분리: 페이지에 비즈니스 로직이 과도하지 않은지 확인. 커스텀 훅으로의 분리 여부 검토."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/LandingPricing.tsx` around lines 106 - 115, The CTA branching in handleCta currently depends on the plan name string ("프로"); change the plans data to include explicit CTA metadata (e.g., add ctaType: "mailto" | "signup" and optional ctaHref or ctaSubject/ctaBody fields to each plan) and update handleCta to switch on that ctaType instead of planName—use ctaHref or construct the mailto from ctaSubject/ctaBody when ctaType === "mailto", and navigate("/signup") (or use ctaHref) when ctaType === "signup"; update any callers that pass plan info to use the new fields and keep function name handleCta as the single location for this behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/landing/LandingHero.tsx`:
- Around line 64-75: The decorative ChevronDown icon in LandingHero.tsx is
exposed to assistive tech; make it ignored by screen readers by adding ARIA
attributes—set aria-hidden="true" and focusable="false" on the icon element (or
its immediate wrapper) where ChevronDown is rendered inside the motion.div so
the decorative chevron is removed from the accessibility tree while preserving
visuals and animation.
---
Nitpick comments:
In `@src/components/landing/LandingPricing.tsx`:
- Around line 106-115: The CTA branching in handleCta currently depends on the
plan name string ("프로"); change the plans data to include explicit CTA metadata
(e.g., add ctaType: "mailto" | "signup" and optional ctaHref or
ctaSubject/ctaBody fields to each plan) and update handleCta to switch on that
ctaType instead of planName—use ctaHref or construct the mailto from
ctaSubject/ctaBody when ctaType === "mailto", and navigate("/signup") (or use
ctaHref) when ctaType === "signup"; update any callers that pass plan info to
use the new fields and keep function name handleCta as the single location for
this behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8ae0c50c-13ed-4ac4-bbac-994f44b14d59
⛔ Files ignored due to path filters (3)
package-lock.jsonis excluded by!**/package-lock.jsonand included by nonepackage.jsonis excluded by none and included by nonepnpm-lock.yamlis excluded by!**/pnpm-lock.yaml,!pnpm-lock.yamland included by none
📒 Files selected for processing (8)
src/components/landing/GuideOverviewChart.tsxsrc/components/landing/LandingFeatures.tsxsrc/components/landing/LandingFooter.tsxsrc/components/landing/LandingHeader.tsxsrc/components/landing/LandingHero.tsxsrc/components/landing/LandingPricing.tsxsrc/components/sidebar/Sidebar.tsxsrc/pages/landing/LandingPage.tsx
✅ Files skipped from review due to trivial changes (1)
- src/components/landing/GuideOverviewChart.tsx
🚧 Files skipped from review as they are similar to previous changes (5)
- src/components/landing/LandingFooter.tsx
- src/pages/landing/LandingPage.tsx
- src/components/sidebar/Sidebar.tsx
- src/components/landing/LandingHeader.tsx
- src/components/landing/LandingFeatures.tsx
랜딩 섹션의 카드 shadow/텍스트 톤을 통일하고 CTA/내비/FAQ에 focus-visible 상태를 추가했습니다. 기능 섹션 소제목은 font-weight 충돌을 고려해 강조를 확실히 했고, 히어로 스크롤 아이콘은 장식 요소로 접근성 트리에서 제외했습니다. Made-with: Cursor
가이드 섹션 설명 문구를 줄바꿈 포함 텍스트로 변경하고, 렌더링을 위해 whitespace-pre-line을 적용했습니다. Made-with: Cursor
YermIm
left a comment
There was a problem hiding this comment.
P4: 깔끔하게 구현 잘하신 것 같습니다!! 수고하셨습니다 :)
🚨 관련 이슈
#140
✨ 변경사항
✏️ 작업 내용
LandingPage 구현 + Motion
Routing / Auth
Dev proxy
스크린샷
😅 미완성 작업
N/A
📢 논의 사항 및 참고 사항
Summary by CodeRabbit
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선
버그 픽스