style(project): 아사나 느낌 색상/카드 디자인 + 사이드바·리스트·타임라인 개편

색상/폰트/카드/사이드바/리스트/타임라인이 아사나와 다르다는 피드백 반영.

- 보라 포인트 컬러(--pj-accent) 도입 — 기본 검정 버튼/활성 탭을 이걸로
  교체(erp.css 등 다른 모듈은 안 건드림, .pj- 클래스 범위 안에서만).
- 카드(.pj-card, .pj-project-card)·보드 컬럼 라운드/그림자 키워 아사나
  카드 느낌으로.
- 왼쪽 사이드바 — 프로젝트마다 업무를 중첩해서 보여주던 트리를 걷어내고
  아사나처럼 "프로젝트 이름 목록만"으로 단순화. 폴더 아이콘 대신 프로젝트
  색 + 첫 글자 아바타.
- 리스트 뷰("이 프로젝트" 스코프) — 세션이 컬럼이 아니라 아사나처럼 그룹
  구분선이 되도록 개편(세션별로 묶어서 보여주고 접기/펼치기, 개수 표시).
  "전체 프로젝트" 스코프는 세션이 프로젝트마다 달라 그룹화 의미가 없으므로
  기존 프로젝트/세션 컬럼 있는 평범한 정렬 테이블 유지.
- 타임라인 — "이 프로젝트" 스코프에서는 프로젝트가 아니라 세션별로 행(스윔
  레인)을 나눔(아사나 타임라인=섹션 단위). "전체 프로젝트"는 기존처럼
  프로젝트별.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 20:05:34 +09:00
parent 3ca0b1de87
commit 9c07aefb29
5 changed files with 222 additions and 195 deletions
+66 -35
View File
@@ -1,17 +1,30 @@
/* 프로젝트 관리(아사나식) 모듈 스타일.
* 기존 erp.css 토큰 위에 아사나 느낌(밝은 캔버스, 색 점, 칸반 컬럼)을 얹는다. */
* 기존 erp.css 토큰(폰트 등) 위에 아사나 느낌의 색·카드·그림자를 별도 변수로
* 얹는다 — 다른 모듈(erp.css)은 그대로 두고 이 모듈(.pj- 클래스)에만 적용. */
.pj-wrap { padding: 4px 2px 40px; }
:root {
--pj-accent: #7b68ee; /* 아사나 특유의 보라 포인트 컬러 */
--pj-accent-dark: #6453d6;
--pj-accent-tint: #f1eeff; /* 선택/호버 배경(연한 보라) */
--pj-ink: #151b26; /* 본문 텍스트(진한 남색 계열, 순검정 대신) */
--pj-ink-soft: #6b6f76; /* 보조 텍스트 */
--pj-border: #e4e4e7;
--pj-card-radius: 12px;
--pj-card-shadow: 0 1px 2px rgba(16,24,40,.04), 0 2px 6px rgba(16,24,40,.06);
--pj-card-shadow-hover: 0 6px 16px rgba(16,24,40,.10), 0 2px 4px rgba(16,24,40,.06);
}
.pj-wrap { padding: 4px 2px 40px; color: var(--pj-ink); }
/* ── 버튼 ── */
.pj-btn {
border: 1px solid #d8dce2; background: #fff; color: #1e1f21;
border: 1px solid #d8dce2; background: #fff; color: var(--pj-ink);
padding: 7px 14px; border-radius: 8px; font-size: 13px; font-weight: 600;
cursor: pointer; transition: background .12s, border-color .12s;
}
.pj-btn:hover { background: #f6f7f8; }
.pj-btn-primary { background: #1e1f21; color: #fff; border-color: #1e1f21; }
.pj-btn-primary:hover { background: #000; }
.pj-btn-primary { background: var(--pj-accent); color: #fff; border-color: var(--pj-accent); }
.pj-btn-primary:hover { background: var(--pj-accent-dark); border-color: var(--pj-accent-dark); }
.pj-btn-danger { background: #fff; color: #c22b10; border-color: #e6c4bd; }
.pj-btn-danger:hover { background: #fbecea; }
.pj-icon-btn {
@@ -36,10 +49,10 @@
.pj-project-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; align-items: start; }
.pj-project-card {
position: relative; border: 1px solid #e7e9ec; border-radius: 14px;
background: #fff; transition: box-shadow .14s, transform .1s;
position: relative; border: 1px solid var(--pj-border); border-radius: var(--pj-card-radius);
background: #fff; box-shadow: var(--pj-card-shadow); transition: box-shadow .14s, transform .1s;
}
.pj-project-card:hover { box-shadow: 0 4px 16px rgba(0,0,0,.08); transform: translateY(-1px); }
.pj-project-card:hover { box-shadow: var(--pj-card-shadow-hover); transform: translateY(-1px); }
.pj-project-cardlink { display: flex; gap: 12px; padding: 16px; text-decoration: none; color: inherit; }
/* 완료 프로젝트 — 비활성(흐리게) */
.pj-project-card.is-done { background: #f6f7f8; opacity: .62; }
@@ -124,28 +137,24 @@
.pj-member-list li:hover { background: #f6f7f8; }
.pj-member-name { font-size: 13px; flex: 1; }
/* ── 아사나식 프로젝트 트리 ── */
/* ── 아사나식 프로젝트 트리(사이드바) — 프로젝트 이름만 나열, 업무 목록 없음 ── */
.pj-tree { list-style: none; margin: 0; padding: 0; }
.pj-tree .pj-tree { padding-left: 0; } /* 들여쓰기는 row 패딩으로 처리 */
.pj-tree-row { display: flex; align-items: center; gap: 2px; border-radius: 7px; padding-right: 2px;
padding-left: calc(var(--pj-indent, 0) * 16px); position: relative; }
.pj-tree-row { display: flex; align-items: center; gap: 2px; border-radius: 8px; padding-right: 2px; position: relative; }
.pj-tree-row:hover { background: #f1f2f4; }
.pj-tree-row.is-active { background: #ececf8; }
.pj-tree-row.is-active .pj-tree-name { font-weight: 700; color: #1e1f21; }
.pj-tree-caret { border: none; background: transparent; cursor: pointer; width: 20px; height: 26px;
display: inline-flex; align-items: center; justify-content: center; color: #6b7280; padding: 0; }
.pj-tree-caret .material-symbols-outlined { font-size: 18px; transition: transform .12s; }
.pj-tree-caret.is-open .material-symbols-outlined { transform: rotate(90deg); }
.pj-tree-caret-spacer { width: 20px; flex: 0 0 auto; }
.pj-tree-link { display: flex; align-items: center; gap: 7px; flex: 1; min-width: 0;
text-decoration: none; color: inherit; padding: 5px 2px; }
.pj-tree-icon { font-size: 18px; flex: 0 0 auto; }
.pj-tree-row.is-active { background: var(--pj-accent-tint); }
.pj-tree-row.is-active .pj-tree-name { font-weight: 700; color: var(--pj-accent-dark); }
.pj-tree-link { display: flex; align-items: center; gap: 9px; flex: 1; min-width: 0;
text-decoration: none; color: inherit; padding: 6px 4px; }
/* 프로젝트 색 + 첫 글자 — 아사나의 색 아이콘 자리를 대신한다 */
.pj-tree-avatar {
width: 22px; height: 22px; border-radius: 6px; flex: 0 0 auto;
display: inline-flex; align-items: center; justify-content: center;
color: #fff; font-size: 11px; font-weight: 700;
}
.pj-tree-name { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pj-tree-acts { display: none; gap: 0; flex: 0 0 auto; }
.pj-tree-row:hover .pj-tree-acts { display: inline-flex; }
.pj-tree-acts .pj-icon-btn { width: 22px; height: 22px; font-size: 14px; }
.pj-tree-done { text-decoration: line-through; color: #9aa1a9; }
.pj-tree-task .pj-tree-name { font-size: 13px; color: #444; }
/* 구글 머티리얼 심볼 아이콘(담당자) */
.material-symbols-outlined { font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24; line-height: 1; vertical-align: middle; }
@@ -160,7 +169,7 @@
.pj-toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.pj-view-tabs { display: inline-flex; background: #eef0f2; border-radius: 10px; padding: 3px; gap: 2px; }
.pj-tab { border: none; background: transparent; padding: 7px 16px; border-radius: 8px; font-size: 13px; font-weight: 600; color: #525860; cursor: pointer; }
.pj-tab.is-active { background: #1e1f21; color: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.18); }
.pj-tab.is-active { background: var(--pj-accent); color: #fff; box-shadow: 0 1px 3px rgba(123,104,238,.35); }
/* 알림 벨 흔들림(미읽음 있을 때) */
@keyframes pj-bell-ring {
@@ -174,19 +183,27 @@
}
/* ── 보드(칸반) ── */
.pj-board { display: flex; gap: 14px; overflow-x: auto; padding-bottom: 8px; align-items: flex-start; }
.pj-col { flex: 0 0 272px; background: #f7f8f9; border-radius: 12px; padding: 10px; }
.pj-col-head { display: flex; align-items: center; gap: 6px; font-weight: 700; font-size: 13px; padding: 4px 6px 10px; }
.pj-col-count { margin-left: auto; color: #9aa1a9; font-weight: 600; }
.pj-board { display: flex; gap: 16px; overflow-x: auto; padding-bottom: 8px; align-items: flex-start; }
.pj-col { flex: 0 0 280px; background: #f6f5fb; border-radius: 14px; padding: 12px; }
.pj-col-head { display: flex; align-items: center; gap: 6px; font-weight: 700; font-size: 13px; padding: 2px 6px 12px; color: var(--pj-ink); }
.pj-col-count {
margin-left: auto; color: var(--pj-ink-soft); font-weight: 700; font-size: 11px;
background: #fff; border-radius: 999px; min-width: 20px; height: 20px; padding: 0 6px;
display: inline-flex; align-items: center; justify-content: center;
}
.pj-col-body { display: flex; flex-direction: column; gap: 8px; min-height: 40px; border-radius: 8px; }
.pj-col-body.is-over { background: #e6ecfa; outline: 2px dashed #aebfe6; }
.pj-card { background: #fff; border: 1px solid #e7e9ec; border-radius: 10px; padding: 10px 12px; cursor: pointer; box-shadow: 0 1px 2px rgba(0,0,0,.04); }
.pj-card:hover { border-color: #c9cdd3; }
.pj-col-body.is-over { background: var(--pj-accent-tint); outline: 2px dashed var(--pj-accent); }
.pj-card {
background: #fff; border: 1px solid var(--pj-border); border-radius: var(--pj-card-radius);
padding: 12px 14px; cursor: pointer; box-shadow: var(--pj-card-shadow);
transition: box-shadow .12s, transform .08s;
}
.pj-card:hover { box-shadow: var(--pj-card-shadow-hover); transform: translateY(-1px); }
.pj-card.is-dragging { opacity: .5; }
.pj-card.is-done .pj-card-title { text-decoration: line-through; color: #9aa1a9; }
.pj-card-title { font-size: 13.5px; font-weight: 600; }
.pj-card-meta { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.pj-card-due { margin-left: auto; font-size: 11px; color: #9aa1a9; }
.pj-card-title { font-size: 13.5px; font-weight: 600; color: var(--pj-ink); line-height: 1.4; }
.pj-card-meta { display: flex; align-items: center; gap: 6px; margin-top: 10px; }
.pj-card-due { margin-left: auto; font-size: 11px; color: var(--pj-ink-soft); font-weight: 600; }
.pj-pri { padding: 1px 7px; border-radius: 999px; font-size: 10px; font-weight: 700; }
.pj-pri-high { background: #fbe3df; color: #c22b10; }
.pj-pri-low { background: #e6eef0; color: #4a6066; }
@@ -198,6 +215,20 @@
.pj-table tr.is-done td { color: #9aa1a9; text-decoration: line-through; }
.pj-table-fixed { table-layout: fixed; }
.pj-table-fixed th, .pj-table-fixed td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 리스트 뷰(이 프로젝트 스코프) — 세션이 컬럼 대신 그룹 구분선이 된다(아사나식) */
.pj-list-group-row { background: #fafafd; }
.pj-list-group-head {
display: flex; align-items: center; gap: 6px; padding: 10px 6px !important;
font-size: 13px; font-weight: 700; color: var(--pj-ink); cursor: pointer;
border-bottom: 1px solid var(--pj-border) !important; white-space: nowrap;
}
.pj-list-group-caret { font-size: 18px; color: var(--pj-ink-soft); }
.pj-list-group-count {
color: var(--pj-ink-soft); font-weight: 700; font-size: 11px; background: #eef0f2;
border-radius: 999px; min-width: 20px; height: 20px; padding: 0 6px;
display: inline-flex; align-items: center; justify-content: center;
}
.pj-th-label { cursor: pointer; user-select: none; display: inline-flex; align-items: center; gap: 4px; }
.pj-th-label:hover { color: #4573d2; }
.pj-th-sort { font-size: 11px; color: #9aa1a9; }