feat: 쇼핑몰 샘플 추가, 홈페이지 서비스 페이지 재디자인, 공통 UI 개선
- 모든 샘플 페이지 우측 하단 맨 위로 스크롤 버튼 추가 (인테리어, 독서) - 독서 기록 노트 상단 '홈페이지 제작 서비스로 돌아가기' 배너 추가 - 개인 쇼핑몰 샘플 (MELLOW STUDIO) 신규 생성 - 베이지/크림 라이트 톤, Cormorant Garamond + Pretendard - 히어로 스플릿 레이아웃, 상품 그리드(카테고리 필터), 브랜드 스토리, 리뷰, CTA, 푸터 - 장바구니 뱃지, 상품 찜하기, 퀵 장바구니 인터랙션 - 홈페이지 서비스 소개 페이지 재디자인 - CookieRun → Pretendard 교체로 한글 폰트 렌더링 개선 - word-break: keep-all 적용으로 이상한 개행 제거 - IntersectionObserver 스크롤 reveal 애니메이션 추가 - Trust badge 섹션, Marquee 추가 - 쇼핑몰 샘플 카드 추가 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
/* ═══════════════════════════════════════
|
||||
@@ -167,14 +168,25 @@ function BookCard({ book, large = false }: { book: Book; large?: boolean }) {
|
||||
═══════════════════════════════════════ */
|
||||
export default function ReadingPage() {
|
||||
const [activeGenre, setActiveGenre] = useState('전체');
|
||||
const [showTop, setShowTop] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const scroller: HTMLElement =
|
||||
(document.querySelector('.main-content') as HTMLElement | null) ??
|
||||
document.documentElement;
|
||||
|
||||
const onScroll = () => setShowTop(scroller.scrollTop > 400);
|
||||
scroller.addEventListener('scroll', onScroll, { passive: true });
|
||||
|
||||
const obs = new IntersectionObserver(
|
||||
entries => entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('rd-visible'); }),
|
||||
{ threshold: 0.1 }
|
||||
{ threshold: 0.1, root: scroller === document.documentElement ? null : scroller }
|
||||
);
|
||||
document.querySelectorAll('.rd-reveal').forEach(el => obs.observe(el));
|
||||
return () => obs.disconnect();
|
||||
return () => {
|
||||
scroller.removeEventListener('scroll', onScroll);
|
||||
obs.disconnect();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const genres = ['전체', '소설', '고전', '자기계발', '과학', '심리학'];
|
||||
@@ -304,6 +316,24 @@ export default function ReadingPage() {
|
||||
}
|
||||
`}} />
|
||||
|
||||
{/* ── BACK BANNER ── */}
|
||||
<div style={{
|
||||
background: 'linear-gradient(135deg,#0C0B09,#1A1710)',
|
||||
borderBottom: '1px solid rgba(212,168,83,0.12)',
|
||||
height: 40, display: 'flex', alignItems: 'center',
|
||||
padding: '0 24px', gap: 12, flexShrink: 0, position: 'relative', zIndex: 300,
|
||||
}}>
|
||||
<Link href="/services/website" style={{ color: 'rgba(212,168,83,0.7)', fontSize: 13, textDecoration: 'none', display: 'flex', alignItems: 'center', gap: 6, transition: 'color 0.2s' }}
|
||||
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.color = '#D4A853')}
|
||||
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.color = 'rgba(212,168,83,0.7)')}>
|
||||
← 홈페이지 제작 서비스로 돌아가기
|
||||
</Link>
|
||||
<span style={{ color: 'rgba(212,168,83,0.2)' }}>|</span>
|
||||
<span style={{ color: 'rgba(212,168,83,0.4)', fontSize: 12, fontFamily: "'Cormorant Garamond', serif", fontStyle: 'italic' }}>
|
||||
SAMPLE · 독서 기록 노트
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="rd-root rd-grain" style={{ position: 'relative' }}>
|
||||
|
||||
{/* ── NAV ── */}
|
||||
@@ -604,6 +634,30 @@ export default function ReadingPage() {
|
||||
<p style={{ fontSize: '0.75rem', color: '#4A4035', margin: 0 }}>책은 시간을 초월한 대화다.</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
{/* ── SCROLL TO TOP ── */}
|
||||
<button
|
||||
onClick={() => {
|
||||
const scroller = (document.querySelector('.main-content') as HTMLElement | null) ?? document.documentElement;
|
||||
scroller.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}}
|
||||
style={{
|
||||
position: 'fixed', bottom: '2rem', right: '2rem', zIndex: 400,
|
||||
width: 48, height: 48, borderRadius: '50%',
|
||||
background: '#D4A853', border: 'none', cursor: 'pointer',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
boxShadow: '0 8px 32px rgba(212,168,83,0.4)',
|
||||
opacity: showTop ? 1 : 0,
|
||||
transform: showTop ? 'translateY(0) scale(1)' : 'translateY(12px) scale(0.9)',
|
||||
transition: 'opacity 0.35s cubic-bezier(0.16,1,0.3,1), transform 0.35s cubic-bezier(0.16,1,0.3,1)',
|
||||
pointerEvents: showTop ? 'auto' : 'none',
|
||||
}}
|
||||
aria-label="맨 위로"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#0C0B09" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="18 15 12 9 6 15"/>
|
||||
</svg>
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user