클래스 페이지 모바일 반응형 버그 수정#706
Conversation
…75 추가 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- footer: 모바일 flex-col + pb 여백 / 텍스트 flex-wrap - my-page-mobile-nav: webkit 스크롤바 숨김 - floating-buttons: 모바일 bottom 위치 조정 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- feed-tab: 컨트롤 영역 flex-wrap으로 iPhone SE 가로 스크롤 방지 - roadmap-tab: 말풍선 텍스트 SVG 꼬리 보정 수직 중앙 정렬 - class-detail-roadmap-section: h-[150px] → h-1875 토큰 교체 - tab-nav, qna-tab, layout 등: 반응형 개선 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 Walkthrough전체 요약이 PR은 모바일 중심의 반응형 레이아웃 개선과 Tailwind 설계 토큰 표준화를 중점적으로 진행합니다. 전체 설계 시스템의 간격 변수를 px에서 rem 단위로 통일하고, 학습/클래스/랜딩 페이지의 각 영역에서 모바일 우선 중단점 기반 레이아웃을 구성합니다. 드롭다운/모달/버튼의 상태 스타일 추가와 safe-area 기반 안전영역 여백 처리도 함께 적용됩니다. 변경사항모바일 우선 반응형 설계 및 토큰 표준화
관련 PR
추천 라벨
시인의 한 마디
🎯 2 (Simple) | ⏱️ ~12 분 🚥 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 docstrings
🧪 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (3)
src/app/global.css (1)
436-474: 💤 Low value토큰 정렬 개선을 고려해볼 수 있습니다.
spacing 토큰들이 숫자 순서대로 정렬되지 않아 유지보수 시 찾기가 어려울 수 있습니다. 예를 들어:
--spacing-6750→--spacing-9250→--spacing-7125(역순) →--spacing-10500→--spacing-3400(큰 폭 역순)기능적으로는 문제없지만, 향후 토큰을 추가하거나 수정할 때 오름차순으로 정렬하면 가독성과 유지보수성이 개선됩니다.
💡 정렬 개선 제안
토큰명의 숫자 부분을 기준으로 오름차순 정렬:
--spacing-1875: 150px; + --spacing-2000: 10rem; --spacing-2125: 170px; --spacing-2250: 180px; ... + --spacing-3000: 15rem; --spacing-3400: 17rem; --spacing-3500: 280px; --spacing-3650: 292px; ... + --spacing-4000: 20rem; --spacing-4275: 342px; --spacing-4425: 354px; ...(현재 PR 범위를 벗어나므로 선택적으로 향후 개선 시 고려하시면 됩니다.)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/app/global.css` around lines 436 - 474, The spacing CSS custom properties are not ordered by their numeric suffix which reduces readability and maintainability; reorder the --spacing-... declarations in src/app/global.css into ascending numeric order (e.g., ensure --spacing-3400 comes before --spacing-3650, --spacing-3750, etc., and that --spacing-6750, --spacing-7000, --spacing-7125, --spacing-7500, --spacing-7850, --spacing-7925, --spacing-8288, --spacing-8875, --spacing-9175, --spacing-9250, --spacing-10000, --spacing-10500 follow numeric order) so all tokens are consistently sorted by their numeric part.src/components/pages/landing/landing-content.tsx (1)
717-717: ⚡ Quick winsafe-area 계산에 하드코딩된 값을 고려하세요.
인라인 스타일의
calc(env(safe-area-inset-bottom, 0px) + 24px)에서24px가 하드코딩되어 있습니다.env()와 결합해야 하므로 인라인 스타일 사용은 적절하지만, CSS 변수(예:var(--spacing-300))를 사용하면 디자인 시스템과의 일관성을 유지할 수 있습니다.♻️ 제안: CSS 변수 사용
- style={{ paddingBottom: 'calc(env(safe-area-inset-bottom, 0px) + 24px)' }} + style={{ paddingBottom: 'calc(env(safe-area-inset-bottom, 0px) + var(--spacing-300))' }}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/pages/landing/landing-content.tsx` at line 717, Replace the hardcoded "24px" in the inline style calc with a design-system CSS variable so the safe-area value composes with spacing consistently; update the JSX style expression (the element using style={{ paddingBottom: 'calc(env(safe-area-inset-bottom, 0px) + 24px)' }}) to use calc(env(safe-area-inset-bottom, 0px) + var(--spacing-300)) (or your project spacing token name) and ensure that the CSS variable is defined in the global/theme so the fallback behavior remains intact.src/components/pages/class/roadmap-tab.tsx (1)
608-613: ⚡ Quick win하단 패딩을 rem 단위로 통일하세요.
safe-area 계산에서
24px를 하드코딩하고 있습니다. PR 전체 목표인 spacing 토큰 rem 표준화와 일관성을 맞추기 위해1.5rem(또는var(--spacing-300))을 사용하는 것이 좋습니다.♻️ 권장 수정안
style={{ - paddingBottom: 'calc(env(safe-area-inset-bottom, 0px) + 24px)', + paddingBottom: 'calc(env(safe-area-inset-bottom, 0px) + 1.5rem)', }}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/pages/class/roadmap-tab.tsx` around lines 608 - 613, Replace the hardcoded "24px" in the inline style on the bottom fixed container (the div with className including "fixed bottom-0" that sets style.paddingBottom) with a rem-based spacing token; change the expression from "calc(env(safe-area-inset-bottom, 0px) + 24px)" to use "1.5rem" or "var(--spacing-300)" (e.g., "calc(env(safe-area-inset-bottom, 0px) + 1.5rem)"), ensuring the change is applied to the paddingBottom property in the same inline style.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/app/`(landing)/class/[slug]/(learning)/_components/feed-tab.tsx:
- Line 217: The element in feed-tab.tsx uses an arbitrary Tailwind class
`max-w-[90vw]`; replace it with a project token: add a CSS variable
`--width-dropdown-mobile-max: 90vw;` to global.css, add a matching key under
theme.extend.maxWidth in your Tailwind config (e.g., "dropdown-mobile-max":
"var(--width-dropdown-mobile-max)"), then update the JSX class on the div to use
the new token class (e.g., `max-w-dropdown-mobile-max`) instead of
`max-w-[90vw]`; this removes the arbitrary value and follows the project's
custom token pattern.
In `@src/app/`(landing)/class/[slug]/(learning)/layout.tsx:
- Line 179: The paragraph element uses Tailwind arbitrary values ("text-[18px]",
"sm:text-[22px]", "tracking-[-0.418px]") which violates the guideline; replace
those classes on the <p> element (the className containing text-[18px]
sm:text-[22px] tracking-[-0.418px]) with the appropriate project typography
token from global.css (for example use the matching font-designer-* token like
font-designer-22b or font-designer-24b and keep existing semantic classes such
as font-semibold and text-gray-800); if no suitable token exists, add a new CSS
variable/token in global.css (e.g., --font-designer-22b) and then reference that
new token class on the same <p> element.
In `@src/app/`(landing)/class/page.tsx:
- Line 257: Replace the inline arbitrary font-size utilities in the className
string ("text-[32px] text-[50px]") with the project's design tokens from
global.css; locate the className on the heading in page.tsx and swap those px
utilities for the appropriate token-based classes (e.g., the token IDs defined
in global.css or token utility names your project uses) so sizing follows the
project's design tokens across breakpoints while preserving the existing
responsive behavior and other classes (whitespace-nowrap, font-extrabold,
leading-normal, text-gray-500).
- Line 97: Replace the arbitrary pixel font-size utilities in the className on
the heading element (the JSX element using className="... text-[32px]
sm:text-[50px] ...") with the project's design token classes from global.css;
locate the className string that contains text-[32px] and sm:text-[50px] and
swap those two tokens for the corresponding project token utility names (the
global.css custom font-size tokens used across the app) so sizes come from the
design system rather than hardcoded px values.
- Line 78: Replace the arbitrary tailwind utilities text-[32px] and
sm:text-[50px] in the className string with the project's design tokens defined
in global.css (use the font-designer-* tokens); e.g. change text-[32px] to the
appropriate token (font-designer-...) and sm:text-[50px] to the matching
responsive token (sm:font-designer-...), keeping the rest of the className
(absolute left-1/2 -translate-x-1/2 whitespace-nowrap font-extrabold
leading-normal text-gray-1000) intact and verifying the exact token names in
global.css before committing.
In `@src/components/pages/class/class-detail-roadmap-section.tsx`:
- Line 22: The div in the ClassDetailRoadmapSection component uses an arbitrary
spacing class "mx-[10.35%]" which violates the no-arbitrary-values rule; replace
it with a named spacing token (e.g., add --spacing-curriculum-inset: 10.35% to
global.css and expose it via Tailwind config) and then update the JSX to use the
corresponding utility (e.g., mx-curriculum-inset) or an existing spacing token
(e.g., mx-1000) instead of the arbitrary value; ensure you update
tailwind.config.js to map the new token so the class resolves correctly.
---
Nitpick comments:
In `@src/app/global.css`:
- Around line 436-474: The spacing CSS custom properties are not ordered by
their numeric suffix which reduces readability and maintainability; reorder the
--spacing-... declarations in src/app/global.css into ascending numeric order
(e.g., ensure --spacing-3400 comes before --spacing-3650, --spacing-3750, etc.,
and that --spacing-6750, --spacing-7000, --spacing-7125, --spacing-7500,
--spacing-7850, --spacing-7925, --spacing-8288, --spacing-8875, --spacing-9175,
--spacing-9250, --spacing-10000, --spacing-10500 follow numeric order) so all
tokens are consistently sorted by their numeric part.
In `@src/components/pages/class/roadmap-tab.tsx`:
- Around line 608-613: Replace the hardcoded "24px" in the inline style on the
bottom fixed container (the div with className including "fixed bottom-0" that
sets style.paddingBottom) with a rem-based spacing token; change the expression
from "calc(env(safe-area-inset-bottom, 0px) + 24px)" to use "1.5rem" or
"var(--spacing-300)" (e.g., "calc(env(safe-area-inset-bottom, 0px) + 1.5rem)"),
ensuring the change is applied to the paddingBottom property in the same inline
style.
In `@src/components/pages/landing/landing-content.tsx`:
- Line 717: Replace the hardcoded "24px" in the inline style calc with a
design-system CSS variable so the safe-area value composes with spacing
consistently; update the JSX style expression (the element using style={{
paddingBottom: 'calc(env(safe-area-inset-bottom, 0px) + 24px)' }}) to use
calc(env(safe-area-inset-bottom, 0px) + var(--spacing-300)) (or your project
spacing token name) and ensure that the CSS variable is defined in the
global/theme so the fallback behavior remains intact.
🪄 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: fdda44e4-b145-4a39-95ba-53ac1bc66e51
📒 Files selected for processing (17)
src/app/(class-lesson)/class/[slug]/lesson/[id]/page.tsxsrc/app/(landing)/class/[slug]/(learning)/_components/feed-tab.tsxsrc/app/(landing)/class/[slug]/(learning)/_components/qna-tab.tsxsrc/app/(landing)/class/[slug]/(learning)/feed/[id]/page.tsxsrc/app/(landing)/class/[slug]/(learning)/layout.tsxsrc/app/(landing)/class/[slug]/(learning)/qa/[id]/page.tsxsrc/app/(landing)/class/[slug]/page.tsxsrc/app/(landing)/class/page.tsxsrc/app/(service)/(my)/my-page/page.tsxsrc/app/global.csssrc/components/common/layout/footer.tsxsrc/components/common/layout/sidebar/my-page-mobile-nav.tsxsrc/components/common/ui/floating-class-action-buttons.tsxsrc/components/pages/class/class-detail-roadmap-section.tsxsrc/components/pages/class/class-detail-tab-nav.tsxsrc/components/pages/class/roadmap-tab.tsxsrc/components/pages/landing/landing-content.tsx
| </button> | ||
| {filterOpen && ( | ||
| <div className="absolute right-0 top-full z-10 mt-75 flex max-h-4000 min-w-2000 flex-col overflow-y-auto rounded-150 border border-border-default bg-background-default p-125 shadow-1"> | ||
| <div className="absolute left-0 top-full z-10 mt-75 flex max-h-4000 w-max max-w-[90vw] flex-col overflow-y-auto rounded-150 border border-border-default bg-background-default p-125 shadow-1"> |
There was a problem hiding this comment.
임의 값 사용 금지 가이드라인 위반
max-w-[90vw]는 임의(arbitrary) 값으로, 프로젝트 코딩 가이드라인을 위반합니다. global.css에 적절한 커스텀 토큰을 정의하거나 기존 토큰을 사용해야 합니다.
As per coding guidelines: "No arbitrary px values for spacing/sizing utilities (p-[4px], w-[320px], h-[100px], gap-[10px]). Use project custom tokens."
🔧 권장 수정안
global.css에 새로운 토큰 추가:
--width-dropdown-mobile-max: 90vw;그 후 Tailwind 설정에서 해당 토큰을 width 스케일에 추가하거나, 또는 기존의 적절한 토큰(예: max-w-7xl 등)을 활용하세요.
-<div className="absolute left-0 top-full z-10 mt-75 flex max-h-4000 w-max max-w-[90vw] flex-col overflow-y-auto rounded-150 border border-border-default bg-background-default p-125 shadow-1">
+<div className="absolute left-0 top-full z-10 mt-75 flex max-h-4000 w-max max-w-dropdown-mobile flex-col overflow-y-auto rounded-150 border border-border-default bg-background-default p-125 shadow-1">🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/app/`(landing)/class/[slug]/(learning)/_components/feed-tab.tsx at line
217, The element in feed-tab.tsx uses an arbitrary Tailwind class
`max-w-[90vw]`; replace it with a project token: add a CSS variable
`--width-dropdown-mobile-max: 90vw;` to global.css, add a matching key under
theme.extend.maxWidth in your Tailwind config (e.g., "dropdown-mobile-max":
"var(--width-dropdown-mobile-max)"), then update the JSX class on the div to use
the new token class (e.g., `max-w-dropdown-mobile-max`) instead of
`max-w-[90vw]`; this removes the arbitrary value and follows the project's
custom token pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Problem
클래스 목록/상세/로드맵·랜딩·마이페이지 등 다수 페이지에서 모바일(390px) 뷰포트 기준 레이아웃 깨짐 및 UX 버그가 존재했음.
Solution
grid-cols-1 lg:grid-cols-content-sidebar-360: 모바일 1열, lg 이상 2열overflow-x-auto [&::-webkit-scrollbar]:hidden+ 오른쪽 그라데이션 fade: 수평 스크롤 가능하게, 스크롤 힌트 제공hidden md:flex: 데스크탑 전용으로 숨김, 모바일은 챕터 카드 뷰만 표시min-w-0 flex-1 truncate: 카드 내 타이틀 overflow 방지calc(env(safe-area-inset-bottom, 0px) + 24px): iOS 홈 인디케이터 영역 침범 방지flex-col sm:flex-row+flex-wrap gap-y-100: 모바일 세로 스택, 텍스트 줄바꿈text-[32px] sm:text-[50px]/font-designer-36b sm:font-designer-62b: 모바일 타이포 축소vibe-intro-claude-code → vibe-intro): 에셋 경로 슬러그 오버라이드로 이미지 404 수정,onErrorfallback 추가Changes
Bug Fixes
src/app/global.csssrc/app/(landing)/class/[slug]/page.tsxsrc/app/(landing)/class/page.tsxsrc/app/(service)/(my)/my-page/page.tsxsrc/components/common/layout/footer.tsxsrc/components/common/ui/floating-class-action-buttons.tsxsrc/components/pages/class/class-detail-tab-nav.tsxsrc/components/pages/class/roadmap-tab.tsxsrc/components/pages/landing/landing-content.tsxResult
Screenshots
랜딩 (/)
클래스 목록 (/class)
클래스 상세 (/class/vibe-intro)
빌더 피드 리스트 (/class/vibe-intro/feed)
빌더 피드 상세 (/class/vibe-intro/feed/19)
질문답변 리스트 (/class/vibe-intro/qa)
질문답변 상세 (/class/vibe-intro/qa/4)
마이페이지 — 빌더 프로필 (/my-page)
마이페이지 — 마이 클래스 (/my-class)
마이페이지 — 내가 작성한 글 (/my-posts)
마이페이지 — 결제 관리 (/class-payment-management)
Test plan
🤖 Generated with Claude Code