/* ============================================
새벽달 앱 디자인 시스템 v2.0
모든 시각적 요소를 변수로 제어
============================================ */
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700;900&display=swap');
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 컬러 토큰
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
:root {
/* 오렌지 (홈/피드/인증) */
--c-orange: #FF8C42;
--c-orange-light: #FFF5EE;
--c-orange-mid: #FFE4CC;
--c-orange-border: #FFD0A8;
--c-orange-text: #D4700A;
--c-orange-shadow: rgba(255,140,66,0.30);
/* 티얼 (내 기록) */
--c-teal: #19A5A3;
--c-teal-light: #F0FAFA;
--c-teal-mid: #B2E8E7;
--c-teal-border: #8ED8D6;
--c-teal-text: #0D7A78;
--c-teal-shadow: rgba(25,165,163,0.25);
/* 블루 (자료) */
--c-blue: #2F8AF5;
--c-blue-light: #EAF2FF;
--c-blue-mid: #B8D8FF;
--c-blue-border: #90C0FF;
--c-blue-text: #1A6AD4;
--c-blue-shadow: rgba(47,138,245,0.25);
/* 보라 (온보딩/로그인) */
--c-purple: #7C5CFF;
--c-purple-light: #F2EEFF;
--c-purple-mid: #D4CAFF;
--c-purple-border: #B8AAFF;
--c-purple-text: #5A3FD4;
--c-purple-shadow: rgba(124,92,255,0.28);
/* 골드 포인트 */
--c-gold: #FFD60A;
--c-gold-light: #FFF9D6;
--c-gold-text: #B89500;
/* 시멘틱 */
--c-danger: #FF5757;
--c-danger-light: #FFF0EE;
--c-danger-text: #CC3030;
--c-warning-light: #FFF5EE;
--c-success: #19A5A3;
/* 네이비 */
--c-navy: #1A1A2E;
/* 중성 */
--c-white: #FFFFFF;
--c-bg: #FAFAF8;
--c-card: #FFFFFF;
/* 텍스트 */
--c-text-primary: #1A1A2E;
--c-text-secondary: #444444;
--c-text-tertiary: #888888;
--c-text-muted: #AAAAAA;
--c-text-disabled: #CCCCCC;
/* 보더 */
--c-border-light: rgba(0,0,0,0.07);
--c-border-medium: rgba(0,0,0,0.12);
--c-divider: #F0F0EE;
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2. 타이포그래피
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
:root {
--font-base: 'Noto Sans KR', -apple-system, sans-serif;
--fs-2xs: 9px;
--fs-xs: 10px;
--fs-sm: 11px;
--fs-base: 12px;
--fs-md: 13px;
--fs-lg: 14px;
--fs-xl: 16px;
--fs-2xl: 18px;
--fs-3xl: 22px;
--fs-4xl: 28px;
--fw-light: 300;
--fw-regular: 400;
--fw-medium: 500;
--fw-bold: 700;
--fw-black: 900;
--lh-tight: 1.2;
--lh-snug: 1.35;
--lh-base: 1.5;
--lh-relaxed: 1.65;
--lh-loose: 1.8;
--ls-tight: -0.02em;
--ls-normal: 0;
--ls-wide: 0.03em;
--ls-wider: 0.06em;
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3. 간격 (8px 베이스)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
:root {
--sp-1: 4px;
--sp-2: 8px;
--sp-3: 12px;
--sp-4: 16px;
--sp-5: 20px;
--sp-6: 24px;
--sp-8: 32px;
--sp-10: 40px;
--pad-page: 16px;
--pad-card: 12px;
--pad-card-sm: 8px;
--pad-header: 10px;
--pad-input: 11px;
--pad-section: 10px;
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
4. 라운드
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
:root {
--r-xs: 6px;
--r-sm: 8px;
--r-md: 12px;
--r-lg: 16px;
--r-xl: 20px;
--r-2xl: 24px;
--r-full: 9999px;
--r-btn: var(--r-full);
--r-card: var(--r-md);
--r-card-lg: var(--r-lg);
--r-input: var(--r-md);
--r-chip: var(--r-xs);
--r-pill: var(--r-full);
--r-sheet: var(--r-xl);
--r-code-box: 14px;
--r-progress: 3px;
--r-tooltip: 8px;
--r-avatar: var(--r-full);
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
5. 고정 크기
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
:root {
--h-tab-bar: 64px;
--h-btn-full: 44px;
--h-btn-md: 36px;
--h-btn-sm: 28px;
--h-btn-xs: 24px;
--h-input: 44px;
--h-input-sm: 36px;
--h-textarea: 60px;
--h-progress: 6px;
--h-code-box: 48px;
--h-feed-img: 115px;
--h-feed-img-sm: 80px;
--sz-tab-plus: 44px;
--sz-avatar-lg: 40px;
--sz-avatar-md: 32px;
--sz-avatar-sm: 26px;
--sz-avatar-xs: 22px;
--sz-cal-day: 26px;
--sz-stepper-btn: 28px;
--sz-icon-md: 20px;
--sz-icon-sm: 16px;
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
6. 쉐도우
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
:root {
--shadow-xs: 0 1px 4px rgba(0,0,0,0.06);
--shadow-sm: 0 2px 8px rgba(0,0,0,0.08);
--shadow-md: 0 4px 16px rgba(0,0,0,0.10);
--shadow-card: 0 2px 8px rgba(0,0,0,0.06);
--shadow-sheet: 0 -4px 20px rgba(0,0,0,0.10);
--shadow-orange: 0 4px 14px var(--c-orange-shadow);
--shadow-teal: 0 4px 14px var(--c-teal-shadow);
--shadow-blue: 0 4px 14px var(--c-blue-shadow);
--shadow-purple: 0 4px 14px var(--c-purple-shadow);
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
7. 전환/애니메이션
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
:root {
--dur-fast: 120ms;
--dur-base: 200ms;
--dur-slow: 320ms;
--dur-sheet: 350ms;
--ease-base: ease;
--ease-spring: cubic-bezier(0.32, 0.72, 0, 1);
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--overlay-grad: linear-gradient(to top, rgba(0,0,0,0.42), transparent);
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
8. Z-index
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
:root {
--z-base: 1;
--z-tab: 100;
--z-overlay: 200;
--z-sheet: 300;
--z-tooltip: 400;
--z-toast: 500;
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
9. 글로벌 리셋
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
-webkit-tap-highlight-color: transparent;
}
body {
font-family: var(--font-base);
font-size: var(--fs-md);
font-weight: var(--fw-regular);
color: var(--c-text-primary);
background: var(--c-bg);
line-height: var(--lh-base);
-webkit-font-smoothing: antialiased;
overscroll-behavior: none;
max-width: 430px;
margin: 0 auto;
min-height: 100dvh;
overflow-x: hidden;
}
input, select, textarea, button { font-family: var(--font-base); }
button { cursor: pointer; border: none; background: none; }
a { text-decoration: none; color: inherit; }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
10. 레이아웃
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.page { min-height: 100dvh; padding-bottom: var(--h-tab-bar); background: var(--c-bg); }
.page-auth { min-height: 100dvh; background: var(--c-white); overflow-y: auto; }
.hide-scrollbar::-webkit-scrollbar { display: none; }
.hide-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
11. 탭바
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.tab-bar {
position: fixed;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 100%;
max-width: 430px;
height: var(--h-tab-bar);
background: var(--c-white);
border-top: 1px solid var(--c-border-light);
display: flex;
align-items: center;
z-index: var(--z-tab);
}
.tab-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 3px;
padding-bottom: 4px;
font-size: var(--fs-2xs);
font-weight: var(--fw-bold);
color: var(--c-text-disabled);
cursor: pointer;
user-select: none;
transition: color var(--dur-fast) var(--ease-base);
}
.tab-item--orange { color: var(--c-orange); }
.tab-item--teal { color: var(--c-teal); }
.tab-item--blue { color: var(--c-blue); }
.tab-item--navy { color: var(--c-navy); }
.tab-indicator {
width: 20px;
height: 3px;
border-radius: 2px;
background: currentColor;
margin-bottom: 1px;
}
.tab-plus {
width: var(--sz-tab-plus);
height: var(--sz-tab-plus);
border-radius: var(--r-full);
background: var(--c-orange);
display: flex;
align-items: center;
justify-content: center;
color: var(--c-white);
font-size: 26px;
font-weight: var(--fw-light);
margin-bottom: 14px;
box-shadow: var(--shadow-orange);
cursor: pointer;
transition: transform var(--dur-fast) var(--ease-base), box-shadow var(--dur-fast) var(--ease-base);
}
.tab-plus:active { transform: scale(0.92); }
.tab-plus--done { background: #D4D4D4; box-shadow: none; }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
12. 카드
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.card {
background: var(--c-card);
border-radius: var(--r-card);
border: 1px solid var(--c-border-light);
padding: var(--pad-card);
box-shadow: var(--shadow-card);
}
.card--lg { border-radius: var(--r-card-lg); overflow: hidden; }
.card--orange { border-color: rgba(255,140,66,0.18); }
.card--teal { border-color: rgba(25,165,163,0.18); }
.card--blue { border-color: rgba(47,138,245,0.18); }
.card--grad-orange { background: linear-gradient(135deg, var(--c-orange), #FFB347); }
.card--grad-teal { background: linear-gradient(135deg, var(--c-teal), #55CCCA); }
.card--locked { opacity: 0.75; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
13. 버튼
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--sp-1);
font-family: var(--font-base);
font-weight: var(--fw-bold);
cursor: pointer;
border: none;
transition: opacity var(--dur-fast), transform var(--dur-fast);
white-space: nowrap;
user-select: none;
}
.btn:active { transform: scale(0.97); opacity: 0.88; }
.btn--full { width: 100%; height: var(--h-btn-full); border-radius: var(--r-btn); font-size: var(--fs-lg); }
.btn--md { height: var(--h-btn-md); border-radius: var(--r-btn); font-size: var(--fs-base); padding: 0 18px; }
.btn--sm { height: var(--h-btn-sm); border-radius: var(--r-sm); font-size: var(--fs-xs); padding: 0 12px; }
.btn--xs { height: var(--h-btn-xs); border-radius: var(--r-sm); font-size: var(--fs-2xs); padding: 0 10px; }
.btn--orange { background: var(--c-orange); color: var(--c-white); }
.btn--teal { background: var(--c-teal); color: var(--c-white); }
.btn--blue { background: var(--c-blue); color: var(--c-white); }
.btn--purple { background: var(--c-purple); color: var(--c-white); }
.btn--navy { background: var(--c-navy); color: var(--c-white); }
.btn--disabled{ background: #D4D4D4; color: var(--c-white); pointer-events: none; }
.btn--inactive{ background: #B8C4D8; color: var(--c-white); pointer-events: none; }
.btn--outline-orange { background: var(--c-white); border: 1.5px solid var(--c-orange); color: var(--c-orange); }
.btn--outline-blue { background: var(--c-white); border: 1.5px solid var(--c-blue); color: var(--c-blue); }
.btn--outline-purple { background: var(--c-white); border: 1.5px solid var(--c-purple); color: var(--c-purple); }
.btn--outline-navy { background: var(--c-white); border: 1.5px solid var(--c-navy); color: var(--c-navy); }
.btn--outline-gray { background: var(--c-white); border: 1.5px solid #E0E0E0; color: var(--c-text-tertiary); }
.btn--buy {
background: var(--c-white);
border: 1.5px solid var(--c-orange);
color: var(--c-orange);
border-radius: var(--r-sm);
font-size: var(--fs-xs);
font-weight: var(--fw-bold);
padding: 5px var(--sp-3);
flex-shrink: 0;
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
14. Pill 뱃지
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.pill {
display: inline-flex;
align-items: center;
border-radius: var(--r-pill);
font-size: var(--fs-2xs);
font-weight: var(--fw-bold);
padding: 2px 8px;
white-space: nowrap;
}
.pill--orange { background: var(--c-orange-light); color: var(--c-orange-text); }
.pill--teal { background: var(--c-teal-light); color: var(--c-teal-text); }
.pill--blue { background: var(--c-blue-light); color: var(--c-blue-text); }
.pill--purple { background: var(--c-purple-light); color: var(--c-purple-text); }
.pill--gold { background: var(--c-gold-light); color: var(--c-gold-text); }
.pill--gray { background: #F5F5F5; color: var(--c-text-muted); }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
15. 미션 칩
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.mission-chip {
display: inline-flex;
align-items: center;
font-size: var(--fs-2xs);
font-weight: var(--fw-bold);
padding: 2px 7px;
border-radius: var(--r-chip);
background: rgba(255,255,255,0.92);
color: var(--c-text-primary);
}
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
16. 아바타
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.avatar { border-radius: var(--r-avatar); display: flex; align-items: center; justify-content: center; font-weight: var(--fw-bold); flex-shrink: 0; }
.avatar--lg { width: var(--sz-avatar-lg); height: var(--sz-avatar-lg); font-size: var(--fs-md); }
.avatar--md { width: var(--sz-avatar-md); height: var(--sz-avatar-md); font-size: var(--fs-sm); }
.avatar--sm { width: var(--sz-avatar-sm); height: var(--sz-avatar-sm); font-size: var(--fs-xs); }
.avatar--xs { width: var(--sz-avatar-xs); height: var(--sz-avatar-xs); font-size: var(--fs-2xs); }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
17. 입력 폼
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.input {
width: 100%;
height: var(--h-input);
padding: var(--pad-input) 14px;
border-radius: var(--r-input);
border: 1.5px solid;
font-size: var(--fs-lg);
font-weight: var(--fw-medium);
color: var(--c-text-primary);
outline: none;
font-family: var(--font-base);
transition: border-color var(--dur-fast), background var(--dur-fast);
letter-spacing: var(--ls-wide);
}
.input--purple { border-color: var(--c-purple-mid); background: var(--c-purple-light); }
.input--purple:focus { border-color: var(--c-purple); background: var(--c-white); }
.input--purple::placeholder { color: #C4B8F0; font-weight: var(--fw-regular); font-size: var(--fs-base); }
.input--teal { border-color: var(--c-teal-mid); background: var(--c-teal-light); }
.input--teal:focus { border-color: var(--c-teal); background: var(--c-white); }
.input--teal::placeholder { color: #B0D8D6; font-weight: var(--fw-regular); font-size: var(--fs-base); }
.select {
width: 100%;
height: var(--h-input-sm);
padding: 0 12px;
border-radius: var(--r-input);
border: 1.5px solid var(--c-purple-mid);
background: var(--c-purple-light);
font-size: var(--fs-base);
color: var(--c-text-primary);
outline: none;
font-family: var(--font-base);
-webkit-appearance: none;
}
.textarea {
width: 100%;
min-height: var(--h-textarea);
padding: var(--sp-2) var(--sp-3);
border-radius: var(--r-input);
border: 1.5px solid #F0F0F0;
background: #FAFAF8;
font-size: var(--fs-base);
color: var(--c-text-primary);
outline: none;
font-family: var(--font-base);
resize: none;
line-height: var(--lh-relaxed);
transition: border-color var(--dur-fast), background var(--dur-fast);
}
.textarea:focus { border-color: var(--c-orange); background: var(--c-white); }
.textarea::placeholder { color: var(--c-text-disabled); }
.code-box {
flex: 1;
height: var(--h-code-box);
border-radius: var(--r-code-box);
border: 1.5px solid var(--c-purple-mid);
background: var(--c-purple-light);
display: flex;
align-items: center;
justify-content: center;
font-size: var(--fs-3xl);
font-weight: var(--fw-bold);
color: var(--c-purple);
transition: all var(--dur-fast);
}
.code-box--filled { border-color: var(--c-purple); }
.code-box--active { border-color: var(--c-gold); background: var(--c-white); box-shadow: 0 0 0 3px rgba(255,214,10,0.2); }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
18. 진행 바
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.progress { height: var(--h-progress); border-radius: var(--r-progress); overflow: hidden; }
.progress--orange { background: var(--c-orange-mid); }
.progress--teal { background: var(--c-teal-mid); }
.progress--blue { background: var(--c-blue-mid); }
.progress__fill { height: 100%; border-radius: var(--r-progress); transition: width 0.5s ease; }
.progress__fill--orange { background: linear-gradient(90deg, var(--c-orange), #FFB347); }
.progress__fill--teal { background: linear-gradient(90deg, var(--c-teal), #55CCCA); }
.progress__fill--blue { background: linear-gradient(90deg, var(--c-blue), #5AABFF); }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
19. 스텝퍼
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.stepper { display: flex; align-items: center; gap: var(--sp-2); }
.stepper__btn {
width: var(--sz-stepper-btn);
height: var(--sz-stepper-btn);
border-radius: var(--r-full);
border: 1.5px solid var(--c-orange);
background: var(--c-white);
color: var(--c-orange);
font-size: var(--fs-xl);
font-weight: var(--fw-bold);
display: flex; align-items: center; justify-content: center;
cursor: pointer; line-height: 1; user-select: none;
transition: background var(--dur-fast);
}
.stepper__btn:active { background: var(--c-orange-light); }
.stepper__val { font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--c-text-primary); min-width: 22px; text-align: center; }
.stepper__unit { font-size: var(--fs-xs); color: var(--c-text-muted); }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
20. 체크박스
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.checkbox {
width: 18px; height: 18px; border-radius: 5px;
border: 1.5px solid var(--c-purple-mid);
background: var(--c-white);
flex-shrink: 0; display: flex; align-items: center; justify-content: center;
cursor: pointer; font-size: var(--fs-xs); font-weight: var(--fw-bold);
color: transparent; transition: all var(--dur-fast);
}
.checkbox--checked { background: var(--c-purple); border-color: var(--c-purple); color: var(--c-white); }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
21. 아코디언
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.accordion__header {
display: flex; align-items: center; justify-content: space-between;
cursor: pointer; padding: var(--sp-2) var(--pad-card);
background: var(--c-card); border-radius: var(--r-card);
border: 1px solid var(--c-border-light); user-select: none;
transition: border-radius var(--dur-fast);
}
.accordion__header--open { border-radius: var(--r-card) var(--r-card) 0 0; border-bottom-color: transparent; }
.accordion__title { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--c-text-primary); }
.accordion__arrow { font-size: var(--fs-sm); color: var(--c-text-muted); transition: transform var(--dur-base); }
.accordion__arrow--open { transform: rotate(180deg); }
.accordion__body { display: none; background: var(--c-card); border-radius: 0 0 var(--r-card) var(--r-card); border: 1px solid var(--c-border-light); border-top: none; padding: var(--sp-2) var(--pad-card) var(--pad-card); }
.accordion__body--open { display: block; }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
22. 오버레이 & 바텀 시트
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.overlay {
position: fixed; inset: 0; background: rgba(0,0,0,0);
z-index: var(--z-overlay); pointer-events: none;
transition: background var(--dur-base); max-width: 430px; margin: 0 auto;
}
.overlay--show { background: rgba(0,0,0,0.40); pointer-events: auto; }
.sheet {
position: fixed; bottom: -100%; left: 50%; transform: translateX(-50%);
width: 100%; max-width: 430px; background: var(--c-white);
border-radius: var(--r-sheet) var(--r-sheet) 0 0;
z-index: var(--z-sheet); transition: bottom var(--dur-sheet) var(--ease-spring);
box-shadow: var(--shadow-sheet);
}
.sheet--open { bottom: 0; }
.sheet__handle { width: 36px; height: 4px; border-radius: 2px; background: #E0E0E0; margin: 10px auto 14px; }
.sheet__header { display: flex; align-items: center; justify-content: space-between; padding: 0 var(--pad-page) var(--sp-3); }
.sheet__title { font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--c-text-primary); }
.sheet__close { width: 26px; height: 26px; border-radius: var(--r-full); background: #F5F5F5; display: flex; align-items: center; justify-content: center; font-size: var(--fs-base); color: var(--c-text-muted); cursor: pointer; }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
23. 툴팁
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.tooltip-wrap { position: relative; }
.tooltip {
display: none; position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
background: var(--c-navy); color: var(--c-white); font-size: var(--fs-2xs); font-weight: var(--fw-bold);
padding: 5px 9px; border-radius: var(--r-tooltip); white-space: nowrap;
z-index: var(--z-tooltip); line-height: var(--lh-relaxed); text-align: center; pointer-events: none;
}
.tooltip::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 4px solid transparent; border-top-color: var(--c-navy); }
.tooltip-wrap:hover .tooltip, .tooltip-wrap.active .tooltip { display: block; }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
24. 캘린더
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.cal-grid { display: grid; grid-template-columns: repeat(7,1fr); gap: 3px; text-align: center; }
.cal-dow { font-size: var(--fs-2xs); color: var(--c-text-disabled); padding: 2px 0; }
.cal-day { width: var(--sz-cal-day); height: var(--sz-cal-day); border-radius: var(--r-full); display: flex; align-items: center; justify-content: center; font-size: var(--fs-xs); margin: auto; color: var(--c-text-muted); }
.cal-day--done { background: var(--c-teal); color: var(--c-white); font-weight: var(--fw-bold); }
.cal-day--partial { background: var(--c-teal-mid); color: var(--c-teal-text); font-weight: var(--fw-bold); }
.cal-day--today { border: 1.5px solid var(--c-teal); color: var(--c-teal); font-weight: var(--fw-bold); }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
25. 피드 이미지 오버레이
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.feed-img { width: 100%; height: var(--h-feed-img); position: relative; overflow: hidden; }
.feed-img__fill { width: 100%; height: 100%; object-fit: cover; }
.feed-img__overlay { position: absolute; bottom: 0; left: 0; right: 0; padding: 7px 10px; background: var(--overlay-grad); display: flex; align-items: flex-end; justify-content: space-between; }
.streak-num { font-size: var(--fs-2xl); font-weight: var(--fw-black); color: var(--c-white); line-height: 1; }
.streak-lbl { font-size: var(--fs-2xs); color: rgba(255,255,255,0.85); font-weight: var(--fw-bold); }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
26. 상태 배지
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.status-badge { font-size: var(--fs-2xs); font-weight: var(--fw-bold); padding: 3px 9px; border-radius: var(--r-xs); white-space: nowrap; flex-shrink: 0; }
.status-badge--done { background: var(--c-teal-light); color: var(--c-teal-text); }
.status-badge--undone { background: var(--c-warning-light); color: var(--c-orange-text); }
.status-badge--missed { background: var(--c-danger-light); color: var(--c-danger-text); }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
27. 섹션 헤더
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.section-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-2); }
.section-title { font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--c-text-muted); letter-spacing: var(--ls-wider); }
.section-more { font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--c-orange); cursor: pointer; }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
28. 애니메이션
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
@keyframes fadeUp { from { opacity:0; transform:translateY(14px); } to { opacity:1; transform:translateY(0); } }
@keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@keyframes slideUp { from { transform:translateY(100%); } to { transform:translateY(0); } }
@keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:0.55; } }
@keyframes scaleIn { from { transform:scale(0.92); opacity:0; } to { transform:scale(1); opacity:1; } }
.anim-fade-up { animation: fadeUp 0.28s var(--ease-spring) both; }
.anim-fade-in { animation: fadeIn 0.22s ease both; }
.anim-scale-in { animation: scaleIn 0.24s var(--ease-bounce) both; }
.anim-pulse { animation: pulse 2s ease infinite; }
.delay-1 { animation-delay: 0.05s; }
.delay-2 { animation-delay: 0.10s; }
.delay-3 { animation-delay: 0.15s; }
.delay-4 { animation-delay: 0.20s; }
/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
29. 유틸리티
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.flex { display: flex; }
.flex-col { display: flex; flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: var(--sp-1); }
.gap-2 { gap: var(--sp-2); }
.gap-3 { gap: var(--sp-3); }
.gap-4 { gap: var(--sp-4); }
.w-full { width: 100%; }
.ml-auto { margin-left: auto; }
.mt-2 { margin-top: var(--sp-2); }
.mt-3 { margin-top: var(--sp-3); }
.mt-4 { margin-top: var(--sp-4); }
.mb-2 { margin-bottom: var(--sp-2); }
.mb-3 { margin-bottom: var(--sp-3); }
.mb-4 { margin-bottom: var(--sp-4); }
.p-4 { padding: var(--sp-4); }
.px { padding-left: var(--pad-page); padding-right: var(--pad-page); }
.text-center { text-align: center; }
.text-orange { color: var(--c-orange); }
.text-teal { color: var(--c-teal); }
.text-blue { color: var(--c-blue); }
.text-purple { color: var(--c-purple); }
.text-muted { color: var(--c-text-muted); }
.text-white { color: var(--c-white); }
.font-bold { font-weight: var(--fw-bold); }
.text-xs { font-size: var(--fs-xs); }
.text-sm { font-size: var(--fs-sm); }
.text-md { font-size: var(--fs-md); }
.text-lg { font-size: var(--fs-lg); }
/* iOS 안전 영역 */
@supports (padding-bottom: env(safe-area-inset-bottom)) {
.tab-bar { padding-bottom: env(safe-area-inset-bottom); }
.page { padding-bottom: calc(var(--h-tab-bar) + env(safe-area-inset-bottom)); }
}





