first commit

This commit is contained in:
2026-06-16 17:12:08 +09:00
commit e1bc5a1dfc
257 changed files with 49823 additions and 0 deletions
+598
View File
@@ -0,0 +1,598 @@
/**
* Relay 디자인 시스템 — 전역 스타일
* - 디자인 토큰(CSS 변수)과 화면 전반에서 공유하는 공통 컴포넌트 클래스를 정의한다.
* - 시안(px) → rem 변환(기준 16px = 1rem). 단, 1px 경계선/그림자는 px 유지(헤어라인 관례).
* - 화면 고유 스타일은 각 SFC 의 <style scoped> 에 둔다.
*/
/* ============================================================
* 1. 디자인 토큰
* ============================================================ */
:root {
/* 표면 / 경계 */
--bg: #f4f5f7;
--panel: #ffffff;
--border: #e6e8ec;
--border-strong: #d7dae0;
/* 텍스트 */
--text: #16181d;
--text-2: #5b626e;
--text-3: #9298a3;
/* 강조(보라) */
--accent: #4f46e5;
--accent-hover: #4338ca;
--accent-weak: #eef0fe;
--accent-border: #c7ccfb;
/* 상태 색상 */
--green: #1f9d57;
--green-weak: #e8f6ee;
--green-border: #cde8d8;
--blue: #1d4ed8;
--blue-weak: #e8efff;
--blue-border: #c9dbff;
--red: #d6455d;
--red-weak: #fdeef0;
--red-border: #f1c0c8;
--amber: #b7791f;
--amber-weak: #fdf4e3;
--amber-border: #f3e2bd;
/* 소셜 */
--kakao: #fee500;
--kakao-text: #191600;
/* 형태 */
--radius: 6px;
--radius-sm: 4px;
/* 그림자 */
--shadow-sm: 0 1px 2px rgba(20, 24, 33, 0.05);
--shadow-md: 0 4px 16px rgba(20, 24, 33, 0.1), 0 1px 3px rgba(20, 24, 33, 0.06);
--shadow-pop: 0 8px 28px rgba(20, 24, 33, 0.16), 0 2px 6px rgba(20, 24, 33, 0.08);
}
/* ============================================================
* 2. 리셋 / 베이스
* ============================================================ */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
background: var(--bg);
color: var(--text);
font-family: 'Pretendard', -apple-system, system-ui, sans-serif;
font-size: 14px; /* 기준 본문 크기(시안 기준) */
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
body {
min-height: 100vh;
}
#app {
min-height: 100vh;
}
/* ============================================================
* 3. 페이지 컨테이너 / 브레드크럼
* ============================================================ */
.page {
max-width: 67.5rem; /* 1080px */
margin: 0 auto;
padding: 0 1.5rem 4.375rem;
}
.crumb {
display: flex;
align-items: center;
gap: 0.4375rem;
color: var(--text-3);
font-size: 0.781rem;
padding: 1.125rem 0 0;
white-space: nowrap;
}
.crumb .lnk {
color: var(--text-2);
font-weight: 600;
text-decoration: none;
}
.crumb .lnk:hover {
color: var(--accent);
}
.crumb .sep {
opacity: 0.5;
}
.crumb b {
color: var(--text-2);
font-weight: 600;
}
/* ============================================================
* 4. 버튼
* ============================================================ */
.btn {
height: 2.25rem;
padding: 0 0.9375rem;
border-radius: var(--radius);
font-size: 0.844rem;
font-weight: 600;
border: 1px solid var(--border-strong);
background: var(--panel);
color: var(--text-2);
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 0.375rem;
line-height: 1;
text-decoration: none;
white-space: nowrap;
font-family: inherit;
}
.btn:hover {
background: #f7f8fa;
color: var(--text);
}
.btn svg {
width: 0.9375rem;
height: 0.9375rem;
}
.btn.primary {
background: var(--accent);
border-color: var(--accent);
color: #fff;
box-shadow: 0 1px 2px rgba(79, 70, 229, 0.4);
}
.btn.primary:hover {
background: var(--accent-hover);
border-color: var(--accent-hover);
color: #fff;
}
.btn.ghost {
border-color: transparent;
background: transparent;
}
.btn.ghost:hover {
background: #eceef1;
}
.btn.sm {
height: 1.875rem;
padding: 0 0.75rem;
font-size: 0.781rem;
}
.btn.icon {
width: 2.125rem;
padding: 0;
justify-content: center;
}
/* ============================================================
* 5. 아바타
* ============================================================ */
.avatar {
width: 1.3125rem;
height: 1.3125rem;
border-radius: 50%;
display: grid;
place-items: center;
font-size: 0.625rem;
font-weight: 700;
color: #fff;
flex-shrink: 0;
}
.av-a {
background: #e0518d;
}
.av-b {
background: #3d8bf2;
}
.av-c {
background: #16a37b;
}
.av-d {
background: #b3631f;
}
.av-e {
background: #7c5cf0;
}
.av-f {
background: #d0982a;
}
.av-more {
background: #eceef1;
color: var(--text-2);
box-shadow: 0 0 0 2px #fff;
}
/* 겹쳐 쌓는 아바타 스택 */
.avstack {
display: flex;
align-items: center;
}
.avstack .avatar {
margin-left: -0.4375rem;
box-shadow: 0 0 0 2px #fff;
}
.avstack .avatar:first-child {
margin-left: 0;
}
/* ============================================================
* 6. 상태 배지 / 상태 점 / 공개여부 배지 / 카운트 필
* ============================================================ */
.st-badge {
font-size: 0.719rem;
font-weight: 600;
padding: 0.1875rem 0.625rem;
border-radius: 20px;
white-space: nowrap;
text-align: center;
}
.st-badge.prog {
color: var(--blue);
background: var(--blue-weak);
}
.st-badge.review {
color: var(--amber);
background: var(--amber-weak);
}
.st-badge.changes {
color: var(--red);
background: var(--red-weak);
}
.st-badge.done {
color: var(--green);
background: var(--green-weak);
}
.st-badge.todo {
color: var(--text-2);
background: #f1f2f4;
}
/* 상태 점(목록/그룹 헤더 공용) */
.st-dot {
width: 0.5625rem;
height: 0.5625rem;
border-radius: 50%;
flex-shrink: 0;
}
.st-dot.done {
background: var(--green);
}
.st-dot.prog {
background: var(--blue);
}
.st-dot.review {
background: var(--amber);
}
.st-dot.todo {
background: #c4c8cf;
}
.st-dot.changes {
background: var(--red);
}
/* 공개여부 배지 */
.vis {
font-size: 0.6875rem;
font-weight: 600;
padding: 0.125rem 0.5rem;
border-radius: 20px;
display: inline-flex;
align-items: center;
gap: 0.25rem;
white-space: nowrap;
line-height: 1.5;
}
.vis svg {
width: 0.6875rem;
height: 0.6875rem;
}
.vis.private {
color: var(--text-2);
background: #f1f2f4;
border: 1px solid var(--border);
}
.vis.public {
color: #1b7a3d;
background: var(--green-weak);
border: 1px solid var(--green-border);
}
/* 카운트 필 */
.count-pill {
font-size: 0.8125rem;
font-weight: 600;
color: var(--text-2);
background: #f1f2f4;
border: 1px solid var(--border);
border-radius: 20px;
padding: 0.125rem 0.6875rem;
}
/* ============================================================
* 7. 진행률 바
* ============================================================ */
.pbar {
height: 0.375rem;
border-radius: 4px;
background: #eceef1;
overflow: hidden;
}
.pbar > i {
display: block;
height: 100%;
border-radius: 4px;
background: var(--green);
}
.pbar > i.mid {
background: var(--accent);
}
.pbar > i.low {
background: var(--amber);
}
/* ============================================================
* 8. 툴바 구성요소 (검색 / 세그먼트 / 정렬)
* ============================================================ */
.toolbar {
display: flex;
align-items: center;
gap: 0.625rem;
margin-bottom: 0.875rem;
}
.search {
display: flex;
align-items: center;
gap: 0.5rem;
height: 2.25rem;
border: 1px solid var(--border-strong);
border-radius: var(--radius);
padding: 0 0.6875rem;
background: #fff;
width: 17.5rem;
}
.search:focus-within {
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-weak);
}
.search svg {
width: 1rem;
height: 1rem;
color: var(--text-3);
}
.search input {
border: none;
outline: none;
flex: 1;
min-width: 0;
font-family: inherit;
font-size: 0.844rem;
background: transparent;
}
.search input::placeholder {
color: var(--text-3);
}
.segmented {
display: flex;
background: #eceef1;
border-radius: var(--radius);
padding: 0.1875rem;
gap: 0.125rem;
}
.segmented button {
border: none;
background: transparent;
font-family: inherit;
font-size: 0.8125rem;
font-weight: 600;
color: var(--text-2);
padding: 0.3125rem 0.8125rem;
border-radius: 4px;
cursor: pointer;
white-space: nowrap;
display: flex;
align-items: center;
gap: 0.375rem;
}
.segmented button.active {
background: #fff;
color: var(--text);
box-shadow: var(--shadow-sm);
}
.segmented button .n {
font-size: 0.6875rem;
color: var(--text-3);
font-weight: 600;
}
.segmented button.active .n {
color: var(--accent);
}
.sort {
margin-left: auto;
display: flex;
align-items: center;
gap: 0.375rem;
height: 2.25rem;
border: 1px solid var(--border-strong);
border-radius: var(--radius);
padding: 0 0.6875rem;
background: #fff;
font-size: 0.8125rem;
font-weight: 500;
color: var(--text-2);
cursor: pointer;
white-space: nowrap;
}
.sort svg {
width: 0.9375rem;
height: 0.9375rem;
color: var(--text-3);
}
/* ============================================================
* 9. 카드 / 목록 컨테이너
* ============================================================ */
.card {
background: var(--panel);
border: 1px solid var(--border);
border-radius: 0.625rem;
box-shadow: var(--shadow-sm);
}
.list {
background: var(--panel);
border: 1px solid var(--border);
border-radius: 0.625rem;
box-shadow: var(--shadow-sm);
overflow: hidden;
}
/* ============================================================
* 10. 모달 공통 백드롭 (세부 모달은 각 화면에서 정의)
* ============================================================ */
.modal-backdrop {
position: fixed;
inset: 0;
background: rgba(20, 24, 33, 0.5);
display: none;
align-items: center;
justify-content: center;
z-index: 100;
padding: 1.5rem;
}
.modal-backdrop.open {
display: flex;
}
.modal {
width: 100%;
max-width: 27.5rem;
background: #fff;
border-radius: 0.875rem;
box-shadow: 0 24px 64px rgba(20, 24, 33, 0.32);
overflow: hidden;
}
.modal-body {
padding: 1.625rem 1.5rem 0.5rem;
text-align: center;
}
.modal-body.left {
text-align: left;
padding: 1.375rem 1.5rem 0.5rem;
}
.modal-ico {
width: 2.875rem;
height: 2.875rem;
border-radius: 50%;
background: var(--red-weak);
color: var(--red);
display: grid;
place-items: center;
margin: 0 auto 0.875rem;
}
.modal-ico.approve {
background: var(--green-weak);
color: var(--green);
}
.modal-ico svg {
width: 1.375rem;
height: 1.375rem;
}
.modal-title {
font-size: 1.0625rem;
font-weight: 700;
letter-spacing: -0.01875rem;
}
.modal-desc {
font-size: 0.8125rem;
color: var(--text-2);
line-height: 1.6;
margin-top: 0.5rem;
}
.modal-desc.spaced {
margin: 0.5rem 0 0.875rem;
}
.modal-desc b {
color: var(--text);
font-weight: 600;
}
.modal-foot {
display: flex;
gap: 0.5625rem;
padding: 1.125rem 1.5rem 1.25rem;
}
.mbtn {
flex: 1;
height: 2.5rem;
border-radius: var(--radius);
font-size: 0.844rem;
font-weight: 600;
border: 1px solid var(--border-strong);
background: #fff;
color: var(--text-2);
cursor: pointer;
font-family: inherit;
}
.mbtn:hover {
background: #f1f2f4;
color: var(--text);
}
.mbtn.danger {
background: var(--red);
border-color: var(--red);
color: #fff;
box-shadow: 0 1px 2px rgba(214, 69, 93, 0.4);
}
.mbtn.danger:hover {
background: #c23a51;
}
.mbtn.approve {
background: var(--green);
border-color: var(--green);
color: #fff;
box-shadow: 0 1px 2px rgba(31, 157, 87, 0.4);
}
.mbtn.approve:hover {
background: #188a4b;
}
.mbtn.request-send {
background: var(--accent);
border-color: var(--accent);
color: #fff;
box-shadow: 0 1px 2px rgba(79, 70, 229, 0.4);
}
.mbtn.request-send:hover {
background: var(--accent-hover);
}
.modal-textarea {
width: 100%;
min-height: 5.75rem;
border: 1px solid var(--border-strong);
border-radius: var(--radius);
padding: 0.625rem 0.75rem;
font-family: inherit;
font-size: 0.844rem;
line-height: 1.6;
color: var(--text);
resize: vertical;
}
.modal-textarea:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-weak);
}
.modal-textarea::placeholder {
color: var(--text-3);
}