first commit
This commit is contained in:
@@ -0,0 +1,329 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>내 업무 · 지시한 업무 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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;
|
||||
--blue: #1d4ed8; --blue-weak: #e8efff; --blue-border: #c9dbff;
|
||||
--red: #d6455d; --red-weak: #fdeef0; --red-border: #f1c0c8;
|
||||
--amber: #b7791f; --amber-weak: #fdf4e3; --amber-border: #f3e2bd;
|
||||
--radius: 6px; --radius-sm: 4px; --shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* topbar */
|
||||
.topbar { height: 52px; background: var(--panel); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 28px; padding: 0 20px; position: sticky; top: 0; z-index: 50; }
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo { width: 26px; height: 26px; border-radius: 7px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; box-shadow: 0 2px 6px rgba(79,70,229,.35); }
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a { color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500; padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap; }
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px; }
|
||||
|
||||
/* page */
|
||||
.page { max-width: 1040px; margin: 0 auto; padding: 0 24px 70px; }
|
||||
.pagehead { display: flex; align-items: flex-end; gap: 12px; padding: 24px 0 16px; }
|
||||
.pagehead h1 { font-size: 22px; font-weight: 700; letter-spacing: -.4px; white-space: nowrap; }
|
||||
.pagehead .sub { font-size: 13px; color: var(--text-2); padding-bottom: 2px; white-space: nowrap; }
|
||||
.pagehead .new-btn { margin-left: auto; height: 36px; padding: 0 15px; border-radius: var(--radius); font-size: 13.5px; font-weight: 600; border: 1px solid var(--accent); background: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; text-decoration: none; white-space: nowrap; }
|
||||
.pagehead .new-btn:hover { background: var(--accent-hover); }
|
||||
.pagehead .new-btn svg { width: 15px; height: 15px; }
|
||||
|
||||
/* view toggle (담당 / 지시) */
|
||||
.viewtabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 18px; }
|
||||
.viewtab { display: flex; align-items: center; gap: 8px; padding: 10px 4px; margin-right: 18px; font-size: 14px; font-weight: 600; color: var(--text-2); background: none; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; white-space: nowrap; text-decoration: none; }
|
||||
.viewtab:hover { color: var(--text); }
|
||||
.viewtab.active { color: var(--accent); border-bottom-color: var(--accent); }
|
||||
.viewtab .vt-count { font-size: 11px; font-weight: 600; color: var(--text-2); background: #f1f2f4; border-radius: 20px; height: 17px; min-width: 17px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
|
||||
.viewtab.active .vt-count { background: var(--accent-weak); color: var(--accent); }
|
||||
.viewtab .vt-flag { font-size: 11px; font-weight: 600; color: var(--amber); background: var(--amber-weak); border: 1px solid var(--amber-border); border-radius: 20px; padding: 1px 7px; line-height: 1.4; white-space: nowrap; }
|
||||
|
||||
/* toolbar */
|
||||
.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
|
||||
.search { display: flex; align-items: center; gap: 8px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; width: 260px; }
|
||||
.search:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.search svg { width: 16px; height: 16px; color: var(--text-3); }
|
||||
.search input { border: none; outline: none; flex: 1; min-width: 0; font-family: inherit; font-size: 13.5px; background: transparent; }
|
||||
.search input::placeholder { color: var(--text-3); }
|
||||
.repofilter { display: flex; align-items: center; gap: 7px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; font-size: 13px; font-weight: 500; color: var(--text-2); cursor: pointer; white-space: nowrap; }
|
||||
.repofilter svg { width: 15px; height: 15px; color: var(--text-3); }
|
||||
.sort { margin-left: auto; display: flex; align-items: center; gap: 6px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; font-size: 13px; font-weight: 500; color: var(--text-2); cursor: pointer; white-space: nowrap; }
|
||||
.sort svg { width: 15px; height: 15px; color: var(--text-3); }
|
||||
|
||||
/* highlight banner for pending approvals */
|
||||
.pending-note { display: flex; align-items: center; gap: 10px; padding: 11px 15px; background: var(--amber-weak); border: 1px solid var(--amber-border); border-radius: 9px; margin-bottom: 22px; font-size: 13px; color: #8a5a12; }
|
||||
.pending-note svg { width: 17px; height: 17px; color: var(--amber); flex-shrink: 0; }
|
||||
.pending-note span { white-space: nowrap; }
|
||||
.pending-note b { font-weight: 700; }
|
||||
|
||||
/* status group */
|
||||
.group { margin-bottom: 22px; }
|
||||
.group-head { display: flex; align-items: center; gap: 9px; margin-bottom: 9px; padding-left: 2px; }
|
||||
.gh-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
|
||||
.gh-dot.changes { background: var(--red); } .gh-dot.prog { background: var(--blue); }
|
||||
.gh-dot.todo { background: #c4c8cf; } .gh-dot.review { background: var(--amber); } .gh-dot.done { background: var(--green); }
|
||||
.gh-label { font-size: 13px; font-weight: 700; color: var(--text); white-space: nowrap; }
|
||||
.gh-count { font-size: 11.5px; font-weight: 600; color: var(--text-2); background: #eceef1; border-radius: 20px; height: 18px; min-width: 18px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
|
||||
.gh-action { margin-left: 4px; font-size: 11.5px; font-weight: 600; color: var(--amber); white-space: nowrap; }
|
||||
|
||||
/* list + rows */
|
||||
.list { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-sm); overflow: hidden; }
|
||||
.list.attn { border-color: var(--amber-border); box-shadow: 0 0 0 3px rgba(183,121,31,.08), var(--shadow-sm); }
|
||||
.task-row { display: flex; align-items: center; gap: 14px; padding: 13px 18px; border-top: 1px solid var(--border); cursor: pointer; text-decoration: none; color: inherit; }
|
||||
.task-row:first-child { border-top: none; }
|
||||
.task-row:hover { background: #fafbfc; }
|
||||
.st-dot { width: 9px; height: 9px; 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); }
|
||||
.task-main { flex: 1; min-width: 0; }
|
||||
.task-title { font-size: 14px; font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 8px; }
|
||||
.task-title .ttext { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.task-title .tid { font-size: 12px; font-weight: 600; color: var(--text-3); flex-shrink: 0; }
|
||||
.task-row:hover .task-title .ttext { color: var(--accent); }
|
||||
.task-row.is-done .task-title { color: var(--text-2); }
|
||||
.task-meta { display: flex; align-items: center; gap: 12px; margin-top: 4px; font-size: 12px; color: var(--text-3); }
|
||||
.repo-chip { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
|
||||
.repo-chip svg { width: 13px; height: 13px; color: var(--accent); flex-shrink: 0; }
|
||||
.mi { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
|
||||
.mi svg { width: 13px; height: 13px; }
|
||||
.mi.attn { color: var(--amber); font-weight: 600; }
|
||||
.meta-sep { width: 3px; height: 3px; border-radius: 50%; background: #d7dae0; flex-shrink: 0; }
|
||||
|
||||
/* assignee avatars */
|
||||
.mini-stack { display: inline-flex; align-items: center; }
|
||||
.mini-av { width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; font-size: 9px; font-weight: 700; color: #fff; box-shadow: 0 0 0 1.5px #fff; flex-shrink: 0; }
|
||||
.mini-stack .mini-av + .mini-av { margin-left: -5px; }
|
||||
.av-a { background: #e0518d; } .av-b { background: #3d8bf2; } .av-c { background: #16a37b; }
|
||||
.av-d { background: #b3631f; } .av-e { background: #7c5cf0; } .av-f { background: #d0982a; }
|
||||
|
||||
.task-right { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }
|
||||
.due { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-2); font-weight: 500; white-space: nowrap; }
|
||||
.due svg { width: 14px; height: 14px; color: var(--text-3); }
|
||||
.due.overdue { color: var(--red); font-weight: 600; }
|
||||
.due.overdue svg { color: var(--red); }
|
||||
.dday { font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 20px; white-space: nowrap; line-height: 1.5; }
|
||||
.dday.urgent { color: var(--red); background: var(--red-weak); border: 1px solid var(--red-border); }
|
||||
.dday.soon { color: var(--amber); background: var(--amber-weak); border: 1px solid var(--amber-border); }
|
||||
.dday.calm { color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); }
|
||||
.st-badge { font-size: 11.5px; font-weight: 600; padding: 3px 10px; border-radius: 20px; white-space: nowrap; min-width: 64px; 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; }
|
||||
/* action button on pending-approval rows */
|
||||
.review-btn { font-size: 12px; font-weight: 600; color: #fff; background: var(--amber); border: 1px solid var(--amber); border-radius: var(--radius); padding: 5px 11px; white-space: nowrap; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="내 업무.html" class="active">내 업무</a>
|
||||
<a href="저장소 목록.html">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg></button>
|
||||
<button class="icon-btn" title="알림"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg></button>
|
||||
<div class="me">정</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page" data-screen-label="내 업무 · 지시한 업무">
|
||||
<div class="pagehead">
|
||||
<h1>내 업무</h1>
|
||||
<span class="sub">나에게 배정되었거나 내가 지시한 업무를 한곳에서 관리하세요.</span>
|
||||
<a class="new-btn" href="업무 작성.html"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5v14"/></svg>새 업무 지시</a>
|
||||
</div>
|
||||
|
||||
<!-- 담당 / 지시 토글 -->
|
||||
<div class="viewtabs">
|
||||
<a class="viewtab" href="내 업무.html"><span class="tb-label">담당 업무</span> <span class="vt-count">6</span></a>
|
||||
<a class="viewtab active" href="내 업무 (지시한 업무).html"><span class="tb-label">지시한 업무</span> <span class="vt-count">5</span> <span class="vt-flag">승인 대기 1</span></a>
|
||||
</div>
|
||||
|
||||
<!-- 툴바 -->
|
||||
<div class="toolbar">
|
||||
<div class="search">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>
|
||||
<input type="text" placeholder="업무 검색…">
|
||||
</div>
|
||||
<div class="repofilter">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
|
||||
모든 저장소
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 5h10M11 9h7M11 13h4M3 17l3 3 3-3M6 18V4"/></svg>
|
||||
마감 임박순
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 승인 대기 강조 배너 -->
|
||||
<div class="pending-note">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 8v4l3 2"/><circle cx="12" cy="12" r="9"/></svg>
|
||||
<span><b>1건</b>의 업무가 내 승인을 기다리고 있어요. 검토 후 승인하거나 수정을 요청하세요.</span>
|
||||
</div>
|
||||
|
||||
<!-- 승인 대기 (내가 결정) -->
|
||||
<div class="group">
|
||||
<div class="group-head"><span class="gh-dot review"></span><span class="gh-label">승인 대기</span><span class="gh-count">1</span><span class="gh-action">· 내 승인 필요</span></div>
|
||||
<div class="list attn">
|
||||
<a class="task-row" href="업무 상세.html">
|
||||
<span class="st-dot review"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">메인 배너 이미지 2종 (가로/세로) 디자인</span> <span class="tid">#9</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>3분기 신제품 런칭 캠페인</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi"><span class="mini-stack"><span class="mini-av av-b">박</span><span class="mini-av av-d">최</span></span></span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi attn">박지훈님이 2시간 전 승인 요청</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>6월 18일 <span class="dday soon">D-3</span></span>
|
||||
<span class="review-btn">검토하기</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 진행 중 -->
|
||||
<div class="group">
|
||||
<div class="group-head"><span class="gh-dot prog"></span><span class="gh-label">진행 중</span><span class="gh-count">2</span></div>
|
||||
<div class="list">
|
||||
<a class="task-row" href="업무 상세.html">
|
||||
<span class="st-dot prog"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">법무 검토 요청 및 회신 반영</span> <span class="tid">#11</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>3분기 신제품 런칭 캠페인</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi"><span class="mini-stack"><span class="mini-av av-c">이</span></span> 이도윤</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due overdue"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>6월 12일 <span class="dday urgent">3일 지남</span></span>
|
||||
<span class="st-badge prog">진행 중</span>
|
||||
</span>
|
||||
</a>
|
||||
<a class="task-row" href="업무 상세.html">
|
||||
<span class="st-dot prog"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">SNS 콘텐츠 2차 시안 제작</span> <span class="tid">#16</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>3분기 신제품 런칭 캠페인</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>3/6</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi"><span class="mini-stack"><span class="mini-av av-e">정</span></span> 정민호</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>6월 19일 <span class="dday soon">D-4</span></span>
|
||||
<span class="st-badge prog">진행 중</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 수정 요청 -->
|
||||
<div class="group">
|
||||
<div class="group-head"><span class="gh-dot changes"></span><span class="gh-label">수정 요청함</span><span class="gh-count">1</span></div>
|
||||
<div class="list">
|
||||
<a class="task-row" href="업무 상세 (수정 요청).html">
|
||||
<span class="st-dot changes"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">상세페이지 카피라이팅</span> <span class="tid">#8</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>3분기 신제품 런칭 캠페인</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi"><span class="mini-stack"><span class="mini-av av-c">이</span></span> 이도윤에게 수정 요청 · 1일 전</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>6월 20일 <span class="dday soon">D-5</span></span>
|
||||
<span class="st-badge changes">수정 요청</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 할 일 -->
|
||||
<div class="group">
|
||||
<div class="group-head"><span class="gh-dot todo"></span><span class="gh-label">할 일</span><span class="gh-count">1</span></div>
|
||||
<div class="list">
|
||||
<a class="task-row" href="업무 상세.html">
|
||||
<span class="st-dot todo"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">SNS 콘텐츠 1차 시안</span> <span class="tid">#7</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>3분기 신제품 런칭 캠페인</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi"><span class="mini-stack"><span class="mini-av av-e">정</span></span> 정민호</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>6월 23일 <span class="dday calm">D-8</span></span>
|
||||
<span class="st-badge todo">할 일</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 완료 -->
|
||||
<div class="group">
|
||||
<div class="group-head"><span class="gh-dot done"></span><span class="gh-label">완료</span><span class="gh-count">2</span></div>
|
||||
<div class="list">
|
||||
<a class="task-row is-done" href="업무 상세 (승인 완료).html">
|
||||
<span class="st-dot done"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">캠페인 핵심 메시지 시안 작성</span> <span class="tid">#6</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>3분기 신제품 런칭 캠페인</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi"><span class="mini-stack"><span class="mini-av av-a">김</span></span> 김서연</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due">6월 9일 승인됨</span>
|
||||
<span class="st-badge done">완료</span>
|
||||
</span>
|
||||
</a>
|
||||
<a class="task-row is-done" href="업무 상세 (승인 완료).html">
|
||||
<span class="st-dot done"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">퍼포먼스 광고 소재 세팅</span> <span class="tid">#4</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>3분기 신제품 런칭 캠페인</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi"><span class="mini-stack"><span class="mini-av av-b">박</span></span> 박지훈</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due">6월 5일 승인됨</span>
|
||||
<span class="st-badge done">완료</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,314 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>내 업무 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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;
|
||||
--blue: #1d4ed8; --blue-weak: #e8efff; --blue-border: #c9dbff;
|
||||
--red: #d6455d; --red-weak: #fdeef0; --red-border: #f1c0c8;
|
||||
--amber: #b7791f; --amber-weak: #fdf4e3; --amber-border: #f3e2bd;
|
||||
--radius: 6px; --radius-sm: 4px; --shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* topbar */
|
||||
.topbar { height: 52px; background: var(--panel); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 28px; padding: 0 20px; position: sticky; top: 0; z-index: 50; }
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo { width: 26px; height: 26px; border-radius: 7px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; box-shadow: 0 2px 6px rgba(79,70,229,.35); }
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a { color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500; padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap; }
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px; }
|
||||
|
||||
/* page */
|
||||
.page { max-width: 1040px; margin: 0 auto; padding: 0 24px 70px; }
|
||||
.pagehead { display: flex; align-items: flex-end; gap: 12px; padding: 24px 0 16px; }
|
||||
.pagehead h1 { font-size: 22px; font-weight: 700; letter-spacing: -.4px; white-space: nowrap; }
|
||||
.pagehead .sub { font-size: 13px; color: var(--text-2); padding-bottom: 2px; white-space: nowrap; }
|
||||
|
||||
/* view toggle (담당 / 지시) */
|
||||
.viewtabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 18px; }
|
||||
.viewtab { display: flex; align-items: center; gap: 8px; padding: 10px 4px; margin-right: 18px; font-size: 14px; font-weight: 600; color: var(--text-2); background: none; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; white-space: nowrap; text-decoration: none; }
|
||||
.viewtab:hover { color: var(--text); }
|
||||
.viewtab.active { color: var(--accent); border-bottom-color: var(--accent); }
|
||||
.viewtab .vt-count { font-size: 11px; font-weight: 600; color: var(--text-2); background: #f1f2f4; border-radius: 20px; height: 17px; min-width: 17px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
|
||||
.viewtab.active .vt-count { background: var(--accent-weak); color: var(--accent); }
|
||||
.viewtab .vt-flag { font-size: 11px; font-weight: 600; color: var(--amber); background: var(--amber-weak); border: 1px solid var(--amber-border); border-radius: 20px; padding: 1px 7px; line-height: 1.4; white-space: nowrap; }
|
||||
|
||||
/* toolbar */
|
||||
.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
|
||||
.search { display: flex; align-items: center; gap: 8px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; width: 260px; }
|
||||
.search:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.search svg { width: 16px; height: 16px; color: var(--text-3); }
|
||||
.search input { border: none; outline: none; flex: 1; min-width: 0; font-family: inherit; font-size: 13.5px; background: transparent; }
|
||||
.search input::placeholder { color: var(--text-3); }
|
||||
.repofilter { display: flex; align-items: center; gap: 7px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; font-size: 13px; font-weight: 500; color: var(--text-2); cursor: pointer; white-space: nowrap; }
|
||||
.repofilter svg { width: 15px; height: 15px; color: var(--text-3); }
|
||||
.sort { margin-left: auto; display: flex; align-items: center; gap: 6px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; font-size: 13px; font-weight: 500; color: var(--text-2); cursor: pointer; white-space: nowrap; }
|
||||
.sort svg { width: 15px; height: 15px; color: var(--text-3); }
|
||||
|
||||
/* status group */
|
||||
.group { margin-bottom: 22px; }
|
||||
.group-head { display: flex; align-items: center; gap: 9px; margin-bottom: 9px; padding-left: 2px; }
|
||||
.gh-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
|
||||
.gh-dot.changes { background: var(--red); } .gh-dot.prog { background: var(--blue); }
|
||||
.gh-dot.todo { background: #c4c8cf; } .gh-dot.review { background: var(--amber); } .gh-dot.done { background: var(--green); }
|
||||
.gh-label { font-size: 13px; font-weight: 700; color: var(--text); white-space: nowrap; }
|
||||
.gh-count { font-size: 11.5px; font-weight: 600; color: var(--text-2); background: #eceef1; border-radius: 20px; height: 18px; min-width: 18px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
|
||||
|
||||
/* list + rows */
|
||||
.list { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-sm); overflow: hidden; }
|
||||
.task-row { display: flex; align-items: center; gap: 14px; padding: 13px 18px; border-top: 1px solid var(--border); cursor: pointer; text-decoration: none; color: inherit; }
|
||||
.task-row:first-child { border-top: none; }
|
||||
.task-row:hover { background: #fafbfc; }
|
||||
.st-dot { width: 9px; height: 9px; 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); }
|
||||
.task-main { flex: 1; min-width: 0; }
|
||||
.task-title { font-size: 14px; font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 8px; }
|
||||
.task-title .ttext { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.task-title .tid { font-size: 12px; font-weight: 600; color: var(--text-3); flex-shrink: 0; }
|
||||
.task-row:hover .task-title .ttext { color: var(--accent); }
|
||||
.task-row.is-done .task-title { color: var(--text-2); }
|
||||
.task-meta { display: flex; align-items: center; gap: 12px; margin-top: 4px; font-size: 12px; color: var(--text-3); }
|
||||
.repo-chip { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
|
||||
.repo-chip svg { width: 13px; height: 13px; color: var(--accent); flex-shrink: 0; }
|
||||
.mi { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
|
||||
.mi svg { width: 13px; height: 13px; }
|
||||
.meta-sep { width: 3px; height: 3px; border-radius: 50%; background: #d7dae0; flex-shrink: 0; }
|
||||
|
||||
.task-right { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }
|
||||
.due { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-2); font-weight: 500; white-space: nowrap; }
|
||||
.due svg { width: 14px; height: 14px; color: var(--text-3); }
|
||||
.dday { font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 20px; white-space: nowrap; line-height: 1.5; }
|
||||
.dday.urgent { color: var(--red); background: var(--red-weak); border: 1px solid var(--red-border); }
|
||||
.dday.soon { color: var(--amber); background: var(--amber-weak); border: 1px solid var(--amber-border); }
|
||||
.dday.calm { color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); }
|
||||
.st-badge { font-size: 11.5px; font-weight: 600; padding: 3px 10px; border-radius: 20px; white-space: nowrap; min-width: 64px; 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; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="#" class="active">내 업무</a>
|
||||
<a href="저장소 목록.html">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg></button>
|
||||
<button class="icon-btn" title="알림"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg></button>
|
||||
<div class="me">정</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page" data-screen-label="내 업무">
|
||||
<div class="pagehead">
|
||||
<h1>내 업무</h1>
|
||||
<span class="sub">나에게 배정되었거나 내가 지시한 업무를 한곳에서 관리하세요.</span>
|
||||
</div>
|
||||
|
||||
<!-- 담당 / 지시 토글 -->
|
||||
<div class="viewtabs">
|
||||
<a class="viewtab active" href="내 업무.html"><span class="tb-label">담당 업무</span> <span class="vt-count">6</span></a>
|
||||
<a class="viewtab" href="내 업무 (지시한 업무).html"><span class="tb-label">지시한 업무</span> <span class="vt-count">5</span> <span class="vt-flag">승인 대기 1</span></a>
|
||||
</div>
|
||||
|
||||
<!-- 툴바 -->
|
||||
<div class="toolbar">
|
||||
<div class="search">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>
|
||||
<input type="text" placeholder="업무 검색…">
|
||||
</div>
|
||||
<div class="repofilter">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
|
||||
모든 저장소
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 5h10M11 9h7M11 13h4M3 17l3 3 3-3M6 18V4"/></svg>
|
||||
마감 임박순
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 수정 요청 -->
|
||||
<div class="group">
|
||||
<div class="group-head"><span class="gh-dot changes"></span><span class="gh-label">수정 요청</span><span class="gh-count">1</span></div>
|
||||
<div class="list">
|
||||
<a class="task-row" href="업무 상세 (수정 요청).html">
|
||||
<span class="st-dot changes"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">3분기 캠페인 예산안 재작성</span> <span class="tid">#14</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>3분기 신제품 런칭 캠페인</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi">지시 · 한승우</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>6월 16일 <span class="dday urgent">D-1</span></span>
|
||||
<span class="st-badge changes">수정 요청</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 진행 중 -->
|
||||
<div class="group">
|
||||
<div class="group-head"><span class="gh-dot prog"></span><span class="gh-label">진행 중</span><span class="gh-count">2</span></div>
|
||||
<div class="list">
|
||||
<a class="task-row" href="업무 상세 (승인 요청).html">
|
||||
<span class="st-dot prog"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">브랜드 리뉴얼 킥오프 기획서 작성</span> <span class="tid">#12</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>브랜드 리뉴얼 2026</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>2/5</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi">지시 · 한승우</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>6월 18일 <span class="dday soon">D-3</span></span>
|
||||
<span class="st-badge prog">진행 중</span>
|
||||
</span>
|
||||
</a>
|
||||
<a class="task-row" href="업무 상세 (승인 요청).html">
|
||||
<span class="st-dot prog"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">9월 신제품 GTM 전략 수립</span> <span class="tid">#10</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>3분기 신제품 런칭 캠페인</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>1/4</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi">지시 · 한승우</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>6월 21일 <span class="dday calm">D-6</span></span>
|
||||
<span class="st-badge prog">진행 중</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 할 일 -->
|
||||
<div class="group">
|
||||
<div class="group-head"><span class="gh-dot todo"></span><span class="gh-label">할 일</span><span class="gh-count">2</span></div>
|
||||
<div class="list">
|
||||
<a class="task-row" href="업무 상세 (승인 요청).html">
|
||||
<span class="st-dot todo"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">월간 뉴스레터 8월호 주제 선정</span> <span class="tid">#15</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>월간 뉴스레터</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi">지시 · 한승우</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>6월 24일 <span class="dday calm">D-9</span></span>
|
||||
<span class="st-badge todo">할 일</span>
|
||||
</span>
|
||||
</a>
|
||||
<a class="task-row" href="업무 상세 (승인 요청).html">
|
||||
<span class="st-dot todo"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">SEO 키워드 전략 분기 리뷰</span> <span class="tid">#13</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>SEO 콘텐츠 허브</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi">지시 · 한승우</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>6월 27일 <span class="dday calm">D-12</span></span>
|
||||
<span class="st-badge todo">할 일</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 승인 대기 -->
|
||||
<div class="group">
|
||||
<div class="group-head"><span class="gh-dot review"></span><span class="gh-label">승인 대기</span><span class="gh-count">1</span></div>
|
||||
<div class="list">
|
||||
<a class="task-row" href="업무 상세 (승인 요청).html">
|
||||
<span class="st-dot review"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">브랜드 무드보드 방향 정리</span> <span class="tid">#2</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>브랜드 리뉴얼 2026</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi">한승우님 검토 중 · 1일 전 요청</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>6월 17일 <span class="dday soon">D-2</span></span>
|
||||
<span class="st-badge review">승인 대기</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 완료 -->
|
||||
<div class="group">
|
||||
<div class="group-head"><span class="gh-dot done"></span><span class="gh-label">완료</span><span class="gh-count">2</span></div>
|
||||
<div class="list">
|
||||
<a class="task-row is-done" href="업무 상세 (승인 완료).html">
|
||||
<span class="st-dot done"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">2분기 캠페인 성과 회고 정리</span> <span class="tid">#6</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>월간 뉴스레터</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi">지시 · 한승우</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due">6월 11일 승인됨</span>
|
||||
<span class="st-badge done">완료</span>
|
||||
</span>
|
||||
</a>
|
||||
<a class="task-row is-done" href="업무 상세 (승인 완료).html">
|
||||
<span class="st-dot done"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title"><span class="ttext">신제품 네이밍 후보 정리</span> <span class="tid">#5</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="repo-chip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>3분기 신제품 런칭 캠페인</span>
|
||||
<span class="meta-sep"></span>
|
||||
<span class="mi">지시 · 한승우</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="due">6월 5일 승인됨</span>
|
||||
<span class="st-badge done">완료</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,187 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>로그인 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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;
|
||||
--kakao: #FEE500; --kakao-text: #191600;
|
||||
--radius: 8px; --radius-sm: 5px;
|
||||
}
|
||||
html, body { height: 100%; }
|
||||
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;
|
||||
}
|
||||
.auth { display: flex; min-height: 100vh; }
|
||||
|
||||
/* ---- brand panel ---- */
|
||||
.brand-panel {
|
||||
flex: 0 0 46%; max-width: 620px; position: relative; overflow: hidden;
|
||||
background: linear-gradient(155deg, #4f46e5 0%, #4338ca 52%, #2e2a8f 100%);
|
||||
color: #fff; padding: 44px 48px; display: flex; flex-direction: column;
|
||||
}
|
||||
.brand-panel .blob { position: absolute; border-radius: 50%; filter: blur(2px); pointer-events: none; }
|
||||
.brand-panel .b1 { width: 360px; height: 360px; right: -120px; top: -90px; background: rgba(255,255,255,.10); }
|
||||
.brand-panel .b2 { width: 260px; height: 260px; left: -90px; bottom: -70px; background: rgba(255,255,255,.07); }
|
||||
.brand-panel .ring { position: absolute; right: 60px; bottom: 80px; width: 180px; height: 180px; border: 1.5px solid rgba(255,255,255,.14); border-radius: 50%; }
|
||||
.brand-panel .ring::after { content: ""; position: absolute; inset: 34px; border: 1.5px solid rgba(255,255,255,.10); border-radius: 50%; }
|
||||
.bp-logo { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 18px; letter-spacing: -.2px; position: relative; z-index: 1; }
|
||||
.bp-logo .logo { width: 32px; height: 32px; border-radius: 9px; background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.22); display: grid; place-items: center; font-size: 17px; font-weight: 800; }
|
||||
.bp-body { margin-top: auto; position: relative; z-index: 1; }
|
||||
.bp-head { font-size: 34px; font-weight: 700; line-height: 1.32; letter-spacing: -.8px; text-wrap: balance; }
|
||||
.bp-sub { margin-top: 18px; font-size: 15px; line-height: 1.7; color: rgba(255,255,255,.82); max-width: 400px; }
|
||||
.bp-points { margin-top: 30px; display: flex; flex-direction: column; gap: 12px; }
|
||||
.bp-point { display: flex; align-items: center; gap: 11px; font-size: 14px; color: rgba(255,255,255,.92); }
|
||||
.bp-point .ic { width: 22px; height: 22px; border-radius: 50%; background: rgba(255,255,255,.16); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.bp-point .ic svg { width: 13px; height: 13px; }
|
||||
.bp-foot { margin-top: 40px; font-size: 12.5px; color: rgba(255,255,255,.6); position: relative; z-index: 1; }
|
||||
|
||||
/* ---- form panel ---- */
|
||||
.form-panel { flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px 24px; }
|
||||
.auth-card { width: 100%; max-width: 384px; }
|
||||
.ac-logo { display: none; }
|
||||
.ac-title { font-size: 24px; font-weight: 700; letter-spacing: -.5px; }
|
||||
.ac-sub { color: var(--text-2); font-size: 14px; margin-top: 7px; }
|
||||
|
||||
.socials { display: flex; flex-direction: column; gap: 10px; margin-top: 28px; }
|
||||
.sbtn {
|
||||
height: 46px; border-radius: var(--radius); border: 1px solid var(--border-strong); background: #fff;
|
||||
display: flex; align-items: center; justify-content: center; gap: 10px; cursor: pointer;
|
||||
font-family: inherit; font-size: 14.5px; font-weight: 600; color: var(--text); text-decoration: none;
|
||||
position: relative; transition: background .12s, border-color .12s;
|
||||
}
|
||||
.sbtn:hover { background: #f7f8fa; }
|
||||
.sbtn .sico { position: absolute; left: 16px; display: grid; place-items: center; }
|
||||
.sbtn.kakao { background: var(--kakao); border-color: var(--kakao); color: var(--kakao-text); }
|
||||
.sbtn.kakao:hover { background: #f2d900; }
|
||||
|
||||
.divider { display: flex; align-items: center; gap: 14px; margin: 22px 0; color: var(--text-3); font-size: 12.5px; }
|
||||
.divider::before, .divider::after { content: ""; height: 1px; background: var(--border); flex: 1; }
|
||||
|
||||
.field { margin-bottom: 14px; }
|
||||
.flabel { font-size: 13px; font-weight: 600; color: var(--text-2); margin-bottom: 7px; display: block; }
|
||||
.tinput { width: 100%; height: 44px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 13px; font-family: inherit; font-size: 14px; color: var(--text); background: #fff; }
|
||||
.tinput:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.tinput::placeholder { color: var(--text-3); }
|
||||
.pw-wrap { position: relative; }
|
||||
.pw-wrap .tinput { padding-right: 44px; }
|
||||
.pw-toggle { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 34px; height: 34px; border: none; background: transparent; color: var(--text-3); display: grid; place-items: center; cursor: pointer; border-radius: 6px; }
|
||||
.pw-toggle:hover { background: #f1f2f4; color: var(--text-2); }
|
||||
.pw-toggle svg { width: 18px; height: 18px; }
|
||||
|
||||
.options { display: flex; align-items: center; justify-content: space-between; margin: 4px 0 22px; }
|
||||
.keep { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; color: var(--text-2); user-select: none; white-space: nowrap; }
|
||||
.keep .box { width: 17px; height: 17px; border-radius: 5px; border: 1.5px solid var(--border-strong); display: grid; place-items: center; background: #fff; }
|
||||
.keep .box.on { background: var(--accent); border-color: var(--accent); }
|
||||
.keep .box svg { width: 11px; height: 11px; color: #fff; opacity: 0; }
|
||||
.keep .box.on svg { opacity: 1; }
|
||||
.link { color: var(--accent); font-size: 13px; font-weight: 600; text-decoration: none; white-space: nowrap; }
|
||||
.link:hover { text-decoration: underline; }
|
||||
|
||||
.submit { width: 100%; height: 46px; border-radius: var(--radius); border: none; background: var(--accent); color: #fff; font-family: inherit; font-size: 15px; font-weight: 700; cursor: pointer; box-shadow: 0 1px 2px rgba(79,70,229,.4); text-decoration: none; display: flex; align-items: center; justify-content: center; }
|
||||
.submit:hover { background: var(--accent-hover); }
|
||||
|
||||
.signup { margin-top: 24px; text-align: center; font-size: 13.5px; color: var(--text-2); }
|
||||
.signup a { color: var(--accent); font-weight: 600; text-decoration: none; }
|
||||
.signup a:hover { text-decoration: underline; }
|
||||
.verify-note { margin-top: 6px; text-align: center; font-size: 12px; color: var(--text-3); display: flex; align-items: center; justify-content: center; gap: 5px; }
|
||||
.verify-note svg { width: 13px; height: 13px; }
|
||||
|
||||
@media (max-width: 880px) {
|
||||
.brand-panel { display: none; }
|
||||
.ac-logo { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 17px; margin-bottom: 26px; }
|
||||
.ac-logo .logo { width: 28px; height: 28px; border-radius: 8px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="auth">
|
||||
|
||||
<aside class="brand-panel">
|
||||
<div class="blob b1"></div>
|
||||
<div class="blob b2"></div>
|
||||
<div class="ring"></div>
|
||||
<div class="bp-logo"><span class="logo">R</span> Relay</div>
|
||||
<div class="bp-body">
|
||||
<div class="bp-head">지시부터 완료까지,<br>팀의 업무 흐름을 하나로</div>
|
||||
<div class="bp-sub">저장소 단위로 업무를 정리하고, 담당자에게 명확하게 지시하세요. 진행 상황은 한눈에 추적됩니다.</div>
|
||||
<div class="bp-points">
|
||||
<div class="bp-point"><span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span> 저장소 · 업무 · 담당자로 이어지는 명확한 구조</div>
|
||||
<div class="bp-point"><span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span> 체크리스트와 마감기한으로 진행 관리</div>
|
||||
<div class="bp-point"><span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span> Gitea 연동으로 안전하게</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bp-foot">© 2026 Relay · 사내 업무 지시 플랫폼</div>
|
||||
</aside>
|
||||
|
||||
<main class="form-panel">
|
||||
<div class="auth-card">
|
||||
<div class="ac-logo"><span class="logo">R</span> Relay</div>
|
||||
<h1 class="ac-title">로그인</h1>
|
||||
<p class="ac-sub">업무 지시를 시작하려면 로그인하세요.</p>
|
||||
|
||||
<!-- 소셜 로그인 -->
|
||||
<div class="socials">
|
||||
<a class="sbtn" href="저장소 목록.html">
|
||||
<span class="sico"><svg width="20" height="20" viewBox="0 0 48 48"><path fill="#FFC107" d="M43.6 20.5H42V20H24v8h11.3C33.7 32.4 29.2 36 24 36c-6.6 0-12-5.4-12-12s5.4-12 12-12c3.1 0 5.9 1.2 8 3.1l5.7-5.7C34.5 6.5 29.5 4 24 4 12.9 4 4 12.9 4 24s8.9 20 20 20 20-8.9 20-20c0-1.3-.1-2.3-.4-3.5z"/><path fill="#FF3D00" d="M6.3 14.7l6.6 4.8C14.7 15.1 19 12 24 12c3.1 0 5.9 1.2 8 3.1l5.7-5.7C34.5 6.5 29.5 4 24 4 16.3 4 9.7 8.3 6.3 14.7z"/><path fill="#4CAF50" d="M24 44c5.4 0 10.3-2.1 14-5.4l-6.5-5.5C29.6 34.6 26.9 36 24 36c-5.2 0-9.6-3.5-11.2-8.3l-6.5 5C9.6 39.6 16.2 44 24 44z"/><path fill="#1976D2" d="M43.6 20.5H42V20H24v8h11.3c-.8 2.2-2.2 4.1-4.1 5.5l6.5 5.5C41.4 36 44 30.5 44 24c0-1.3-.1-2.3-.4-3.5z"/></svg></span>
|
||||
Google로 계속하기
|
||||
</a>
|
||||
<a class="sbtn kakao" href="저장소 목록.html">
|
||||
<span class="sico"><svg width="19" height="19" viewBox="0 0 24 24" fill="#191600"><path d="M12 3C6.5 3 2 6.5 2 10.8c0 2.8 1.9 5.2 4.7 6.6-.2.7-.7 2.6-.8 3-.1.5.2.5.4.4.2-.1 2.6-1.8 3.7-2.5.6.1 1.3.1 2 .1 5.5 0 10-3.5 10-7.8C22 6.5 17.5 3 12 3z"/></svg></span>
|
||||
카카오로 계속하기
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="divider">또는 이메일로 로그인</div>
|
||||
|
||||
<!-- 이메일 로그인 -->
|
||||
<div class="field">
|
||||
<label class="flabel">이메일</label>
|
||||
<input class="tinput" type="email" placeholder="name@acme.co" value="">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="flabel">비밀번호</label>
|
||||
<div class="pw-wrap">
|
||||
<input class="tinput" type="password" placeholder="비밀번호 입력" value="">
|
||||
<button class="pw-toggle" type="button" title="비밀번호 표시"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="options">
|
||||
<span class="keep"><span class="box on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span> 로그인 상태 유지</span>
|
||||
<a class="link" href="#">비밀번호 찾기</a>
|
||||
</div>
|
||||
|
||||
<a class="submit" href="저장소 목록.html">로그인</a>
|
||||
|
||||
<div class="signup">계정이 없으신가요? <a href="회원가입.html">회원가입</a></div>
|
||||
<div class="verify-note">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16v16H4z" opacity="0"/><path d="M22 6 12 13 2 6"/><rect x="2" y="4" width="20" height="16" rx="2"/></svg>
|
||||
이메일 회원가입은 인증 메일 확인 후 완료됩니다
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 비밀번호 표시 토글 (정적 시안용 최소 인터랙션)
|
||||
document.querySelector('.pw-toggle').addEventListener('click', function () {
|
||||
var input = this.parentElement.querySelector('input');
|
||||
input.type = input.type === 'password' ? 'text' : 'password';
|
||||
});
|
||||
document.querySelector('.keep').addEventListener('click', function () {
|
||||
this.querySelector('.box').classList.toggle('on');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,469 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>메인 배너 이미지 2종 디자인 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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; --blue: #1d4ed8; --blue-weak: #e8efff; --blue-border: #c9dbff;
|
||||
--red: #d6455d; --red-weak: #fdeef0; --red-border: #f1c0c8; --amber: #b7791f; --amber-weak: #fdf4e3; --amber-border: #f3e2bd;
|
||||
--radius: 6px; --radius-sm: 4px; --shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* topbar */
|
||||
.topbar { height: 52px; background: var(--panel); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 28px; padding: 0 20px; position: sticky; top: 0; z-index: 50; }
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo { width: 26px; height: 26px; border-radius: 7px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; box-shadow: 0 2px 6px rgba(79,70,229,.35); }
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a { color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500; padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap; }
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px; }
|
||||
|
||||
/* page */
|
||||
.page { max-width: 1080px; margin: 0 auto; padding: 0 24px 60px; }
|
||||
.crumb { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12.5px; padding: 16px 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: .5; }
|
||||
.crumb b { color: var(--text-2); font-weight: 600; }
|
||||
|
||||
.pagehead { display: flex; align-items: flex-start; gap: 14px; padding: 12px 0 18px; }
|
||||
.ph-main { flex: 1; min-width: 0; }
|
||||
.ph-titlerow { display: flex; align-items: center; gap: 10px; }
|
||||
.st-badge { font-size: 11.5px; font-weight: 600; padding: 3px 10px; border-radius: 20px; white-space: nowrap; }
|
||||
.st-badge.prog { color: var(--blue); background: var(--blue-weak); border: 1px solid var(--blue-border); }
|
||||
.st-badge.review { color: var(--amber); background: var(--amber-weak); border: 1px solid var(--amber-border); }
|
||||
.st-badge.done { color: var(--green); background: var(--green-weak); border: 1px solid #cde8d8; }
|
||||
.st-badge.changes { color: var(--red); background: var(--red-weak); border: 1px solid var(--red-border); }
|
||||
.ph-tid { font-size: 14px; font-weight: 600; color: var(--text-3); }
|
||||
h1.ph-title { font-size: 23px; font-weight: 700; letter-spacing: -.5px; margin-top: 8px; line-height: 1.3; }
|
||||
.pagehead .actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; padding-top: 2px; }
|
||||
.btn { height: 34px; padding: 0 14px; border-radius: var(--radius); font-size: 13.5px; 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: 6px; line-height: 1; text-decoration: none; white-space: nowrap; }
|
||||
.btn:hover { background: #f7f8fa; color: var(--text); }
|
||||
.btn svg { width: 15px; height: 15px; }
|
||||
.btn.icon { width: 34px; padding: 0; justify-content: center; }
|
||||
|
||||
/* more menu */
|
||||
.more-wrap { position: relative; }
|
||||
.menu { display: none; position: absolute; top: calc(100% + 6px); right: 0; z-index: 40; width: 168px; background: #fff; border: 1px solid var(--border); border-radius: 9px; box-shadow: 0 12px 32px rgba(20,24,33,.16); padding: 5px; }
|
||||
.menu.open { display: block; }
|
||||
.menu-item { display: flex; align-items: center; gap: 10px; width: 100%; border: none; background: transparent; font-family: inherit; font-size: 13px; font-weight: 500; color: var(--text); padding: 8px 9px; border-radius: var(--radius-sm); cursor: pointer; text-align: left; white-space: nowrap; }
|
||||
.menu-item:hover { background: #f5f6f8; }
|
||||
.menu-item svg { width: 16px; height: 16px; color: var(--text-3); flex-shrink: 0; }
|
||||
.menu-item.danger { color: var(--red); }
|
||||
.menu-item.danger svg { color: var(--red); }
|
||||
.menu-item.danger:hover { background: var(--red-weak); }
|
||||
.menu-sep { height: 1px; background: var(--border); margin: 5px 0; }
|
||||
|
||||
/* modal */
|
||||
.modal-backdrop { position: fixed; inset: 0; background: rgba(20,24,33,.5); display: none; align-items: center; justify-content: center; z-index: 100; padding: 24px; }
|
||||
.modal-backdrop.open { display: flex; }
|
||||
.modal { width: 100%; max-width: 440px; background: #fff; border-radius: 14px; box-shadow: 0 24px 64px rgba(20,24,33,.32); overflow: hidden; }
|
||||
.modal-body { padding: 26px 24px 8px; text-align: center; }
|
||||
.modal-ico { width: 46px; height: 46px; border-radius: 50%; background: var(--red-weak); color: var(--red); display: grid; place-items: center; margin: 0 auto 14px; }
|
||||
.modal-ico svg { width: 22px; height: 22px; }
|
||||
.modal-title { font-size: 17px; font-weight: 700; letter-spacing: -.3px; }
|
||||
.modal-desc { font-size: 13px; color: var(--text-2); line-height: 1.6; margin-top: 8px; }
|
||||
.modal-desc b { color: var(--text); font-weight: 600; }
|
||||
.modal-foot { display: flex; gap: 9px; padding: 18px 24px 20px; }
|
||||
.mbtn { flex: 1; height: 40px; border-radius: var(--radius); font-size: 13.5px; font-weight: 600; border: 1px solid var(--border-strong); background: #fff; color: var(--text-2); cursor: pointer; }
|
||||
.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,.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,.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,.4); }
|
||||
.mbtn.request-send:hover { background: var(--accent-hover); }
|
||||
.modal-textarea { width: 100%; min-height: 92px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 10px 12px; font-family: inherit; font-size: 13.5px; 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); }
|
||||
|
||||
/* approval sidebar card */
|
||||
.ap-card { padding: 16px 18px 18px; border-width: 1px; border-style: solid; }
|
||||
.ap-card.review { border-color: var(--amber-border); background: var(--amber-weak); }
|
||||
.ap-card.request { border-color: var(--accent-border); background: var(--accent-weak); }
|
||||
.ap-card.changes { border-color: var(--red-border); background: var(--red-weak); }
|
||||
.ap-card.changes .ap-card-ico { color: var(--red); border-color: var(--red-border); }
|
||||
.ap-card.changes .ap-card-title { color: var(--red); }
|
||||
.ap-card.changes .ap-card-note { border-color: var(--red-border); }
|
||||
.ap-card-head { display: flex; align-items: center; gap: 9px; }
|
||||
.ap-card-ico { width: 30px; height: 30px; border-radius: 8px; background: #fff; display: grid; place-items: center; flex-shrink: 0; border: 1px solid; }
|
||||
.ap-card.review .ap-card-ico { color: var(--amber); border-color: var(--amber-border); }
|
||||
.ap-card.request .ap-card-ico { color: var(--accent); border-color: var(--accent-border); }
|
||||
.ap-card-ico svg { width: 17px; height: 17px; }
|
||||
.ap-card-title { font-size: 14px; font-weight: 700; white-space: nowrap; }
|
||||
.ap-card.review .ap-card-title { color: #8a5a12; }
|
||||
.ap-card.request .ap-card-title { color: var(--accent-hover); }
|
||||
.ap-card-meta { font-size: 12px; color: var(--text-2); margin-top: 10px; line-height: 1.5; }
|
||||
.ap-card-meta b { color: var(--text); font-weight: 600; }
|
||||
.ap-card-desc { font-size: 12.5px; color: var(--text-2); margin-top: 10px; line-height: 1.55; }
|
||||
.ap-card-note { font-size: 12.5px; color: var(--text); background: #fff; border: 1px solid var(--amber-border); border-radius: 8px; padding: 9px 11px; margin-top: 10px; line-height: 1.5; }
|
||||
.ap-card-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 13px; }
|
||||
.ap-btn { height: 38px; padding: 0 14px; border-radius: var(--radius); font-size: 13.5px; font-weight: 600; cursor: pointer; border: 1px solid var(--border-strong); background: #fff; color: var(--text-2); display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
|
||||
.ap-btn svg { width: 15px; height: 15px; }
|
||||
.ap-btn.reject:hover { background: #fdeef0; border-color: var(--red-border); color: var(--red); }
|
||||
.ap-btn.approve { background: var(--green); border-color: var(--green); color: #fff; box-shadow: 0 1px 2px rgba(31,157,87,.4); }
|
||||
.ap-btn.approve:hover { background: #188a4b; }
|
||||
.ap-btn.request-send { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.ap-btn.request-send:hover { background: var(--accent-hover); }
|
||||
|
||||
/* approval system event in thread */
|
||||
.sys-event { display: flex; align-items: center; gap: 10px; padding: 12px 0; border-top: 1px solid var(--border); font-size: 13px; color: var(--text-2); }
|
||||
.sys-event .se-ico { width: 26px; height: 26px; border-radius: 50%; background: var(--amber-weak); color: var(--amber); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.sys-event .se-ico svg { width: 14px; height: 14px; }
|
||||
.sys-event b { color: var(--text); font-weight: 600; }
|
||||
.sys-event .se-time { margin-left: auto; font-size: 12px; color: var(--text-3); white-space: nowrap; }
|
||||
|
||||
/* layout */
|
||||
.layout { display: grid; grid-template-columns: 1fr 320px; gap: 20px; align-items: start; }
|
||||
.card { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-sm); }
|
||||
.main-card { padding: 22px 26px 26px; }
|
||||
|
||||
.sect + .sect { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--border); }
|
||||
.sect-label { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; color: var(--text-2); margin-bottom: 12px; white-space: nowrap; }
|
||||
.sect-label .pr { margin-left: auto; display: flex; align-items: center; gap: 9px; }
|
||||
.progress-bar { width: 92px; height: 6px; border-radius: 4px; background: #eceef1; overflow: hidden; }
|
||||
.progress-bar > i { display: block; height: 100%; background: var(--green); border-radius: 4px; }
|
||||
.progress-txt { font-size: 12px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
|
||||
|
||||
.content { font-size: 14px; color: var(--text); line-height: 1.7; }
|
||||
.content p { margin-bottom: 11px; }
|
||||
.content p:last-child { margin-bottom: 0; }
|
||||
.content .mention { color: var(--accent); font-weight: 600; background: var(--accent-weak); padding: 0 3px; border-radius: 3px; }
|
||||
|
||||
/* checklist */
|
||||
.checklist { display: flex; flex-direction: column; }
|
||||
.citem { display: flex; align-items: center; gap: 11px; padding: 8px 0; border-radius: var(--radius-sm); }
|
||||
.cbox { width: 18px; height: 18px; border-radius: 5px; border: 1.5px solid var(--border-strong); flex-shrink: 0; display: grid; place-items: center; background: #fff; }
|
||||
.cbox.done { background: var(--green); border-color: var(--green); }
|
||||
.cbox svg { width: 12px; height: 12px; color: #fff; opacity: 0; }
|
||||
.cbox.done svg { opacity: 1; }
|
||||
.citem .ctext { font-size: 13.5px; color: var(--text); white-space: nowrap; }
|
||||
.citem.done .ctext { color: var(--text-3); text-decoration: line-through; }
|
||||
|
||||
/* nested subtasks (read-only) */
|
||||
.task-group + .task-group { margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--border); }
|
||||
.citem.parent .ctext { font-weight: 600; }
|
||||
.sub-count { margin-left: auto; font-size: 11px; font-weight: 600; color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); border-radius: 20px; padding: 1px 8px; line-height: 1.55; white-space: nowrap; }
|
||||
.citem.parent.done .sub-count { color: var(--green); background: var(--green-weak); border-color: #cde8d8; }
|
||||
.subtasks { margin-left: 29px; padding-left: 14px; border-left: 1.5px solid var(--border); display: flex; flex-direction: column; }
|
||||
.subtask { display: flex; align-items: center; gap: 10px; padding: 6px 0; border-radius: var(--radius-sm); }
|
||||
.cbox.sm { width: 16px; height: 16px; border-radius: 5px; }
|
||||
.cbox.sm svg { width: 11px; height: 11px; }
|
||||
.subtask .ctext { font-size: 13px; color: var(--text-2); white-space: nowrap; }
|
||||
.subtask.done .ctext { color: var(--text-3); text-decoration: line-through; }
|
||||
|
||||
/* comments */
|
||||
.comment { display: flex; gap: 11px; padding: 14px 0; border-top: 1px solid var(--border); }
|
||||
.comment:first-of-type { border-top: none; }
|
||||
.c-av { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; font-size: 12px; font-weight: 700; color: #fff; flex-shrink: 0; }
|
||||
.c-body { flex: 1; min-width: 0; }
|
||||
.c-head { display: flex; align-items: center; gap: 8px; }
|
||||
.c-name { font-size: 13.5px; font-weight: 600; white-space: nowrap; }
|
||||
.c-role { font-size: 11px; font-weight: 600; color: var(--accent); background: var(--accent-weak); border-radius: 20px; padding: 1px 7px; white-space: nowrap; }
|
||||
.c-time { font-size: 12px; color: var(--text-3); white-space: nowrap; }
|
||||
.c-text { font-size: 13.5px; color: var(--text); line-height: 1.6; margin-top: 4px; }
|
||||
.c-file { display: inline-flex; align-items: center; gap: 7px; margin-top: 8px; padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--radius); font-size: 12.5px; font-weight: 600; color: var(--text-2); }
|
||||
.c-file .fi { width: 22px; height: 22px; border-radius: 5px; background: #e25950; color: #fff; display: grid; place-items: center; font-size: 8px; font-weight: 800; }
|
||||
.composer { display: flex; gap: 11px; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
|
||||
.composer .field { flex: 1; }
|
||||
.composer textarea { width: 100%; min-height: 64px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 10px 12px; font-family: inherit; font-size: 13.5px; resize: vertical; color: var(--text); }
|
||||
.composer textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.composer textarea::placeholder { color: var(--text-3); }
|
||||
.composer .crow { display: flex; justify-content: flex-end; margin-top: 9px; }
|
||||
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
|
||||
|
||||
/* sidebar */
|
||||
.side { display: flex; flex-direction: column; gap: 16px; }
|
||||
.side-card { padding: 16px 18px 18px; }
|
||||
.side-field + .side-field { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
|
||||
.side-label { font-size: 12px; font-weight: 600; color: var(--text-3); margin-bottom: 9px; white-space: nowrap; }
|
||||
.status-badge { display: inline-flex; align-items: center; gap: 8px; height: 30px; padding: 0 13px; border: 1px solid var(--blue-border); background: var(--blue-weak); border-radius: 20px; font-size: 13px; font-weight: 600; color: var(--blue); white-space: nowrap; }
|
||||
.status-badge .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--blue); }
|
||||
.status-badge.review { color: var(--amber); background: var(--amber-weak); border-color: var(--amber-border); }
|
||||
.status-badge.review .dot { background: var(--amber); }
|
||||
.status-badge.changes { color: var(--red); background: var(--red-weak); border-color: var(--red-border); }
|
||||
.status-badge.changes .dot { background: var(--red); }
|
||||
.assignees { display: flex; flex-direction: column; gap: 9px; }
|
||||
.ass { display: flex; align-items: center; gap: 9px; }
|
||||
.avatar { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; font-size: 11px; 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-f { background: #d0982a; }
|
||||
.ass .nm { font-size: 13px; font-weight: 600; white-space: nowrap; }
|
||||
.ass .rl { font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
|
||||
.dl { display: flex; align-items: center; gap: 9px; font-size: 13.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
|
||||
.dl svg { width: 16px; height: 16px; color: var(--text-3); }
|
||||
.dl .dday { font-size: 11.5px; font-weight: 700; color: var(--amber); background: #fdf4e3; border: 1px solid #f3e2bd; border-radius: 20px; padding: 1px 7px; margin-left: auto; white-space: nowrap; }
|
||||
.files { display: flex; flex-direction: column; gap: 7px; }
|
||||
.file { display: flex; align-items: center; gap: 10px; padding: 8px 9px; border: 1px solid var(--border); border-radius: var(--radius); }
|
||||
.file-ico { width: 28px; height: 28px; border-radius: 6px; display: grid; place-items: center; flex-shrink: 0; font-size: 9px; font-weight: 800; color: #fff; }
|
||||
.fi-img { background: #2aa775; } .fi-zip { background: #8a64d6; }
|
||||
.file-info { min-width: 0; flex: 1; }
|
||||
.file-name { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
|
||||
.file-size { font-size: 11.5px; color: var(--text-3); display: block; }
|
||||
.issuer { display: flex; align-items: center; gap: 10px; }
|
||||
.issuer .nm { font-size: 13px; font-weight: 600; white-space: nowrap; }
|
||||
.issuer .rl { font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
|
||||
.meta-line { font-size: 12px; color: var(--text-3); margin-top: 4px; white-space: nowrap; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="내 업무.html">내 업무</a>
|
||||
<a href="저장소 목록.html" class="active">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg></button>
|
||||
<button class="icon-btn" title="알림"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg></button>
|
||||
<div class="me" style="background:#3d8bf2">박</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page" data-screen-label="업무 상세">
|
||||
<div class="crumb">
|
||||
<a href="저장소 목록.html" class="lnk">저장소</a>
|
||||
<span class="sep">/</span>
|
||||
<a href="저장소 상세.html" class="lnk">3분기 신제품 런칭 캠페인</a>
|
||||
<span class="sep">/</span>
|
||||
<a href="저장소 상세.html" class="lnk">업무</a>
|
||||
<span class="sep">/</span>
|
||||
<b>#9</b>
|
||||
</div>
|
||||
|
||||
<div class="pagehead">
|
||||
<div class="ph-main">
|
||||
<div class="ph-titlerow">
|
||||
<span class="st-badge changes">수정 요청</span>
|
||||
<span class="ph-tid">#9</span>
|
||||
</div>
|
||||
<h1 class="ph-title">메인 배너 이미지 2종 (가로/세로) 디자인</h1>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<a class="btn" href="업무 작성.html"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>수정</a>
|
||||
<div class="more-wrap">
|
||||
<button class="btn icon" id="moreBtn" type="button" title="더보기"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="5" r="1.5"/><circle cx="12" cy="12" r="1.5"/><circle cx="12" cy="19" r="1.5"/></svg></button>
|
||||
<div class="menu" id="moreMenu">
|
||||
<button class="menu-item" type="button">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||
업무 복제
|
||||
</button>
|
||||
<button class="menu-item" type="button">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1"/><path d="M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1"/></svg>
|
||||
링크 복사
|
||||
</button>
|
||||
<div class="menu-sep"></div>
|
||||
<button class="menu-item danger" id="deleteOpen" type="button">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
|
||||
업무 삭제
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout">
|
||||
<!-- main -->
|
||||
<section class="card main-card">
|
||||
<div class="sect">
|
||||
<div class="sect-label">업무 내용</div>
|
||||
<div class="content">
|
||||
<p>9월 신제품 런칭 캠페인에 사용할 메인 배너를 가로형/세로형 2종으로 제작합니다. 톤앤매너는 <span class="mention">@브랜드_가이드라인.pdf</span> 기준을 따라주세요.</p>
|
||||
<p>퍼포먼스 광고와 자사몰 상단에 동시 노출되므로, 두 비율 모두 핵심 메시지("민감 피부 저자극")가 명확히 보이도록 구성해주세요. 1차 시안 확정 후 모바일 적응형까지 진행합니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sect">
|
||||
<div class="sect-label">해야 할 일
|
||||
<span class="pr"><span class="progress-bar"><i style="width:33%"></i></span><span class="progress-txt">1 / 3 완료</span></span>
|
||||
</div>
|
||||
<div class="checklist">
|
||||
<div class="citem done">
|
||||
<span class="cbox done"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="ctext">가로형 메인 배너 1920×1080</span>
|
||||
</div>
|
||||
<div class="citem">
|
||||
<span class="cbox"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="ctext">세로형 메인 배너 1080×1920</span>
|
||||
</div>
|
||||
<div class="citem">
|
||||
<span class="cbox"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="ctext">모바일 적응형 600×600</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sect">
|
||||
<div class="sect-label">댓글 <span style="color:var(--text-3);font-weight:500">3</span></div>
|
||||
|
||||
<div class="comment">
|
||||
<span class="c-av av-f">정</span>
|
||||
<div class="c-body">
|
||||
<div class="c-head"><span class="c-name">정태경</span><span class="c-role">지시자</span><span class="c-time">2일 전</span></div>
|
||||
<div class="c-text">가로형부터 확정하고 세로형 진행해주세요. 카피 위치는 좌측 정렬 기준입니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="comment">
|
||||
<span class="c-av av-b">박</span>
|
||||
<div class="c-body">
|
||||
<div class="c-head"><span class="c-name">박지훈</span><span class="c-time">1일 전</span></div>
|
||||
<div class="c-text">가로형 1차 시안 업로드했습니다. 검토 부탁드려요.</div>
|
||||
<div class="c-file"><span class="fi">IMG</span>main_banner_h_v1.png</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="comment">
|
||||
<span class="c-av av-d">최</span>
|
||||
<div class="c-body">
|
||||
<div class="c-head"><span class="c-name">최유진</span><span class="c-time">3시간 전</span></div>
|
||||
<div class="c-text">세로형은 내일 오전까지 공유하겠습니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sys-event">
|
||||
<span class="se-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg></span>
|
||||
<span><b>박지훈</b>님이 승인을 요청했습니다</span>
|
||||
<span class="se-time">2시간 전</span>
|
||||
</div>
|
||||
|
||||
<div class="composer">
|
||||
<span class="c-av" style="background:#3d8bf2">박</span>
|
||||
<div class="field">
|
||||
<textarea placeholder="댓글을 입력하세요…"></textarea>
|
||||
<div class="crow"><button class="btn primary" type="button">댓글 등록</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- sidebar -->
|
||||
<aside class="side">
|
||||
<!-- 수정 요청됨: 작업자(박지훈) 시점 -->
|
||||
<div class="card ap-card changes">
|
||||
<div class="ap-card-head">
|
||||
<span class="ap-card-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7v6h6"/><path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"/></svg></span>
|
||||
<span class="ap-card-title">수정 요청됨</span>
|
||||
</div>
|
||||
<div class="ap-card-meta"><b>정태경</b>님이 수정을 요청했습니다 · 1시간 전</div>
|
||||
<div class="ap-card-note">세로형 카피 가독성이 낮으니 자간과 대비를 조정해주세요. 모바일 적응형까지 포함해 다시 올려주세요.</div>
|
||||
<div class="ap-card-actions">
|
||||
<button class="ap-btn request-send" id="requestOpen" type="button"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg>다시 승인 요청</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card side-card">
|
||||
<div class="side-field">
|
||||
<div class="side-label">상태</div>
|
||||
<span class="status-badge changes"><span class="dot"></span>수정 요청</span>
|
||||
</div>
|
||||
<div class="side-field">
|
||||
<div class="side-label">담당자 · 2명</div>
|
||||
<div class="assignees">
|
||||
<div class="ass"><span class="avatar av-b">박</span><span><div class="nm">박지훈</div><div class="rl">퍼포먼스 마케팅</div></span></div>
|
||||
<div class="ass"><span class="avatar av-d">최</span><span><div class="nm">최유진</div><div class="rl">UX 디자인</div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="side-field">
|
||||
<div class="side-label">마감기한</div>
|
||||
<div class="dl">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
|
||||
6월 18일 (목)
|
||||
<span class="dday">D-3</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card side-card">
|
||||
<div class="side-field">
|
||||
<div class="side-label">첨부파일 · 2개</div>
|
||||
<div class="files">
|
||||
<div class="file"><span class="file-ico fi-img">IMG</span><span class="file-info"><span class="file-name">레퍼런스_무드보드.png</span><span class="file-size">3.2 MB</span></span></div>
|
||||
<div class="file"><span class="file-ico fi-zip">ZIP</span><span class="file-info"><span class="file-name">배너_소스_파일.zip</span><span class="file-size">18.4 MB</span></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card side-card">
|
||||
<div class="side-field">
|
||||
<div class="side-label">지시자</div>
|
||||
<div class="issuer"><span class="avatar av-f">정</span><span><div class="nm">정태경</div><div class="rl">마케팅 그룹 리드</div></span></div>
|
||||
<div class="meta-line">6월 8일 지시 · #9</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 삭제 확인 모달 -->
|
||||
<div class="modal-backdrop" id="deleteModal">
|
||||
<div class="modal" role="dialog" aria-modal="true">
|
||||
<div class="modal-body">
|
||||
<div class="modal-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg></div>
|
||||
<h2 class="modal-title">업무를 삭제할까요?</h2>
|
||||
<p class="modal-desc"><b>#9 메인 배너 이미지 2종 (가로/세로) 디자인</b> 업무와 체크리스트·댓글·첨부파일이 영구적으로 삭제됩니다. 이 작업은 되돌릴 수 없습니다.</p>
|
||||
</div>
|
||||
<div class="modal-foot">
|
||||
<button class="mbtn" id="deleteCancel" type="button">취소</button>
|
||||
<button class="mbtn danger" type="button">삭제</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 승인 요청 모달 -->
|
||||
<div class="modal-backdrop" id="requestModal">
|
||||
<div class="modal" role="dialog" aria-modal="true">
|
||||
<div class="modal-body" style="text-align:left;padding:22px 24px 8px">
|
||||
<h2 class="modal-title">승인 요청 보내기</h2>
|
||||
<p class="modal-desc" style="margin:8px 0 14px">지시자 <b>정태경</b>님에게 검토 승인을 요청합니다. 완료한 작업과 전달할 내용을 간단히 적어주세요. 업무가 <b>승인 대기</b> 상태로 변경됩니다.</p>
|
||||
<textarea class="modal-textarea" placeholder="예) 가로형/세로형 메인 배너 1차 제작을 완료했습니다. 검토 부탁드립니다."></textarea>
|
||||
</div>
|
||||
<div class="modal-foot">
|
||||
<button class="mbtn" data-close="requestModal" type="button">취소</button>
|
||||
<button class="mbtn request-send" type="button">요청 보내기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var moreBtn = document.getElementById('moreBtn');
|
||||
var moreMenu = document.getElementById('moreMenu');
|
||||
moreBtn.addEventListener('click', function (e) { e.stopPropagation(); moreMenu.classList.toggle('open'); });
|
||||
document.addEventListener('click', function () { moreMenu.classList.remove('open'); });
|
||||
moreMenu.addEventListener('click', function (e) { e.stopPropagation(); });
|
||||
|
||||
/* 삭제 모달 */
|
||||
var dModal = document.getElementById('deleteModal');
|
||||
document.getElementById('deleteOpen').addEventListener('click', function () { moreMenu.classList.remove('open'); dModal.classList.add('open'); });
|
||||
document.getElementById('deleteCancel').addEventListener('click', function () { dModal.classList.remove('open'); });
|
||||
dModal.addEventListener('click', function (e) { if (e.target === dModal) dModal.classList.remove('open'); });
|
||||
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') dModal.classList.remove('open'); });
|
||||
|
||||
/* 승인 요청 모달 */
|
||||
function openModal(id) { document.getElementById(id).classList.add('open'); }
|
||||
function closeModal(el) { el.classList.remove('open'); }
|
||||
document.getElementById('requestOpen').addEventListener('click', function () { openModal('requestModal'); });
|
||||
document.querySelectorAll('[data-close]').forEach(function (b) {
|
||||
b.addEventListener('click', function () { closeModal(document.getElementById(b.getAttribute('data-close'))); });
|
||||
});
|
||||
var reqModal = document.getElementById('requestModal');
|
||||
reqModal.addEventListener('click', function (e) { if (e.target === reqModal) closeModal(reqModal); });
|
||||
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeModal(reqModal); });
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,463 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>메인 배너 이미지 2종 디자인 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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; --blue: #1d4ed8; --blue-weak: #e8efff; --blue-border: #c9dbff;
|
||||
--red: #d6455d; --red-weak: #fdeef0; --red-border: #f1c0c8; --amber: #b7791f; --amber-weak: #fdf4e3; --amber-border: #f3e2bd;
|
||||
--radius: 6px; --radius-sm: 4px; --shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* topbar */
|
||||
.topbar { height: 52px; background: var(--panel); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 28px; padding: 0 20px; position: sticky; top: 0; z-index: 50; }
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo { width: 26px; height: 26px; border-radius: 7px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; box-shadow: 0 2px 6px rgba(79,70,229,.35); }
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a { color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500; padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap; }
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px; }
|
||||
|
||||
/* page */
|
||||
.page { max-width: 1080px; margin: 0 auto; padding: 0 24px 60px; }
|
||||
.crumb { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12.5px; padding: 16px 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: .5; }
|
||||
.crumb b { color: var(--text-2); font-weight: 600; }
|
||||
|
||||
.pagehead { display: flex; align-items: flex-start; gap: 14px; padding: 12px 0 18px; }
|
||||
.ph-main { flex: 1; min-width: 0; }
|
||||
.ph-titlerow { display: flex; align-items: center; gap: 10px; }
|
||||
.st-badge { font-size: 11.5px; font-weight: 600; padding: 3px 10px; border-radius: 20px; white-space: nowrap; }
|
||||
.st-badge.prog { color: var(--blue); background: var(--blue-weak); border: 1px solid var(--blue-border); }
|
||||
.st-badge.review { color: var(--amber); background: var(--amber-weak); border: 1px solid var(--amber-border); }
|
||||
.st-badge.done { color: var(--green); background: var(--green-weak); border: 1px solid #cde8d8; }
|
||||
.st-badge.changes { color: var(--red); background: var(--red-weak); border: 1px solid var(--red-border); }
|
||||
.ph-tid { font-size: 14px; font-weight: 600; color: var(--text-3); }
|
||||
h1.ph-title { font-size: 23px; font-weight: 700; letter-spacing: -.5px; margin-top: 8px; line-height: 1.3; }
|
||||
.pagehead .actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; padding-top: 2px; }
|
||||
.btn { height: 34px; padding: 0 14px; border-radius: var(--radius); font-size: 13.5px; 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: 6px; line-height: 1; text-decoration: none; white-space: nowrap; }
|
||||
.btn:hover { background: #f7f8fa; color: var(--text); }
|
||||
.btn svg { width: 15px; height: 15px; }
|
||||
.btn.icon { width: 34px; padding: 0; justify-content: center; }
|
||||
|
||||
/* more menu */
|
||||
.more-wrap { position: relative; }
|
||||
.menu { display: none; position: absolute; top: calc(100% + 6px); right: 0; z-index: 40; width: 168px; background: #fff; border: 1px solid var(--border); border-radius: 9px; box-shadow: 0 12px 32px rgba(20,24,33,.16); padding: 5px; }
|
||||
.menu.open { display: block; }
|
||||
.menu-item { display: flex; align-items: center; gap: 10px; width: 100%; border: none; background: transparent; font-family: inherit; font-size: 13px; font-weight: 500; color: var(--text); padding: 8px 9px; border-radius: var(--radius-sm); cursor: pointer; text-align: left; white-space: nowrap; }
|
||||
.menu-item:hover { background: #f5f6f8; }
|
||||
.menu-item svg { width: 16px; height: 16px; color: var(--text-3); flex-shrink: 0; }
|
||||
.menu-item.danger { color: var(--red); }
|
||||
.menu-item.danger svg { color: var(--red); }
|
||||
.menu-item.danger:hover { background: var(--red-weak); }
|
||||
.menu-sep { height: 1px; background: var(--border); margin: 5px 0; }
|
||||
|
||||
/* modal */
|
||||
.modal-backdrop { position: fixed; inset: 0; background: rgba(20,24,33,.5); display: none; align-items: center; justify-content: center; z-index: 100; padding: 24px; }
|
||||
.modal-backdrop.open { display: flex; }
|
||||
.modal { width: 100%; max-width: 440px; background: #fff; border-radius: 14px; box-shadow: 0 24px 64px rgba(20,24,33,.32); overflow: hidden; }
|
||||
.modal-body { padding: 26px 24px 8px; text-align: center; }
|
||||
.modal-ico { width: 46px; height: 46px; border-radius: 50%; background: var(--red-weak); color: var(--red); display: grid; place-items: center; margin: 0 auto 14px; }
|
||||
.modal-ico svg { width: 22px; height: 22px; }
|
||||
.modal-title { font-size: 17px; font-weight: 700; letter-spacing: -.3px; }
|
||||
.modal-desc { font-size: 13px; color: var(--text-2); line-height: 1.6; margin-top: 8px; }
|
||||
.modal-desc b { color: var(--text); font-weight: 600; }
|
||||
.modal-foot { display: flex; gap: 9px; padding: 18px 24px 20px; }
|
||||
.mbtn { flex: 1; height: 40px; border-radius: var(--radius); font-size: 13.5px; font-weight: 600; border: 1px solid var(--border-strong); background: #fff; color: var(--text-2); cursor: pointer; }
|
||||
.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,.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,.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,.4); }
|
||||
.mbtn.request-send:hover { background: var(--accent-hover); }
|
||||
.modal-textarea { width: 100%; min-height: 92px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 10px 12px; font-family: inherit; font-size: 13.5px; 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); }
|
||||
|
||||
/* approval sidebar card */
|
||||
.ap-card { padding: 16px 18px 18px; border-width: 1px; border-style: solid; }
|
||||
.ap-card.review { border-color: var(--amber-border); background: var(--amber-weak); }
|
||||
.ap-card.request { border-color: var(--accent-border); background: var(--accent-weak); }
|
||||
.ap-card.done { border-color: #cde8d8; background: var(--green-weak); }
|
||||
.ap-card.done .ap-card-ico { color: var(--green); border-color: #cde8d8; }
|
||||
.ap-card.done .ap-card-title { color: #167a44; }
|
||||
.ap-card-head { display: flex; align-items: center; gap: 9px; }
|
||||
.ap-card-ico { width: 30px; height: 30px; border-radius: 8px; background: #fff; display: grid; place-items: center; flex-shrink: 0; border: 1px solid; }
|
||||
.ap-card.review .ap-card-ico { color: var(--amber); border-color: var(--amber-border); }
|
||||
.ap-card.request .ap-card-ico { color: var(--accent); border-color: var(--accent-border); }
|
||||
.ap-card-ico svg { width: 17px; height: 17px; }
|
||||
.ap-card-title { font-size: 14px; font-weight: 700; white-space: nowrap; }
|
||||
.ap-card.review .ap-card-title { color: #8a5a12; }
|
||||
.ap-card.request .ap-card-title { color: var(--accent-hover); }
|
||||
.ap-card-meta { font-size: 12px; color: var(--text-2); margin-top: 10px; line-height: 1.5; }
|
||||
.ap-card-meta b { color: var(--text); font-weight: 600; }
|
||||
.ap-card-desc { font-size: 12.5px; color: var(--text-2); margin-top: 10px; line-height: 1.55; }
|
||||
.ap-card-note { font-size: 12.5px; color: var(--text); background: #fff; border: 1px solid var(--amber-border); border-radius: 8px; padding: 9px 11px; margin-top: 10px; line-height: 1.5; }
|
||||
.ap-card-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 13px; }
|
||||
.ap-btn { height: 38px; padding: 0 14px; border-radius: var(--radius); font-size: 13.5px; font-weight: 600; cursor: pointer; border: 1px solid var(--border-strong); background: #fff; color: var(--text-2); display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
|
||||
.ap-btn svg { width: 15px; height: 15px; }
|
||||
.ap-btn.reject:hover { background: #fdeef0; border-color: var(--red-border); color: var(--red); }
|
||||
.ap-btn.approve { background: var(--green); border-color: var(--green); color: #fff; box-shadow: 0 1px 2px rgba(31,157,87,.4); }
|
||||
.ap-btn.approve:hover { background: #188a4b; }
|
||||
.ap-btn.request-send { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.ap-btn.request-send:hover { background: var(--accent-hover); }
|
||||
|
||||
/* approval system event in thread */
|
||||
.sys-event { display: flex; align-items: center; gap: 10px; padding: 12px 0; border-top: 1px solid var(--border); font-size: 13px; color: var(--text-2); }
|
||||
.sys-event .se-ico { width: 26px; height: 26px; border-radius: 50%; background: var(--amber-weak); color: var(--amber); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.sys-event .se-ico svg { width: 14px; height: 14px; }
|
||||
.sys-event b { color: var(--text); font-weight: 600; }
|
||||
.sys-event .se-time { margin-left: auto; font-size: 12px; color: var(--text-3); white-space: nowrap; }
|
||||
|
||||
/* layout */
|
||||
.layout { display: grid; grid-template-columns: 1fr 320px; gap: 20px; align-items: start; }
|
||||
.card { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-sm); }
|
||||
.main-card { padding: 22px 26px 26px; }
|
||||
|
||||
.sect + .sect { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--border); }
|
||||
.sect-label { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; color: var(--text-2); margin-bottom: 12px; white-space: nowrap; }
|
||||
.sect-label .pr { margin-left: auto; display: flex; align-items: center; gap: 9px; }
|
||||
.progress-bar { width: 92px; height: 6px; border-radius: 4px; background: #eceef1; overflow: hidden; }
|
||||
.progress-bar > i { display: block; height: 100%; background: var(--green); border-radius: 4px; }
|
||||
.progress-txt { font-size: 12px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
|
||||
|
||||
.content { font-size: 14px; color: var(--text); line-height: 1.7; }
|
||||
.content p { margin-bottom: 11px; }
|
||||
.content p:last-child { margin-bottom: 0; }
|
||||
.content .mention { color: var(--accent); font-weight: 600; background: var(--accent-weak); padding: 0 3px; border-radius: 3px; }
|
||||
|
||||
/* checklist */
|
||||
.checklist { display: flex; flex-direction: column; }
|
||||
.citem { display: flex; align-items: center; gap: 11px; padding: 8px 0; border-radius: var(--radius-sm); }
|
||||
.cbox { width: 18px; height: 18px; border-radius: 5px; border: 1.5px solid var(--border-strong); flex-shrink: 0; display: grid; place-items: center; background: #fff; }
|
||||
.cbox.done { background: var(--green); border-color: var(--green); }
|
||||
.cbox svg { width: 12px; height: 12px; color: #fff; opacity: 0; }
|
||||
.cbox.done svg { opacity: 1; }
|
||||
.citem .ctext { font-size: 13.5px; color: var(--text); white-space: nowrap; }
|
||||
.citem.done .ctext { color: var(--text-3); text-decoration: line-through; }
|
||||
|
||||
/* nested subtasks (read-only) */
|
||||
.task-group + .task-group { margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--border); }
|
||||
.citem.parent .ctext { font-weight: 600; }
|
||||
.sub-count { margin-left: auto; font-size: 11px; font-weight: 600; color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); border-radius: 20px; padding: 1px 8px; line-height: 1.55; white-space: nowrap; }
|
||||
.citem.parent.done .sub-count { color: var(--green); background: var(--green-weak); border-color: #cde8d8; }
|
||||
.subtasks { margin-left: 29px; padding-left: 14px; border-left: 1.5px solid var(--border); display: flex; flex-direction: column; }
|
||||
.subtask { display: flex; align-items: center; gap: 10px; padding: 6px 0; border-radius: var(--radius-sm); }
|
||||
.cbox.sm { width: 16px; height: 16px; border-radius: 5px; }
|
||||
.cbox.sm svg { width: 11px; height: 11px; }
|
||||
.subtask .ctext { font-size: 13px; color: var(--text-2); white-space: nowrap; }
|
||||
.subtask.done .ctext { color: var(--text-3); text-decoration: line-through; }
|
||||
|
||||
/* comments */
|
||||
.comment { display: flex; gap: 11px; padding: 14px 0; border-top: 1px solid var(--border); }
|
||||
.comment:first-of-type { border-top: none; }
|
||||
.c-av { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; font-size: 12px; font-weight: 700; color: #fff; flex-shrink: 0; }
|
||||
.c-body { flex: 1; min-width: 0; }
|
||||
.c-head { display: flex; align-items: center; gap: 8px; }
|
||||
.c-name { font-size: 13.5px; font-weight: 600; white-space: nowrap; }
|
||||
.c-role { font-size: 11px; font-weight: 600; color: var(--accent); background: var(--accent-weak); border-radius: 20px; padding: 1px 7px; white-space: nowrap; }
|
||||
.c-time { font-size: 12px; color: var(--text-3); white-space: nowrap; }
|
||||
.c-text { font-size: 13.5px; color: var(--text); line-height: 1.6; margin-top: 4px; }
|
||||
.c-file { display: inline-flex; align-items: center; gap: 7px; margin-top: 8px; padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--radius); font-size: 12.5px; font-weight: 600; color: var(--text-2); }
|
||||
.c-file .fi { width: 22px; height: 22px; border-radius: 5px; background: #e25950; color: #fff; display: grid; place-items: center; font-size: 8px; font-weight: 800; }
|
||||
.composer { display: flex; gap: 11px; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
|
||||
.composer .field { flex: 1; }
|
||||
.composer textarea { width: 100%; min-height: 64px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 10px 12px; font-family: inherit; font-size: 13.5px; resize: vertical; color: var(--text); }
|
||||
.composer textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.composer textarea::placeholder { color: var(--text-3); }
|
||||
.composer .crow { display: flex; justify-content: flex-end; margin-top: 9px; }
|
||||
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
|
||||
|
||||
/* sidebar */
|
||||
.side { display: flex; flex-direction: column; gap: 16px; }
|
||||
.side-card { padding: 16px 18px 18px; }
|
||||
.side-field + .side-field { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
|
||||
.side-label { font-size: 12px; font-weight: 600; color: var(--text-3); margin-bottom: 9px; white-space: nowrap; }
|
||||
.status-badge { display: inline-flex; align-items: center; gap: 8px; height: 30px; padding: 0 13px; border: 1px solid var(--blue-border); background: var(--blue-weak); border-radius: 20px; font-size: 13px; font-weight: 600; color: var(--blue); white-space: nowrap; }
|
||||
.status-badge .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--blue); }
|
||||
.status-badge.review { color: var(--amber); background: var(--amber-weak); border-color: var(--amber-border); }
|
||||
.status-badge.review .dot { background: var(--amber); }
|
||||
.status-badge.done { color: var(--green); background: var(--green-weak); border-color: #cde8d8; }
|
||||
.status-badge.done .dot { background: var(--green); }
|
||||
.assignees { display: flex; flex-direction: column; gap: 9px; }
|
||||
.ass { display: flex; align-items: center; gap: 9px; }
|
||||
.avatar { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; font-size: 11px; 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-f { background: #d0982a; }
|
||||
.ass .nm { font-size: 13px; font-weight: 600; white-space: nowrap; }
|
||||
.ass .rl { font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
|
||||
.dl { display: flex; align-items: center; gap: 9px; font-size: 13.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
|
||||
.dl svg { width: 16px; height: 16px; color: var(--text-3); }
|
||||
.dl .dday { font-size: 11.5px; font-weight: 700; color: var(--amber); background: #fdf4e3; border: 1px solid #f3e2bd; border-radius: 20px; padding: 1px 7px; margin-left: auto; white-space: nowrap; }
|
||||
.files { display: flex; flex-direction: column; gap: 7px; }
|
||||
.file { display: flex; align-items: center; gap: 10px; padding: 8px 9px; border: 1px solid var(--border); border-radius: var(--radius); }
|
||||
.file-ico { width: 28px; height: 28px; border-radius: 6px; display: grid; place-items: center; flex-shrink: 0; font-size: 9px; font-weight: 800; color: #fff; }
|
||||
.fi-img { background: #2aa775; } .fi-zip { background: #8a64d6; }
|
||||
.file-info { min-width: 0; flex: 1; }
|
||||
.file-name { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
|
||||
.file-size { font-size: 11.5px; color: var(--text-3); display: block; }
|
||||
.issuer { display: flex; align-items: center; gap: 10px; }
|
||||
.issuer .nm { font-size: 13px; font-weight: 600; white-space: nowrap; }
|
||||
.issuer .rl { font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
|
||||
.meta-line { font-size: 12px; color: var(--text-3); margin-top: 4px; white-space: nowrap; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="내 업무.html">내 업무</a>
|
||||
<a href="저장소 목록.html" class="active">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg></button>
|
||||
<button class="icon-btn" title="알림"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg></button>
|
||||
<div class="me" style="background:#3d8bf2">박</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page" data-screen-label="업무 상세">
|
||||
<div class="crumb">
|
||||
<a href="저장소 목록.html" class="lnk">저장소</a>
|
||||
<span class="sep">/</span>
|
||||
<a href="저장소 상세.html" class="lnk">3분기 신제품 런칭 캠페인</a>
|
||||
<span class="sep">/</span>
|
||||
<a href="저장소 상세.html" class="lnk">업무</a>
|
||||
<span class="sep">/</span>
|
||||
<b>#9</b>
|
||||
</div>
|
||||
|
||||
<div class="pagehead">
|
||||
<div class="ph-main">
|
||||
<div class="ph-titlerow">
|
||||
<span class="st-badge done">완료</span>
|
||||
<span class="ph-tid">#9</span>
|
||||
</div>
|
||||
<h1 class="ph-title">메인 배너 이미지 2종 (가로/세로) 디자인</h1>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<a class="btn" href="업무 작성.html"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>수정</a>
|
||||
<div class="more-wrap">
|
||||
<button class="btn icon" id="moreBtn" type="button" title="더보기"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="5" r="1.5"/><circle cx="12" cy="12" r="1.5"/><circle cx="12" cy="19" r="1.5"/></svg></button>
|
||||
<div class="menu" id="moreMenu">
|
||||
<button class="menu-item" type="button">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||
업무 복제
|
||||
</button>
|
||||
<button class="menu-item" type="button">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1"/><path d="M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1"/></svg>
|
||||
링크 복사
|
||||
</button>
|
||||
<div class="menu-sep"></div>
|
||||
<button class="menu-item danger" id="deleteOpen" type="button">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
|
||||
업무 삭제
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout">
|
||||
<!-- main -->
|
||||
<section class="card main-card">
|
||||
<div class="sect">
|
||||
<div class="sect-label">업무 내용</div>
|
||||
<div class="content">
|
||||
<p>9월 신제품 런칭 캠페인에 사용할 메인 배너를 가로형/세로형 2종으로 제작합니다. 톤앤매너는 <span class="mention">@브랜드_가이드라인.pdf</span> 기준을 따라주세요.</p>
|
||||
<p>퍼포먼스 광고와 자사몰 상단에 동시 노출되므로, 두 비율 모두 핵심 메시지("민감 피부 저자극")가 명확히 보이도록 구성해주세요. 1차 시안 확정 후 모바일 적응형까지 진행합니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sect">
|
||||
<div class="sect-label">해야 할 일
|
||||
<span class="pr"><span class="progress-bar"><i style="width:100%"></i></span><span class="progress-txt">3 / 3 완료</span></span>
|
||||
</div>
|
||||
<div class="checklist">
|
||||
<div class="citem done">
|
||||
<span class="cbox done"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="ctext">가로형 메인 배너 1920×1080</span>
|
||||
</div>
|
||||
<div class="citem done">
|
||||
<span class="cbox done"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="ctext">세로형 메인 배너 1080×1920</span>
|
||||
</div>
|
||||
<div class="citem done">
|
||||
<span class="cbox done"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="ctext">모바일 적응형 600×600</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sect">
|
||||
<div class="sect-label">댓글 <span style="color:var(--text-3);font-weight:500">3</span></div>
|
||||
|
||||
<div class="comment">
|
||||
<span class="c-av av-f">정</span>
|
||||
<div class="c-body">
|
||||
<div class="c-head"><span class="c-name">정태경</span><span class="c-role">지시자</span><span class="c-time">2일 전</span></div>
|
||||
<div class="c-text">가로형부터 확정하고 세로형 진행해주세요. 카피 위치는 좌측 정렬 기준입니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="comment">
|
||||
<span class="c-av av-b">박</span>
|
||||
<div class="c-body">
|
||||
<div class="c-head"><span class="c-name">박지훈</span><span class="c-time">1일 전</span></div>
|
||||
<div class="c-text">가로형 1차 시안 업로드했습니다. 검토 부탁드려요.</div>
|
||||
<div class="c-file"><span class="fi">IMG</span>main_banner_h_v1.png</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="comment">
|
||||
<span class="c-av av-d">최</span>
|
||||
<div class="c-body">
|
||||
<div class="c-head"><span class="c-name">최유진</span><span class="c-time">3시간 전</span></div>
|
||||
<div class="c-text">세로형은 내일 오전까지 공유하겠습니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sys-event">
|
||||
<span class="se-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg></span>
|
||||
<span><b>박지훈</b>님이 승인을 요청했습니다</span>
|
||||
<span class="se-time">2시간 전</span>
|
||||
</div>
|
||||
|
||||
<div class="composer">
|
||||
<span class="c-av" style="background:#3d8bf2">박</span>
|
||||
<div class="field">
|
||||
<textarea placeholder="댓글을 입력하세요…"></textarea>
|
||||
<div class="crow"><button class="btn primary" type="button">댓글 등록</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- sidebar -->
|
||||
<aside class="side">
|
||||
<!-- 승인 완료 -->
|
||||
<div class="card ap-card done">
|
||||
<div class="ap-card-head">
|
||||
<span class="ap-card-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="M22 4 12 14.01l-3-3"/></svg></span>
|
||||
<span class="ap-card-title">승인 완료</span>
|
||||
</div>
|
||||
<div class="ap-card-meta"><b>정태경</b>님이 검토를 승인했습니다 · 방금 · 해야 할 일이 모두 완료되었습니다.</div>
|
||||
</div>
|
||||
|
||||
<div class="card side-card">
|
||||
<div class="side-field">
|
||||
<div class="side-label">상태</div>
|
||||
<span class="status-badge done"><span class="dot"></span>완료</span>
|
||||
</div>
|
||||
<div class="side-field">
|
||||
<div class="side-label">담당자 · 2명</div>
|
||||
<div class="assignees">
|
||||
<div class="ass"><span class="avatar av-b">박</span><span><div class="nm">박지훈</div><div class="rl">퍼포먼스 마케팅</div></span></div>
|
||||
<div class="ass"><span class="avatar av-d">최</span><span><div class="nm">최유진</div><div class="rl">UX 디자인</div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="side-field">
|
||||
<div class="side-label">마감기한</div>
|
||||
<div class="dl">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
|
||||
6월 18일 (목)
|
||||
<span class="dday">D-3</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card side-card">
|
||||
<div class="side-field">
|
||||
<div class="side-label">첨부파일 · 2개</div>
|
||||
<div class="files">
|
||||
<div class="file"><span class="file-ico fi-img">IMG</span><span class="file-info"><span class="file-name">레퍼런스_무드보드.png</span><span class="file-size">3.2 MB</span></span></div>
|
||||
<div class="file"><span class="file-ico fi-zip">ZIP</span><span class="file-info"><span class="file-name">배너_소스_파일.zip</span><span class="file-size">18.4 MB</span></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card side-card">
|
||||
<div class="side-field">
|
||||
<div class="side-label">지시자</div>
|
||||
<div class="issuer"><span class="avatar av-f">정</span><span><div class="nm">정태경</div><div class="rl">마케팅 그룹 리드</div></span></div>
|
||||
<div class="meta-line">6월 8일 지시 · #9</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 삭제 확인 모달 -->
|
||||
<div class="modal-backdrop" id="deleteModal">
|
||||
<div class="modal" role="dialog" aria-modal="true">
|
||||
<div class="modal-body">
|
||||
<div class="modal-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg></div>
|
||||
<h2 class="modal-title">업무를 삭제할까요?</h2>
|
||||
<p class="modal-desc"><b>#9 메인 배너 이미지 2종 (가로/세로) 디자인</b> 업무와 체크리스트·댓글·첨부파일이 영구적으로 삭제됩니다. 이 작업은 되돌릴 수 없습니다.</p>
|
||||
</div>
|
||||
<div class="modal-foot">
|
||||
<button class="mbtn" id="deleteCancel" type="button">취소</button>
|
||||
<button class="mbtn danger" type="button">삭제</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 승인 요청 모달 -->
|
||||
<div class="modal-backdrop" id="requestModal">
|
||||
<div class="modal" role="dialog" aria-modal="true">
|
||||
<div class="modal-body" style="text-align:left;padding:22px 24px 8px">
|
||||
<h2 class="modal-title">승인 요청 보내기</h2>
|
||||
<p class="modal-desc" style="margin:8px 0 14px">지시자 <b>정태경</b>님에게 검토 승인을 요청합니다. 완료한 작업과 전달할 내용을 간단히 적어주세요. 업무가 <b>승인 대기</b> 상태로 변경됩니다.</p>
|
||||
<textarea class="modal-textarea" placeholder="예) 가로형/세로형 메인 배너 1차 제작을 완료했습니다. 검토 부탁드립니다."></textarea>
|
||||
</div>
|
||||
<div class="modal-foot">
|
||||
<button class="mbtn" data-close="requestModal" type="button">취소</button>
|
||||
<button class="mbtn request-send" type="button">요청 보내기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var moreBtn = document.getElementById('moreBtn');
|
||||
var moreMenu = document.getElementById('moreMenu');
|
||||
moreBtn.addEventListener('click', function (e) { e.stopPropagation(); moreMenu.classList.toggle('open'); });
|
||||
document.addEventListener('click', function () { moreMenu.classList.remove('open'); });
|
||||
moreMenu.addEventListener('click', function (e) { e.stopPropagation(); });
|
||||
|
||||
/* 삭제 모달 */
|
||||
var dModal = document.getElementById('deleteModal');
|
||||
document.getElementById('deleteOpen').addEventListener('click', function () { moreMenu.classList.remove('open'); dModal.classList.add('open'); });
|
||||
document.getElementById('deleteCancel').addEventListener('click', function () { dModal.classList.remove('open'); });
|
||||
dModal.addEventListener('click', function (e) { if (e.target === dModal) dModal.classList.remove('open'); });
|
||||
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') dModal.classList.remove('open'); });
|
||||
|
||||
/* 승인 요청 모달 */
|
||||
function openModal(id) { document.getElementById(id).classList.add('open'); }
|
||||
function closeModal(el) { el.classList.remove('open'); }
|
||||
document.querySelectorAll('[data-close]').forEach(function (b) {
|
||||
b.addEventListener('click', function () { closeModal(document.getElementById(b.getAttribute('data-close'))); });
|
||||
});
|
||||
var reqModal = document.getElementById('requestModal');
|
||||
reqModal.addEventListener('click', function (e) { if (e.target === reqModal) closeModal(reqModal); });
|
||||
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeModal(reqModal); });
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,462 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>메인 배너 이미지 2종 디자인 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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; --blue: #1d4ed8; --blue-weak: #e8efff; --blue-border: #c9dbff;
|
||||
--red: #d6455d; --red-weak: #fdeef0; --red-border: #f1c0c8; --amber: #b7791f; --amber-weak: #fdf4e3; --amber-border: #f3e2bd;
|
||||
--radius: 6px; --radius-sm: 4px; --shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* topbar */
|
||||
.topbar { height: 52px; background: var(--panel); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 28px; padding: 0 20px; position: sticky; top: 0; z-index: 50; }
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo { width: 26px; height: 26px; border-radius: 7px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; box-shadow: 0 2px 6px rgba(79,70,229,.35); }
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a { color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500; padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap; }
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px; }
|
||||
|
||||
/* page */
|
||||
.page { max-width: 1080px; margin: 0 auto; padding: 0 24px 60px; }
|
||||
.crumb { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12.5px; padding: 16px 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: .5; }
|
||||
.crumb b { color: var(--text-2); font-weight: 600; }
|
||||
|
||||
.pagehead { display: flex; align-items: flex-start; gap: 14px; padding: 12px 0 18px; }
|
||||
.ph-main { flex: 1; min-width: 0; }
|
||||
.ph-titlerow { display: flex; align-items: center; gap: 10px; }
|
||||
.st-badge { font-size: 11.5px; font-weight: 600; padding: 3px 10px; border-radius: 20px; white-space: nowrap; }
|
||||
.st-badge.prog { color: var(--blue); background: var(--blue-weak); border: 1px solid var(--blue-border); }
|
||||
.st-badge.review { color: var(--amber); background: var(--amber-weak); border: 1px solid var(--amber-border); }
|
||||
.st-badge.done { color: var(--green); background: var(--green-weak); border: 1px solid #cde8d8; }
|
||||
.st-badge.changes { color: var(--red); background: var(--red-weak); border: 1px solid var(--red-border); }
|
||||
.ph-tid { font-size: 14px; font-weight: 600; color: var(--text-3); }
|
||||
h1.ph-title { font-size: 23px; font-weight: 700; letter-spacing: -.5px; margin-top: 8px; line-height: 1.3; }
|
||||
.pagehead .actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; padding-top: 2px; }
|
||||
.btn { height: 34px; padding: 0 14px; border-radius: var(--radius); font-size: 13.5px; 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: 6px; line-height: 1; text-decoration: none; white-space: nowrap; }
|
||||
.btn:hover { background: #f7f8fa; color: var(--text); }
|
||||
.btn svg { width: 15px; height: 15px; }
|
||||
.btn.icon { width: 34px; padding: 0; justify-content: center; }
|
||||
|
||||
/* more menu */
|
||||
.more-wrap { position: relative; }
|
||||
.menu { display: none; position: absolute; top: calc(100% + 6px); right: 0; z-index: 40; width: 168px; background: #fff; border: 1px solid var(--border); border-radius: 9px; box-shadow: 0 12px 32px rgba(20,24,33,.16); padding: 5px; }
|
||||
.menu.open { display: block; }
|
||||
.menu-item { display: flex; align-items: center; gap: 10px; width: 100%; border: none; background: transparent; font-family: inherit; font-size: 13px; font-weight: 500; color: var(--text); padding: 8px 9px; border-radius: var(--radius-sm); cursor: pointer; text-align: left; white-space: nowrap; }
|
||||
.menu-item:hover { background: #f5f6f8; }
|
||||
.menu-item svg { width: 16px; height: 16px; color: var(--text-3); flex-shrink: 0; }
|
||||
.menu-item.danger { color: var(--red); }
|
||||
.menu-item.danger svg { color: var(--red); }
|
||||
.menu-item.danger:hover { background: var(--red-weak); }
|
||||
.menu-sep { height: 1px; background: var(--border); margin: 5px 0; }
|
||||
|
||||
/* modal */
|
||||
.modal-backdrop { position: fixed; inset: 0; background: rgba(20,24,33,.5); display: none; align-items: center; justify-content: center; z-index: 100; padding: 24px; }
|
||||
.modal-backdrop.open { display: flex; }
|
||||
.modal { width: 100%; max-width: 440px; background: #fff; border-radius: 14px; box-shadow: 0 24px 64px rgba(20,24,33,.32); overflow: hidden; }
|
||||
.modal-body { padding: 26px 24px 8px; text-align: center; }
|
||||
.modal-ico { width: 46px; height: 46px; border-radius: 50%; background: var(--red-weak); color: var(--red); display: grid; place-items: center; margin: 0 auto 14px; }
|
||||
.modal-ico svg { width: 22px; height: 22px; }
|
||||
.modal-title { font-size: 17px; font-weight: 700; letter-spacing: -.3px; }
|
||||
.modal-desc { font-size: 13px; color: var(--text-2); line-height: 1.6; margin-top: 8px; }
|
||||
.modal-desc b { color: var(--text); font-weight: 600; }
|
||||
.modal-foot { display: flex; gap: 9px; padding: 18px 24px 20px; }
|
||||
.mbtn { flex: 1; height: 40px; border-radius: var(--radius); font-size: 13.5px; font-weight: 600; border: 1px solid var(--border-strong); background: #fff; color: var(--text-2); cursor: pointer; }
|
||||
.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,.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,.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,.4); }
|
||||
.mbtn.request-send:hover { background: var(--accent-hover); }
|
||||
.modal-textarea { width: 100%; min-height: 92px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 10px 12px; font-family: inherit; font-size: 13.5px; 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); }
|
||||
|
||||
/* approval sidebar card */
|
||||
.ap-card { padding: 16px 18px 18px; border-width: 1px; border-style: solid; }
|
||||
.ap-card.review { border-color: var(--amber-border); background: var(--amber-weak); }
|
||||
.ap-card.request { border-color: var(--accent-border); background: var(--accent-weak); }
|
||||
.ap-card-head { display: flex; align-items: center; gap: 9px; }
|
||||
.ap-card-ico { width: 30px; height: 30px; border-radius: 8px; background: #fff; display: grid; place-items: center; flex-shrink: 0; border: 1px solid; }
|
||||
.ap-card.review .ap-card-ico { color: var(--amber); border-color: var(--amber-border); }
|
||||
.ap-card.request .ap-card-ico { color: var(--accent); border-color: var(--accent-border); }
|
||||
.ap-card-ico svg { width: 17px; height: 17px; }
|
||||
.ap-card-title { font-size: 14px; font-weight: 700; white-space: nowrap; }
|
||||
.ap-card.review .ap-card-title { color: #8a5a12; }
|
||||
.ap-card.request .ap-card-title { color: var(--accent-hover); }
|
||||
.ap-card-meta { font-size: 12px; color: var(--text-2); margin-top: 10px; line-height: 1.5; }
|
||||
.ap-card-meta b { color: var(--text); font-weight: 600; }
|
||||
.ap-card-desc { font-size: 12.5px; color: var(--text-2); margin-top: 10px; line-height: 1.55; }
|
||||
.ap-card-note { font-size: 12.5px; color: var(--text); background: #fff; border: 1px solid var(--amber-border); border-radius: 8px; padding: 9px 11px; margin-top: 10px; line-height: 1.5; }
|
||||
.ap-card-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 13px; }
|
||||
.ap-btn { height: 38px; padding: 0 14px; border-radius: var(--radius); font-size: 13.5px; font-weight: 600; cursor: pointer; border: 1px solid var(--border-strong); background: #fff; color: var(--text-2); display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
|
||||
.ap-btn svg { width: 15px; height: 15px; }
|
||||
.ap-btn.reject:hover { background: #fdeef0; border-color: var(--red-border); color: var(--red); }
|
||||
.ap-btn.approve { background: var(--green); border-color: var(--green); color: #fff; box-shadow: 0 1px 2px rgba(31,157,87,.4); }
|
||||
.ap-btn.approve:hover { background: #188a4b; }
|
||||
.ap-btn.request-send { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.ap-btn.request-send:hover { background: var(--accent-hover); }
|
||||
|
||||
/* approval system event in thread */
|
||||
.sys-event { display: flex; align-items: center; gap: 10px; padding: 12px 0; border-top: 1px solid var(--border); font-size: 13px; color: var(--text-2); }
|
||||
.sys-event .se-ico { width: 26px; height: 26px; border-radius: 50%; background: var(--amber-weak); color: var(--amber); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.sys-event .se-ico svg { width: 14px; height: 14px; }
|
||||
.sys-event b { color: var(--text); font-weight: 600; }
|
||||
.sys-event .se-time { margin-left: auto; font-size: 12px; color: var(--text-3); white-space: nowrap; }
|
||||
|
||||
/* layout */
|
||||
.layout { display: grid; grid-template-columns: 1fr 320px; gap: 20px; align-items: start; }
|
||||
.card { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-sm); }
|
||||
.main-card { padding: 22px 26px 26px; }
|
||||
|
||||
.sect + .sect { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--border); }
|
||||
.sect-label { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; color: var(--text-2); margin-bottom: 12px; white-space: nowrap; }
|
||||
.sect-label .pr { margin-left: auto; display: flex; align-items: center; gap: 9px; }
|
||||
.progress-bar { width: 92px; height: 6px; border-radius: 4px; background: #eceef1; overflow: hidden; }
|
||||
.progress-bar > i { display: block; height: 100%; background: var(--green); border-radius: 4px; }
|
||||
.progress-txt { font-size: 12px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
|
||||
|
||||
.content { font-size: 14px; color: var(--text); line-height: 1.7; }
|
||||
.content p { margin-bottom: 11px; }
|
||||
.content p:last-child { margin-bottom: 0; }
|
||||
.content .mention { color: var(--accent); font-weight: 600; background: var(--accent-weak); padding: 0 3px; border-radius: 3px; }
|
||||
|
||||
/* checklist */
|
||||
.checklist { display: flex; flex-direction: column; }
|
||||
.citem { display: flex; align-items: center; gap: 11px; padding: 8px 0; border-radius: var(--radius-sm); }
|
||||
.cbox { width: 18px; height: 18px; border-radius: 5px; border: 1.5px solid var(--border-strong); flex-shrink: 0; display: grid; place-items: center; background: #fff; }
|
||||
.cbox.done { background: var(--green); border-color: var(--green); }
|
||||
.cbox svg { width: 12px; height: 12px; color: #fff; opacity: 0; }
|
||||
.cbox.done svg { opacity: 1; }
|
||||
.citem .ctext { font-size: 13.5px; color: var(--text); white-space: nowrap; }
|
||||
.citem.done .ctext { color: var(--text-3); text-decoration: line-through; }
|
||||
|
||||
/* nested subtasks (read-only) */
|
||||
.task-group + .task-group { margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--border); }
|
||||
.citem.parent .ctext { font-weight: 600; }
|
||||
.sub-count { margin-left: auto; font-size: 11px; font-weight: 600; color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); border-radius: 20px; padding: 1px 8px; line-height: 1.55; white-space: nowrap; }
|
||||
.citem.parent.done .sub-count { color: var(--green); background: var(--green-weak); border-color: #cde8d8; }
|
||||
.subtasks { margin-left: 29px; padding-left: 14px; border-left: 1.5px solid var(--border); display: flex; flex-direction: column; }
|
||||
.subtask { display: flex; align-items: center; gap: 10px; padding: 6px 0; border-radius: var(--radius-sm); }
|
||||
.cbox.sm { width: 16px; height: 16px; border-radius: 5px; }
|
||||
.cbox.sm svg { width: 11px; height: 11px; }
|
||||
.subtask .ctext { font-size: 13px; color: var(--text-2); white-space: nowrap; }
|
||||
.subtask.done .ctext { color: var(--text-3); text-decoration: line-through; }
|
||||
|
||||
/* comments */
|
||||
.comment { display: flex; gap: 11px; padding: 14px 0; border-top: 1px solid var(--border); }
|
||||
.comment:first-of-type { border-top: none; }
|
||||
.c-av { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; font-size: 12px; font-weight: 700; color: #fff; flex-shrink: 0; }
|
||||
.c-body { flex: 1; min-width: 0; }
|
||||
.c-head { display: flex; align-items: center; gap: 8px; }
|
||||
.c-name { font-size: 13.5px; font-weight: 600; white-space: nowrap; }
|
||||
.c-role { font-size: 11px; font-weight: 600; color: var(--accent); background: var(--accent-weak); border-radius: 20px; padding: 1px 7px; white-space: nowrap; }
|
||||
.c-time { font-size: 12px; color: var(--text-3); white-space: nowrap; }
|
||||
.c-text { font-size: 13.5px; color: var(--text); line-height: 1.6; margin-top: 4px; }
|
||||
.c-file { display: inline-flex; align-items: center; gap: 7px; margin-top: 8px; padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--radius); font-size: 12.5px; font-weight: 600; color: var(--text-2); }
|
||||
.c-file .fi { width: 22px; height: 22px; border-radius: 5px; background: #e25950; color: #fff; display: grid; place-items: center; font-size: 8px; font-weight: 800; }
|
||||
.composer { display: flex; gap: 11px; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
|
||||
.composer .field { flex: 1; }
|
||||
.composer textarea { width: 100%; min-height: 64px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 10px 12px; font-family: inherit; font-size: 13.5px; resize: vertical; color: var(--text); }
|
||||
.composer textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.composer textarea::placeholder { color: var(--text-3); }
|
||||
.composer .crow { display: flex; justify-content: flex-end; margin-top: 9px; }
|
||||
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
|
||||
|
||||
/* sidebar */
|
||||
.side { display: flex; flex-direction: column; gap: 16px; }
|
||||
.side-card { padding: 16px 18px 18px; }
|
||||
.side-field + .side-field { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
|
||||
.side-label { font-size: 12px; font-weight: 600; color: var(--text-3); margin-bottom: 9px; white-space: nowrap; }
|
||||
.status-badge { display: inline-flex; align-items: center; gap: 8px; height: 30px; padding: 0 13px; border: 1px solid var(--blue-border); background: var(--blue-weak); border-radius: 20px; font-size: 13px; font-weight: 600; color: var(--blue); white-space: nowrap; }
|
||||
.status-badge .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--blue); }
|
||||
.status-badge.review { color: var(--amber); background: var(--amber-weak); border-color: var(--amber-border); }
|
||||
.status-badge.review .dot { background: var(--amber); }
|
||||
.assignees { display: flex; flex-direction: column; gap: 9px; }
|
||||
.ass { display: flex; align-items: center; gap: 9px; }
|
||||
.avatar { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; font-size: 11px; 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-f { background: #d0982a; }
|
||||
.ass .nm { font-size: 13px; font-weight: 600; white-space: nowrap; }
|
||||
.ass .rl { font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
|
||||
.dl { display: flex; align-items: center; gap: 9px; font-size: 13.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
|
||||
.dl svg { width: 16px; height: 16px; color: var(--text-3); }
|
||||
.dl .dday { font-size: 11.5px; font-weight: 700; color: var(--amber); background: #fdf4e3; border: 1px solid #f3e2bd; border-radius: 20px; padding: 1px 7px; margin-left: auto; white-space: nowrap; }
|
||||
.files { display: flex; flex-direction: column; gap: 7px; }
|
||||
.file { display: flex; align-items: center; gap: 10px; padding: 8px 9px; border: 1px solid var(--border); border-radius: var(--radius); }
|
||||
.file-ico { width: 28px; height: 28px; border-radius: 6px; display: grid; place-items: center; flex-shrink: 0; font-size: 9px; font-weight: 800; color: #fff; }
|
||||
.fi-img { background: #2aa775; } .fi-zip { background: #8a64d6; }
|
||||
.file-info { min-width: 0; flex: 1; }
|
||||
.file-name { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
|
||||
.file-size { font-size: 11.5px; color: var(--text-3); display: block; }
|
||||
.issuer { display: flex; align-items: center; gap: 10px; }
|
||||
.issuer .nm { font-size: 13px; font-weight: 600; white-space: nowrap; }
|
||||
.issuer .rl { font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
|
||||
.meta-line { font-size: 12px; color: var(--text-3); margin-top: 4px; white-space: nowrap; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="내 업무.html">내 업무</a>
|
||||
<a href="저장소 목록.html" class="active">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg></button>
|
||||
<button class="icon-btn" title="알림"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg></button>
|
||||
<div class="me" style="background:#3d8bf2">박</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page" data-screen-label="업무 상세">
|
||||
<div class="crumb">
|
||||
<a href="저장소 목록.html" class="lnk">저장소</a>
|
||||
<span class="sep">/</span>
|
||||
<a href="저장소 상세.html" class="lnk">3분기 신제품 런칭 캠페인</a>
|
||||
<span class="sep">/</span>
|
||||
<a href="저장소 상세.html" class="lnk">업무</a>
|
||||
<span class="sep">/</span>
|
||||
<b>#9</b>
|
||||
</div>
|
||||
|
||||
<div class="pagehead">
|
||||
<div class="ph-main">
|
||||
<div class="ph-titlerow">
|
||||
<span class="st-badge prog">진행 중</span>
|
||||
<span class="ph-tid">#9</span>
|
||||
</div>
|
||||
<h1 class="ph-title">메인 배너 이미지 2종 (가로/세로) 디자인</h1>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<a class="btn" href="업무 작성.html"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>수정</a>
|
||||
<div class="more-wrap">
|
||||
<button class="btn icon" id="moreBtn" type="button" title="더보기"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="5" r="1.5"/><circle cx="12" cy="12" r="1.5"/><circle cx="12" cy="19" r="1.5"/></svg></button>
|
||||
<div class="menu" id="moreMenu">
|
||||
<button class="menu-item" type="button">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||
업무 복제
|
||||
</button>
|
||||
<button class="menu-item" type="button">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1"/><path d="M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1"/></svg>
|
||||
링크 복사
|
||||
</button>
|
||||
<div class="menu-sep"></div>
|
||||
<button class="menu-item danger" id="deleteOpen" type="button">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
|
||||
업무 삭제
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout">
|
||||
<!-- main -->
|
||||
<section class="card main-card">
|
||||
<div class="sect">
|
||||
<div class="sect-label">업무 내용</div>
|
||||
<div class="content">
|
||||
<p>9월 신제품 런칭 캠페인에 사용할 메인 배너를 가로형/세로형 2종으로 제작합니다. 톤앤매너는 <span class="mention">@브랜드_가이드라인.pdf</span> 기준을 따라주세요.</p>
|
||||
<p>퍼포먼스 광고와 자사몰 상단에 동시 노출되므로, 두 비율 모두 핵심 메시지("민감 피부 저자극")가 명확히 보이도록 구성해주세요. 1차 시안 확정 후 모바일 적응형까지 진행합니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sect">
|
||||
<div class="sect-label">해야 할 일
|
||||
<span class="pr"><span class="progress-bar"><i style="width:33%"></i></span><span class="progress-txt">1 / 3 완료</span></span>
|
||||
</div>
|
||||
<div class="checklist">
|
||||
<div class="citem done">
|
||||
<span class="cbox done"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="ctext">가로형 메인 배너 1920×1080</span>
|
||||
</div>
|
||||
<div class="citem">
|
||||
<span class="cbox"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="ctext">세로형 메인 배너 1080×1920</span>
|
||||
</div>
|
||||
<div class="citem">
|
||||
<span class="cbox"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="ctext">모바일 적응형 600×600</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sect">
|
||||
<div class="sect-label">댓글 <span style="color:var(--text-3);font-weight:500">3</span></div>
|
||||
|
||||
<div class="comment">
|
||||
<span class="c-av av-f">정</span>
|
||||
<div class="c-body">
|
||||
<div class="c-head"><span class="c-name">정태경</span><span class="c-role">지시자</span><span class="c-time">2일 전</span></div>
|
||||
<div class="c-text">가로형부터 확정하고 세로형 진행해주세요. 카피 위치는 좌측 정렬 기준입니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="comment">
|
||||
<span class="c-av av-b">박</span>
|
||||
<div class="c-body">
|
||||
<div class="c-head"><span class="c-name">박지훈</span><span class="c-time">1일 전</span></div>
|
||||
<div class="c-text">가로형 1차 시안 업로드했습니다. 검토 부탁드려요.</div>
|
||||
<div class="c-file"><span class="fi">IMG</span>main_banner_h_v1.png</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="comment">
|
||||
<span class="c-av av-d">최</span>
|
||||
<div class="c-body">
|
||||
<div class="c-head"><span class="c-name">최유진</span><span class="c-time">3시간 전</span></div>
|
||||
<div class="c-text">세로형은 내일 오전까지 공유하겠습니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sys-event">
|
||||
<span class="se-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg></span>
|
||||
<span><b>박지훈</b>님이 승인을 요청했습니다</span>
|
||||
<span class="se-time">2시간 전</span>
|
||||
</div>
|
||||
|
||||
<div class="composer">
|
||||
<span class="c-av" style="background:#3d8bf2">박</span>
|
||||
<div class="field">
|
||||
<textarea placeholder="댓글을 입력하세요…"></textarea>
|
||||
<div class="crow"><button class="btn primary" type="button">댓글 등록</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- sidebar -->
|
||||
<aside class="side">
|
||||
<!-- 승인 대기: 지시자(정태경) 시점 결정 카드 -->
|
||||
<div class="card ap-card request">
|
||||
<div class="ap-card-head">
|
||||
<span class="ap-card-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg></span>
|
||||
<span class="ap-card-title">지시자에게 승인 요청</span>
|
||||
</div>
|
||||
<div class="ap-card-desc">작업을 마쳤다면 지시자 <b style="color:var(--text);font-weight:600">정태경</b>님에게 검토 승인을 요청하세요. 승인되면 업무가 완료 처리됩니다.</div>
|
||||
<div class="ap-card-actions">
|
||||
<button class="ap-btn request-send" id="requestOpen" type="button"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg>승인 요청 보내기</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card side-card">
|
||||
<div class="side-field">
|
||||
<div class="side-label">상태</div>
|
||||
<span class="status-badge"><span class="dot"></span>진행 중</span>
|
||||
</div>
|
||||
<div class="side-field">
|
||||
<div class="side-label">담당자 · 2명</div>
|
||||
<div class="assignees">
|
||||
<div class="ass"><span class="avatar av-b">박</span><span><div class="nm">박지훈</div><div class="rl">퍼포먼스 마케팅</div></span></div>
|
||||
<div class="ass"><span class="avatar av-d">최</span><span><div class="nm">최유진</div><div class="rl">UX 디자인</div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="side-field">
|
||||
<div class="side-label">마감기한</div>
|
||||
<div class="dl">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
|
||||
6월 18일 (목)
|
||||
<span class="dday">D-3</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card side-card">
|
||||
<div class="side-field">
|
||||
<div class="side-label">첨부파일 · 2개</div>
|
||||
<div class="files">
|
||||
<div class="file"><span class="file-ico fi-img">IMG</span><span class="file-info"><span class="file-name">레퍼런스_무드보드.png</span><span class="file-size">3.2 MB</span></span></div>
|
||||
<div class="file"><span class="file-ico fi-zip">ZIP</span><span class="file-info"><span class="file-name">배너_소스_파일.zip</span><span class="file-size">18.4 MB</span></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card side-card">
|
||||
<div class="side-field">
|
||||
<div class="side-label">지시자</div>
|
||||
<div class="issuer"><span class="avatar av-f">정</span><span><div class="nm">정태경</div><div class="rl">마케팅 그룹 리드</div></span></div>
|
||||
<div class="meta-line">6월 8일 지시 · #9</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 삭제 확인 모달 -->
|
||||
<div class="modal-backdrop" id="deleteModal">
|
||||
<div class="modal" role="dialog" aria-modal="true">
|
||||
<div class="modal-body">
|
||||
<div class="modal-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg></div>
|
||||
<h2 class="modal-title">업무를 삭제할까요?</h2>
|
||||
<p class="modal-desc"><b>#9 메인 배너 이미지 2종 (가로/세로) 디자인</b> 업무와 체크리스트·댓글·첨부파일이 영구적으로 삭제됩니다. 이 작업은 되돌릴 수 없습니다.</p>
|
||||
</div>
|
||||
<div class="modal-foot">
|
||||
<button class="mbtn" id="deleteCancel" type="button">취소</button>
|
||||
<button class="mbtn danger" type="button">삭제</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 승인 요청 모달 -->
|
||||
<div class="modal-backdrop" id="requestModal">
|
||||
<div class="modal" role="dialog" aria-modal="true">
|
||||
<div class="modal-body" style="text-align:left;padding:22px 24px 8px">
|
||||
<h2 class="modal-title">승인 요청 보내기</h2>
|
||||
<p class="modal-desc" style="margin:8px 0 14px">지시자 <b>정태경</b>님에게 검토 승인을 요청합니다. 완료한 작업과 전달할 내용을 간단히 적어주세요. 업무가 <b>승인 대기</b> 상태로 변경됩니다.</p>
|
||||
<textarea class="modal-textarea" placeholder="예) 가로형/세로형 메인 배너 1차 제작을 완료했습니다. 검토 부탁드립니다."></textarea>
|
||||
</div>
|
||||
<div class="modal-foot">
|
||||
<button class="mbtn" data-close="requestModal" type="button">취소</button>
|
||||
<button class="mbtn request-send" type="button">요청 보내기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var moreBtn = document.getElementById('moreBtn');
|
||||
var moreMenu = document.getElementById('moreMenu');
|
||||
moreBtn.addEventListener('click', function (e) { e.stopPropagation(); moreMenu.classList.toggle('open'); });
|
||||
document.addEventListener('click', function () { moreMenu.classList.remove('open'); });
|
||||
moreMenu.addEventListener('click', function (e) { e.stopPropagation(); });
|
||||
|
||||
/* 삭제 모달 */
|
||||
var dModal = document.getElementById('deleteModal');
|
||||
document.getElementById('deleteOpen').addEventListener('click', function () { moreMenu.classList.remove('open'); dModal.classList.add('open'); });
|
||||
document.getElementById('deleteCancel').addEventListener('click', function () { dModal.classList.remove('open'); });
|
||||
dModal.addEventListener('click', function (e) { if (e.target === dModal) dModal.classList.remove('open'); });
|
||||
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') dModal.classList.remove('open'); });
|
||||
|
||||
/* 승인 요청 모달 */
|
||||
function openModal(id) { document.getElementById(id).classList.add('open'); }
|
||||
function closeModal(el) { el.classList.remove('open'); }
|
||||
document.getElementById('requestOpen').addEventListener('click', function () { openModal('requestModal'); });
|
||||
document.querySelectorAll('[data-close]').forEach(function (b) {
|
||||
b.addEventListener('click', function () { closeModal(document.getElementById(b.getAttribute('data-close'))); });
|
||||
});
|
||||
var reqModal = document.getElementById('requestModal');
|
||||
reqModal.addEventListener('click', function (e) { if (e.target === reqModal) closeModal(reqModal); });
|
||||
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeModal(reqModal); });
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,482 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>새 업무 작성 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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;
|
||||
--amber: #b7791f;
|
||||
--radius: 6px;
|
||||
--radius-sm: 4px;
|
||||
--shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
--shadow-md: 0 4px 16px rgba(20,24,33,.10), 0 1px 3px rgba(20,24,33,.06);
|
||||
--shadow-pop: 0 8px 28px rgba(20,24,33,.16), 0 2px 6px rgba(20,24,33,.08);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* ---------- Top app bar ---------- */
|
||||
.topbar {
|
||||
height: 52px;
|
||||
background: var(--panel);
|
||||
border-bottom: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 28px;
|
||||
padding: 0 20px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
}
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo {
|
||||
width: 26px; height: 26px; border-radius: 7px;
|
||||
background: linear-gradient(135deg, #5b54f0, #4338ca);
|
||||
display: grid; place-items: center; color: #fff;
|
||||
font-size: 15px; font-weight: 800;
|
||||
box-shadow: 0 2px 6px rgba(79,70,229,.35);
|
||||
}
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a {
|
||||
color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500;
|
||||
padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap;
|
||||
}
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.crumb .lnk { color: var(--text-2); font-weight: 600; text-decoration: none; }
|
||||
.crumb .lnk:hover { color: var(--accent); }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn {
|
||||
width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent;
|
||||
color: var(--text-2); display: grid; place-items: center; cursor: pointer;
|
||||
}
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me {
|
||||
width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center;
|
||||
font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px;
|
||||
}
|
||||
|
||||
/* ---------- Page header ---------- */
|
||||
.page { max-width: 1240px; margin: 0 auto; padding: 0 24px 60px; }
|
||||
.crumb { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12.5px; padding: 16px 0 0; white-space: nowrap; }
|
||||
.crumb b { color: var(--text-2); font-weight: 600; }
|
||||
.crumb .sep { opacity: .5; }
|
||||
.pagehead { display: flex; align-items: center; gap: 16px; padding: 8px 0 18px; }
|
||||
.pagehead h1 { font-size: 21px; font-weight: 700; letter-spacing: -.4px; white-space: nowrap; flex-shrink: 0; }
|
||||
.draft-tag {
|
||||
font-size: 11.5px; font-weight: 600; color: var(--amber); background: #fdf4e3;
|
||||
border: 1px solid #f3e2bd; padding: 3px 8px; border-radius: 20px; line-height: 1; white-space: nowrap;
|
||||
}
|
||||
.pagehead .actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.btn {
|
||||
height: 34px; padding: 0 14px; border-radius: var(--radius); font-size: 13.5px; 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: 6px; line-height: 1; text-decoration: none;
|
||||
}
|
||||
.btn:hover { background: #f7f8fa; color: var(--text); }
|
||||
.btn.ghost { border-color: transparent; background: transparent; }
|
||||
.btn.ghost:hover { background: #eceef1; }
|
||||
.btn.primary {
|
||||
background: var(--accent); border-color: var(--accent); color: #fff;
|
||||
box-shadow: 0 1px 2px rgba(79,70,229,.4);
|
||||
}
|
||||
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
|
||||
|
||||
/* ---------- Layout ---------- */
|
||||
.layout { display: grid; grid-template-columns: 1fr 348px; gap: 20px; align-items: start; }
|
||||
|
||||
.card {
|
||||
background: var(--panel); border: 1px solid var(--border);
|
||||
border-radius: 10px; box-shadow: var(--shadow-sm);
|
||||
}
|
||||
.main-card { padding: 8px 26px 26px; }
|
||||
|
||||
/* Title field */
|
||||
.title-input {
|
||||
width: 100%; border: none; outline: none; background: transparent;
|
||||
font-family: inherit; font-size: 24px; font-weight: 700; letter-spacing: -.5px;
|
||||
color: var(--text); padding: 20px 0 14px; line-height: 1.3;
|
||||
}
|
||||
.title-input::placeholder { color: #c4c8cf; }
|
||||
|
||||
.divider { height: 1px; background: var(--border); margin: 0 -26px; }
|
||||
|
||||
.field { padding-top: 22px; }
|
||||
.field-label {
|
||||
display: flex; align-items: center; gap: 7px;
|
||||
font-size: 12.5px; font-weight: 600; color: var(--text-2); margin-bottom: 9px; white-space: nowrap;
|
||||
}
|
||||
.field-label .req { color: var(--accent); font-weight: 700; }
|
||||
.field-label .hint { margin-left: auto; font-weight: 500; color: var(--text-3); font-size: 12px; }
|
||||
|
||||
/* Content editor */
|
||||
.editor { border: 1px solid var(--border-strong); border-radius: var(--radius); overflow: hidden; }
|
||||
.editor:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.toolbar {
|
||||
display: flex; align-items: center; gap: 2px; padding: 6px 8px;
|
||||
border-bottom: 1px solid var(--border); background: #fafbfc;
|
||||
}
|
||||
.tb {
|
||||
height: 28px; min-width: 28px; padding: 0 7px; border-radius: var(--radius-sm); border: none; background: transparent;
|
||||
color: var(--text-2); font-size: 13px; font-weight: 600; cursor: pointer; display: grid; place-items: center;
|
||||
}
|
||||
.tb:hover { background: #eceef1; color: var(--text); }
|
||||
.tb svg { width: 16px; height: 16px; }
|
||||
.tb-sep { width: 1px; height: 18px; background: var(--border-strong); margin: 0 5px; }
|
||||
.editor-body { padding: 14px 16px; font-size: 14px; color: var(--text); min-height: 150px; line-height: 1.65; }
|
||||
.editor-body p { margin-bottom: 11px; }
|
||||
.editor-body p:last-child { margin-bottom: 0; }
|
||||
.editor-body .mention { color: var(--accent); font-weight: 600; background: var(--accent-weak); padding: 0 3px; border-radius: 3px; }
|
||||
|
||||
/* Checklist */
|
||||
.check-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
|
||||
.progress-wrap { margin-left: auto; display: flex; align-items: center; gap: 9px; }
|
||||
.progress-bar { width: 92px; height: 6px; border-radius: 4px; background: #eceef1; overflow: hidden; }
|
||||
.progress-bar > i { display: block; height: 100%; background: var(--green); border-radius: 4px; }
|
||||
.progress-txt { font-size: 12px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
|
||||
|
||||
.checklist { display: flex; flex-direction: column; }
|
||||
.check-item {
|
||||
display: flex; align-items: center; gap: 11px; padding: 9px 0;
|
||||
border-radius: var(--radius-sm); position: relative;
|
||||
}
|
||||
.check-item:hover { background: #f7f8fa; }
|
||||
.check-item .grip { position: absolute; left: -21px; top: 50%; transform: translateY(-50%); color: #c4c8cf; cursor: grab; opacity: 0; font-size: 14px; line-height: 1; letter-spacing: -2px; }
|
||||
.check-item:hover .grip { opacity: 1; }
|
||||
.cbox {
|
||||
width: 18px; height: 18px; border-radius: 5px; border: 1.5px solid var(--border-strong);
|
||||
flex-shrink: 0; display: grid; place-items: center; background: #fff; cursor: pointer;
|
||||
}
|
||||
.cbox.done { background: var(--green); border-color: var(--green); }
|
||||
.cbox svg { width: 12px; height: 12px; color: #fff; opacity: 0; }
|
||||
.cbox.done svg { opacity: 1; }
|
||||
.check-item .txt { font-size: 13.5px; color: var(--text); flex: 1; }
|
||||
.check-item.done .txt { color: var(--text-3); text-decoration: line-through; }
|
||||
.check-item .row-del { opacity: 0; color: var(--text-3); cursor: pointer; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 4px; }
|
||||
.check-item:hover .row-del { opacity: 1; }
|
||||
.check-item .row-del:hover { background: #eceef1; color: #d6455d; }
|
||||
.add-row {
|
||||
display: flex; align-items: center; gap: 11px; padding: 10px 0 4px 0; color: var(--text-3);
|
||||
font-size: 13.5px; cursor: text;
|
||||
}
|
||||
.add-row .plus { width: 18px; height: 18px; border-radius: 5px; border: 1.5px dashed var(--border-strong); display: grid; place-items: center; font-size: 13px; line-height: 1; }
|
||||
|
||||
/* nested subtasks */
|
||||
.task-group + .task-group { border-top: 1px solid var(--border); }
|
||||
.check-item.parent .txt { font-weight: 600; }
|
||||
.sub-count {
|
||||
font-size: 11px; font-weight: 600; color: var(--text-2); background: #f1f2f4;
|
||||
border: 1px solid var(--border); border-radius: 20px; padding: 1px 8px; line-height: 1.55; white-space: nowrap;
|
||||
}
|
||||
.check-item.parent.done .sub-count { color: var(--green); background: var(--green-weak); border-color: #cde8d8; }
|
||||
.subtasks { margin-left: 31px; padding-left: 14px; border-left: 1.5px solid var(--border); display: flex; flex-direction: column; }
|
||||
.subtask {
|
||||
display: flex; align-items: center; gap: 10px; padding: 6px 0;
|
||||
border-radius: var(--radius-sm); position: relative;
|
||||
}
|
||||
.subtask:hover { background: #f7f8fa; }
|
||||
.subtask .grip { position: absolute; left: -19px; top: 50%; transform: translateY(-50%); color: #c4c8cf; cursor: grab; opacity: 0; font-size: 13px; line-height: 1; letter-spacing: -2px; }
|
||||
.subtask:hover .grip { opacity: 1; }
|
||||
.cbox.sm { width: 16px; height: 16px; border-radius: 5px; }
|
||||
.cbox.sm svg { width: 11px; height: 11px; }
|
||||
.subtask .txt { font-size: 13px; color: var(--text-2); flex: 1; }
|
||||
.subtask.done .txt { color: var(--text-3); text-decoration: line-through; }
|
||||
.subtask .row-del { opacity: 0; color: var(--text-3); cursor: pointer; width: 22px; height: 22px; display: grid; place-items: center; border-radius: 4px; }
|
||||
.subtask:hover .row-del { opacity: 1; }
|
||||
.subtask .row-del:hover { background: #eceef1; color: #d6455d; }
|
||||
.add-sub {
|
||||
display: flex; align-items: center; gap: 9px; margin-left: 31px; padding: 7px 0 9px 0;
|
||||
color: var(--text-3); font-size: 12.5px; cursor: text;
|
||||
}
|
||||
.add-sub .plus-sm { width: 16px; height: 16px; border-radius: 5px; border: 1.5px dashed var(--border-strong); display: grid; place-items: center; font-size: 12px; line-height: 1; }
|
||||
|
||||
/* ---------- Sidebar ---------- */
|
||||
.side { display: flex; flex-direction: column; gap: 16px; }
|
||||
.side-card { padding: 16px 18px 18px; }
|
||||
.side-field + .side-field { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--border); }
|
||||
.side-label { font-size: 12px; font-weight: 600; color: var(--text-2); margin-bottom: 9px; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
|
||||
.side-label .req { color: var(--accent); }
|
||||
|
||||
/* assignee combobox */
|
||||
.combo { position: relative; }
|
||||
.combo-field {
|
||||
border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 7px 8px; background: #fff;
|
||||
display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
|
||||
}
|
||||
.combo-field:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.combo-caret { color: var(--text-3); display: grid; place-items: center; margin-left: auto; flex-shrink: 0; }
|
||||
.combo-caret svg { width: 16px; height: 16px; }
|
||||
.chip {
|
||||
display: inline-flex; align-items: center; gap: 6px; background: #f1f2f4; border: 1px solid var(--border);
|
||||
border-radius: 20px; padding: 3px 8px 3px 3px; font-size: 12.5px; font-weight: 600; color: var(--text); white-space: nowrap;
|
||||
}
|
||||
.chip .x { color: var(--text-3); cursor: pointer; font-size: 13px; line-height: 1; margin-left: 1px; }
|
||||
.chip .x:hover { color: #d6455d; }
|
||||
.combo-input { flex: 1; min-width: 70px; border: none; outline: none; font-family: inherit; font-size: 13px; padding: 4px 2px; background: transparent; }
|
||||
.combo-input::placeholder { color: var(--text-3); }
|
||||
|
||||
.avatar { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; font-size: 10.5px; 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; }
|
||||
|
||||
.dropdown {
|
||||
position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 40;
|
||||
background: #fff; border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--shadow-pop);
|
||||
padding: 6px; overflow: hidden;
|
||||
}
|
||||
.dd-search { font-size: 11px; color: var(--text-3); padding: 4px 8px 6px; font-weight: 600; }
|
||||
.dd-item {
|
||||
display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: var(--radius-sm); cursor: pointer;
|
||||
}
|
||||
.dd-item:hover { background: #f5f6f8; }
|
||||
.dd-item.sel { background: var(--accent-weak); }
|
||||
.dd-meta { display: flex; flex-direction: column; min-width: 0; flex: 1; }
|
||||
.dd-name { font-size: 13px; font-weight: 600; color: var(--text); line-height: 1.3; }
|
||||
.dd-role { font-size: 11.5px; color: var(--text-3); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.dd-check { flex-shrink: 0; width: 17px; height: 17px; border-radius: 5px; border: 1.5px solid var(--border-strong); display: grid; place-items: center; background: #fff; }
|
||||
.dd-item.sel .dd-check { background: var(--accent); border-color: var(--accent); }
|
||||
.dd-check svg { width: 11px; height: 11px; color: #fff; opacity: 0; }
|
||||
.dd-item.sel .dd-check svg { opacity: 1; }
|
||||
|
||||
/* date */
|
||||
.input {
|
||||
width: 100%; height: 38px; border: 1px solid var(--border-strong); border-radius: var(--radius);
|
||||
padding: 0 11px; font-family: inherit; font-size: 13.5px; color: var(--text); background: #fff;
|
||||
display: flex; align-items: center; gap: 9px;
|
||||
}
|
||||
.input .ico { color: var(--text-3); display: grid; place-items: center; }
|
||||
.input .ico svg { width: 16px; height: 16px; }
|
||||
.date-meta { font-size: 12px; color: var(--amber); font-weight: 600; margin-top: 7px; display: flex; align-items: center; gap: 5px; }
|
||||
.date-meta .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--amber); }
|
||||
|
||||
/* attachments */
|
||||
.dropzone {
|
||||
border: 1.5px dashed var(--border-strong); border-radius: var(--radius); padding: 13px;
|
||||
text-align: center; color: var(--text-3); font-size: 12.5px; cursor: pointer; background: #fafbfc;
|
||||
}
|
||||
.dropzone:hover { border-color: var(--accent-border); background: var(--accent-weak); color: var(--accent); }
|
||||
.dropzone b { color: var(--accent); font-weight: 600; }
|
||||
.files { display: flex; flex-direction: column; gap: 7px; margin-bottom: 10px; }
|
||||
.file {
|
||||
display: flex; align-items: center; gap: 10px; padding: 8px 9px; border: 1px solid var(--border);
|
||||
border-radius: var(--radius); background: #fff;
|
||||
}
|
||||
.file-ico { width: 30px; height: 30px; border-radius: 6px; display: grid; place-items: center; flex-shrink: 0; font-size: 10px; font-weight: 800; color: #fff; letter-spacing: -.3px; }
|
||||
.fi-pdf { background: #e25950; } .fi-zip { background: #8a64d6; } .fi-doc { background: #3d8bf2; }
|
||||
.file-info { min-width: 0; flex: 1; }
|
||||
.file-name { font-size: 12.5px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
|
||||
.file-size { font-size: 11.5px; color: var(--text-3); display: block; }
|
||||
.file .x { color: var(--text-3); cursor: pointer; width: 22px; height: 22px; display: grid; place-items: center; border-radius: 4px; flex-shrink: 0; }
|
||||
.file .x:hover { background: #eceef1; color: #d6455d; }
|
||||
|
||||
/* issuer meta */
|
||||
.issuer { display: flex; align-items: center; gap: 10px; }
|
||||
.issuer .avatar { width: 30px; height: 30px; font-size: 12px; }
|
||||
.issuer .nm { font-size: 13px; font-weight: 600; }
|
||||
.issuer .rl { font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
|
||||
.side-foot { font-size: 11.5px; color: var(--text-3); line-height: 1.6; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="내 업무.html">내 업무</a>
|
||||
<a href="저장소 목록.html" class="active">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색">
|
||||
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>
|
||||
</button>
|
||||
<button class="icon-btn" title="알림">
|
||||
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg>
|
||||
</button>
|
||||
<div class="me">정</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page">
|
||||
<div class="crumb"><a href="저장소 목록.html" class="lnk">저장소</a> <span class="sep">/</span> <a href="저장소 상세.html" class="lnk">3분기 신제품 런칭 캠페인</a> <span class="sep">/</span> 새 업무</div>
|
||||
<div class="pagehead">
|
||||
<h1>새 업무 작성</h1>
|
||||
<span class="draft-tag">임시저장됨 · 방금</span>
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="저장소 상세.html">취소</a>
|
||||
<button class="btn">임시저장</button>
|
||||
<button class="btn primary">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg>
|
||||
지시 보내기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout">
|
||||
<!-- ============ MAIN ============ -->
|
||||
<section class="card main-card">
|
||||
<input class="title-input" value="3분기 신제품 런칭 캠페인 소재 제작" placeholder="업무 제목을 입력하세요">
|
||||
<div class="divider"></div>
|
||||
|
||||
<!-- 내용 -->
|
||||
<div class="field">
|
||||
<div class="field-label"><span class="req">*</span> 업무 내용</div>
|
||||
<div class="editor">
|
||||
<div class="toolbar">
|
||||
<button class="tb" style="font-weight:800">B</button>
|
||||
<button class="tb" style="font-style:italic;font-family:Georgia,serif">I</button>
|
||||
<button class="tb" style="text-decoration:underline">U</button>
|
||||
<span class="tb-sep"></span>
|
||||
<button class="tb" title="목록"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/></svg></button>
|
||||
<button class="tb" title="번호 목록"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 6h11M10 12h11M10 18h11M4 6h1v4M4 10h2M6 18H4l2-3H4"/></svg></button>
|
||||
<span class="tb-sep"></span>
|
||||
<button class="tb" title="링크"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1"/><path d="M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1"/></svg></button>
|
||||
<button class="tb" title="멘션">@</button>
|
||||
<button class="tb" title="코드"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m16 18 6-6-6-6M8 6l-6 6 6 6"/></svg></button>
|
||||
</div>
|
||||
<div class="editor-body">
|
||||
<p>9월 신제품(라인 클렌저) 정식 출시에 맞춰 사용할 캠페인 소재 일체를 제작합니다. 톤앤매너는 <span class="mention">@브랜드_가이드라인.pdf</span> 기준을 따라주세요.</p>
|
||||
<p>퍼포먼스 광고용 배너와 자사몰 상세페이지를 우선순위로 진행하고, SNS 콘텐츠는 1차 시안 확정 후 착수합니다. 카피는 "민감 피부 저자극" 메시지를 핵심으로 잡되, 과장 광고 표현은 법무 검토를 반드시 거쳐주세요.</p>
|
||||
<p>각 산출물은 아래 체크리스트 기준으로 관리하며, 진행 상황은 업무 상세에서 코멘트로 공유 바랍니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 체크리스트 -->
|
||||
<div class="field">
|
||||
<div class="check-head">
|
||||
<div class="field-label" style="margin-bottom:0">해야 할 일</div>
|
||||
<div class="progress-wrap">
|
||||
<div class="progress-bar"><i style="width:40%"></i></div>
|
||||
<span class="progress-txt">2 / 5 완료</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="checklist">
|
||||
<div class="check-item done">
|
||||
<span class="grip">⠿</span>
|
||||
<span class="cbox done"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="txt">캠페인 핵심 메시지 3개 시안 작성</span>
|
||||
<span class="row-del"><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg></span>
|
||||
</div>
|
||||
<div class="check-item done">
|
||||
<span class="grip">⠿</span>
|
||||
<span class="cbox done"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="txt">레퍼런스 리서치 및 무드보드 정리</span>
|
||||
<span class="row-del"><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg></span>
|
||||
</div>
|
||||
<div class="check-item">
|
||||
<span class="grip">⠿</span>
|
||||
<span class="cbox"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="txt">메인 배너 이미지 2종 (가로/세로) 디자인</span>
|
||||
<span class="row-del"><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg></span>
|
||||
</div>
|
||||
<div class="check-item">
|
||||
<span class="grip">⠿</span>
|
||||
<span class="cbox"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="txt">상세페이지 카피라이팅 및 법무 검토</span>
|
||||
<span class="row-del"><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg></span>
|
||||
</div>
|
||||
<div class="check-item">
|
||||
<span class="grip">⠿</span>
|
||||
<span class="cbox"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span class="txt">최종 산출물 공유 드라이브 업로드</span>
|
||||
<span class="row-del"><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg></span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="add-row"><span class="plus">+</span> 항목 추가</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ SIDEBAR ============ -->
|
||||
<aside class="side">
|
||||
<div class="card side-card">
|
||||
<!-- 담당자 (열린 드롭다운) -->
|
||||
<div class="side-field">
|
||||
<div class="side-label"><span class="req">*</span> 담당자 <span style="color:var(--text-3);font-weight:500">· 3명</span></div>
|
||||
<div class="combo">
|
||||
<div class="combo-field">
|
||||
<span class="chip"><span class="avatar av-a">김</span>김서연 <span class="x">×</span></span>
|
||||
<span class="chip"><span class="avatar av-b">박</span>박지훈 <span class="x">×</span></span>
|
||||
<span class="chip"><span class="avatar av-c">이</span>이도윤 <span class="x">×</span></span>
|
||||
<input class="combo-input" placeholder="이름 검색…" value="">
|
||||
<span class="combo-caret"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card side-card">
|
||||
<!-- 마감기한 -->
|
||||
<div class="side-field">
|
||||
<div class="side-label"><span class="req">*</span> 마감기한</div>
|
||||
<div class="input">
|
||||
<span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg></span>
|
||||
2026년 6월 30일 (화) 18:00
|
||||
</div>
|
||||
<div class="date-meta"><span class="dot"></span> 마감까지 15일 남음</div>
|
||||
</div>
|
||||
|
||||
<!-- 첨부파일 -->
|
||||
<div class="side-field">
|
||||
<div class="side-label">첨부파일 <span style="color:var(--text-3);font-weight:500">· 3개</span></div>
|
||||
<div class="files">
|
||||
<div class="file">
|
||||
<span class="file-ico fi-pdf">PDF</span>
|
||||
<span class="file-info"><span class="file-name">캠페인_브리프_v2.pdf</span><span class="file-size">2.4 MB</span></span>
|
||||
<span class="x"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg></span>
|
||||
</div>
|
||||
<div class="file">
|
||||
<span class="file-ico fi-pdf">PDF</span>
|
||||
<span class="file-info"><span class="file-name">브랜드_가이드라인.pdf</span><span class="file-size">8.1 MB</span></span>
|
||||
<span class="x"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg></span>
|
||||
</div>
|
||||
<div class="file">
|
||||
<span class="file-ico fi-zip">ZIP</span>
|
||||
<span class="file-info"><span class="file-name">레퍼런스_이미지.zip</span><span class="file-size">34.7 MB</span></span>
|
||||
<span class="x"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6 6 18M6 6l12 12"/></svg></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropzone">파일을 끌어다 놓거나 <b>찾아보기</b></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card side-card">
|
||||
<div class="side-field" style="border:none;padding:0;margin:0">
|
||||
<div class="side-label">지시자</div>
|
||||
<div class="issuer">
|
||||
<span class="avatar av-f">정</span>
|
||||
<span><div class="nm">정태경</div><div class="rl">마케팅 그룹 리드</div></span>
|
||||
</div>
|
||||
<div class="side-foot" style="margin-top:12px">지시를 보내면 담당자 3명에게 알림이 전송되고, 업무가 각자의 ‘내 업무’에 추가됩니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,430 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>q3-launch-campaign · 멤버 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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; --red: #d6455d; --amber: #b7791f;
|
||||
--radius: 6px; --radius-sm: 4px; --shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* topbar */
|
||||
.topbar { height: 52px; background: var(--panel); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 28px; padding: 0 20px; position: sticky; top: 0; z-index: 50; }
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo { width: 26px; height: 26px; border-radius: 7px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; box-shadow: 0 2px 6px rgba(79,70,229,.35); }
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a { color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500; padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap; }
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px; }
|
||||
|
||||
/* page */
|
||||
.page { max-width: 1080px; margin: 0 auto; padding: 0 24px 70px; }
|
||||
.crumb { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12.5px; padding: 18px 0 12px; white-space: nowrap; }
|
||||
.crumb .lnk { color: var(--text-2); font-weight: 600; text-decoration: none; }
|
||||
.crumb .lnk:hover { color: var(--accent); }
|
||||
.crumb .sep { opacity: .5; }
|
||||
.crumb b { color: var(--text-2); font-weight: 600; }
|
||||
|
||||
/* btn */
|
||||
.btn { height: 36px; padding: 0 15px; border-radius: var(--radius); font-size: 13.5px; 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: 6px; line-height: 1; text-decoration: none; white-space: nowrap; }
|
||||
.btn:hover { background: #f7f8fa; color: var(--text); }
|
||||
.btn svg { width: 15px; height: 15px; }
|
||||
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
|
||||
|
||||
/* repo header */
|
||||
.repo-head { display: flex; align-items: flex-start; gap: 16px; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 20px 22px; box-shadow: var(--shadow-sm); }
|
||||
.repo-ico { width: 46px; height: 46px; border-radius: 10px; background: var(--accent-weak); color: var(--accent); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.repo-ico svg { width: 24px; height: 24px; }
|
||||
.rh-main { flex: 1; min-width: 0; }
|
||||
.rh-title { display: flex; align-items: center; gap: 10px; }
|
||||
.rh-name { font-size: 18px; font-weight: 700; letter-spacing: -.3px; white-space: nowrap; }
|
||||
.rh-name .owner { color: var(--text-3); font-weight: 500; }
|
||||
.rh-slug { font-size: 12.5px; color: var(--text-3); margin-top: 5px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
.vis { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 20px; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; line-height: 1.5; }
|
||||
.vis svg { width: 11px; height: 11px; }
|
||||
.vis.private { color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); }
|
||||
.rh-desc { font-size: 13.5px; color: var(--text-2); margin-top: 6px; }
|
||||
.rh-meta { display: flex; align-items: center; gap: 15px; margin-top: 12px; font-size: 12px; color: var(--text-3); }
|
||||
.rh-meta .mi { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
|
||||
.rh-meta .mi svg { width: 13px; height: 13px; }
|
||||
.rh-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
|
||||
|
||||
.avatar { width: 21px; height: 21px; border-radius: 50%; display: grid; place-items: center; font-size: 10px; font-weight: 700; color: #fff; flex-shrink: 0; }
|
||||
.avstack { display: flex; align-items: center; }
|
||||
.avstack .avatar { margin-left: -7px; box-shadow: 0 0 0 2px #fff; }
|
||||
.avstack .avatar:first-child { margin-left: 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; }
|
||||
|
||||
/* tabs */
|
||||
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin: 20px 0 6px; }
|
||||
.tabs a { padding: 10px 14px; font-size: 13.5px; font-weight: 600; color: var(--text-2); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
|
||||
.tabs a:hover { color: var(--text); }
|
||||
.tabs a.active { color: var(--accent); border-bottom-color: var(--accent); }
|
||||
.tabs a .tb-label { line-height: 1; }
|
||||
.tabs a .tb-count { font-size: 11px; font-weight: 600; color: var(--text-2); background: #f1f2f4; border-radius: 20px; padding: 0 7px; height: 17px; min-width: 17px; display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
|
||||
.tabs a.active .tb-count { background: var(--accent-weak); color: var(--accent); }
|
||||
|
||||
.tab-note { font-size: 12.5px; color: var(--text-3); margin: 12px 0 16px; display: flex; align-items: center; gap: 7px; }
|
||||
.tab-note svg { width: 14px; height: 14px; color: var(--text-3); flex-shrink: 0; }
|
||||
|
||||
/* toolbar */
|
||||
.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
|
||||
.search { display: flex; align-items: center; gap: 8px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; width: 240px; }
|
||||
.search:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.search svg { width: 16px; height: 16px; color: var(--text-3); }
|
||||
.search input { border: none; outline: none; flex: 1; min-width: 0; font-family: inherit; font-size: 13.5px; background: transparent; }
|
||||
.search input::placeholder { color: var(--text-3); }
|
||||
.segmented { display: flex; background: #eceef1; border-radius: var(--radius); padding: 3px; gap: 2px; }
|
||||
.segmented button { border: none; background: transparent; font-family: inherit; font-size: 13px; font-weight: 600; color: var(--text-2); padding: 5px 12px; border-radius: 4px; cursor: pointer; white-space: nowrap; display: flex; align-items: center; gap: 6px; }
|
||||
.segmented button.active { background: #fff; color: var(--text); box-shadow: var(--shadow-sm); }
|
||||
.segmented button .n { font-size: 11px; color: var(--text-3); font-weight: 600; }
|
||||
.segmented button.active .n { color: var(--accent); }
|
||||
|
||||
/* member list */
|
||||
.list { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-sm); overflow: hidden; }
|
||||
.mem-row { display: flex; align-items: center; gap: 14px; padding: 14px 18px; border-top: 1px solid var(--border); }
|
||||
.mem-row:first-child { border-top: none; }
|
||||
.mem-row:hover { background: #fafbfc; }
|
||||
.mem-av { width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; font-size: 14px; font-weight: 700; color: #fff; flex-shrink: 0; }
|
||||
.mem-info { flex: 1; min-width: 0; }
|
||||
.mem-name { font-size: 14px; font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 8px; }
|
||||
.you-pill { font-size: 10.5px; font-weight: 700; color: var(--accent); background: var(--accent-weak); border: 1px solid var(--accent-border); border-radius: 20px; padding: 1px 7px; line-height: 1.5; }
|
||||
.mem-sub { font-size: 12.5px; color: var(--text-3); margin-top: 2px; }
|
||||
.mem-sub .dot { margin: 0 6px; opacity: .5; }
|
||||
.mem-tasks { font-size: 12.5px; color: var(--text-2); width: 86px; text-align: right; flex-shrink: 0; white-space: nowrap; }
|
||||
.mem-tasks b { color: var(--text); }
|
||||
.mem-tasks.zero { color: var(--text-3); }
|
||||
|
||||
/* role control */
|
||||
.role { display: inline-flex; align-items: center; gap: 7px; height: 32px; padding: 0 11px; border: 1px solid var(--border-strong); border-radius: var(--radius); font-size: 13px; font-weight: 600; color: var(--text-2); background: #fff; cursor: pointer; white-space: nowrap; width: 104px; }
|
||||
.role:hover { background: #f7f8fa; }
|
||||
.role .role-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-3); flex-shrink: 0; }
|
||||
.role.admin { color: var(--accent); border-color: var(--accent-border); background: var(--accent-weak); }
|
||||
.role.admin .role-dot { background: var(--accent); }
|
||||
.role .caret { margin-left: auto; color: var(--text-3); display: grid; place-items: center; }
|
||||
.role .caret svg { width: 14px; height: 14px; }
|
||||
.role.fixed { background: #f1f2f4; cursor: not-allowed; color: var(--text-2); border-color: var(--border-strong); }
|
||||
.role.fixed .role-dot { background: var(--accent); }
|
||||
.role.fixed .caret { color: var(--text-3); }
|
||||
.role.fixed .lock { margin-left: auto; color: var(--text-3); display: grid; place-items: center; }
|
||||
.role.fixed .lock svg { width: 13px; height: 13px; }
|
||||
|
||||
.mem-remove { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-3); display: grid; place-items: center; cursor: pointer; flex-shrink: 0; opacity: 0; }
|
||||
.mem-row:hover .mem-remove { opacity: 1; }
|
||||
.mem-remove:hover { background: #f1f2f4; color: var(--red); }
|
||||
.mem-remove svg { width: 16px; height: 16px; }
|
||||
.mem-remove.disabled { opacity: 0 !important; pointer-events: none; }
|
||||
|
||||
/* invite modal */
|
||||
.modal-backdrop { position: fixed; inset: 0; background: rgba(20,24,33,.5); display: none; align-items: center; justify-content: center; z-index: 100; padding: 24px; }
|
||||
.modal-backdrop.open { display: flex; }
|
||||
.modal { width: 100%; max-width: 524px; background: #fff; border-radius: 14px; box-shadow: 0 24px 64px rgba(20,24,33,.32); overflow: hidden; animation: pop .14s ease-out; }
|
||||
@keyframes pop { from { transform: translateY(8px) scale(.98); opacity: 0; } to { transform: none; opacity: 1; } }
|
||||
.modal-head { display: flex; align-items: flex-start; gap: 12px; padding: 22px 24px 16px; }
|
||||
.modal-head h2 { font-size: 18px; font-weight: 700; letter-spacing: -.3px; }
|
||||
.modal-head .mh-sub { font-size: 13px; color: var(--text-2); margin-top: 4px; }
|
||||
.modal-close { margin-left: auto; width: 32px; height: 32px; border: none; background: transparent; color: var(--text-3); border-radius: var(--radius-sm); display: grid; place-items: center; cursor: pointer; flex-shrink: 0; }
|
||||
.modal-close:hover { background: #f1f2f4; color: var(--text); }
|
||||
.modal-close svg { width: 18px; height: 18px; }
|
||||
.modal-body { padding: 4px 24px 8px; }
|
||||
.m-label { font-size: 12.5px; font-weight: 600; color: var(--text-2); margin-bottom: 8px; display: block; }
|
||||
|
||||
.icombo { position: relative; }
|
||||
.icombo-field { border: 1px solid var(--accent); border-radius: var(--radius); padding: 7px 8px; background: #fff; box-shadow: 0 0 0 3px var(--accent-weak); display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
|
||||
.ichip { display: inline-flex; align-items: center; gap: 6px; background: #f1f2f4; border: 1px solid var(--border); border-radius: 20px; padding: 3px 8px 3px 4px; font-size: 12.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
|
||||
.ichip.ext { background: var(--accent-weak); border-color: var(--accent-border); color: var(--accent); }
|
||||
.ichip .x { color: var(--text-3); cursor: pointer; font-size: 13px; line-height: 1; }
|
||||
.ichip .x:hover { color: var(--red); }
|
||||
.icombo-input { flex: 1; min-width: 120px; border: none; outline: none; font-family: inherit; font-size: 13px; padding: 4px 2px; background: transparent; }
|
||||
.icombo-input::placeholder { color: var(--text-3); }
|
||||
.idd { display: none; position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 5; background: #fff; border: 1px solid var(--border); border-radius: 9px; box-shadow: 0 12px 32px rgba(20,24,33,.16); padding: 6px; }
|
||||
.icombo .idd.show { display: block; }
|
||||
.idd-cap { font-size: 11px; color: var(--text-3); font-weight: 600; padding: 5px 8px; }
|
||||
.idd-item { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: var(--radius-sm); cursor: pointer; }
|
||||
.idd-item:hover { background: #f5f6f8; }
|
||||
.idd-item .nm { font-size: 13px; font-weight: 600; white-space: nowrap; }
|
||||
.idd-item .em { font-size: 12px; color: var(--text-3); margin-left: auto; white-space: nowrap; flex-shrink: 0; }
|
||||
.idd-invite { display: flex; align-items: center; gap: 10px; padding: 8px; border-radius: var(--radius-sm); cursor: pointer; border-top: 1px solid var(--border); margin-top: 4px; }
|
||||
.idd-invite:hover { background: var(--accent-weak); }
|
||||
.idd-invite .pl { width: 26px; height: 26px; border-radius: 50%; background: var(--accent-weak); color: var(--accent); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.idd-invite .pl svg { width: 15px; height: 15px; }
|
||||
.idd-invite .t1 { font-size: 13px; font-weight: 600; color: var(--accent); }
|
||||
.idd-invite .t2 { font-size: 11.5px; color: var(--text-3); }
|
||||
|
||||
.m-row { display: flex; gap: 12px; margin-top: 18px; }
|
||||
.m-role { flex: 0 0 150px; }
|
||||
.m-grow { flex: 1; }
|
||||
.select-wrap { position: relative; }
|
||||
.select-wrap select { appearance: none; -webkit-appearance: none; width: 100%; height: 40px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 34px 0 12px; font-family: inherit; font-size: 13.5px; font-weight: 600; color: var(--text); background: #fff; cursor: pointer; }
|
||||
.select-wrap select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.select-wrap .caret { position: absolute; right: 11px; top: 50%; transform: translateY(-50%); color: var(--text-3); pointer-events: none; display: grid; place-items: center; }
|
||||
.select-wrap .caret svg { width: 15px; height: 15px; }
|
||||
.m-input { width: 100%; height: 40px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 12px; font-family: inherit; font-size: 13.5px; color: var(--text); background: #fff; }
|
||||
.m-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.m-input::placeholder { color: var(--text-3); }
|
||||
.role-hint { font-size: 12px; color: var(--text-3); margin-top: 8px; line-height: 1.5; }
|
||||
|
||||
.modal-foot { display: flex; align-items: center; gap: 9px; padding: 16px 24px; border-top: 1px solid var(--border); background: #fafbfc; margin-top: 16px; }
|
||||
.modal-foot .fnote { font-size: 12px; color: var(--text-3); margin-right: auto; }
|
||||
.mbtn { height: 38px; padding: 0 16px; border-radius: var(--radius); font-size: 13.5px; font-weight: 600; border: 1px solid var(--border-strong); background: #fff; color: var(--text-2); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
|
||||
.mbtn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.mbtn.primary { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.mbtn.primary:hover { background: var(--accent-hover); }
|
||||
.mbtn svg { width: 15px; height: 15px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="내 업무.html">내 업무</a>
|
||||
<a href="저장소 목록.html" class="active">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg></button>
|
||||
<button class="icon-btn" title="알림"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg></button>
|
||||
<div class="me">정</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page" data-screen-label="저장소 멤버">
|
||||
<div class="crumb">
|
||||
<a href="저장소 목록.html" class="lnk">저장소</a>
|
||||
<span class="sep">/</span>
|
||||
<a href="저장소 상세.html" class="lnk">3분기 신제품 런칭 캘페인</a>
|
||||
<span class="sep">/</span>
|
||||
<b>멤버</b>
|
||||
</div>
|
||||
|
||||
<!-- 저장소 헤더 -->
|
||||
<div class="repo-head">
|
||||
<div class="repo-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
||||
<div class="rh-main">
|
||||
<div class="rh-title">
|
||||
<span class="rh-name">3분기 신제품 런칭 캘페인</span>
|
||||
<span class="vis private"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>비공개</span>
|
||||
</div>
|
||||
<div class="rh-slug">marketing-team / q3-launch-campaign</div>
|
||||
<div class="rh-desc">3분기 신제품(라인 클렌저) 런칭 캠페인 소재 제작 및 검수</div>
|
||||
<div class="rh-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>main</span>
|
||||
<span class="mi avstack"><span class="avatar av-f">정</span><span class="avatar av-a">김</span><span class="avatar av-b">박</span><span class="avatar av-c">이</span><span class="avatar av-d">최</span></span>
|
||||
<span class="mi">멤버 5명</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rh-actions">
|
||||
<a class="btn primary" href="업무 작성.html"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5v14"/></svg>새 업무</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 서브탭 -->
|
||||
<nav class="tabs">
|
||||
<a href="저장소 상세.html"><span class="tb-label">업무</span> <span class="tb-count">12</span></a>
|
||||
<a href="#" class="active"><span class="tb-label">멤버</span> <span class="tb-count">5</span></a>
|
||||
<a href="저장소 활동.html"><span class="tb-label">활동</span></a>
|
||||
<a href="저장소 설정.html"><span class="tb-label">설정</span></a>
|
||||
</nav>
|
||||
|
||||
<div class="tab-note">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></svg>
|
||||
이 저장소의 멤버만 업무 담당자로 지정할 수 있습니다. <b style="color:var(--text-2);font-weight:600;white-space:nowrap">관리자</b>는 업무 지시·멤버 관리가 가능하고, <b style="color:var(--text-2);font-weight:600;white-space:nowrap">멤버</b>는 담당자로 배정되어 업무를 수행합니다.
|
||||
</div>
|
||||
|
||||
<!-- 툴바 -->
|
||||
<div class="toolbar">
|
||||
<div class="search">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>
|
||||
<input type="text" placeholder="이름·이메일 검색…">
|
||||
</div>
|
||||
<div class="segmented">
|
||||
<button class="active">전체 <span class="n">5</span></button>
|
||||
<button>관리자 <span class="n">1</span></button>
|
||||
<button>멤버 <span class="n">4</span></button>
|
||||
</div>
|
||||
<button class="btn primary" id="inviteBtn" type="button" style="margin-left:auto;border:none">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M19 8v6M22 11h-6"/></svg>
|
||||
멤버 초대
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 멤버 목록 -->
|
||||
<div class="list">
|
||||
|
||||
<!-- 관리자 (소유자·현재 사용자) -->
|
||||
<div class="mem-row">
|
||||
<span class="mem-av av-f">정</span>
|
||||
<div class="mem-info">
|
||||
<div class="mem-name">정태경 <span class="you-pill">나</span></div>
|
||||
<div class="mem-sub">tkjung@acme.co <span class="dot">·</span> 리드</div>
|
||||
</div>
|
||||
<div class="mem-tasks"><b>1</b>건 담당</div>
|
||||
<div class="role fixed admin">
|
||||
<span class="role-dot"></span>관리자
|
||||
<span class="lock"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></span>
|
||||
</div>
|
||||
<button class="mem-remove disabled" title="소유자는 제거할 수 없습니다"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
|
||||
</div>
|
||||
|
||||
<!-- 멤버 -->
|
||||
<div class="mem-row">
|
||||
<span class="mem-av av-a">김</span>
|
||||
<div class="mem-info">
|
||||
<div class="mem-name">김서연</div>
|
||||
<div class="mem-sub">sykim@acme.co <span class="dot">·</span> 콘텐츠 디자인</div>
|
||||
</div>
|
||||
<div class="mem-tasks"><b>2</b>건 담당</div>
|
||||
<div class="role">
|
||||
<span class="role-dot"></span>멤버
|
||||
<span class="caret"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg></span>
|
||||
</div>
|
||||
<button class="mem-remove" title="멤버 제거"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
|
||||
</div>
|
||||
|
||||
<div class="mem-row">
|
||||
<span class="mem-av av-b">박</span>
|
||||
<div class="mem-info">
|
||||
<div class="mem-name">박지훈</div>
|
||||
<div class="mem-sub">jhpark@acme.co <span class="dot">·</span> 퍼포먼스 마케팅</div>
|
||||
</div>
|
||||
<div class="mem-tasks"><b>2</b>건 담당</div>
|
||||
<div class="role">
|
||||
<span class="role-dot"></span>멤버
|
||||
<span class="caret"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg></span>
|
||||
</div>
|
||||
<button class="mem-remove" title="멤버 제거"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
|
||||
</div>
|
||||
|
||||
<div class="mem-row">
|
||||
<span class="mem-av av-c">이</span>
|
||||
<div class="mem-info">
|
||||
<div class="mem-name">이도윤</div>
|
||||
<div class="mem-sub">dylee@acme.co <span class="dot">·</span> 카피라이터</div>
|
||||
</div>
|
||||
<div class="mem-tasks"><b>2</b>건 담당</div>
|
||||
<div class="role">
|
||||
<span class="role-dot"></span>멤버
|
||||
<span class="caret"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg></span>
|
||||
</div>
|
||||
<button class="mem-remove" title="멤버 제거"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
|
||||
</div>
|
||||
|
||||
<div class="mem-row">
|
||||
<span class="mem-av av-d">최</span>
|
||||
<div class="mem-info">
|
||||
<div class="mem-name">최유진</div>
|
||||
<div class="mem-sub">yjchoi@acme.co <span class="dot">·</span> UX 디자인</div>
|
||||
</div>
|
||||
<div class="mem-tasks"><b>1</b>건 담당</div>
|
||||
<div class="role">
|
||||
<span class="role-dot"></span>멤버
|
||||
<span class="caret"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg></span>
|
||||
</div>
|
||||
<button class="mem-remove" title="멤버 제거"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 멤버 초대 모달 -->
|
||||
<div class="modal-backdrop" id="inviteModal">
|
||||
<div class="modal" role="dialog" aria-modal="true">
|
||||
<div class="modal-head">
|
||||
<div>
|
||||
<h2>멤버 초대</h2>
|
||||
<div class="mh-sub"><b style="color:var(--text-2);font-weight:600">3분기 신제품 런칭 캠페인</b> 저장소에 멤버를 추가합니다.</div>
|
||||
</div>
|
||||
<button class="modal-close" id="inviteClose" type="button"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<label class="m-label">초대할 사람</label>
|
||||
<div class="icombo">
|
||||
<div class="icombo-field">
|
||||
<span class="ichip"><span class="avatar av-f" style="width:18px;height:18px;font-size:9px">한</span>한지민 <span class="x">×</span></span>
|
||||
<span class="ichip ext"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 6-10 7L2 6"/></svg>partner@vendor.com <span class="x">×</span></span>
|
||||
<input class="icombo-input" placeholder="이름 또는 이메일 입력…">
|
||||
</div>
|
||||
<div class="idd">
|
||||
<div class="idd-cap">조직 멤버 · 이 저장소에 없는 사람</div>
|
||||
<div class="idd-item">
|
||||
<span class="avatar av-b" style="width:26px;height:26px;font-size:11px">오</span>
|
||||
<span class="nm">오세훈</span><span class="em">sehoon.oh@acme.co</span>
|
||||
</div>
|
||||
<div class="idd-item">
|
||||
<span class="avatar av-c" style="width:26px;height:26px;font-size:11px">강</span>
|
||||
<span class="nm">강민서</span><span class="em">minseo.kang@acme.co</span>
|
||||
</div>
|
||||
<div class="idd-item">
|
||||
<span class="avatar av-e" style="width:26px;height:26px;font-size:11px">윤</span>
|
||||
<span class="nm">윤하늘</span><span class="em">haneul.yoon@acme.co</span>
|
||||
</div>
|
||||
<div class="idd-invite">
|
||||
<span class="pl"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5v14"/></svg></span>
|
||||
<span><div class="t1">이메일로 외부 초대</div><div class="t2">조직에 없는 사람도 이메일로 초대할 수 있어요</div></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="m-row">
|
||||
<div class="m-role">
|
||||
<label class="m-label">역할</label>
|
||||
<div class="select-wrap">
|
||||
<select>
|
||||
<option>멤버</option>
|
||||
<option>관리자</option>
|
||||
</select>
|
||||
<span class="caret"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-grow">
|
||||
<label class="m-label">초대 메시지 <span style="color:var(--text-3);font-weight:500">(선택)</span></label>
|
||||
<input class="m-input" type="text" placeholder="함께 캠페인 준비해요!">
|
||||
</div>
|
||||
</div>
|
||||
<div class="role-hint"><b style="color:var(--text-2);font-weight:600">멤버</b>는 담당자로 배정되어 업무를 수행하고, <b style="color:var(--text-2);font-weight:600">관리자</b>는 업무 지시와 멤버 관리도 할 수 있습니다.</div>
|
||||
</div>
|
||||
<div class="modal-foot">
|
||||
<span class="fnote">초대받은 사람에게 메일이 발송됩니다.</span>
|
||||
<button class="mbtn" id="inviteCancel" type="button">취소</button>
|
||||
<button class="mbtn primary" type="button">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg>
|
||||
초대 보내기 (2)
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var modal = document.getElementById('inviteModal');
|
||||
function openModal() { modal.classList.add('open'); }
|
||||
function closeModal() { modal.classList.remove('open'); }
|
||||
document.getElementById('inviteBtn').addEventListener('click', openModal);
|
||||
document.getElementById('inviteClose').addEventListener('click', closeModal);
|
||||
document.getElementById('inviteCancel').addEventListener('click', closeModal);
|
||||
modal.addEventListener('click', function (e) { if (e.target === modal) closeModal(); });
|
||||
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeModal(); });
|
||||
var iInput = document.querySelector('.icombo-input');
|
||||
var idd = document.querySelector('.idd');
|
||||
iInput.addEventListener('focus', function () { idd.classList.add('show'); });
|
||||
iInput.addEventListener('blur', function () { setTimeout(function () { idd.classList.remove('show'); }, 120); });
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,301 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>저장소 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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; --amber: #b7791f;
|
||||
--radius: 6px; --radius-sm: 4px;
|
||||
--shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* topbar */
|
||||
.topbar { height: 52px; background: var(--panel); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 28px; padding: 0 20px; position: sticky; top: 0; z-index: 50; }
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo { width: 26px; height: 26px; border-radius: 7px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; box-shadow: 0 2px 6px rgba(79,70,229,.35); }
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a { color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500; padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap; }
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px; }
|
||||
|
||||
/* page */
|
||||
.page { max-width: 1080px; margin: 0 auto; padding: 0 24px 70px; }
|
||||
.crumb { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12.5px; padding: 18px 0 0; white-space: nowrap; }
|
||||
.crumb b { color: var(--text-2); font-weight: 600; }
|
||||
.pagehead { display: flex; align-items: center; gap: 11px; padding: 9px 0 4px; }
|
||||
.pagehead h1 { font-size: 22px; font-weight: 700; letter-spacing: -.4px; white-space: nowrap; }
|
||||
.count-pill { font-size: 13px; font-weight: 600; color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); border-radius: 20px; padding: 2px 11px; }
|
||||
.gitea-badge { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: #1b7a3d; background: var(--green-weak); border: 1px solid #cde8d8; padding: 4px 10px; border-radius: 20px; line-height: 1; white-space: nowrap; }
|
||||
.gitea-badge svg { width: 13px; height: 13px; }
|
||||
.lede { color: var(--text-2); font-size: 13.5px; margin: 4px 0 18px; }
|
||||
|
||||
/* btn */
|
||||
.btn { height: 36px; padding: 0 15px; border-radius: var(--radius); font-size: 13.5px; 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: 6px; line-height: 1; text-decoration: none; white-space: nowrap; }
|
||||
.btn:hover { background: #f7f8fa; color: var(--text); }
|
||||
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
|
||||
|
||||
/* toolbar */
|
||||
.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
|
||||
.search { display: flex; align-items: center; gap: 8px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; width: 280px; }
|
||||
.search:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.search svg { width: 16px; height: 16px; color: var(--text-3); }
|
||||
.search input { border: none; outline: none; flex: 1; min-width: 0; font-family: inherit; font-size: 13.5px; background: transparent; }
|
||||
.search input::placeholder { color: var(--text-3); }
|
||||
.segmented { display: flex; background: #eceef1; border-radius: var(--radius); padding: 3px; gap: 2px; }
|
||||
.segmented button { border: none; background: transparent; font-family: inherit; font-size: 13px; font-weight: 600; color: var(--text-2); padding: 5px 13px; border-radius: 4px; cursor: pointer; white-space: nowrap; }
|
||||
.segmented button.active { background: #fff; color: var(--text); box-shadow: var(--shadow-sm); }
|
||||
.sort { margin-left: auto; display: flex; align-items: center; gap: 6px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; font-size: 13px; font-weight: 500; color: var(--text-2); cursor: pointer; white-space: nowrap; }
|
||||
.sort svg { width: 15px; height: 15px; color: var(--text-3); }
|
||||
|
||||
/* list */
|
||||
.list { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-sm); overflow: hidden; }
|
||||
.repo-row { display: flex; align-items: center; gap: 16px; padding: 16px 20px; border-top: 1px solid var(--border); cursor: pointer; text-decoration: none; color: inherit; }
|
||||
.repo-row:first-child { border-top: none; }
|
||||
.repo-row:hover { background: #fafbfc; }
|
||||
.repo-ico { width: 40px; height: 40px; border-radius: 9px; background: var(--accent-weak); color: var(--accent); display: grid; place-items: center; flex-shrink: 0; align-self: flex-start; margin-top: 2px; }
|
||||
.repo-ico svg { width: 21px; height: 21px; }
|
||||
|
||||
.repo-main { flex: 1; min-width: 0; }
|
||||
.repo-title { display: flex; align-items: center; column-gap: 9px; row-gap: 2px; flex-wrap: wrap; }
|
||||
.repo-name { font-size: 15px; font-weight: 600; color: var(--text); white-space: nowrap; }
|
||||
.repo-name .owner { color: var(--text-3); font-weight: 500; }
|
||||
.repo-slug { order: 2; flex-basis: 100%; font-size: 12px; font-weight: 500; color: var(--text-3); margin-top: 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
.repo-row:hover .repo-name { color: var(--accent); }
|
||||
.vis { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 20px; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; line-height: 1.5; }
|
||||
.vis svg { width: 11px; height: 11px; }
|
||||
.vis.private { color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); }
|
||||
.vis.public { color: #1b7a3d; background: var(--green-weak); border: 1px solid #cde8d8; }
|
||||
.repo-desc { font-size: 13px; color: var(--text-2); margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 480px; }
|
||||
.repo-meta { display: flex; align-items: center; gap: 15px; margin-top: 10px; font-size: 12px; color: var(--text-3); }
|
||||
.repo-meta .mi { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
|
||||
.repo-meta .mi svg { width: 13px; height: 13px; }
|
||||
.avstack { display: flex; align-items: center; }
|
||||
.avstack .avatar { margin-left: -7px; box-shadow: 0 0 0 2px #fff; }
|
||||
.avstack .avatar:first-child { margin-left: 0; }
|
||||
.avatar { width: 21px; height: 21px; border-radius: 50%; display: grid; place-items: center; font-size: 10px; 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; }
|
||||
|
||||
.repo-stat { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; width: 168px; flex-shrink: 0; }
|
||||
.stat-top { font-size: 12.5px; color: var(--text-2); font-weight: 600; white-space: nowrap; }
|
||||
.stat-top b { color: var(--text); }
|
||||
.pbar { width: 156px; height: 6px; 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); }
|
||||
.stat-pct { font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
|
||||
.chev { color: var(--text-3); flex-shrink: 0; display: grid; place-items: center; }
|
||||
.chev svg { width: 18px; height: 18px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="내 업무.html">내 업무</a>
|
||||
<a href="저장소 목록.html" class="active">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg></button>
|
||||
<button class="icon-btn" title="알림"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg></button>
|
||||
<div class="me">정</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page" data-screen-label="저장소 목록">
|
||||
<div class="crumb"><b>저장소</b></div>
|
||||
<div class="pagehead">
|
||||
<h1>저장소</h1>
|
||||
<span class="count-pill">6</span>
|
||||
<span class="gitea-badge"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 17H7A5 5 0 0 1 7 7h2"/><path d="M15 7h2a5 5 0 0 1 0 10h-2"/><path d="M8 12h8"/></svg> Gitea 연동됨</span>
|
||||
</div>
|
||||
<p class="lede"><b style="color:var(--text-2)">marketing-team</b> 조직의 저장소입니다. 저장소를 열어 업무를 작성하고 담당자에게 전달하세요.</p>
|
||||
|
||||
<div class="toolbar">
|
||||
<div class="search">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>
|
||||
<input type="text" placeholder="저장소 검색…">
|
||||
</div>
|
||||
<div class="segmented">
|
||||
<button class="active">전체</button>
|
||||
<button>비공개</button>
|
||||
<button>공개</button>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 5h10M11 9h7M11 13h4M3 17l3 3 3-3M6 18V4"/></svg>
|
||||
최근 업데이트순
|
||||
</div>
|
||||
<a class="btn primary" href="저장소 생성.html">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5v14"/></svg>
|
||||
새 저장소
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="list">
|
||||
|
||||
<!-- 1 -->
|
||||
<a class="repo-row" href="저장소 상세.html">
|
||||
<div class="repo-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
||||
<div class="repo-main">
|
||||
<div class="repo-title">
|
||||
<span class="repo-name">3분기 신제품 런칭 캘페인</span>
|
||||
<span class="repo-slug">marketing-team/q3-launch-campaign</span>
|
||||
<span class="vis private"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>비공개</span>
|
||||
</div>
|
||||
<div class="repo-desc">3분기 신제품(라인 클렌저) 런칭 캠페인 소재 제작 및 검수</div>
|
||||
<div class="repo-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>main</span>
|
||||
<span class="mi avstack"><span class="avatar av-a">김</span><span class="avatar av-b">박</span><span class="avatar av-c">이</span><span class="avatar av-more">+2</span></span>
|
||||
<span class="mi">2시간 전 업데이트</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="repo-stat">
|
||||
<div class="stat-top"><b>8</b> / 12 업무</div>
|
||||
<div class="pbar"><i class="mid" style="width:67%"></i></div>
|
||||
<div class="stat-pct">67% 완료</div>
|
||||
</div>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</a>
|
||||
|
||||
<!-- 2 -->
|
||||
<a class="repo-row" href="저장소 상세.html">
|
||||
<div class="repo-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
||||
<div class="repo-main">
|
||||
<div class="repo-title">
|
||||
<span class="repo-name">브랜드 리뉴얼 2026</span>
|
||||
<span class="repo-slug">marketing-team/brand-refresh-2026</span>
|
||||
<span class="vis private"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>비공개</span>
|
||||
</div>
|
||||
<div class="repo-desc">브랜드 아이덴티티 리뉴얼 및 가이드라인 개편 프로젝트</div>
|
||||
<div class="repo-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>main</span>
|
||||
<span class="mi avstack"><span class="avatar av-d">최</span><span class="avatar av-e">정</span><span class="avatar av-f">한</span><span class="avatar av-more">+1</span></span>
|
||||
<span class="mi">어제 업데이트</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="repo-stat">
|
||||
<div class="stat-top"><b>5</b> / 9 업무</div>
|
||||
<div class="pbar"><i class="mid" style="width:56%"></i></div>
|
||||
<div class="stat-pct">56% 완료</div>
|
||||
</div>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</a>
|
||||
|
||||
<!-- 3 -->
|
||||
<a class="repo-row" href="저장소 상세.html">
|
||||
<div class="repo-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
||||
<div class="repo-main">
|
||||
<div class="repo-title">
|
||||
<span class="repo-name">월간 뉴스레터 운영</span>
|
||||
<span class="repo-slug">marketing-team/monthly-newsletter</span>
|
||||
<span class="vis public"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20M12 2a15 15 0 0 0 0 20"/></svg>공개</span>
|
||||
</div>
|
||||
<div class="repo-desc">월간 뉴스레터 기획 · 콘텐츠 작성 · 발송 정기 운영</div>
|
||||
<div class="repo-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>main</span>
|
||||
<span class="mi avstack"><span class="avatar av-c">이</span><span class="avatar av-b">박</span><span class="avatar av-a">김</span></span>
|
||||
<span class="mi">3일 전 업데이트</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="repo-stat">
|
||||
<div class="stat-top"><b>14</b> / 14 업무</div>
|
||||
<div class="pbar"><i style="width:100%"></i></div>
|
||||
<div class="stat-pct">100% 완료</div>
|
||||
</div>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</a>
|
||||
|
||||
<!-- 4 -->
|
||||
<a class="repo-row" href="저장소 상세.html">
|
||||
<div class="repo-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
||||
<div class="repo-main">
|
||||
<div class="repo-title">
|
||||
<span class="repo-name">SEO 콘텐츠 허브</span>
|
||||
<span class="repo-slug">marketing-team/seo-content-hub</span>
|
||||
<span class="vis private"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>비공개</span>
|
||||
</div>
|
||||
<div class="repo-desc">검색 유입 강화를 위한 SEO 콘텐츠 기획 및 제작 허브</div>
|
||||
<div class="repo-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>main</span>
|
||||
<span class="mi avstack"><span class="avatar av-b">박</span><span class="avatar av-f">한</span><span class="avatar av-c">이</span><span class="avatar av-more">+3</span></span>
|
||||
<span class="mi">5시간 전 업데이트</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="repo-stat">
|
||||
<div class="stat-top"><b>2</b> / 11 업무</div>
|
||||
<div class="pbar"><i class="low" style="width:18%"></i></div>
|
||||
<div class="stat-pct">18% 완료</div>
|
||||
</div>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</a>
|
||||
|
||||
<!-- 5 -->
|
||||
<a class="repo-row" href="저장소 상세.html">
|
||||
<div class="repo-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
||||
<div class="repo-main">
|
||||
<div class="repo-title">
|
||||
<span class="repo-name">사내 행사 핵드북</span>
|
||||
<span class="repo-slug">marketing-team/event-handbook</span>
|
||||
<span class="vis public"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20M12 2a15 15 0 0 0 0 20"/></svg>공개</span>
|
||||
</div>
|
||||
<div class="repo-desc">사내 행사 운영 가이드 및 준비 체크리스트 모음</div>
|
||||
<div class="repo-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>main</span>
|
||||
<span class="mi avstack"><span class="avatar av-e">정</span><span class="avatar av-a">김</span></span>
|
||||
<span class="mi">1주 전 업데이트</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="repo-stat">
|
||||
<div class="stat-top"><b>0</b> / 4 업무</div>
|
||||
<div class="pbar"><i class="low" style="width:0%"></i></div>
|
||||
<div class="stat-pct">시작 전</div>
|
||||
</div>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</a>
|
||||
|
||||
<!-- 6 -->
|
||||
<a class="repo-row" href="저장소 상세.html">
|
||||
<div class="repo-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
||||
<div class="repo-main">
|
||||
<div class="repo-title">
|
||||
<span class="repo-name">디자인 시스템 에셋</span>
|
||||
<span class="repo-slug">marketing-team/design-system-assets</span>
|
||||
<span class="vis private"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>비공개</span>
|
||||
</div>
|
||||
<div class="repo-desc">공통 디자인 시스템 에셋 및 컴포넌트 관리</div>
|
||||
<div class="repo-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>develop</span>
|
||||
<span class="mi avstack"><span class="avatar av-a">김</span><span class="avatar av-d">최</span><span class="avatar av-c">이</span><span class="avatar av-more">+1</span></span>
|
||||
<span class="mi">30분 전 업데이트</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="repo-stat">
|
||||
<div class="stat-top"><b>9</b> / 10 업무</div>
|
||||
<div class="pbar"><i style="width:90%"></i></div>
|
||||
<div class="stat-pct">90% 완료</div>
|
||||
</div>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,350 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>q3-launch-campaign — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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; --blue: #1d4ed8; --blue-weak: #e8efff; --blue-border: #c9dbff;
|
||||
--red: #d6455d; --red-weak: #fdecef; --amber: #b7791f; --amber-weak: #fdf4e3; --amber-border: #f3e2bd;
|
||||
--radius: 6px; --radius-sm: 4px; --shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* topbar */
|
||||
.topbar { height: 52px; background: var(--panel); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 28px; padding: 0 20px; position: sticky; top: 0; z-index: 50; }
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo { width: 26px; height: 26px; border-radius: 7px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; box-shadow: 0 2px 6px rgba(79,70,229,.35); }
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a { color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500; padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap; }
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px; }
|
||||
|
||||
/* page */
|
||||
.page { max-width: 1080px; margin: 0 auto; padding: 0 24px 70px; }
|
||||
.crumb { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12.5px; padding: 18px 0 12px; white-space: nowrap; }
|
||||
.crumb .lnk { color: var(--text-2); font-weight: 600; text-decoration: none; }
|
||||
.crumb .lnk:hover { color: var(--accent); }
|
||||
.crumb .sep { opacity: .5; }
|
||||
.crumb b { color: var(--text-2); font-weight: 600; }
|
||||
|
||||
/* btn */
|
||||
.btn { height: 36px; padding: 0 15px; border-radius: var(--radius); font-size: 13.5px; 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: 6px; line-height: 1; text-decoration: none; white-space: nowrap; }
|
||||
.btn:hover { background: #f7f8fa; color: var(--text); }
|
||||
.btn svg { width: 15px; height: 15px; }
|
||||
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
|
||||
|
||||
/* repo header */
|
||||
.repo-head { display: flex; align-items: flex-start; gap: 16px; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 20px 22px; box-shadow: var(--shadow-sm); }
|
||||
.repo-ico { width: 46px; height: 46px; border-radius: 10px; background: var(--accent-weak); color: var(--accent); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.repo-ico svg { width: 24px; height: 24px; }
|
||||
.rh-main { flex: 1; min-width: 0; }
|
||||
.rh-title { display: flex; align-items: center; gap: 10px; }
|
||||
.rh-name { font-size: 18px; font-weight: 700; letter-spacing: -.3px; white-space: nowrap; }
|
||||
.rh-name .owner { color: var(--text-3); font-weight: 500; }
|
||||
.rh-slug { font-size: 12.5px; color: var(--text-3); margin-top: 5px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
.vis { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 20px; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; line-height: 1.5; }
|
||||
.vis svg { width: 11px; height: 11px; }
|
||||
.vis.private { color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); }
|
||||
.rh-desc { font-size: 13.5px; color: var(--text-2); margin-top: 6px; }
|
||||
.rh-meta { display: flex; align-items: center; gap: 15px; margin-top: 12px; font-size: 12px; color: var(--text-3); }
|
||||
.rh-meta .mi { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
|
||||
.rh-meta .mi svg { width: 13px; height: 13px; }
|
||||
.avstack { display: flex; align-items: center; }
|
||||
.avstack .avatar { margin-left: -7px; box-shadow: 0 0 0 2px #fff; }
|
||||
.avstack .avatar:first-child { margin-left: 0; }
|
||||
.avatar { width: 21px; height: 21px; border-radius: 50%; display: grid; place-items: center; font-size: 10px; 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; }
|
||||
.rh-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
|
||||
|
||||
/* progress strip */
|
||||
.prog-strip { display: flex; align-items: center; gap: 16px; margin-top: 16px; padding-top: 15px; border-top: 1px solid var(--border); }
|
||||
.prog-strip .pbar { flex: 1; height: 8px; border-radius: 5px; background: #eceef1; overflow: hidden; max-width: 360px; }
|
||||
.prog-strip .pbar > i { display: block; height: 100%; border-radius: 5px; background: var(--green); }
|
||||
.prog-txt { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; }
|
||||
.prog-txt span { color: var(--text-3); font-weight: 500; }
|
||||
.prog-warn { font-size: 12.5px; font-weight: 600; color: var(--red); display: flex; align-items: center; gap: 5px; white-space: nowrap; }
|
||||
.prog-warn svg { width: 14px; height: 14px; }
|
||||
|
||||
/* tabs */
|
||||
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin: 20px 0 18px; }
|
||||
.tabs a { padding: 10px 14px; font-size: 13.5px; font-weight: 600; color: var(--text-2); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
|
||||
.tabs a:hover { color: var(--text); }
|
||||
.tabs a.active { color: var(--accent); border-bottom-color: var(--accent); }
|
||||
.tabs a .tb-label { line-height: 1; }
|
||||
.tabs a .tb-count { font-size: 11px; font-weight: 600; color: var(--text-2); background: #f1f2f4; border-radius: 20px; padding: 0 7px; height: 17px; min-width: 17px; display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
|
||||
.tabs a.active .tb-count { background: var(--accent-weak); color: var(--accent); }
|
||||
|
||||
/* toolbar */
|
||||
.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
|
||||
.search { display: flex; align-items: center; gap: 8px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; width: 240px; }
|
||||
.search:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.search svg { width: 16px; height: 16px; color: var(--text-3); }
|
||||
.search input { border: none; outline: none; flex: 1; min-width: 0; font-family: inherit; font-size: 13.5px; background: transparent; }
|
||||
.search input::placeholder { color: var(--text-3); }
|
||||
.segmented { display: flex; background: #eceef1; border-radius: var(--radius); padding: 3px; gap: 2px; }
|
||||
.segmented button { border: none; background: transparent; font-family: inherit; font-size: 13px; font-weight: 600; color: var(--text-2); padding: 5px 12px; border-radius: 4px; cursor: pointer; white-space: nowrap; display: flex; align-items: center; gap: 6px; }
|
||||
.segmented button.active { background: #fff; color: var(--text); box-shadow: var(--shadow-sm); }
|
||||
.segmented button .n { font-size: 11px; color: var(--text-3); font-weight: 600; }
|
||||
.segmented button.active .n { color: var(--accent); }
|
||||
.sort { margin-left: auto; display: flex; align-items: center; gap: 6px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; font-size: 13px; font-weight: 500; color: var(--text-2); cursor: pointer; white-space: nowrap; }
|
||||
.sort svg { width: 15px; height: 15px; color: var(--text-3); }
|
||||
|
||||
/* task list */
|
||||
.list { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-sm); overflow: hidden; }
|
||||
.task-row { display: flex; align-items: center; gap: 14px; padding: 14px 18px; border-top: 1px solid var(--border); cursor: pointer; text-decoration: none; color: inherit; }
|
||||
.task-row:first-child { border-top: none; }
|
||||
.task-row:hover { background: #fafbfc; }
|
||||
.st-dot { width: 9px; height: 9px; 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; }
|
||||
.task-main { flex: 1; min-width: 0; }
|
||||
.task-title { font-size: 14px; font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 8px; }
|
||||
.task-title .tid { font-size: 12px; font-weight: 600; color: var(--text-3); }
|
||||
.task-row.is-done .task-title { color: var(--text-2); }
|
||||
.task-meta { display: flex; align-items: center; gap: 13px; margin-top: 3px; font-size: 12px; color: var(--text-3); }
|
||||
.task-meta .mi { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
|
||||
.task-meta .mi svg { width: 13px; height: 13px; }
|
||||
.task-meta .mi.overdue { color: var(--red); font-weight: 600; }
|
||||
.task-right { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }
|
||||
.st-badge { font-size: 11.5px; font-weight: 600; padding: 3px 10px; border-radius: 20px; white-space: nowrap; min-width: 56px; text-align: center; }
|
||||
.st-badge.done { color: var(--green); background: var(--green-weak); border: 1px solid #cde8d8; }
|
||||
.st-badge.prog { color: var(--blue); background: var(--blue-weak); border: 1px solid var(--blue-border); }
|
||||
.st-badge.review { color: var(--amber); background: var(--amber-weak); border: 1px solid var(--amber-border); }
|
||||
.st-badge.todo { color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); }
|
||||
.chev { color: var(--text-3); display: grid; place-items: center; }
|
||||
.chev svg { width: 18px; height: 18px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="내 업무.html">내 업무</a>
|
||||
<a href="저장소 목록.html" class="active">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg></button>
|
||||
<button class="icon-btn" title="알림"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg></button>
|
||||
<div class="me">정</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page" data-screen-label="저장소 상세">
|
||||
<div class="crumb">
|
||||
<a href="저장소 목록.html" class="lnk">저장소</a>
|
||||
<span class="sep">/</span>
|
||||
<b>3분기 신제품 런칭 캘페인</b>
|
||||
</div>
|
||||
|
||||
<!-- 저장소 헤더 -->
|
||||
<div class="repo-head">
|
||||
<div class="repo-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
||||
<div class="rh-main">
|
||||
<div class="rh-title">
|
||||
<span class="rh-name">3분기 신제품 런칭 캘페인</span>
|
||||
<span class="vis private"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>비공개</span>
|
||||
</div>
|
||||
<div class="rh-slug">marketing-team / q3-launch-campaign</div>
|
||||
<div class="rh-desc">3분기 신제품(라인 클렌저) 런칭 캠페인 소재 제작 및 검수</div>
|
||||
<div class="rh-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>main</span>
|
||||
<span class="mi avstack"><span class="avatar av-a">김</span><span class="avatar av-b">박</span><span class="avatar av-c">이</span><span class="avatar av-d">최</span><span class="avatar av-more">+1</span></span>
|
||||
<span class="mi">2시간 전 업데이트</span>
|
||||
</div>
|
||||
<div class="prog-strip">
|
||||
<span class="prog-txt">8 <span>/ 12 업무 완료</span> · 67%</span>
|
||||
<div class="pbar"><i style="width:67%"></i></div>
|
||||
<span class="prog-warn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>지연 1건</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rh-actions">
|
||||
<a class="btn primary" href="업무 작성.html"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5v14"/></svg>새 업무</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 서브탭 -->
|
||||
<nav class="tabs">
|
||||
<a href="#" class="active"><span class="tb-label">업무</span> <span class="tb-count">12</span></a>
|
||||
<a href="저장소 멤버.html"><span class="tb-label">멤버</span> <span class="tb-count">5</span></a>
|
||||
<a href="저장소 활동.html"><span class="tb-label">활동</span></a>
|
||||
<a href="저장소 설정.html"><span class="tb-label">설정</span></a>
|
||||
</nav>
|
||||
|
||||
<!-- 툴바 -->
|
||||
<div class="toolbar">
|
||||
<div class="search">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>
|
||||
<input type="text" placeholder="업무 검색…">
|
||||
</div>
|
||||
<div class="segmented">
|
||||
<button class="active">전체 <span class="n">12</span></button>
|
||||
<button>진행 중 <span class="n">2</span></button>
|
||||
<button>대기 <span class="n">2</span></button>
|
||||
<button>완료 <span class="n">8</span></button>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 5h10M11 9h7M11 13h4M3 17l3 3 3-3M6 18V4"/></svg>
|
||||
마감 임박순
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 업무 목록 -->
|
||||
<div class="list">
|
||||
|
||||
<a class="task-row" href="업무 상세.html">
|
||||
<span class="st-dot prog"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title">법무 검토 요청 및 회신 반영 <span class="tid">#11</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="mi overdue"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>2일 지남</span>
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>1/3</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="avstack"><span class="avatar av-c">이</span></span>
|
||||
<span class="st-badge prog">진행 중</span>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a class="task-row" href="업무 상세.html">
|
||||
<span class="st-dot review"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title">메인 배너 이미지 2종 (가로/세로) 디자인 <span class="tid">#9</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>D-3</span>
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>1/3</span>
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>2</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="avstack"><span class="avatar av-b">박</span><span class="avatar av-d">최</span></span>
|
||||
<span class="st-badge review">승인 대기</span>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a class="task-row" href="업무 상세.html">
|
||||
<span class="st-dot todo"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title">상세페이지 카피라이팅 <span class="tid">#8</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>D-5</span>
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>0/3</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="avstack"><span class="avatar av-c">이</span></span>
|
||||
<span class="st-badge todo">대기</span>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a class="task-row" href="업무 상세.html">
|
||||
<span class="st-dot todo"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title">SNS 콘텐츠 1차 시안 <span class="tid">#7</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>D-8</span>
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>0/4</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="avstack"><span class="avatar av-e">정</span></span>
|
||||
<span class="st-badge todo">대기</span>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a class="task-row is-done" href="업무 상세.html">
|
||||
<span class="st-dot done"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title">캠페인 핵심 메시지 시안 작성 <span class="tid">#6</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>3/3</span>
|
||||
<span class="mi">6월 9일 완료</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="avstack"><span class="avatar av-a">김</span></span>
|
||||
<span class="st-badge done">완료</span>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a class="task-row is-done" href="업무 상세.html">
|
||||
<span class="st-dot done"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title">레퍼런스 리서치 및 무드보드 정리 <span class="tid">#5</span></span>
|
||||
<span class="task-meta"><span class="mi">6월 6일 완료</span></span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="avstack"><span class="avatar av-a">김</span></span>
|
||||
<span class="st-badge done">완료</span>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a class="task-row is-done" href="업무 상세.html">
|
||||
<span class="st-dot done"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title">퍼포먼스 광고 소재 세팅 <span class="tid">#4</span></span>
|
||||
<span class="task-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>2/2</span>
|
||||
<span class="mi">6월 5일 완료</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="avstack"><span class="avatar av-b">박</span></span>
|
||||
<span class="st-badge done">완료</span>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a class="task-row is-done" href="업무 상세.html">
|
||||
<span class="st-dot done"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title">타깃 오디언스 정의 및 페르소나 정리 <span class="tid">#3</span></span>
|
||||
<span class="task-meta"><span class="mi">6월 4일 완료</span></span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="avstack"><span class="avatar av-b">박</span></span>
|
||||
<span class="st-badge done">완료</span>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a class="task-row is-done" href="업무 상세.html">
|
||||
<span class="st-dot done"></span>
|
||||
<span class="task-main">
|
||||
<span class="task-title">킥오프 미팅 및 일정 수립 <span class="tid">#1</span></span>
|
||||
<span class="task-meta"><span class="mi">6월 2일 완료</span></span>
|
||||
</span>
|
||||
<span class="task-right">
|
||||
<span class="avstack"><span class="avatar av-f">정</span></span>
|
||||
<span class="st-badge done">완료</span>
|
||||
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,289 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>새 저장소 만들기 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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;
|
||||
--amber: #b7791f;
|
||||
--radius: 6px;
|
||||
--radius-sm: 4px;
|
||||
--shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
--shadow-md: 0 4px 16px rgba(20,24,33,.10), 0 1px 3px rgba(20,24,33,.06);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* ---------- Top app bar ---------- */
|
||||
.topbar {
|
||||
height: 52px; background: var(--panel); border-bottom: 1px solid var(--border);
|
||||
display: flex; align-items: center; gap: 28px; padding: 0 20px;
|
||||
position: sticky; top: 0; z-index: 50;
|
||||
}
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo {
|
||||
width: 26px; height: 26px; border-radius: 7px;
|
||||
background: linear-gradient(135deg, #5b54f0, #4338ca);
|
||||
display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800;
|
||||
box-shadow: 0 2px 6px rgba(79,70,229,.35);
|
||||
}
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a {
|
||||
color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500;
|
||||
padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap;
|
||||
}
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.crumb .lnk { color: var(--text-2); font-weight: 600; text-decoration: none; }
|
||||
.crumb .lnk:hover { color: var(--accent); }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px; }
|
||||
|
||||
/* ---------- Page ---------- */
|
||||
.page { max-width: 760px; margin: 0 auto; padding: 0 24px 70px; }
|
||||
.crumb { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12.5px; padding: 18px 0 0; white-space: nowrap; }
|
||||
.crumb b { color: var(--text-2); font-weight: 600; }
|
||||
.crumb .sep { opacity: .5; }
|
||||
.pagehead { display: flex; align-items: center; gap: 12px; padding: 9px 0 6px; }
|
||||
.pagehead h1 { font-size: 22px; font-weight: 700; letter-spacing: -.4px; white-space: nowrap; flex-shrink: 0; }
|
||||
.gitea-badge {
|
||||
display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600;
|
||||
color: #1b7a3d; background: var(--green-weak); border: 1px solid #cde8d8;
|
||||
padding: 4px 10px; border-radius: 20px; line-height: 1; white-space: nowrap;
|
||||
}
|
||||
.gitea-badge svg { width: 13px; height: 13px; }
|
||||
.lede { color: var(--text-2); font-size: 13.5px; margin-bottom: 20px; }
|
||||
|
||||
/* ---------- Card / form ---------- */
|
||||
.card { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-sm); }
|
||||
.fblock { padding: 22px 24px; border-top: 1px solid var(--border); }
|
||||
.fblock:first-child { border-top: none; }
|
||||
.flabel { font-size: 13px; font-weight: 600; color: var(--text); margin-bottom: 4px; display: flex; align-items: center; gap: 7px; }
|
||||
.flabel .req { color: var(--accent); font-weight: 700; }
|
||||
.fhint { font-size: 12.5px; color: var(--text-3); margin-bottom: 11px; line-height: 1.5; }
|
||||
.fhint.below { margin-top: 9px; margin-bottom: 0; }
|
||||
|
||||
.tinput { width: 100%; height: 40px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 12px; font-family: inherit; font-size: 14px; color: var(--text); background: #fff; }
|
||||
.tinput:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.tinput::placeholder { color: var(--text-3); }
|
||||
textarea.tarea { min-height: 96px; padding: 10px 12px; line-height: 1.6; resize: vertical; height: auto; }
|
||||
|
||||
/* owner / repo name */
|
||||
.repo-id { display: flex; }
|
||||
.owner-fixed {
|
||||
display: flex; align-items: center; gap: 8px; height: 40px; padding: 0 13px;
|
||||
background: #f1f2f4; border: 1px solid var(--border-strong); border-right: none;
|
||||
border-radius: var(--radius) 0 0 var(--radius); color: var(--text-2);
|
||||
font-weight: 600; font-size: 14px; cursor: not-allowed; white-space: nowrap; user-select: none;
|
||||
}
|
||||
.owner-fixed .lock { color: var(--text-3); display: grid; place-items: center; }
|
||||
.owner-avatar { width: 20px; height: 20px; border-radius: 5px; background: #0ea5a3; color: #fff; display: grid; place-items: center; font-size: 10.5px; font-weight: 700; }
|
||||
.name-wrap { flex: 1; height: 40px; display: flex; align-items: center; border: 1px solid var(--border-strong); border-radius: 0 var(--radius) var(--radius) 0; background: #fff; padding: 0 12px; min-width: 0; }
|
||||
.name-wrap:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); position: relative; z-index: 1; }
|
||||
.name-wrap .slash { color: var(--text-3); margin-right: 7px; font-weight: 500; font-size: 15px; }
|
||||
.name-wrap input { flex: 1; min-width: 0; border: none; outline: none; height: 100%; font-family: inherit; font-size: 14px; background: transparent; }
|
||||
.name-wrap input::placeholder { color: var(--text-3); }
|
||||
.avail { display: flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; color: var(--green); margin-top: 9px; }
|
||||
.avail svg { width: 14px; height: 14px; }
|
||||
.fixed-pill { font-size: 11px; font-weight: 600; color: var(--text-2); background: #e9ebef; border: 1px solid var(--border-strong); padding: 1px 7px; border-radius: 20px; line-height: 1.5; white-space: nowrap; }
|
||||
|
||||
/* visibility radio cards */
|
||||
.radio-group { display: flex; flex-direction: column; gap: 10px; }
|
||||
.radio-card { display: flex; align-items: flex-start; gap: 13px; padding: 13px 14px; border: 1px solid var(--border-strong); border-radius: 8px; cursor: pointer; background: #fff; transition: border-color .12s, background .12s; }
|
||||
.radio-card:hover { border-color: var(--accent-border); }
|
||||
.radio-card.sel { border-color: var(--accent); background: var(--accent-weak); }
|
||||
.rc-ico { width: 34px; height: 34px; border-radius: 8px; background: #f1f2f4; color: var(--text-2); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.rc-ico svg { width: 18px; height: 18px; }
|
||||
.radio-card.sel .rc-ico { background: #fff; color: var(--accent); }
|
||||
.rc-body { flex: 1; }
|
||||
.rc-title { font-size: 14px; font-weight: 600; color: var(--text); }
|
||||
.rc-desc { font-size: 12.5px; color: var(--text-2); margin-top: 2px; line-height: 1.45; }
|
||||
.rc-radio { width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--border-strong); flex-shrink: 0; margin-top: 8px; display: grid; place-items: center; background: #fff; }
|
||||
.radio-card.sel .rc-radio { border-color: var(--accent); }
|
||||
.radio-card.sel .rc-radio::after { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--accent); }
|
||||
|
||||
/* select */
|
||||
.select-wrap { position: relative; }
|
||||
.select-wrap select {
|
||||
appearance: none; -webkit-appearance: none; width: 100%; height: 40px;
|
||||
border: 1px solid var(--border-strong); border-radius: var(--radius);
|
||||
padding: 0 38px 0 12px; font-family: inherit; font-size: 14px; color: var(--text); background: #fff; cursor: pointer;
|
||||
}
|
||||
.select-wrap select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.select-wrap .caret { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); color: var(--text-3); pointer-events: none; display: grid; place-items: center; }
|
||||
.select-wrap .caret svg { width: 16px; height: 16px; }
|
||||
|
||||
/* input with icon */
|
||||
.input-ico { display: flex; align-items: center; border: 1px solid var(--border-strong); border-radius: var(--radius); background: #fff; padding: 0 12px; gap: 9px; }
|
||||
.input-ico:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.input-ico .ico { color: var(--text-3); display: grid; place-items: center; }
|
||||
.input-ico .ico svg { width: 16px; height: 16px; }
|
||||
.input-ico input { flex: 1; border: none; outline: none; height: 40px; font-family: inherit; font-size: 14px; background: transparent; color: var(--text); }
|
||||
|
||||
/* footer */
|
||||
.form-footer { display: flex; align-items: center; gap: 9px; padding: 16px 24px; border-top: 1px solid var(--border); background: #fafbfc; border-radius: 0 0 10px 10px; }
|
||||
.form-footer .note { color: var(--text-3); font-size: 12.5px; margin-right: auto; display: flex; align-items: center; gap: 7px; white-space: nowrap; }
|
||||
.form-footer .note .step { display: inline-grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; background: var(--accent-weak); color: var(--accent); font-size: 10px; font-weight: 700; }
|
||||
.btn { height: 36px; padding: 0 16px; border-radius: var(--radius); font-size: 13.5px; 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: 6px; line-height: 1; text-decoration: none; }
|
||||
.btn:hover { background: #f7f8fa; color: var(--text); }
|
||||
.btn.ghost { border-color: transparent; background: transparent; }
|
||||
.btn.ghost:hover { background: #eceef1; }
|
||||
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="내 업무.html">내 업무</a>
|
||||
<a href="저장소 목록.html" class="active">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색">
|
||||
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>
|
||||
</button>
|
||||
<button class="icon-btn" title="알림">
|
||||
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg>
|
||||
</button>
|
||||
<div class="me">정</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page">
|
||||
<div class="crumb"><a href="저장소 목록.html" class="lnk">저장소</a> <span class="sep">/</span> 새 저장소</div>
|
||||
<div class="pagehead">
|
||||
<h1>새 저장소 만들기</h1>
|
||||
<span class="gitea-badge">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 17H7A5 5 0 0 1 7 7h2"/><path d="M15 7h2a5 5 0 0 1 0 10h-2"/><path d="M8 12h8"/></svg>
|
||||
Gitea 연동됨
|
||||
</span>
|
||||
</div>
|
||||
<p class="lede">Gitea 저장소를 연동하여 새 프로젝트를 생성합니다. 생성 후 이 저장소에 업무를 작성하고 담당자에게 전달할 수 있습니다.</p>
|
||||
|
||||
<div class="card">
|
||||
|
||||
<!-- 소유자 / 저장소 이름 -->
|
||||
<div class="fblock">
|
||||
<div class="flabel"><span class="req">*</span> 소유자 / 저장소 이름 <span class="fixed-pill">소유자 고정</span></div>
|
||||
<div class="fhint">소유자는 현재 조직으로 고정되어 변경할 수 없습니다.</div>
|
||||
<div class="repo-id">
|
||||
<div class="owner-fixed" title="소유자는 변경할 수 없습니다">
|
||||
<span class="owner-avatar">M</span>
|
||||
marketing-team
|
||||
<span class="lock"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></span>
|
||||
</div>
|
||||
<div class="name-wrap">
|
||||
<span class="slash">/</span>
|
||||
<input type="text" value="q3-launch-campaign" placeholder="repository-name" spellcheck="false">
|
||||
</div>
|
||||
</div>
|
||||
<div class="avail">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>
|
||||
사용 가능한 이름입니다
|
||||
</div>
|
||||
<div class="fhint below">영문 소문자·숫자와 하이픈(-)·밑줄(_)만 사용할 수 있습니다. 한글·공백은 입력할 수 없습니다.</div>
|
||||
</div>
|
||||
|
||||
<!-- 표시 제목 -->
|
||||
<div class="fblock">
|
||||
<div class="flabel"><span class="req">*</span> 표시 제목</div>
|
||||
<div class="fhint">Relay 목록과 화면에 표시되는 이름입니다. 한글로 입력하면 저장소를 알아보기 쉽습니다. 위 Gitea 저장소 이름(영문)과는 별개이며 언제든 바꿀 수 있습니다.</div>
|
||||
<input type="text" class="tinput" value="3분기 신제품 런칭 캠페인" placeholder="예: 3분기 신제품 런칭 캠페인" maxlength="40">
|
||||
</div>
|
||||
|
||||
<!-- 공개 범위 -->
|
||||
<div class="fblock">
|
||||
<div class="flabel"><span class="req">*</span> 공개 범위</div>
|
||||
<div class="fhint">저장소와 그 안의 업무를 누가 볼 수 있는지 결정합니다.</div>
|
||||
<div class="radio-group">
|
||||
<label class="radio-card sel">
|
||||
<span class="rc-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></span>
|
||||
<span class="rc-body">
|
||||
<span class="rc-title">비공개</span>
|
||||
<span class="rc-desc">저장소에 초대된 멤버만 접근하고 업무를 확인할 수 있습니다.</span>
|
||||
</span>
|
||||
<span class="rc-radio"></span>
|
||||
</label>
|
||||
<label class="radio-card">
|
||||
<span class="rc-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20M12 2a15 15 0 0 0 0 20"/></svg></span>
|
||||
<span class="rc-body">
|
||||
<span class="rc-title">공개</span>
|
||||
<span class="rc-desc">조직 내 모든 구성원이 저장소를 보고 업무 현황을 열람할 수 있습니다.</span>
|
||||
</span>
|
||||
<span class="rc-radio"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 프로젝트 설명 -->
|
||||
<div class="fblock">
|
||||
<div class="flabel">프로젝트 설명</div>
|
||||
<div class="fhint">저장소 목록과 상단에 표시됩니다. (선택)</div>
|
||||
<textarea class="tinput tarea" placeholder="이 프로젝트의 목적과 범위를 간단히 적어주세요.">3분기 신제품(라인 클렌저) 런칭 관련 캠페인 소재 제작 및 검수 업무를 관리하는 저장소입니다.</textarea>
|
||||
</div>
|
||||
|
||||
<!-- 템플릿 -->
|
||||
<div class="fblock">
|
||||
<div class="flabel">템플릿</div>
|
||||
<div class="fhint">선택한 템플릿의 폴더 구조와 기본 업무가 새 저장소에 복제됩니다.</div>
|
||||
<div class="select-wrap">
|
||||
<select>
|
||||
<option>없음 (빈 저장소)</option>
|
||||
<option>기본 업무 템플릿</option>
|
||||
<option>디자인 프로젝트 템플릿</option>
|
||||
<option>개발 프로젝트 템플릿</option>
|
||||
</select>
|
||||
<span class="caret"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 메인 브랜치 -->
|
||||
<div class="fblock">
|
||||
<div class="flabel"><span class="req">*</span> 메인 브랜치</div>
|
||||
<div class="fhint">저장소의 기본 브랜치 이름입니다.</div>
|
||||
<div class="input-ico" style="max-width:280px">
|
||||
<span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg></span>
|
||||
<input type="text" value="main" spellcheck="false">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- footer -->
|
||||
<div class="form-footer">
|
||||
<span class="note"><span class="step">1</span> 저장소 생성 → 업무 생성 → 전달</span>
|
||||
<a class="btn ghost" href="저장소 목록.html">취소</a>
|
||||
<a class="btn primary" href="저장소 상세.html">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5v14"/></svg>
|
||||
저장소 생성
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,275 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>q3-launch-campaign · 설정 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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; --red: #d6455d; --red-weak: #fdeef0; --red-border: #f1c0c8;
|
||||
--radius: 6px; --radius-sm: 4px; --shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* topbar */
|
||||
.topbar { height: 52px; background: var(--panel); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 28px; padding: 0 20px; position: sticky; top: 0; z-index: 50; }
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo { width: 26px; height: 26px; border-radius: 7px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; box-shadow: 0 2px 6px rgba(79,70,229,.35); }
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a { color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500; padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap; }
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px; }
|
||||
|
||||
/* page */
|
||||
.page { max-width: 1080px; margin: 0 auto; padding: 0 24px 70px; }
|
||||
.crumb { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12.5px; padding: 18px 0 12px; white-space: nowrap; }
|
||||
.crumb .lnk { color: var(--text-2); font-weight: 600; text-decoration: none; }
|
||||
.crumb .lnk:hover { color: var(--accent); }
|
||||
.crumb .sep { opacity: .5; }
|
||||
.crumb b { color: var(--text-2); font-weight: 600; }
|
||||
|
||||
.btn { height: 36px; padding: 0 15px; border-radius: var(--radius); font-size: 13.5px; 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: 6px; line-height: 1; text-decoration: none; white-space: nowrap; }
|
||||
.btn:hover { background: #f7f8fa; color: var(--text); }
|
||||
.btn svg { width: 15px; height: 15px; }
|
||||
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
|
||||
|
||||
/* repo header */
|
||||
.repo-head { display: flex; align-items: flex-start; gap: 16px; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 20px 22px; box-shadow: var(--shadow-sm); }
|
||||
.repo-ico { width: 46px; height: 46px; border-radius: 10px; background: var(--accent-weak); color: var(--accent); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.repo-ico svg { width: 24px; height: 24px; }
|
||||
.rh-main { flex: 1; min-width: 0; }
|
||||
.rh-title { display: flex; align-items: center; gap: 10px; }
|
||||
.rh-name { font-size: 18px; font-weight: 700; letter-spacing: -.3px; white-space: nowrap; }
|
||||
.rh-slug { font-size: 12.5px; color: var(--text-3); margin-top: 5px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
.vis { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 20px; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; line-height: 1.5; }
|
||||
.vis svg { width: 11px; height: 11px; }
|
||||
.vis.private { color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); }
|
||||
.rh-desc { font-size: 13.5px; color: var(--text-2); margin-top: 6px; }
|
||||
.rh-meta { display: flex; align-items: center; gap: 15px; margin-top: 12px; font-size: 12px; color: var(--text-3); }
|
||||
.rh-meta .mi { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
|
||||
.rh-meta .mi svg { width: 13px; height: 13px; }
|
||||
.avatar { width: 21px; height: 21px; border-radius: 50%; display: grid; place-items: center; font-size: 10px; font-weight: 700; color: #fff; flex-shrink: 0; }
|
||||
.avstack { display: flex; align-items: center; }
|
||||
.avstack .avatar { margin-left: -7px; box-shadow: 0 0 0 2px #fff; }
|
||||
.avstack .avatar:first-child { margin-left: 0; }
|
||||
.av-a { background: #e0518d; } .av-b { background: #3d8bf2; } .av-c { background: #16a37b; }
|
||||
.av-d { background: #b3631f; } .av-f { background: #d0982a; }
|
||||
.rh-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
|
||||
|
||||
/* tabs */
|
||||
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin: 20px 0 22px; }
|
||||
.tabs a { padding: 10px 14px; font-size: 13.5px; font-weight: 600; color: var(--text-2); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
|
||||
.tabs a:hover { color: var(--text); }
|
||||
.tabs a.active { color: var(--accent); border-bottom-color: var(--accent); }
|
||||
.tabs a .tb-label { line-height: 1; }
|
||||
.tabs a .tb-count { font-size: 11px; font-weight: 600; color: var(--text-2); background: #f1f2f4; border-radius: 20px; padding: 0 7px; height: 17px; min-width: 17px; display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
|
||||
|
||||
/* settings layout */
|
||||
.settings { max-width: 720px; }
|
||||
.sec-title { font-size: 15px; font-weight: 700; letter-spacing: -.2px; margin: 0 0 12px; }
|
||||
.sec-title.danger { color: var(--red); }
|
||||
.card { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-sm); margin-bottom: 30px; }
|
||||
.fblock { padding: 20px 22px; border-top: 1px solid var(--border); }
|
||||
.fblock:first-child { border-top: none; }
|
||||
.flabel { font-size: 13px; font-weight: 600; color: var(--text); margin-bottom: 5px; display: flex; align-items: center; gap: 7px; }
|
||||
.fhint { font-size: 12.5px; color: var(--text-3); margin-bottom: 11px; line-height: 1.5; }
|
||||
.fixed-pill { font-size: 11px; font-weight: 600; color: var(--text-2); background: #e9ebef; border: 1px solid var(--border-strong); padding: 1px 7px; border-radius: 20px; line-height: 1.5; white-space: nowrap; }
|
||||
|
||||
.tinput { width: 100%; height: 40px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 12px; font-family: inherit; font-size: 14px; color: var(--text); background: #fff; }
|
||||
.tinput:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
textarea.tarea { min-height: 84px; padding: 10px 12px; line-height: 1.6; resize: vertical; height: auto; }
|
||||
|
||||
.readonly { display: flex; align-items: center; gap: 9px; height: 40px; padding: 0 13px; background: #f5f6f8; border: 1px solid var(--border); border-radius: var(--radius); color: var(--text-2); font-size: 14px; font-weight: 500; cursor: not-allowed; }
|
||||
.readonly .owner-avatar { width: 20px; height: 20px; border-radius: 5px; background: #0ea5a3; color: #fff; display: grid; place-items: center; font-size: 10.5px; font-weight: 700; }
|
||||
.readonly .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--text); font-weight: 600; }
|
||||
.readonly .lock { margin-left: auto; color: var(--text-3); display: grid; place-items: center; }
|
||||
.readonly .lock svg { width: 14px; height: 14px; }
|
||||
|
||||
/* visibility radio cards */
|
||||
.radio-group { display: flex; flex-direction: column; gap: 10px; }
|
||||
.radio-card { display: flex; align-items: flex-start; gap: 13px; padding: 13px 14px; border: 1px solid var(--border-strong); border-radius: 8px; cursor: pointer; background: #fff; }
|
||||
.radio-card:hover { border-color: var(--accent-border); }
|
||||
.radio-card.sel { border-color: var(--accent); background: var(--accent-weak); }
|
||||
.rc-ico { width: 32px; height: 32px; border-radius: 8px; background: #f1f2f4; color: var(--text-2); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.rc-ico svg { width: 17px; height: 17px; }
|
||||
.radio-card.sel .rc-ico { background: #fff; color: var(--accent); }
|
||||
.rc-body { flex: 1; }
|
||||
.rc-title { font-size: 14px; font-weight: 600; color: var(--text); }
|
||||
.rc-desc { font-size: 12.5px; color: var(--text-2); margin-top: 2px; line-height: 1.45; }
|
||||
.rc-radio { width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--border-strong); flex-shrink: 0; margin-top: 7px; display: grid; place-items: center; background: #fff; }
|
||||
.radio-card.sel .rc-radio { border-color: var(--accent); }
|
||||
.radio-card.sel .rc-radio::after { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--accent); }
|
||||
|
||||
.input-ico { display: flex; align-items: center; border: 1px solid var(--border-strong); border-radius: var(--radius); background: #fff; padding: 0 12px; gap: 9px; max-width: 300px; }
|
||||
.input-ico:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.input-ico .ico { color: var(--text-3); display: grid; place-items: center; }
|
||||
.input-ico .ico svg { width: 16px; height: 16px; }
|
||||
.input-ico input { flex: 1; border: none; outline: none; height: 40px; font-family: inherit; font-size: 14px; background: transparent; color: var(--text); }
|
||||
|
||||
.card-foot { display: flex; justify-content: flex-end; padding: 14px 22px; border-top: 1px solid var(--border); background: #fafbfc; border-radius: 0 0 10px 10px; }
|
||||
|
||||
/* danger zone */
|
||||
.danger-card { background: #fff; border: 1px solid var(--red-border); border-radius: 10px; box-shadow: var(--shadow-sm); overflow: hidden; }
|
||||
.danger-row { display: flex; align-items: center; gap: 16px; padding: 16px 20px; border-top: 1px solid #f6dde2; }
|
||||
.danger-row:first-child { border-top: none; }
|
||||
.dr-main { flex: 1; min-width: 0; }
|
||||
.dr-title { font-size: 14px; font-weight: 600; color: var(--text); }
|
||||
.dr-desc { font-size: 12.5px; color: var(--text-2); margin-top: 3px; line-height: 1.5; }
|
||||
.btn-danger { height: 34px; padding: 0 14px; border-radius: var(--radius); font-size: 13px; font-weight: 600; border: 1px solid var(--red-border); background: #fff; color: var(--red); cursor: pointer; white-space: nowrap; flex-shrink: 0; }
|
||||
.btn-danger:hover { background: var(--red-weak); }
|
||||
.btn-danger.solid { background: var(--red); border-color: var(--red); color: #fff; }
|
||||
.btn-danger.solid:hover { background: #c23a51; }
|
||||
|
||||
.admin-note { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text-3); margin-bottom: 18px; }
|
||||
.admin-note svg { width: 14px; height: 14px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="내 업무.html">내 업무</a>
|
||||
<a href="저장소 목록.html" class="active">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg></button>
|
||||
<button class="icon-btn" title="알림"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg></button>
|
||||
<div class="me">정</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page" data-screen-label="저장소 설정">
|
||||
<div class="crumb">
|
||||
<a href="저장소 목록.html" class="lnk">저장소</a>
|
||||
<span class="sep">/</span>
|
||||
<a href="저장소 상세.html" class="lnk">3분기 신제품 런칭 캠페인</a>
|
||||
<span class="sep">/</span>
|
||||
<b>설정</b>
|
||||
</div>
|
||||
|
||||
<!-- 저장소 헤더 -->
|
||||
<div class="repo-head">
|
||||
<div class="repo-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
||||
<div class="rh-main">
|
||||
<div class="rh-title">
|
||||
<span class="rh-name">3분기 신제품 런칭 캠페인</span>
|
||||
<span class="vis private"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>비공개</span>
|
||||
</div>
|
||||
<div class="rh-slug">marketing-team / q3-launch-campaign</div>
|
||||
<div class="rh-desc">3분기 신제품(라인 클렌저) 런칭 캠페인 소재 제작 및 검수</div>
|
||||
<div class="rh-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>main</span>
|
||||
<span class="mi avstack"><span class="avatar av-f">정</span><span class="avatar av-a">김</span><span class="avatar av-b">박</span><span class="avatar av-c">이</span><span class="avatar av-d">최</span></span>
|
||||
<span class="mi">멤버 5명</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rh-actions">
|
||||
<a class="btn primary" href="업무 작성.html"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5v14"/></svg>새 업무</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 서브탭 -->
|
||||
<nav class="tabs">
|
||||
<a href="저장소 상세.html"><span class="tb-label">업무</span> <span class="tb-count">12</span></a>
|
||||
<a href="저장소 멤버.html"><span class="tb-label">멤버</span> <span class="tb-count">5</span></a>
|
||||
<a href="저장소 활동.html"><span class="tb-label">활동</span></a>
|
||||
<a href="#" class="active"><span class="tb-label">설정</span></a>
|
||||
</nav>
|
||||
|
||||
<div class="settings">
|
||||
<div class="admin-note">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
|
||||
저장소 설정은 <b style="color:var(--text-2);font-weight:600;white-space:nowrap">관리자</b>만 변경할 수 있습니다.
|
||||
</div>
|
||||
|
||||
<!-- ===== 일반 ===== -->
|
||||
<h2 class="sec-title">일반</h2>
|
||||
<div class="card">
|
||||
<div class="fblock">
|
||||
<div class="flabel">표시 제목</div>
|
||||
<div class="fhint">Relay 목록과 화면에 표시되는 이름입니다. (한글 가능)</div>
|
||||
<input class="tinput" type="text" value="3분기 신제품 런칭 캠페인" maxlength="40">
|
||||
</div>
|
||||
|
||||
<div class="fblock">
|
||||
<div class="flabel">소유자 / Gitea 저장소 이름 <span class="fixed-pill">소유자 고정</span></div>
|
||||
<div class="fhint">Gitea 저장소 이름(영문)은 주소에 사용됩니다. 변경은 아래 위험 구역에서 할 수 있습니다.</div>
|
||||
<div class="readonly">
|
||||
<span class="owner-avatar">M</span> marketing-team <span style="color:var(--text-3)">/</span> <span class="mono">q3-launch-campaign</span>
|
||||
<span class="lock"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="fblock">
|
||||
<div class="flabel">프로젝트 설명</div>
|
||||
<textarea class="tinput tarea">3분기 신제품(라인 클렌저) 런칭 관련 캠페인 소재 제작 및 검수 업무를 관리하는 저장소입니다.</textarea>
|
||||
</div>
|
||||
|
||||
<div class="fblock">
|
||||
<div class="flabel">공개 범위</div>
|
||||
<div class="fhint">저장소와 그 안의 업무를 누가 볼 수 있는지 결정합니다.</div>
|
||||
<div class="radio-group">
|
||||
<label class="radio-card sel">
|
||||
<span class="rc-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></span>
|
||||
<span class="rc-body"><span class="rc-title">비공개</span><span class="rc-desc">저장소에 초대된 멤버만 접근하고 업무를 확인할 수 있습니다.</span></span>
|
||||
<span class="rc-radio"></span>
|
||||
</label>
|
||||
<label class="radio-card">
|
||||
<span class="rc-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20M12 2a15 15 0 0 0 0 20"/></svg></span>
|
||||
<span class="rc-body"><span class="rc-title">공개</span><span class="rc-desc">조직 내 모든 구성원이 저장소를 보고 업무 현황을 열람할 수 있습니다.</span></span>
|
||||
<span class="rc-radio"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="fblock">
|
||||
<div class="flabel">메인 브랜치</div>
|
||||
<div class="fhint">저장소의 기본 브랜치 이름입니다.</div>
|
||||
<div class="input-ico">
|
||||
<span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg></span>
|
||||
<input type="text" value="main" spellcheck="false">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-foot">
|
||||
<button class="btn primary" type="button">변경 저장</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 위험 구역 ===== -->
|
||||
<h2 class="sec-title danger">위험 구역</h2>
|
||||
<div class="danger-card">
|
||||
<div class="danger-row">
|
||||
<div class="dr-main">
|
||||
<div class="dr-title">Gitea 저장소 이름 변경</div>
|
||||
<div class="dr-desc">영문 저장소 이름과 Gitea 주소가 함께 바뀝니다. 기존 링크가 동작하지 않을 수 있습니다.</div>
|
||||
</div>
|
||||
<button class="btn-danger" type="button">이름 변경</button>
|
||||
</div>
|
||||
<div class="danger-row">
|
||||
<div class="dr-main">
|
||||
<div class="dr-title">저장소 삭제</div>
|
||||
<div class="dr-desc">저장소와 그 안의 모든 업무·활동 기록이 영구 삭제됩니다. 되돌릴 수 없습니다.</div>
|
||||
</div>
|
||||
<button class="btn-danger solid" type="button">저장소 삭제</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,286 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>q3-launch-campaign · 활동 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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; --blue: #1d4ed8; --blue-weak: #e8efff; --blue-border: #c9dbff;
|
||||
--red: #d6455d; --amber: #b7791f; --amber-weak: #fdf4e3;
|
||||
--radius: 6px; --radius-sm: 4px; --shadow-sm: 0 1px 2px rgba(20,24,33,.05);
|
||||
}
|
||||
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; }
|
||||
|
||||
/* topbar */
|
||||
.topbar { height: 52px; background: var(--panel); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 28px; padding: 0 20px; position: sticky; top: 0; z-index: 50; }
|
||||
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; letter-spacing: -.2px; }
|
||||
.brand .logo { width: 26px; height: 26px; border-radius: 7px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; box-shadow: 0 2px 6px rgba(79,70,229,.35); }
|
||||
.topnav { display: flex; align-items: center; gap: 2px; }
|
||||
.topnav a { color: var(--text-2); text-decoration: none; font-size: 13.5px; font-weight: 500; padding: 7px 12px; border-radius: var(--radius-sm); line-height: 1; white-space: nowrap; }
|
||||
.topnav a:hover { background: #f1f2f4; color: var(--text); }
|
||||
.topnav a.active { color: var(--accent); background: var(--accent-weak); font-weight: 600; }
|
||||
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
|
||||
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
|
||||
.icon-btn:hover { background: #f1f2f4; color: var(--text); }
|
||||
.me { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; color: #fff; background: #0ea5a3; margin-left: 4px; }
|
||||
|
||||
/* page */
|
||||
.page { max-width: 1080px; margin: 0 auto; padding: 0 24px 70px; }
|
||||
.crumb { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12.5px; padding: 18px 0 12px; white-space: nowrap; }
|
||||
.crumb .lnk { color: var(--text-2); font-weight: 600; text-decoration: none; }
|
||||
.crumb .lnk:hover { color: var(--accent); }
|
||||
.crumb .sep { opacity: .5; }
|
||||
.crumb b { color: var(--text-2); font-weight: 600; }
|
||||
|
||||
.btn { height: 36px; padding: 0 15px; border-radius: var(--radius); font-size: 13.5px; 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: 6px; line-height: 1; text-decoration: none; white-space: nowrap; }
|
||||
.btn:hover { background: #f7f8fa; color: var(--text); }
|
||||
.btn svg { width: 15px; height: 15px; }
|
||||
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 2px rgba(79,70,229,.4); }
|
||||
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
|
||||
|
||||
/* repo header */
|
||||
.repo-head { display: flex; align-items: flex-start; gap: 16px; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 20px 22px; box-shadow: var(--shadow-sm); }
|
||||
.repo-ico { width: 46px; height: 46px; border-radius: 10px; background: var(--accent-weak); color: var(--accent); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.repo-ico svg { width: 24px; height: 24px; }
|
||||
.rh-main { flex: 1; min-width: 0; }
|
||||
.rh-title { display: flex; align-items: center; gap: 10px; }
|
||||
.rh-name { font-size: 18px; font-weight: 700; letter-spacing: -.3px; white-space: nowrap; }
|
||||
.rh-slug { font-size: 12.5px; color: var(--text-3); margin-top: 5px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
.vis { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 20px; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; line-height: 1.5; }
|
||||
.vis svg { width: 11px; height: 11px; }
|
||||
.vis.private { color: var(--text-2); background: #f1f2f4; border: 1px solid var(--border); }
|
||||
.rh-desc { font-size: 13.5px; color: var(--text-2); margin-top: 6px; }
|
||||
.rh-meta { display: flex; align-items: center; gap: 15px; margin-top: 12px; font-size: 12px; color: var(--text-3); }
|
||||
.rh-meta .mi { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
|
||||
.rh-meta .mi svg { width: 13px; height: 13px; }
|
||||
.avatar { width: 21px; height: 21px; border-radius: 50%; display: grid; place-items: center; font-size: 10px; font-weight: 700; color: #fff; flex-shrink: 0; }
|
||||
.avstack { display: flex; align-items: center; }
|
||||
.avstack .avatar { margin-left: -7px; box-shadow: 0 0 0 2px #fff; }
|
||||
.avstack .avatar:first-child { margin-left: 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; }
|
||||
.rh-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
|
||||
|
||||
/* tabs */
|
||||
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin: 20px 0 18px; }
|
||||
.tabs a { padding: 10px 14px; font-size: 13.5px; font-weight: 600; color: var(--text-2); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
|
||||
.tabs a:hover { color: var(--text); }
|
||||
.tabs a.active { color: var(--accent); border-bottom-color: var(--accent); }
|
||||
.tabs a .tb-label { line-height: 1; }
|
||||
.tabs a .tb-count { font-size: 11px; font-weight: 600; color: var(--text-2); background: #f1f2f4; border-radius: 20px; padding: 0 7px; height: 17px; min-width: 17px; display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
|
||||
.tabs a.active .tb-count { background: var(--accent-weak); color: var(--accent); }
|
||||
|
||||
/* toolbar */
|
||||
.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
|
||||
.segmented { display: flex; background: #eceef1; border-radius: var(--radius); padding: 3px; gap: 2px; }
|
||||
.segmented button { border: none; background: transparent; font-family: inherit; font-size: 13px; font-weight: 600; color: var(--text-2); padding: 5px 13px; border-radius: 4px; cursor: pointer; white-space: nowrap; }
|
||||
.segmented button.active { background: #fff; color: var(--text); box-shadow: var(--shadow-sm); }
|
||||
.mfilter { margin-left: auto; display: flex; align-items: center; gap: 7px; height: 36px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 11px; background: #fff; font-size: 13px; font-weight: 500; color: var(--text-2); cursor: pointer; white-space: nowrap; }
|
||||
.mfilter svg { width: 15px; height: 15px; color: var(--text-3); }
|
||||
|
||||
/* activity feed */
|
||||
.feed { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-sm); padding: 6px 20px 18px; }
|
||||
.day { font-size: 12px; font-weight: 700; color: var(--text-3); letter-spacing: .2px; padding: 18px 0 6px; }
|
||||
.act { display: flex; align-items: center; gap: 13px; padding: 9px 0; position: relative; }
|
||||
.act-ico { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; flex-shrink: 0; z-index: 1; }
|
||||
.act-ico svg { width: 16px; height: 16px; }
|
||||
.act-ico.task { background: var(--blue-weak); color: var(--blue); }
|
||||
.act-ico.member { background: var(--green-weak); color: var(--green); }
|
||||
.act-ico.setting { background: var(--amber-weak); color: var(--amber); }
|
||||
.act-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; }
|
||||
.act-av { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; font-size: 10px; font-weight: 700; color: #fff; flex-shrink: 0; }
|
||||
.act-text { font-size: 13.5px; color: var(--text-2); line-height: 1.5; }
|
||||
.act-text b { color: var(--text); font-weight: 600; }
|
||||
.act-text .tgt { color: var(--accent); font-weight: 600; text-decoration: none; }
|
||||
.act-text .tgt:hover { text-decoration: underline; }
|
||||
.act-text .st { font-weight: 600; }
|
||||
.act-text .st.prog { color: var(--blue); } .act-text .st.done { color: var(--green); }
|
||||
.act-time { font-size: 12px; color: var(--text-3); white-space: nowrap; flex-shrink: 0; margin-left: 12px; }
|
||||
|
||||
/* vertical connector line */
|
||||
.feed-inner { position: relative; }
|
||||
.act::before { content: ""; position: absolute; left: 15.5px; top: 50%; bottom: -9px; width: 1.5px; background: var(--border); z-index: 0; }
|
||||
.act.last-in-group::before { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="brand"><div class="logo">R</div>Relay</div>
|
||||
<nav class="topnav">
|
||||
<a href="내 업무.html">내 업무</a>
|
||||
<a href="저장소 목록.html" class="active">저장소</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<button class="icon-btn" title="검색"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg></button>
|
||||
<button class="icon-btn" title="알림"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg></button>
|
||||
<div class="me">정</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page" data-screen-label="저장소 활동">
|
||||
<div class="crumb">
|
||||
<a href="저장소 목록.html" class="lnk">저장소</a>
|
||||
<span class="sep">/</span>
|
||||
<a href="저장소 상세.html" class="lnk">3분기 신제품 런칭 캠페인</a>
|
||||
<span class="sep">/</span>
|
||||
<b>활동</b>
|
||||
</div>
|
||||
|
||||
<!-- 저장소 헤더 -->
|
||||
<div class="repo-head">
|
||||
<div class="repo-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></div>
|
||||
<div class="rh-main">
|
||||
<div class="rh-title">
|
||||
<span class="rh-name">3분기 신제품 런칭 캠페인</span>
|
||||
<span class="vis private"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>비공개</span>
|
||||
</div>
|
||||
<div class="rh-slug">marketing-team / q3-launch-campaign</div>
|
||||
<div class="rh-desc">3분기 신제품(라인 클렌저) 런칭 캠페인 소재 제작 및 검수</div>
|
||||
<div class="rh-meta">
|
||||
<span class="mi"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>main</span>
|
||||
<span class="mi avstack"><span class="avatar av-f">정</span><span class="avatar av-a">김</span><span class="avatar av-b">박</span><span class="avatar av-c">이</span><span class="avatar av-d">최</span></span>
|
||||
<span class="mi">2시간 전 업데이트</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rh-actions">
|
||||
<a class="btn primary" href="업무 작성.html"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5v14"/></svg>새 업무</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 서브탭 -->
|
||||
<nav class="tabs">
|
||||
<a href="저장소 상세.html"><span class="tb-label">업무</span> <span class="tb-count">12</span></a>
|
||||
<a href="저장소 멤버.html"><span class="tb-label">멤버</span> <span class="tb-count">5</span></a>
|
||||
<a href="#" class="active"><span class="tb-label">활동</span></a>
|
||||
<a href="저장소 설정.html"><span class="tb-label">설정</span></a>
|
||||
</nav>
|
||||
|
||||
<!-- 툴바 -->
|
||||
<div class="toolbar">
|
||||
<div class="segmented">
|
||||
<button class="active">전체</button>
|
||||
<button>업무</button>
|
||||
<button>멤버</button>
|
||||
<button>설정</button>
|
||||
</div>
|
||||
<div class="mfilter">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
||||
모든 멤버
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 활동 피드 -->
|
||||
<div class="feed">
|
||||
<div class="feed-inner">
|
||||
|
||||
<div class="day">오늘</div>
|
||||
<div class="act">
|
||||
<span class="act-ico task"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg></span>
|
||||
<div class="act-main">
|
||||
<span class="act-av av-c">이</span>
|
||||
<span class="act-text"><b>이도윤</b>님이 <a class="tgt" href="#">법무 검토 요청 및 회신 반영</a> 업무를 <span class="st prog">진행 중</span>으로 변경했습니다</span>
|
||||
</div>
|
||||
<span class="act-time">2시간 전</span>
|
||||
</div>
|
||||
<div class="act">
|
||||
<span class="act-ico task"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg></span>
|
||||
<div class="act-main">
|
||||
<span class="act-av av-b">박</span>
|
||||
<span class="act-text"><b>박지훈</b>님이 <a class="tgt" href="#">메인 배너 이미지 2종 디자인</a>의 체크리스트 ‘가로형 메인 배너’를 완료했습니다</span>
|
||||
</div>
|
||||
<span class="act-time">3시간 전</span>
|
||||
</div>
|
||||
<div class="act">
|
||||
<span class="act-ico member"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M19 8v6M22 11h-6"/></svg></span>
|
||||
<div class="act-main">
|
||||
<span class="act-av av-f">정</span>
|
||||
<span class="act-text"><b>정태경</b>님이 <b>한지민</b>님을 멤버로 초대했습니다</span>
|
||||
</div>
|
||||
<span class="act-time">5시간 전</span>
|
||||
</div>
|
||||
<div class="act last-in-group">
|
||||
<span class="act-ico member"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="m17 11 2 2 4-4"/></svg></span>
|
||||
<div class="act-main">
|
||||
<span class="act-av av-d">한</span>
|
||||
<span class="act-text"><b>한지민</b>님이 멤버로 합류했습니다</span>
|
||||
</div>
|
||||
<span class="act-time">5시간 전</span>
|
||||
</div>
|
||||
|
||||
<div class="day">어제</div>
|
||||
<div class="act">
|
||||
<span class="act-ico task"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg></span>
|
||||
<div class="act-main">
|
||||
<span class="act-av av-d">최</span>
|
||||
<span class="act-text"><b>최유진</b>님이 <a class="tgt" href="#">메인 비주얼 컨셉 확정</a> 업무를 <span class="st done">완료</span>했습니다</span>
|
||||
</div>
|
||||
<span class="act-time">어제 18:40</span>
|
||||
</div>
|
||||
<div class="act last-in-group">
|
||||
<span class="act-ico task"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg></span>
|
||||
<div class="act-main">
|
||||
<span class="act-av av-f">정</span>
|
||||
<span class="act-text"><b>정태경</b>님이 <a class="tgt" href="#">SNS 콘텐츠 1차 시안</a> 업무를 지시했습니다 <span style="color:var(--text-3)">· 담당 정민호</span></span>
|
||||
</div>
|
||||
<span class="act-time">어제 14:10</span>
|
||||
</div>
|
||||
|
||||
<div class="day">이번 주</div>
|
||||
<div class="act">
|
||||
<span class="act-ico setting"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></span>
|
||||
<div class="act-main">
|
||||
<span class="act-av av-f">정</span>
|
||||
<span class="act-text"><b>정태경</b>님이 저장소 공개 범위를 <b>비공개</b>로 변경했습니다</span>
|
||||
</div>
|
||||
<span class="act-time">6월 11일</span>
|
||||
</div>
|
||||
<div class="act">
|
||||
<span class="act-ico member"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 11h-6"/></svg></span>
|
||||
<div class="act-main">
|
||||
<span class="act-av av-b">박</span>
|
||||
<span class="act-text"><b>박지훈</b>님의 역할이 <b>멤버</b>로 설정되었습니다</span>
|
||||
</div>
|
||||
<span class="act-time">6월 11일</span>
|
||||
</div>
|
||||
<div class="act">
|
||||
<span class="act-ico setting"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg></span>
|
||||
<div class="act-main">
|
||||
<span class="act-av av-f">정</span>
|
||||
<span class="act-text"><b>정태경</b>님이 표시 제목을 ‘3분기 신제품 런칭 캠페인’으로 변경했습니다</span>
|
||||
</div>
|
||||
<span class="act-time">6월 10일</span>
|
||||
</div>
|
||||
<div class="act">
|
||||
<span class="act-ico task"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg></span>
|
||||
<div class="act-main">
|
||||
<span class="act-av av-a">김</span>
|
||||
<span class="act-text"><b>김서연</b>님이 <a class="tgt" href="#">캠페인 핵심 메시지 시안 작성</a> 업무를 <span class="st done">완료</span>했습니다</span>
|
||||
</div>
|
||||
<span class="act-time">6월 9일</span>
|
||||
</div>
|
||||
<div class="act last-in-group">
|
||||
<span class="act-ico setting"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg></span>
|
||||
<div class="act-main">
|
||||
<span class="act-av av-f">정</span>
|
||||
<span class="act-text"><b>정태경</b>님이 저장소를 생성했습니다</span>
|
||||
</div>
|
||||
<span class="act-time">6월 2일</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,222 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>회원가입 — Relay</title>
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
: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; --kakao: #FEE500; --kakao-text: #191600;
|
||||
--radius: 8px; --radius-sm: 5px;
|
||||
}
|
||||
html, body { height: 100%; }
|
||||
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; }
|
||||
.auth { display: flex; min-height: 100vh; }
|
||||
|
||||
/* brand panel */
|
||||
.brand-panel { flex: 0 0 46%; max-width: 620px; position: relative; overflow: hidden; background: linear-gradient(155deg, #4f46e5 0%, #4338ca 52%, #2e2a8f 100%); color: #fff; padding: 44px 48px; display: flex; flex-direction: column; }
|
||||
.brand-panel .blob { position: absolute; border-radius: 50%; pointer-events: none; }
|
||||
.brand-panel .b1 { width: 360px; height: 360px; right: -120px; top: -90px; background: rgba(255,255,255,.10); }
|
||||
.brand-panel .b2 { width: 260px; height: 260px; left: -90px; bottom: -70px; background: rgba(255,255,255,.07); }
|
||||
.brand-panel .ring { position: absolute; right: 60px; bottom: 80px; width: 180px; height: 180px; border: 1.5px solid rgba(255,255,255,.14); border-radius: 50%; }
|
||||
.brand-panel .ring::after { content: ""; position: absolute; inset: 34px; border: 1.5px solid rgba(255,255,255,.10); border-radius: 50%; }
|
||||
.bp-logo { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 18px; letter-spacing: -.2px; position: relative; z-index: 1; }
|
||||
.bp-logo .logo { width: 32px; height: 32px; border-radius: 9px; background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.22); display: grid; place-items: center; font-size: 17px; font-weight: 800; }
|
||||
.bp-body { margin-top: auto; position: relative; z-index: 1; }
|
||||
.bp-head { font-size: 34px; font-weight: 700; line-height: 1.32; letter-spacing: -.8px; text-wrap: balance; }
|
||||
.bp-sub { margin-top: 18px; font-size: 15px; line-height: 1.7; color: rgba(255,255,255,.82); max-width: 400px; }
|
||||
.bp-points { margin-top: 30px; display: flex; flex-direction: column; gap: 12px; }
|
||||
.bp-point { display: flex; align-items: center; gap: 11px; font-size: 14px; color: rgba(255,255,255,.92); }
|
||||
.bp-point .ic { width: 22px; height: 22px; border-radius: 50%; background: rgba(255,255,255,.16); display: grid; place-items: center; flex-shrink: 0; }
|
||||
.bp-point .ic svg { width: 13px; height: 13px; }
|
||||
.bp-foot { margin-top: 40px; font-size: 12.5px; color: rgba(255,255,255,.6); position: relative; z-index: 1; }
|
||||
|
||||
/* form panel */
|
||||
.form-panel { flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px 24px; }
|
||||
.auth-card { width: 100%; max-width: 384px; }
|
||||
.ac-logo { display: none; }
|
||||
.ac-title { font-size: 24px; font-weight: 700; letter-spacing: -.5px; }
|
||||
.ac-sub { color: var(--text-2); font-size: 14px; margin-top: 7px; }
|
||||
|
||||
.socials { display: flex; flex-direction: column; gap: 10px; margin-top: 26px; }
|
||||
.sbtn { height: 46px; border-radius: var(--radius); border: 1px solid var(--border-strong); background: #fff; display: flex; align-items: center; justify-content: center; gap: 10px; cursor: pointer; font-family: inherit; font-size: 14.5px; font-weight: 600; color: var(--text); text-decoration: none; position: relative; transition: background .12s; }
|
||||
.sbtn:hover { background: #f7f8fa; }
|
||||
.sbtn .sico { position: absolute; left: 16px; display: grid; place-items: center; }
|
||||
.sbtn.kakao { background: var(--kakao); border-color: var(--kakao); color: var(--kakao-text); }
|
||||
.sbtn.kakao:hover { background: #f2d900; }
|
||||
|
||||
.divider { display: flex; align-items: center; gap: 14px; margin: 20px 0; color: var(--text-3); font-size: 12.5px; }
|
||||
.divider::before, .divider::after { content: ""; height: 1px; background: var(--border); flex: 1; }
|
||||
|
||||
.field { margin-bottom: 13px; }
|
||||
.flabel { font-size: 13px; font-weight: 600; color: var(--text-2); margin-bottom: 7px; display: block; }
|
||||
.tinput { width: 100%; height: 44px; border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 0 13px; font-family: inherit; font-size: 14px; color: var(--text); background: #fff; }
|
||||
.tinput:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
|
||||
.tinput::placeholder { color: var(--text-3); }
|
||||
.pw-wrap { position: relative; }
|
||||
.pw-wrap .tinput { padding-right: 44px; }
|
||||
.pw-toggle { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 34px; height: 34px; border: none; background: transparent; color: var(--text-3); display: grid; place-items: center; cursor: pointer; border-radius: 6px; }
|
||||
.pw-toggle:hover { background: #f1f2f4; color: var(--text-2); }
|
||||
.pw-toggle svg { width: 18px; height: 18px; }
|
||||
.field-hint { font-size: 12px; color: var(--text-3); margin-top: 7px; display: flex; align-items: center; gap: 5px; }
|
||||
.field-hint svg { width: 13px; height: 13px; flex-shrink: 0; }
|
||||
|
||||
.terms { display: flex; align-items: flex-start; gap: 9px; margin: 6px 0 18px; font-size: 13px; color: var(--text-2); cursor: pointer; user-select: none; line-height: 1.5; }
|
||||
.terms .box { width: 18px; height: 18px; border-radius: 5px; border: 1.5px solid var(--border-strong); display: grid; place-items: center; background: #fff; flex-shrink: 0; margin-top: 1px; }
|
||||
.terms .box.on { background: var(--accent); border-color: var(--accent); }
|
||||
.terms .box svg { width: 12px; height: 12px; color: #fff; opacity: 0; }
|
||||
.terms .box.on svg { opacity: 1; }
|
||||
.terms a { color: var(--accent); font-weight: 600; text-decoration: none; }
|
||||
.terms a:hover { text-decoration: underline; }
|
||||
|
||||
.submit { width: 100%; height: 46px; border-radius: var(--radius); border: none; background: var(--accent); color: #fff; font-family: inherit; font-size: 15px; font-weight: 700; cursor: pointer; box-shadow: 0 1px 2px rgba(79,70,229,.4); display: flex; align-items: center; justify-content: center; gap: 7px; }
|
||||
.submit:hover { background: var(--accent-hover); }
|
||||
.submit svg { width: 17px; height: 17px; }
|
||||
|
||||
.alt { margin-top: 22px; text-align: center; font-size: 13.5px; color: var(--text-2); }
|
||||
.alt a { color: var(--accent); font-weight: 600; text-decoration: none; }
|
||||
.alt a:hover { text-decoration: underline; }
|
||||
|
||||
/* verification sent state */
|
||||
.verify { text-align: center; display: none; }
|
||||
.verify .vicon { width: 66px; height: 66px; border-radius: 50%; background: var(--accent-weak); color: var(--accent); display: grid; place-items: center; margin: 0 auto 22px; }
|
||||
.verify .vicon svg { width: 30px; height: 30px; }
|
||||
.verify h1 { font-size: 23px; font-weight: 700; letter-spacing: -.4px; }
|
||||
.verify .vtext { color: var(--text-2); font-size: 14px; line-height: 1.7; margin-top: 12px; }
|
||||
.verify .vmail { display: inline-flex; align-items: center; gap: 6px; margin-top: 16px; padding: 9px 14px; background: #f7f8fa; border: 1px solid var(--border); border-radius: var(--radius); font-size: 14px; font-weight: 600; color: var(--text); }
|
||||
.verify .vmail svg { width: 15px; height: 15px; color: var(--text-3); }
|
||||
.verify .vspam { font-size: 12.5px; color: var(--text-3); margin-top: 18px; line-height: 1.6; }
|
||||
.verify .vactions { margin-top: 26px; display: flex; flex-direction: column; gap: 10px; }
|
||||
.btn-ghost { height: 44px; border-radius: var(--radius); border: 1px solid var(--border-strong); background: #fff; color: var(--text); font-family: inherit; font-size: 14px; font-weight: 600; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 7px; text-decoration: none; }
|
||||
.btn-ghost:hover { background: #f7f8fa; }
|
||||
.btn-ghost svg { width: 16px; height: 16px; }
|
||||
.vchange { background: none; border: none; font-family: inherit; font-size: 13px; color: var(--text-2); cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
|
||||
.vchange:hover { color: var(--text); }
|
||||
|
||||
@media (max-width: 880px) {
|
||||
.brand-panel { display: none; }
|
||||
.ac-logo { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 17px; margin-bottom: 24px; }
|
||||
.ac-logo .logo { width: 28px; height: 28px; border-radius: 8px; background: linear-gradient(135deg, #5b54f0, #4338ca); display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="auth">
|
||||
|
||||
<aside class="brand-panel">
|
||||
<div class="blob b1"></div>
|
||||
<div class="blob b2"></div>
|
||||
<div class="ring"></div>
|
||||
<div class="bp-logo"><span class="logo">R</span> Relay</div>
|
||||
<div class="bp-body">
|
||||
<div class="bp-head">팀에 합류하고<br>업무 지시를 시작하세요</div>
|
||||
<div class="bp-sub">계정을 만들면 저장소에 초대되어, 받은 업무를 확인하고 직접 업무를 지시할 수 있습니다.</div>
|
||||
<div class="bp-points">
|
||||
<div class="bp-point"><span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span> 이메일로 1분이면 가입 완료</div>
|
||||
<div class="bp-point"><span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span> 이메일 인증으로 안전한 가입</div>
|
||||
<div class="bp-point"><span class="ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span> 가입 후 바로 업무 흐름에 참여</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bp-foot">© 2026 Relay · 사내 업무 지시 플랫폼</div>
|
||||
</aside>
|
||||
|
||||
<main class="form-panel">
|
||||
<div class="auth-card">
|
||||
<div class="ac-logo"><span class="logo">R</span> Relay</div>
|
||||
|
||||
<!-- ===== 상태 1: 가입 폼 ===== -->
|
||||
<div class="signup-form">
|
||||
<h1 class="ac-title">이메일로 회원가입</h1>
|
||||
<p class="ac-sub">구글·카카오 계정은 <a href="로그인.html" style="color:var(--accent);font-weight:600;text-decoration:none">로그인 화면</a>에서 바로 시작할 수 있어요.</p>
|
||||
|
||||
<div class="field" style="margin-top:26px">
|
||||
<label class="flabel">이름</label>
|
||||
<input class="tinput" type="text" placeholder="홍길동" value="">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="flabel">이메일</label>
|
||||
<input class="tinput" id="email" type="email" placeholder="name@acme.co" value="">
|
||||
<div class="field-hint"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 6-10 7L2 6"/></svg> 가입 후 이 주소로 인증 메일이 발송됩니다.</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="flabel">비밀번호</label>
|
||||
<div class="pw-wrap">
|
||||
<input class="tinput" type="password" placeholder="비밀번호 입력" value="">
|
||||
<button class="pw-toggle" type="button" title="비밀번호 표시"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
|
||||
</div>
|
||||
<div class="field-hint"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></svg> 8자 이상, 영문과 숫자를 포함해주세요.</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="flabel">비밀번호 확인</label>
|
||||
<div class="pw-wrap">
|
||||
<input class="tinput" type="password" placeholder="비밀번호 다시 입력" value="">
|
||||
<button class="pw-toggle" type="button" title="비밀번호 표시"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label class="terms" id="terms">
|
||||
<span class="box on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
|
||||
<span><a href="#">이용약관</a> 및 <a href="#">개인정보 처리방침</a>에 동의합니다. (필수)</span>
|
||||
</label>
|
||||
|
||||
<button class="submit" type="button" id="submitBtn">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 6-10 7L2 6"/></svg>
|
||||
인증 메일 받고 가입하기
|
||||
</button>
|
||||
|
||||
<div class="alt">이미 계정이 있으신가요? <a href="로그인.html">로그인</a></div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 상태 2: 인증 메일 전송됨 ===== -->
|
||||
<div class="verify" id="verifyView">
|
||||
<div class="vicon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 6-10 7L2 6"/></svg></div>
|
||||
<h1>이메일을 확인해주세요</h1>
|
||||
<div class="vtext">아래 주소로 인증 메일을 보냈습니다.<br>메일 속 링크를 클릭하면 가입이 완료됩니다.</div>
|
||||
<div class="vmail"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 6-10 7L2 6"/></svg><span id="verifyEmail">name@acme.co</span></div>
|
||||
<div class="vspam">메일이 보이지 않나요? 스팸함을 확인하거나 잠시 후 다시 시도해주세요.</div>
|
||||
<div class="vactions">
|
||||
<button class="btn-ghost" type="button"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/></svg> 인증 메일 다시 보내기</button>
|
||||
<button class="vchange" type="button" id="backBtn">다른 이메일로 가입하기</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 비밀번호 표시 토글
|
||||
document.querySelectorAll('.pw-toggle').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
var input = this.parentElement.querySelector('input');
|
||||
input.type = input.type === 'password' ? 'text' : 'password';
|
||||
});
|
||||
});
|
||||
// 약관 동의 토글
|
||||
document.getElementById('terms').addEventListener('click', function (e) {
|
||||
if (e.target.closest('a')) return;
|
||||
e.preventDefault();
|
||||
this.querySelector('.box').classList.toggle('on');
|
||||
});
|
||||
// 가입하기 → 인증 메일 전송 상태로 전환
|
||||
document.getElementById('submitBtn').addEventListener('click', function () {
|
||||
var email = document.getElementById('email').value.trim() || 'name@acme.co';
|
||||
document.getElementById('verifyEmail').textContent = email;
|
||||
document.querySelector('.signup-form').style.display = 'none';
|
||||
document.getElementById('verifyView').style.display = 'block';
|
||||
});
|
||||
// 다른 이메일로 가입하기 → 폼으로 복귀
|
||||
document.getElementById('backBtn').addEventListener('click', function () {
|
||||
document.getElementById('verifyView').style.display = 'none';
|
||||
document.querySelector('.signup-form').style.display = 'block';
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user