You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

555 lines
11 KiB
CSS

/* frontend/styles/globals.css */
/* Pretendard CDN (Google Fonts 미제공 — 원본 대시보드.html 8~17행과 동일 소스) */
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css");
@import "./tokens.css";
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
}
body {
font-family: var(--font-ui);
color: var(--ink);
background: linear-gradient(178deg, var(--bg-top) 0%, var(--bg-mid) 20%, var(--bg-bot) 100%);
background-attachment: fixed;
min-height: 100vh;
-webkit-font-smoothing: antialiased;
letter-spacing: -0.011em; /* 한국어 가독성 */
word-break: keep-all; /* 한국어 줄바꿈 */
}
button {
font-family: inherit;
cursor: pointer;
border: none;
background: none;
color: inherit;
}
input {
font-family: inherit;
}
:focus-visible {
outline: 2px solid var(--blue);
outline-offset: 2px;
border-radius: 6px;
}
.ic {
width: 1em;
height: 1em;
flex-shrink: 0;
display: block;
}
.mono {
font-family: var(--font-mono);
font-variant-numeric: tabular-nums;
}
/* 페이지 컨테이너 (원본 .dash) */
.shell-page {
max-width: 1620px;
margin: 0 auto;
padding: 0 26px 40px;
}
/* 큰 페이지 제목 (원본 .ph-title 232~239행) */
.ph-title {
font-family: var(--font-disp);
font-size: clamp(30px, 3.4vw, 46px);
letter-spacing: -0.03em;
font-weight: 700;
margin: 24px 0 0;
}
/* ===== 상단바 — 메인 메뉴 (원본 .topbar 102~204행 그대로) ===== */
.topbar {
position: sticky;
top: 0;
z-index: 40;
display: flex;
align-items: center;
gap: 24px;
height: 70px;
margin: 0 -26px;
padding: 0 30px;
-webkit-backdrop-filter: blur(14px) saturate(150%);
backdrop-filter: blur(14px) saturate(150%);
}
.brand {
display: flex;
align-items: center;
gap: 11px;
flex-shrink: 0;
text-decoration: none;
color: inherit;
}
.brand-mark {
width: 40px;
height: 40px;
border-radius: 12px;
background: var(--fill);
color: var(--coral);
display: grid;
place-items: center;
position: relative;
}
.brand-mark .ic {
width: 21px;
height: 21px;
}
.brand-mark::after {
content: "";
position: absolute;
top: -2px;
right: -2px;
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--coral);
border: 2px solid var(--bg-top);
}
.brand-tag {
line-height: 1.15;
}
.brand-tag b {
display: block;
font-size: 15px;
font-weight: 700;
letter-spacing: -0.02em;
white-space: nowrap;
}
.brand-tag span {
font-size: 9.5px;
font-weight: 700;
letter-spacing: 0.08em;
color: var(--muted);
text-transform: uppercase;
white-space: nowrap;
}
.mainnav {
display: flex;
align-items: center;
gap: 2px;
min-width: 0;
overflow-x: auto;
scrollbar-width: none;
}
.mainnav::-webkit-scrollbar {
display: none;
}
.mainnav a {
text-decoration: none;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 8px;
font-size: 14px;
font-weight: 500;
color: var(--ink-2);
padding: 9px 16px;
border-radius: 999px;
white-space: nowrap;
transition:
background 0.16s,
color 0.16s,
box-shadow 0.16s;
}
.mainnav a .ic {
width: 16px;
height: 16px;
color: var(--muted);
transition: color 0.16s;
}
.mainnav a:hover {
color: var(--ink);
}
.mainnav a:hover .ic {
color: var(--ink-2);
}
.mainnav a.active {
background: var(--glass);
-webkit-backdrop-filter: var(--blur);
backdrop-filter: var(--blur);
color: var(--ink);
font-weight: 600;
box-shadow: var(--shadow-sm);
border: 1px solid var(--glass-brd);
}
.mainnav a.active .ic {
color: var(--ink);
}
.mainnav a .badge {
font-size: 11px;
font-weight: 700;
background: var(--coral);
color: #fff;
border-radius: 999px;
padding: 0 6px;
min-width: 18px;
text-align: center;
}
.top-actions {
margin-left: auto;
display: flex;
align-items: center;
gap: 9px;
flex-shrink: 0;
}
.t-btn {
width: 40px;
height: 40px;
border-radius: 50%;
display: grid;
place-items: center;
color: var(--ink-2);
text-decoration: none;
background: var(--glass);
-webkit-backdrop-filter: var(--blur);
backdrop-filter: var(--blur);
border: 1px solid var(--glass-brd);
box-shadow: var(--shadow-sm);
position: relative;
transition:
transform 0.12s,
color 0.16s;
}
.t-btn .ic {
width: 18px;
height: 18px;
}
.t-btn:hover {
color: var(--ink);
transform: translateY(-1px);
}
.t-btn.dot::after {
content: "";
position: absolute;
top: 9px;
right: 10px;
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--coral);
border: 2px solid var(--card);
}
.t-ava {
width: 40px;
height: 40px;
border-radius: 50%;
background: linear-gradient(135deg, var(--coral), var(--violet));
color: #fff;
display: grid;
place-items: center;
font-weight: 700;
font-size: 15px;
text-decoration: none;
box-shadow: var(--shadow-sm);
cursor: pointer;
}
.t-btn.active {
color: var(--ink);
background: var(--fill);
}
.t-btn.active .ic {
color: var(--on-fill);
}
/* ===== 좌측 서브 레일 (원본 .rail 264~300행) ===== */
.rail {
position: sticky;
top: 86px;
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
flex-shrink: 0;
}
.rail button {
width: 44px;
height: 44px;
border-radius: 13px;
display: grid;
place-items: center;
color: var(--muted);
position: relative;
transition:
background 0.15s,
color 0.15s;
}
.rail button .ic {
width: 19px;
height: 19px;
}
.rail button:hover {
background: var(--glass);
-webkit-backdrop-filter: var(--blur);
backdrop-filter: var(--blur);
color: var(--ink-2);
box-shadow: var(--shadow-sm);
border: 1px solid var(--glass-brd);
}
.rail button.active {
background: var(--fill);
color: var(--on-fill);
box-shadow: var(--shadow);
}
.rail button .tip {
position: absolute;
left: 50%;
bottom: calc(100% + 8px);
transform: translateX(-50%) translateY(4px) scale(0.96);
background: var(--fill);
color: var(--on-fill);
font-size: 12px;
font-weight: 600;
white-space: nowrap;
padding: 5px 10px;
border-radius: 8px;
opacity: 0;
pointer-events: none;
transition:
opacity 0.14s,
transform 0.14s;
z-index: 60;
box-shadow: var(--shadow-sm);
}
.rail button .tip::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border: 5px solid transparent;
border-top-color: var(--fill);
}
.rail button:hover .tip {
opacity: 1;
transform: translateX(-50%) translateY(0) scale(1);
}
.rail .sp {
height: 10px;
}
.rail button .rdot {
position: absolute;
top: 7px;
right: 7px;
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--coral);
border: 2px solid var(--bg-top);
}
.rail button.active .rdot {
border-color: var(--fill);
}
/* ===== 공유 프리미티브 ===== */
/* GlassCard = 원본 .card (309~321행) */
.glass-card {
background: var(--glass);
-webkit-backdrop-filter: var(--blur);
backdrop-filter: var(--blur);
border: 1px solid var(--glass-brd);
border-radius: var(--radius);
box-shadow:
var(--shadow),
var(--glass-hi);
padding: 20px;
display: flex;
flex-direction: column;
min-width: 0;
}
/* Badge = 원본 .mainnav .badge 색을 재사용한 독립 토큰 */
.badge-pill {
font-size: 11px;
font-weight: 700;
color: #fff;
background: var(--coral);
border-radius: 999px;
padding: 0 6px;
min-width: 18px;
text-align: center;
display: inline-flex;
align-items: center;
justify-content: center;
}
.badge-pill[data-tone="blue"] {
background: var(--blue);
}
.badge-pill[data-tone="green"] {
background: var(--green);
}
.badge-pill[data-tone="violet"] {
background: var(--violet);
}
.badge-pill[data-tone="amber"] {
background: var(--amber);
}
.badge-pill[data-tone="ink"] {
background: var(--fill);
color: var(--on-fill);
}
/* 차분한 카운트 배지 = 원본 .ch .count (344~349행) */
.badge-count {
font-size: 12px;
font-weight: 700;
color: var(--ink-2);
background: var(--glass-2);
border: 1px solid var(--glass-brd);
border-radius: 999px;
padding: 3px 10px;
}
/* Chip = 원본 .chip (413~423행) */
.chip {
display: inline-flex;
align-items: center;
gap: 7px;
font-size: 12.5px;
font-weight: 500;
color: var(--ink-2);
background: var(--glass-2);
border: 1px solid var(--glass-brd);
padding: 7px 12px;
border-radius: 999px;
transition: background 0.14s;
}
.chip .ic {
width: 14px;
height: 14px;
color: var(--muted);
}
.chip:hover {
background: var(--card-2);
}
/* Button — 라임 CTA / 필(검정) CTA / 글래스 */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
font-size: 13.5px;
font-weight: 600;
padding: 10px 16px;
border-radius: 13px;
white-space: nowrap;
transition:
filter 0.14s,
background 0.14s,
transform 0.12s;
}
.btn .ic {
width: 16px;
height: 16px;
}
.btn-fill {
background: var(--fill);
color: var(--on-fill);
} /* 원본 .mtg-cta/.send/.rs-cta */
.btn-fill:hover {
filter: brightness(1.1);
}
.btn-lime {
background: var(--lime);
color: var(--lime-ink);
} /* 라임 CTA (--lime/--lime-ink) */
.btn-lime:hover {
background: var(--lime-hi);
}
.btn-glass {
background: var(--glass-2);
color: var(--ink);
border: 1px solid var(--glass-brd);
}
.btn-glass:hover {
background: var(--card-2);
}
/* SegmentToggle (칸반/리스트(캘린더는 post-MVP)) — 글래스 트랙 + 필 선택 */
.seg {
display: inline-flex;
gap: 2px;
padding: 3px;
background: var(--glass-2);
border: 1px solid var(--glass-brd);
border-radius: 999px;
}
.seg button {
font-size: 13px;
font-weight: 600;
color: var(--ink-2);
padding: 7px 14px;
border-radius: 999px;
display: inline-flex;
align-items: center;
gap: 6px;
transition:
background 0.14s,
color 0.14s;
}
.seg button .ic {
width: 15px;
height: 15px;
}
.seg button[aria-selected="true"] {
background: var(--fill);
color: var(--on-fill);
}
/* Avatar (원본 .mtg-people .av / .dg-av 톤 컬러) */
.avatar {
width: 30px;
height: 30px;
border-radius: 50%;
display: grid;
place-items: center;
font-size: 11px;
font-weight: 700;
color: #fff;
flex-shrink: 0;
}
.avatar[data-tone="blue"] {
background: var(--blue);
}
.avatar[data-tone="violet"] {
background: var(--violet);
}
.avatar[data-tone="green"] {
background: var(--green);
}
.avatar[data-tone="coral"] {
background: var(--coral);
}
.avatar[data-tone="amber"] {
background: var(--amber);
}
/* ===== 반응형 (원본 786~800행) ===== */
@media (max-width: 720px) {
.shell-page {
padding: 0 14px 30px;
}
.topbar {
margin: 0 -14px;
padding: 0 16px;
gap: 14px;
}
/* 원본은 모바일에서 .mainnav { display:none } 이지만,
MVP에선 가로 스크롤 유지가 더 유용하므로 §6.4 결정에 따라 유지한다. */
.rail {
flex-direction: row;
position: static;
overflow-x: auto;
width: 100%;
}
}