generated from ttipo/project-base
docs: 2단계(임시 저장·서명·받는 사람 추천) 계약과 디자인
캔버스 19 에서 확정한 2단계 화면(Settings · ComposeAssist)을 저장소에 두고, 계약 2절에 임시 저장 · 서명 · 받는 사람 추천 절과 서식 본문의 서명 그림 예외를 더한다. 구현과 리뷰에서 정한 것도 함께 적는다: - 엔진의 destroy 는 되돌릴 수 없어, 사용자 메일을 지우는 경로는 확인한 상태 그대로일 때만(ifInState) 지운다 - 본문에 그림으로 보인 부분은 첨부 목록·클립에서 뺀다(isInline · hasAttachment) — 서명 그림이 매번 첨부로 보이지 않게 - 서명 그림 한도(서명 3장 · 보관 10장 · 300KB · 4096px), 사내 추천은 최근 90일 로그인 - 저장하지 않는 경우(찾지 못한 첨부 · 본문 한도 초과)와 남의 저장본 원본 보존, 알려진 한계 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,251 @@
|
||||
<!doctype html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>메일 쓰기 · 임시 저장 · 자동 완성 · 서명</title>
|
||||
<script src="./support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<x-dc>
|
||||
<helmet>
|
||||
<style>
|
||||
@font-face{font-family:'Pretendard';src:url('/_blob/16067b9aa5137abf808e3dbef30c42e0') format('woff2-variations'),url('/_blob/16067b9aa5137abf808e3dbef30c42e0') format('woff2');font-weight:45 920;font-style:normal;font-display:swap}
|
||||
body{margin:0}
|
||||
a{color:#0E7C86}a:hover{color:#0A5F67}
|
||||
:focus-visible{outline:2px solid #0E7C86;outline-offset:2px}
|
||||
.on-dark:focus-visible{outline-color:#9ED6DB}
|
||||
.ghost{background:transparent;color:#344054}
|
||||
.ghost:hover{background:#F2F4F7;color:#171C26}
|
||||
.row:hover{background:#F8F9FB}
|
||||
</style>
|
||||
</helmet>
|
||||
<div style="width: 1440px; height: 1400px; box-sizing: border-box; padding: 48px; display: flex; flex-direction: column; gap: 28px; background: #F6F7F9; color: #171C26; font-family: Pretendard, -apple-system, 'Apple SD Gothic Neo', 'Malgun Gothic', system-ui, sans-serif; font-size: 13px; line-height: 1.5">
|
||||
|
||||
<div style="display: flex; flex-direction: column; gap: 6px; max-width: 820px">
|
||||
<h1 style="margin: 0; font-size: 24px; font-weight: 700; letter-spacing: -0.02em">메일 쓰기 · 임시 저장 · 자동 완성 · 서명</h1>
|
||||
<p style="margin: 0; font-size: 13.5px; color: #4A5363">쓰기 화면에 더해지는 세 가지입니다. 서명을 고치는 화면은 「설정 · 메일 서명」 보드에 있습니다. 문구 중 오류는 에러 코드 사전에서 가져옵니다.</p>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; align-items: start">
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">임시 저장 · 자동 저장</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">입력이 3초 멈추면 · 10초에 한 번까지 · 화면을 떠날 때</p>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">바꾼 내용이 있으면 임시보관함에 저장합니다. 아무것도 쓰지 않은 쓰기 화면은 저장하지 않습니다. 쓰기 화면의 「취소」는 「임시 저장」으로 바뀌고, 저장된 채로는 닫기(✕)·다른 메일함으로 가도 묻지 않습니다.</p>
|
||||
<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px 12px; border: 1px solid #E6E8EC; border-radius: 10px">
|
||||
<button type="button" style="display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 18px; border: 0; border-radius: 8px; background: #0E7C86; color: #FFFFFF; font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
|
||||
<span>보내기</span>
|
||||
</button>
|
||||
<button type="button" class="ghost" style="min-height: 44px; padding: 0 14px; border: 0; border-radius: 8px; font: inherit; font-weight: 500; cursor: pointer">임시 저장</button>
|
||||
<span role="status" style="display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: #667085">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12a9 9 0 1 1-6.22-8.56"></path></svg>
|
||||
<span>저장하는 중…</span>
|
||||
</span>
|
||||
</div>
|
||||
<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px 12px; border: 1px solid #E6E8EC; border-radius: 10px">
|
||||
<button type="button" style="display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 18px; border: 0; border-radius: 8px; background: #0E7C86; color: #FFFFFF; font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
|
||||
<span>보내기</span>
|
||||
</button>
|
||||
<button type="button" class="ghost" style="min-height: 44px; padding: 0 14px; border: 0; border-radius: 8px; font: inherit; font-weight: 500; cursor: pointer">임시 저장</button>
|
||||
<span role="status" style="display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: #667085">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#0E7C86" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"></polyline></svg>
|
||||
<span>오후 3:12에 임시 저장됨</span>
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">임시 저장 · 실패</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">에러 코드 · MAIL_001 · MAIL_003</p>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">자동 저장이 실패하면 알림 없이 이 자리에만 보이고 조금 뒤 다시 시도합니다. 「임시 저장」을 눌러 실패하면 사전 문구 알림도 띄웁니다.</p>
|
||||
<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px 12px; border: 1px solid #E6E8EC; border-radius: 10px">
|
||||
<button type="button" style="display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 18px; border: 0; border-radius: 8px; background: #0E7C86; color: #FFFFFF; font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
|
||||
<span>보내기</span>
|
||||
</button>
|
||||
<button type="button" class="ghost" style="min-height: 44px; padding: 0 14px; border: 0; border-radius: 8px; font: inherit; font-weight: 500; cursor: pointer">임시 저장</button>
|
||||
<span role="status" style="display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: #B42318">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>
|
||||
<span>임시 저장하지 못했습니다</span>
|
||||
</span>
|
||||
<button type="button" class="ghost" style="min-height: 44px; padding: 0 10px; border: 0; border-radius: 8px; color: #0E7C86; font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer">다시 시도</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">임시 저장 · 다른 곳에서 바뀐 저장본</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">에러 코드 · MAIL_008</p>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">같은 저장본을 다른 창·기기에서 먼저 고쳤거나 지웠으면, 막지 않고 지금 내용을 새 저장본으로 남깁니다 — 어느 쪽도 지우지 않으므로 임시보관함에 두 통이 보입니다.</p>
|
||||
<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px 12px; border: 1px solid #E6E8EC; border-radius: 10px">
|
||||
<button type="button" style="display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 18px; border: 0; border-radius: 8px; background: #0E7C86; color: #FFFFFF; font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
|
||||
<span>보내기</span>
|
||||
</button>
|
||||
<button type="button" class="ghost" style="min-height: 44px; padding: 0 14px; border: 0; border-radius: 8px; font: inherit; font-weight: 500; cursor: pointer">임시 저장</button>
|
||||
<span role="status" style="display: inline-flex; align-items: flex-start; gap: 6px; font-size: 12px; color: #7A5200">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="flex: 0 0 auto; margin-top: 2px"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>
|
||||
<span>다른 곳에서 바뀐 저장본이 있어 새로 저장했습니다 · 오후 3:14</span>
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">임시보관함 목록</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">누르면 쓰기 화면에서 이어 씁니다</p>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">보낸 사람 자리에 받는 사람을 보이고, 시각은 마지막으로 저장한 때입니다. 보내면 임시보관함에서 사라집니다.</p>
|
||||
<ul aria-label="임시보관함" style="list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; border: 1px solid #E6E8EC; border-radius: 10px; overflow: hidden">
|
||||
<li><a href="Compose.dc.html" class="row" style="display: flex; flex-direction: column; gap: 2px; padding: 9px 12px; border-bottom: 1px solid #EEF0F3; color: #171C26; text-decoration: none">
|
||||
<span style="display: flex; justify-content: space-between; gap: 8px"><span style="font-weight: 500">이도윤</span><span style="font-size: 12px; color: #667085; font-variant-numeric: tabular-nums">오후 3:12</span></span>
|
||||
<span style="display: flex; align-items: center; gap: 6px">
|
||||
<span style="flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #344054">Re: 메일 서버 이전 일정 공유</span>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#667085" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" role="img" aria-label="첨부 있음"><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"></path></svg>
|
||||
</span>
|
||||
</a></li>
|
||||
<li><a href="Compose.dc.html" class="row" style="display: flex; flex-direction: column; gap: 2px; padding: 9px 12px; border-bottom: 1px solid #EEF0F3; color: #171C26; text-decoration: none">
|
||||
<span style="display: flex; justify-content: space-between; gap: 8px"><span style="font-weight: 500">박준호, 인프라팀</span><span style="font-size: 12px; color: #667085; font-variant-numeric: tabular-nums">어제</span></span>
|
||||
<span style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #344054">10월 장애 보고서 초안</span>
|
||||
</a></li>
|
||||
<li><a href="Compose.dc.html" class="row" style="display: flex; flex-direction: column; gap: 2px; padding: 9px 12px; color: #171C26; text-decoration: none">
|
||||
<span style="display: flex; justify-content: space-between; gap: 8px"><span style="color: #667085">(받는 사람 없음)</span><span style="font-size: 12px; color: #667085; font-variant-numeric: tabular-nums">10월 24일</span></span>
|
||||
<span style="color: #667085">(제목 없음)</span>
|
||||
</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">임시 저장본 삭제</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">쓰기 화면 머리의 휴지통 단추</p>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">삭제는 임시 저장본을 휴지통으로 옮기고 쓰기 화면을 닫습니다 — 알림의 「되돌리기」로 다시 꺼냅니다. 닫기(✕)는 저장한 채 닫습니다.</p>
|
||||
<div style="display: flex; align-items: center; gap: 2px; min-height: 52px; box-sizing: border-box; padding: 4px 6px 4px 16px; border: 1px solid #E6E8EC; border-radius: 10px">
|
||||
<span style="flex: 1 1 auto; font-size: 15px; font-weight: 700; letter-spacing: -0.01em">답장</span>
|
||||
<button type="button" class="ghost" aria-label="이 메일 삭제" title="삭제" style="width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 8px; cursor: pointer">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
|
||||
</button>
|
||||
<button type="button" class="ghost" aria-label="쓰기 닫기" title="닫기" style="width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 8px; cursor: pointer">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div role="status" style="display: flex; align-items: center; gap: 10px; padding: 6px 6px 6px 14px; border-radius: 10px; background: #0B3640; color: #FFFFFF; box-shadow: 0 10px 28px rgba(16, 24, 28, 0.22)">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#9FE0B5" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="flex: 0 0 auto"><polyline points="20 6 9 17 4 12"></polyline></svg>
|
||||
<span style="flex: 1 1 auto; font-weight: 500">임시 저장한 메일을 휴지통으로 옮겼습니다.</span>
|
||||
<button type="button" class="on-dark" style="flex: 0 0 auto; min-height: 44px; padding: 0 10px; border: 0; border-radius: 6px; background: transparent; color: #9ED6DB; font: inherit; font-weight: 600; cursor: pointer">되돌리기</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">나가기 확인 · 저장하지 못했을 때</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">자동 저장이 되는 동안에는 묻지 않습니다</p>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">저장이 실패했거나 아직 저장하지 못한 내용이 있을 때만 지금의 나가기 확인을 띄웁니다. 단추와 키는 그대로입니다.</p>
|
||||
<dialog open aria-labelledby="unsaved-title" aria-describedby="unsaved-text" style="position: static; margin: 0; padding: 18px 18px 14px; width: auto; border: 1px solid #E6E8EC; border-radius: 12px; background: #FFFFFF; color: #171C26; box-shadow: 0 14px 36px rgba(16, 24, 28, 0.14); display: flex; flex-direction: column; gap: 8px">
|
||||
<h3 id="unsaved-title" style="margin: 0; font-size: 15px; font-weight: 700">저장하지 못한 내용이 있습니다</h3>
|
||||
<p id="unsaved-text" style="margin: 0; color: #4A5363">이 화면을 나가면 마지막으로 바꾼 내용이 사라집니다.</p>
|
||||
<div style="display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px">
|
||||
<button type="button" style="min-height: 44px; padding: 0 16px; border: 0; border-radius: 8px; background: #0E7C86; color: #FFFFFF; font: inherit; font-weight: 600; cursor: pointer">계속 쓰기</button>
|
||||
<button type="button" class="ghost" style="min-height: 44px; padding: 0 14px; border: 0; border-radius: 8px; font: inherit; font-weight: 500; cursor: pointer">나가기</button>
|
||||
</div>
|
||||
</dialog>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">받는 사람 자동 완성</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">받는 사람 · 참조 · 숨은참조 공통</p>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">이름이나 주소를 한 글자 이상 치면 사내(웹메일에 로그인한 적 있는 직원)와 최근 주고받은 주소에서 찾아 보입니다. 초성으로도 찾습니다(ㄷㅇ → 도윤). 이미 넣은 주소는 빼고 최대 8개, 맞는 글자는 굵게 보입니다.</p>
|
||||
<div style="display: flex; flex-direction: column; gap: 4px">
|
||||
<div style="display: flex; align-items: center; gap: 6px 12px; min-height: 44px; box-sizing: border-box; padding: 4px 12px; border-bottom: 2px solid #0E7C86; background: #FFFFFF">
|
||||
<label for="assist-to" style="flex: 0 0 auto; font-size: 12.5px; font-weight: 600; color: #4A5363">받는 사람</label>
|
||||
<span style="display: inline-flex; align-items: center; min-height: 28px; padding: 0 8px; border-radius: 4px; background: #F2F4F7; color: #171C26; font-size: 13px">박준호</span>
|
||||
<input id="assist-to" type="text" value="도윤" role="combobox" aria-autocomplete="list" aria-expanded="true" aria-controls="assist-list" aria-activedescendant="assist-opt-1" style="flex: 1 1 80px; min-width: 60px; min-height: 34px; border: 0; outline: none; font: inherit; color: #171C26; background: transparent">
|
||||
</div>
|
||||
<div id="assist-list" role="listbox" aria-label="받는 사람 추천" style="display: flex; flex-direction: column; padding: 6px; border: 1px solid #E6E8EC; border-radius: 10px; background: #FFFFFF; box-shadow: 0 10px 28px rgba(16, 24, 28, 0.12)">
|
||||
<div role="group" aria-label="사내" style="display: flex; flex-direction: column">
|
||||
<span aria-hidden="true" style="padding: 4px 8px 2px; font-size: 12px; font-weight: 600; color: #667085">사내</span>
|
||||
<div id="assist-opt-1" role="option" aria-selected="true" style="display: flex; align-items: baseline; gap: 8px; min-height: 40px; box-sizing: border-box; padding: 9px 8px; border-radius: 6px; background: #E3F2F3">
|
||||
<span style="flex: 0 0 auto; color: #171C26">이<strong>도윤</strong></span>
|
||||
<span style="min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: #4A5363"><strong>doyun</strong>.lee@arasystem.it.kr</span>
|
||||
</div>
|
||||
<div role="option" aria-selected="false" style="display: flex; align-items: baseline; gap: 8px; min-height: 40px; box-sizing: border-box; padding: 9px 8px; border-radius: 6px">
|
||||
<span style="flex: 0 0 auto; color: #171C26">김<strong>도윤</strong></span>
|
||||
<span style="min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: #4A5363"><strong>doyun</strong>.kim@arasystem.it.kr</span>
|
||||
</div>
|
||||
</div>
|
||||
<div role="group" aria-label="최근 주고받은 주소" style="display: flex; flex-direction: column; margin-top: 4px; padding-top: 4px; border-top: 1px solid #EEF0F3">
|
||||
<span aria-hidden="true" style="padding: 4px 8px 2px; font-size: 12px; font-weight: 600; color: #667085">최근 주고받은 주소</span>
|
||||
<div role="option" aria-selected="false" style="display: flex; align-items: baseline; gap: 8px; min-height: 40px; box-sizing: border-box; padding: 9px 8px; border-radius: 6px">
|
||||
<span style="flex: 0 0 auto; color: #171C26">최<strong>도윤</strong></span>
|
||||
<span style="min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: #4A5363">[협력사 주소]</span>
|
||||
</div>
|
||||
</div>
|
||||
<p style="margin: 4px 8px 2px; font-size: 12px; color: #667085">↑↓ 고르기 · Enter · Tab 넣기 · Esc 닫기</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">자동 완성 · 주소를 끝까지 친 경우</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">엉뚱한 사람이 들어가지 않게</p>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">친 글자가 완전한 메일 주소면 추천을 미리 고르지 않습니다 — Enter 는 친 주소를 그대로 넣습니다. 화살표로 고른 뒤에만 추천이 들어갑니다.</p>
|
||||
<div style="display: flex; flex-direction: column; gap: 4px">
|
||||
<div style="display: flex; align-items: center; gap: 6px 12px; min-height: 44px; box-sizing: border-box; padding: 4px 12px; border-bottom: 2px solid #0E7C86; background: #FFFFFF">
|
||||
<label for="assist-to-full" style="flex: 0 0 auto; font-size: 12.5px; font-weight: 600; color: #4A5363">받는 사람</label>
|
||||
<input id="assist-to-full" type="text" value="doyun.lee@partner.example" role="combobox" aria-autocomplete="list" aria-expanded="true" aria-controls="assist-list-full" style="flex: 1 1 120px; min-width: 80px; min-height: 34px; border: 0; outline: none; font: inherit; color: #171C26; background: transparent">
|
||||
</div>
|
||||
<div id="assist-list-full" role="listbox" aria-label="받는 사람 추천" style="display: flex; flex-direction: column; padding: 6px; border: 1px solid #E6E8EC; border-radius: 10px; background: #FFFFFF; box-shadow: 0 10px 28px rgba(16, 24, 28, 0.12)">
|
||||
<div role="option" aria-selected="false" style="display: flex; align-items: baseline; gap: 8px; min-height: 40px; box-sizing: border-box; padding: 9px 8px; border-radius: 6px">
|
||||
<span style="flex: 0 0 auto; color: #171C26">이도윤</span>
|
||||
<span style="min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: #4A5363"><strong>doyun.lee@</strong>arasystem.it.kr</span>
|
||||
</div>
|
||||
<p style="margin: 4px 8px 2px; font-size: 12px; color: #667085">Enter 는 친 주소를 그대로 넣습니다</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 14px; padding: 20px; background: #FFFFFF; border: 1px solid #E6E8EC; border-radius: 12px">
|
||||
<div style="display: flex; flex-direction: column; gap: 2px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-weight: 700">서명이 들어간 답장</h2>
|
||||
<p style="margin: 0; font-size: 12px; color: #667085">새 메일은 본문 끝 · 답장 · 전달은 인용 위</p>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #4A5363">쓰기 화면을 열 때 서명을 보통 글로 넣어 둡니다 — 그 메일에서 바로 고치거나 지울 수 있고, 임시 저장에도 그대로 남습니다. 서명 그림은 보낼 때 메일 안에 함께 실어 보냅니다.</p>
|
||||
<div style="box-sizing: border-box; padding: 14px 16px; border: 1px solid #E6E8EC; border-radius: 10px; font-family: 'Malgun Gothic', '맑은 고딕', 'Apple SD Gothic Neo', sans-serif; font-size: 14px; line-height: 1.75; color: #1F2733">
|
||||
<p style="margin: 0">도윤님, 확인했습니다.</p>
|
||||
<p style="margin: 0"><br></p>
|
||||
<p style="margin: 0"><strong>김아라</strong> · 인프라팀</p>
|
||||
<p style="margin: 0">ARA SYSTEM · [전화번호]</p>
|
||||
<p style="margin: 6px 0 0"><span role="img" aria-label="[회사 로고]" style="display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; width: 144px; height: 43px; border: 1px dashed #98A2B3; border-radius: 4px; color: #667085; font-family: Pretendard, -apple-system, 'Apple SD Gothic Neo', 'Malgun Gothic', system-ui, sans-serif; font-size: 12px">[회사 로고]</span></p>
|
||||
<blockquote style="margin: 16px 0 0; padding: 2px 0 2px 14px; border-left: 2px solid #D0D5DD; color: #4A5363">
|
||||
<p style="margin: 0; font-size: 12.5px; font-weight: 600">원본 메일</p>
|
||||
<p style="margin: 0; font-size: 12.5px">보낸 사람 이도윤 · 2026. 10. 26. (월) 오전 10:42</p>
|
||||
<p style="margin: 4px 0 0">김아라님, 안녕하세요.</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</x-dc>
|
||||
<script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1400}}'>
|
||||
class Component extends DCLogic {
|
||||
renderVals() {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,11 +1,12 @@
|
||||
# 웹메일 디자인 원본 (1단계)
|
||||
# 웹메일 디자인 원본 (1·2단계)
|
||||
|
||||
확정된 디자인 캔버스의 원본이다. 화면 구현의 기준으로 쓴다.
|
||||
|
||||
- 캔버스: https://claude.ai/artifact/WJvVsKvXepxn3p75CGJAr2 (확정본: 2026-10-27, 버전 14)
|
||||
- 캔버스: https://claude.ai/artifact/WJvVsKvXepxn3p75CGJAr2 (확정본: 2026-10-27, 버전 19)
|
||||
- 화면: `Login`(로그인) · `Main`(분할 보기: 메일함·목록·본문) · `MainList`(목록 보기: 게시판형 표) · `MainListRead`(목록 보기에서 연 메일)
|
||||
· `Compose`(메일 쓰기 — 서식 편집기) · `ComposeEditor`(메일 쓰기 · 편집기 상태: 포커스·툴바·메뉴·팝오버·인용·이미지 첨부)
|
||||
· `States`(오류·빈 상태·피드백 모음)
|
||||
· 2단계: `Settings`(설정 · 메일 서명) · `ComposeAssist`(메일 쓰기 · 임시 저장 · 받는 사람 자동 완성 · 서명) — 아래 "2단계"
|
||||
- 파일 형식은 캔버스 전용(`<x-dc>` 마크업 + `DCLogic` 클래스)이다. 그대로 쓰지 말고 **구조·간격·색·문구의 기준**으로만 본다.
|
||||
`Compose` 의 툴바·메뉴는 눌러 볼 수 있는 시안이다 — 버튼 상태만 바뀌고 본문 글자에 서식이 입혀지지는 않는다.
|
||||
|
||||
@@ -157,10 +158,12 @@
|
||||
떠난 화면이나 새로 연 쓰기 화면은 그 결과로 바뀌지 않는다 (2026-10-27 리뷰 반영).
|
||||
단 보내는 중에 탭을 닫거나 새로고침하면 브라우저 기본 확인창은 뜬다 — 요청이 끊길 수 있고 결과를 알릴 화면이 남지 않기 때문이다.
|
||||
- 맥의 ⌘[ 를 본문 밖에서 눌러 브라우저 "뒤로"가 되어도 이 확인에 걸린다.
|
||||
- **2단계(임시 저장)부터는 저장된 채로는 묻지 않는다** — 저장하지 못한 내용이 있을 때만 이 확인을 띄우고 제목 · 글이 바뀐다
|
||||
(아래 "2단계 › 임시 저장"). 단추 · 키 · 묻지 않는 경우는 그대로다.
|
||||
|
||||
### 본문 이미지 → 첨부 파일
|
||||
|
||||
- 본문에는 이미지를 넣지 않는다(사용자 확정). 툴바에 이미지 버튼이 없다.
|
||||
- 본문에는 이미지를 넣지 않는다(사용자 확정). 툴바에 이미지 버튼이 없다. **서명 그림만 예외**다 (아래 "2단계 › 서명").
|
||||
- 본문에 붙여 넣거나(Ctrl+V) 끌어다 놓은 이미지는 첨부 파일로 올린다. 끌어다 놓은 다른 파일도 첨부로 올린다(쓰기 화면 어디에 놓아도 같다).
|
||||
한도는 첨부와 같다 — 넘치면 첨부 목록에 실패로 보인다(`States` 의 "첨부 업로드").
|
||||
- 클립보드에 **글이 함께 있으면 글을 붙여 넣는다** — 워드 · 엑셀에서 복사하면 고른 부분의 그림이 글과 함께 따라오기 때문이다.
|
||||
@@ -171,6 +174,47 @@
|
||||
받지 않는 곳에 놓으면 브라우저가 그 파일을 열어 쓰던 메일을 잃기 때문이다 (2026-10-27 구현하며 정함).
|
||||
- 이미지를 첨부로 돌렸을 때만 성공 알림 "이미지는 본문 대신 첨부 파일로 올렸습니다."를 띄운다(성공 알림과 같은 모양 · 5초).
|
||||
|
||||
## 2단계 — 임시 저장 · 서명 · 받는 사람 자동 완성 (2026-10-27 확정 — `Settings` · `ComposeAssist`)
|
||||
|
||||
### 임시 저장
|
||||
|
||||
- **자동 저장**: 바꾼 내용이 있으면 입력이 3초 멈출 때(10초에 한 번까지)와 화면을 떠날 때 임시보관함에 저장한다.
|
||||
아무것도 쓰지 않은 쓰기 화면은 저장하지 않는다. 저장은 한 번에 하나씩이고, 보내기 전에는 진행 중인 저장이 끝나기를 기다린다.
|
||||
- **아래 단추 줄**: [보내기] [임시 저장] 뒤에 상태 글(12px) — "저장하는 중…"(#667085) · "오후 3:12에 임시 저장됨"(✓ #0E7C86) ·
|
||||
실패 "임시 저장하지 못했습니다"(#B42318) + [다시 시도]. 「취소」는 없앤다 — 닫기(✕)가 저장한 채 닫는다.
|
||||
- 자동 저장이 실패하면 알림 없이 그 자리에만 보이고 조금 뒤 다시 시도한다. 「임시 저장」을 눌러 실패하면 사전 문구 알림도 띄운다.
|
||||
- 같은 저장본을 다른 창 · 기기에서 먼저 고쳤거나 지웠으면(`MAIL_008`, 휴지통으로 옮겼으면 PUT 의 404 `RES_001`) 막지 않고 지금 내용을 새 저장본으로 남긴다 —
|
||||
상태 글 "다른 곳에서 바뀐 저장본이 있어 새로 저장했습니다 · 오후 3:14"(정보 아이콘, #7A5200). 임시보관함에 두 통이 남는다.
|
||||
- **삭제**: 쓰기 화면 머리의 휴지통 단추(44 · "이 메일 삭제") — 임시 저장본을 휴지통으로 옮기고 닫는다. 알림 "임시 저장한 메일을 휴지통으로 옮겼습니다."
|
||||
+ [되돌리기](임시보관함으로 되돌린다). 저장본이 아직 없으면 그냥 닫는다.
|
||||
- **임시보관함 목록**: 보낸 사람 자리에 받는 사람(없으면 "(받는 사람 없음)"), 제목이 없으면 "(제목 없음)" — 둘 다 #667085.
|
||||
시각은 마지막으로 저장한 때. 누르면 읽기 화면이 아니라 쓰기 화면에서 이어 쓴다. 보내면 임시보관함에서 사라진다.
|
||||
- **나가기 확인**: 저장된 채로는 묻지 않는다. 떠나기 전에 남은 변경을 먼저 저장하고, 저장하지 못한 내용이 있을 때만
|
||||
제목 "저장하지 못한 내용이 있습니다", 글 "이 화면을 나가면 마지막으로 바꾼 내용이 사라집니다."로 묻는다.
|
||||
|
||||
### 서명
|
||||
|
||||
- **설정 › 메일 › 서명** — 앱 레일의 "설정"에서 연다. 왼쪽 패널(208 · #F8F9FB)의 "메일" 묶음에 "서명", 오른쪽은 콘텐츠 열(최대 800).
|
||||
- 서명 칸: 굵게 · 기울임 · 밑줄 · 글자 색 · 링크 · 그림. 글꼴은 쓰기 화면 본문과 같은 맑은 고딕 14px · 줄 간격 1.75.
|
||||
- **그림**: 그림 단추 · 붙여 넣기 · 끌어다 놓기로 넣는다 — PNG · JPG · GIF, 한 장 300KB 이하, 3장까지.
|
||||
그림을 고르면 칸 아래에 크기 줄(작게 96px · 보통 144px · 원본 — 최대 600px · 그림 빼기). 메일 안에 함께 실어 보내므로
|
||||
받는 쪽에서 외부 이미지처럼 막히지 않는다. 지금 있는 흰 로고는 흰 메일 바탕에서 보이지 않으니 서명에는 색이 있는 로고를 쓴다.
|
||||
- 서명을 넣을 메일: 새 메일 · 답장 · 전달(인용한 원문 위) — 둘 다 기본으로 켠다. 미리 보기에서 [새 메일 | 답장]을 바꿔 본다.
|
||||
- [저장] → "저장했습니다. 새로 여는 쓰기 화면부터 들어갑니다."(#067647).
|
||||
- 쓰기 화면을 열 때 서명을 보통 글로 넣어 둔다 — 새 메일은 본문 끝(빈 줄 하나 뒤), 답장 · 전달은 인용 위. 그 메일에서 고치거나 지울 수 있고
|
||||
임시 저장에도 남는다. 임시 저장본을 이어 쓸 때는 서명을 다시 넣지 않는다. 본문에 붙여 넣은 다른 그림은 지금처럼 첨부로 올린다.
|
||||
- 서명 그림처럼 **본문 안에 그림으로 보인 부분은 첨부로 보이지 않는다** — 읽기 화면의 첨부 목록과 목록의 첨부 클립에서 뺀다
|
||||
(받은 메일의 본문 그림도 같다). 전달할 때는 원문 그림을 잃지 않게 원본 첨부로 함께 붙는다 (인용 본문에서는 그림이 빠지기 때문이다).
|
||||
|
||||
### 받는 사람 자동 완성
|
||||
|
||||
- 받는 사람 · 참조 · 숨은참조에서 한 글자 이상 치면 칸 바로 아래에 추천 목록(최대 8개) — "사내"(웹메일에 로그인한 적 있는 직원) ·
|
||||
"최근 주고받은 주소" 두 묶음(묶음 이름 12px #667085 굵게). 줄은 높이 40 · 이름(맞는 글자 굵게) + 주소(12px #4A5363), 고른 줄은 #E3F2F3.
|
||||
- 이미 넣은 주소는 빼고, 초성으로도 찾는다(ㄷㅇ → 도윤). 목록 아래 안내 "↑↓ 고르기 · Enter · Tab 넣기 · Esc 닫기".
|
||||
- 친 글자가 완전한 메일 주소면 추천을 미리 고르지 않는다 — Enter 는 친 주소를 그대로 넣고("Enter 는 친 주소를 그대로 넣습니다"),
|
||||
화살표로 고른 뒤에만 추천이 들어간다. 엉뚱한 사람이 받는 사람에 들어가지 않게 하기 위해서다.
|
||||
- 쓰기 화면을 열 때 추천 목록을 한 번 받아 두고 치는 대로 바로 거른다 — 모자랄 때만 서버에 다시 묻는다.
|
||||
|
||||
## 구현하며 정한 보완 (2026-10-26 — 캔버스에는 아직 없다)
|
||||
|
||||
- 찾지 못한 첨부(보관 시간이 지난 업로드·지워진 원본)는 실패로 표시하고, 전달 원본에는 "빼기"만 둔다(다시 올릴 수 없다).
|
||||
@@ -181,3 +225,34 @@
|
||||
- 서버가 HTML 을 정화 한도 때문에 비웠을 때(`isHtmlBodyOmitted`): 글자 본문이 있으면 "본문이 복잡해 서식 없이 글자만 표시합니다.",
|
||||
없으면 "본문이 너무 크거나 복잡해 표시할 수 없습니다."
|
||||
- 보여 주는 본문이 읽기 한도(2MB)에서 잘렸을 때(`isBodyTruncated`): "본문이 길어 앞부분만 표시합니다."
|
||||
|
||||
### 2단계 구현하며 정한 보완 (2026-10-27 — 캔버스에는 아직 없다)
|
||||
|
||||
- **임시 저장**
|
||||
- 쉬지 않고 쓰는 동안에도 처음 바꾼 때(또는 마지막 저장을 시작한 때)부터 30초가 지나면 저장한다 — 멈춤을 기다리다 오래 쓴 글을 잃지 않게.
|
||||
- 저장할 때마다 주소를 `/mail/compose?draft=<새 id>` 로 맞춘다 — 새로고침하거나 다시 열면 마지막 저장본을 이어 쓴다.
|
||||
떠나기 전 저장은 주소를 바꾸지 않는다(가던 이동이 취소되므로). 대신 같은 탭에서 옛 `?draft=` 로 돌아오면(뒤로 가기) 마지막 저장본을 연다
|
||||
— 저장본이 바뀐 차례는 탭 메모리에만 두고 로그아웃 · 세션 만료 때 지운다.
|
||||
- 자동 저장 실패 가운데 메일 서버 장애·용량·요청 과다는 15초 → 30초 → 60초 뒤 저절로 다시 한다. 그 밖의 실패는 내용을 고치면 다시 저장한다.
|
||||
- 「임시 저장」은 아직 한 번도 저장하지 않았으면 바꾼 것이 없어도 저장한다 (빈 메일 · 미리 채운 답장 포함).
|
||||
- 형식이 틀린 주소 · 사전 검사에 걸린 첨부는 저장하지 않는다 (칸에는 남는다). 올리는 중인 첨부는 "저장하지 못한 내용"으로 친다.
|
||||
- 찾지 못한 첨부(`MAIL_004`)가 남아 있는 동안은 저장하지 않는다(「임시 저장」 · [다시 시도] 포함) — 첨부가 빠진 판으로 멀쩡한 저장본을 덮지 않게.
|
||||
그 첨부를 빼면 다시 저장한다.
|
||||
- 본문이 한도를 넘으면 보내기처럼 인용을 줄여 저장한다(편집기 화면은 그대로). 인용을 다 줄여도 넘으면 저장하지 않고 보내기와 같은 안내를
|
||||
본문 아래에 보이며, 내용을 고칠 때까지 다시 시도하지 않는다.
|
||||
- 다른 메일 프로그램이 만든 저장본에 우리가 실을 수 없는 첨부(허용 목록 밖 · 개수 · 합계 초과)가 있으면, 첫 저장은 원본을 지우지 않고 새 저장본으로 남긴다
|
||||
— 원본은 첨부째 임시보관함에 그대로 있다.
|
||||
- 떠나기 전 저장은 5초까지만 기다린다. 끝나지 않으면 "저장하지 못한 내용이 있습니다"로 묻고, 묻는 사이에 저장이 끝나면 그대로 떠난다.
|
||||
- 보내는 중에 화면을 떠났는데 발송이 실패하면, 보내려던 내용을 임시 저장본으로 한 번 남긴다 (실패 알림은 그대로).
|
||||
- 알려진 한계: 떠나기 전 저장이 첫 저장이었던 새 메일 · 답장 · 전달은, 뒤로 가기로 돌아오면 새 양식이 열린다 (저장본은 임시보관함에 있다).
|
||||
- 휴지통 단추는 저장본을 휴지통 메일함으로 **옮긴다**(삭제 요청이 아니다 — 다른 창에서 먼저 휴지통으로 옮긴 것을 영구 삭제하지 않게).
|
||||
[되돌리기]로 되돌리면 "임시보관함으로 되돌렸습니다." 알림을 띄운다. 휴지통 메일함을 알 수 없으면 지우지 않고 실패로 알린다.
|
||||
이미 없는 저장본이면 알림 없이 닫는다. 단추가 있는 알림은 10초 보인다. 알림은 마우스 · 초점이 그 위에 있는 동안 사라지지 않고,
|
||||
놓으면 그 알림의 시간을 처음부터 다시 센다.
|
||||
- 이어 쓰는 저장본의 제목 줄: 답장 대상이 있으면 답장, 제목이 `Fwd:`·`FW:`·`전달:` 로 시작하면 전달, 그 밖은 새 메일.
|
||||
- **서명**
|
||||
- 서명을 바꾸고 저장하지 않은 채 떠나면 묻는다 — 제목 "저장하지 않은 서명이 있습니다", 글 "이 화면을 나가면 바꾼 서명이 사라집니다.", [계속 고치기] [나가기].
|
||||
- 서명 그림 3장은 서명 칸에 있는 그림 수로 센다. 미리 보기의 답장 원문 자리는 예시 이름 대신 "(보낸 사람)" 같은 괄호 글이다.
|
||||
- 설정 화면의 미리 보기 전환 단추와 그림 크기 줄(작게 · 보통 · 원본 · 그림 빼기, 36px)은 목록의 보기 전환처럼 밀도 예외다 (캔버스 확정값).
|
||||
- **받는 사람 자동 완성**: Tab 은 고른 추천을 넣고 그 칸에 머문다(고른 것이 없으면 원래 Tab). 화살표는 끝에서 처음으로 돌고, 마우스를 올린 줄이 골라진다.
|
||||
초성 · 자모만 친 글자는 서버에 묻지 않는다(받아 둔 목록에서만 거른다).
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
<!doctype html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>설정 · 메일 서명</title>
|
||||
<script src="./support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<x-dc>
|
||||
<helmet>
|
||||
<style>
|
||||
@font-face{font-family:'Pretendard';src:url('/_blob/16067b9aa5137abf808e3dbef30c42e0') format('woff2-variations'),url('/_blob/16067b9aa5137abf808e3dbef30c42e0') format('woff2');font-weight:45 920;font-style:normal;font-display:swap}
|
||||
body{margin:0}
|
||||
a{color:#0E7C86}a:hover{color:#0A5F67}
|
||||
:focus-visible{outline:2px solid #0E7C86;outline-offset:2px}
|
||||
/* 서명 편집 칸: 쓰기 화면 본문과 같은 글꼴 · 문단 여백 0 */
|
||||
.se p{margin:0}
|
||||
.se:focus,.se:focus-visible{outline:none}
|
||||
.sig-box:has(.se:focus){border-color:#0E7C86 !important;box-shadow:0 0 0 1px #0E7C86}
|
||||
.tb{background:transparent;color:#344054}
|
||||
.tb:hover{background:#F2F4F7;color:#171C26}
|
||||
/* 미리 보기 전환 (분할 | 목록 전환과 같은 모양) */
|
||||
.seg{background:transparent;color:#4A5363}
|
||||
.seg[aria-pressed="true"]{background:#FFFFFF;color:#171C26;box-shadow:0 1px 2px rgba(16,24,28,.14)}
|
||||
</style>
|
||||
</helmet>
|
||||
<div style="min-height: 100vh; display: flex; background: #FFFFFF; color: #171C26; font-family: Pretendard, -apple-system, 'Apple SD Gothic Neo', 'Malgun Gothic', system-ui, sans-serif; font-size: 13px; line-height: 1.5">
|
||||
|
||||
<nav aria-label="사내 시스템" style="flex: 0 0 72px; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 10px 0 12px; background: #0B3640">
|
||||
<a href="Main.dc.html" style="display: inline-flex; align-items: center; justify-content: center; width: 60px; min-height: 44px; border-radius: 10px; text-decoration: none">
|
||||
<img src="/_blob/2b9ef4349333debc969432c859eaf1bf" alt="ARA SYSTEM" width="48" height="17" style="display: block; width: 48px; height: auto">
|
||||
</a>
|
||||
<ul style="list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px">
|
||||
<li>
|
||||
<a href="Main.dc.html" style="display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; color: #A3C2C6; font-size: 11px; font-weight: 500; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>
|
||||
<span>메일</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" style="display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; color: #A3C2C6; font-size: 11px; font-weight: 500; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>
|
||||
<span>캘린더</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" style="display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; color: #A3C2C6; font-size: 11px; font-weight: 500; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path></svg>
|
||||
<span>파일</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" style="display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; color: #A3C2C6; font-size: 11px; font-weight: 500; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="7" width="20" height="14" rx="2" ry="2"></rect><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"></path></svg>
|
||||
<span>ERP</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" style="display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; color: #A3C2C6; font-size: 11px; font-weight: 500; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
|
||||
<span>주소록</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<a href="#" aria-current="page" style="margin-top: auto; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: 60px; min-height: 56px; border-radius: 10px; background: #155A64; color: #FFFFFF; font-size: 11px; font-weight: 600; text-decoration: none">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
|
||||
<span>설정</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<div style="flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column">
|
||||
|
||||
<header style="display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; box-sizing: border-box; min-height: 56px; padding: 6px 12px 6px 20px; border-bottom: 1px solid #E6E8EC">
|
||||
<span style="font-size: 16px; font-weight: 700; letter-spacing: -0.01em">설정</span>
|
||||
<div style="flex: 1 1 280px; max-width: 520px; display: flex; align-items: center; gap: 8px; box-sizing: border-box; height: 40px; padding: 0 12px; border: 1px solid #8A94A3; border-radius: 8px; background: #FFFFFF">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#667085" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
|
||||
<input type="search" aria-label="통합 검색" placeholder="통합 검색" style="flex: 1 1 auto; min-width: 0; border: 0; background: transparent; font: inherit; color: #171C26">
|
||||
</div>
|
||||
<div style="margin-left: auto; display: flex; align-items: center; gap: 10px">
|
||||
<span aria-hidden="true" style="display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%; background: #E3F2F3; color: #0A5F67; font-size: 13px; font-weight: 600">김</span>
|
||||
<div style="display: flex; flex-direction: column; line-height: 1.3">
|
||||
<span style="font-weight: 600">김아라</span>
|
||||
<span style="font-size: 12px; color: #667085">ara.kim@arasystem.it.kr</span>
|
||||
</div>
|
||||
<a href="Login.dc.html" style="display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 10px; border-radius: 8px; color: #4A5363; font-weight: 500; text-decoration: none">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
|
||||
<span>로그아웃</span>
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div style="flex: 1 1 auto; display: flex; flex-wrap: wrap; align-items: stretch">
|
||||
|
||||
<nav aria-label="설정 메뉴" style="flex: 1 1 208px; box-sizing: border-box; display: flex; flex-direction: column; gap: 4px; padding: 14px 10px; background: #F8F9FB; border-right: 1px solid #E6E8EC">
|
||||
<p style="margin: 4px 10px 4px; font-size: 12px; font-weight: 600; color: #667085">메일</p>
|
||||
<ul style="list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px">
|
||||
<li><a href="#" aria-current="page" style="display: flex; align-items: center; gap: 10px; min-height: 40px; box-sizing: border-box; padding: 0 10px; border-radius: 7px; background: #E3F2F3; color: #0A5F67; font-weight: 600; text-decoration: none">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20h9"></path><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path></svg>
|
||||
<span>서명</span>
|
||||
</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<main style="flex: 999 1 560px; min-width: 0; box-sizing: border-box; display: flex; flex-direction: column">
|
||||
<div style="max-width: 800px; box-sizing: border-box; padding: 20px 32px 36px; display: flex; flex-direction: column; gap: 22px">
|
||||
|
||||
<div style="display: flex; flex-direction: column; gap: 4px">
|
||||
<h1 style="margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -0.01em">서명</h1>
|
||||
<p style="margin: 0; color: #4A5363">보내는 메일 끝에 넣는 글입니다. 쓰기 화면을 열 때 본문에 넣어 두므로, 그 메일에서만 고치거나 지울 수도 있습니다.</p>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; flex-direction: column; gap: 8px">
|
||||
<p id="signature-label" style="margin: 0; font-weight: 600">서명 내용</p>
|
||||
<div class="sig-box" style="display: flex; flex-direction: column; border: 1px solid #D0D5DD; border-radius: 10px; background: #FFFFFF">
|
||||
<div role="toolbar" aria-label="서명 서식" aria-controls="signature-body" style="display: flex; align-items: center; gap: 2px; min-height: 52px; box-sizing: border-box; padding: 4px 8px; border-bottom: 1px solid #EEF0F3">
|
||||
<button type="button" class="tb" aria-label="굵게" aria-keyshortcuts="Control+B" title="굵게 (Ctrl+B)" style="width: 40px; height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 8px; cursor: pointer">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 4h8a4 4 0 0 1 0 8H6z"></path><path d="M6 12h9a4 4 0 0 1 0 8H6z"></path></svg>
|
||||
</button>
|
||||
<button type="button" class="tb" aria-label="기울임" aria-keyshortcuts="Control+I" title="기울임 (Ctrl+I)" style="width: 40px; height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 8px; cursor: pointer">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="19" y1="4" x2="10" y2="4"></line><line x1="14" y1="20" x2="5" y2="20"></line><line x1="15" y1="4" x2="9" y2="20"></line></svg>
|
||||
</button>
|
||||
<button type="button" class="tb" aria-label="밑줄" aria-keyshortcuts="Control+U" title="밑줄 (Ctrl+U)" style="width: 40px; height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 8px; cursor: pointer">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 3v7a6 6 0 0 0 12 0V3"></path><line x1="4" y1="21" x2="20" y2="21"></line></svg>
|
||||
</button>
|
||||
<span aria-hidden="true" style="flex: 0 0 auto; width: 1px; height: 20px; margin: 0 4px; background: #E6E8EC"></span>
|
||||
<button type="button" class="tb" aria-label="글자 색: 기본" title="글자 색" style="width: 40px; height: 44px; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; padding: 0; border: 0; border-radius: 8px; cursor: pointer">
|
||||
<svg width="16" height="14" viewBox="0 0 24 20" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 17 12 3l7 14"></path><line x1="7.5" y1="12" x2="16.5" y2="12"></line></svg>
|
||||
<span aria-hidden="true" style="width: 16px; height: 3px; border-radius: 1px; background: #1F2733"></span>
|
||||
</button>
|
||||
<button type="button" class="tb" aria-label="링크" aria-keyshortcuts="Control+K" title="링크 (Ctrl+K)" style="width: 40px; height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 8px; cursor: pointer">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
|
||||
</button>
|
||||
<button type="button" class="tb" aria-label="그림 넣기" title="그림 넣기 — PNG · JPG · GIF" style="width: 40px; height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 8px; cursor: pointer">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div id="signature-body" class="se" contenteditable="true" tabindex="0" role="textbox" aria-multiline="true" aria-labelledby="signature-label" style="min-height: 132px; box-sizing: border-box; padding: 14px 16px; font-family: 'Malgun Gothic', '맑은 고딕', 'Apple SD Gothic Neo', sans-serif; font-size: 14px; line-height: 1.75; color: #1F2733">
|
||||
<p><strong>김아라</strong> · 인프라팀</p>
|
||||
<p>ARA SYSTEM · [전화번호]</p>
|
||||
<p><a href="mailto:ara.kim@arasystem.it.kr">ara.kim@arasystem.it.kr</a></p>
|
||||
<p style="margin-top: 8px"><span role="img" aria-label="[회사 로고] — 고른 그림" style="display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; width: {{ logoWidth }}px; height: {{ logoHeight }}px; border: 1px dashed #98A2B3; border-radius: 4px; outline: 2px solid #0E7C86; outline-offset: 2px; color: #667085; font-family: Pretendard, -apple-system, 'Apple SD Gothic Neo', 'Malgun Gothic', system-ui, sans-serif; font-size: 12px">[회사 로고]</span></p>
|
||||
</div>
|
||||
<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 6px 12px 8px; border-top: 1px solid #EEF0F3">
|
||||
<span style="font-size: 12.5px; font-weight: 600; color: #4A5363">그림 크기</span>
|
||||
<div role="group" aria-label="그림 크기" style="display: inline-flex; gap: 2px; padding: 2px; border-radius: 8px; background: #F2F4F7">
|
||||
<button type="button" class="seg" aria-pressed="{{ smallPressed }}" onClick="{{ sizeSmall }}" style="min-height: 36px; padding: 0 12px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer">작게</button>
|
||||
<button type="button" class="seg" aria-pressed="{{ mediumPressed }}" onClick="{{ sizeMedium }}" style="min-height: 36px; padding: 0 12px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer">보통</button>
|
||||
<button type="button" class="seg" aria-pressed="{{ originalPressed }}" onClick="{{ sizeOriginal }}" style="min-height: 36px; padding: 0 12px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer">원본</button>
|
||||
</div>
|
||||
<button type="button" class="tb" style="min-height: 36px; padding: 0 10px; border: 0; border-radius: 6px; font: inherit; font-size: 12.5px; font-weight: 500; cursor: pointer">그림 빼기</button>
|
||||
<span style="font-size: 12px; color: #667085">그림을 고르면 나오는 줄입니다</span>
|
||||
</div>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #667085">굵게 · 기울임 · 밑줄 · 글자 색 · 링크 · 그림을 쓸 수 있습니다. 그림은 PNG · JPG · GIF, 한 장 300KB 이하, 3장까지이고 붙여 넣거나 끌어다 놓아도 됩니다. 메일 안에 함께 실어 보내므로 받는 쪽에서 외부 이미지처럼 막히지 않습니다.</p>
|
||||
</div>
|
||||
|
||||
<fieldset style="display: flex; flex-direction: column; gap: 0; margin: 0; padding: 0; border: 0">
|
||||
<legend style="margin: 0 0 4px; padding: 0; font-weight: 600; color: #171C26">서명을 넣을 메일</legend>
|
||||
<label style="display: flex; align-items: center; gap: 10px; min-height: 44px; cursor: pointer">
|
||||
<input type="checkbox" checked="{{ inNew }}" onChange="{{ toggleNew }}" style="width: 18px; height: 18px; margin: 0; accent-color: #0E7C86; cursor: pointer">
|
||||
<span>새 메일</span>
|
||||
</label>
|
||||
<label style="display: flex; align-items: center; gap: 10px; min-height: 44px; cursor: pointer">
|
||||
<input type="checkbox" checked="{{ inReply }}" onChange="{{ toggleReply }}" style="width: 18px; height: 18px; margin: 0; accent-color: #0E7C86; cursor: pointer">
|
||||
<span>답장 · 전달</span>
|
||||
<span style="color: #667085">— 인용한 원문 위에 넣습니다</span>
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 12px">
|
||||
<button type="button" onClick="{{ save }}" style="display: inline-flex; align-items: center; min-height: 44px; padding: 0 22px; border: 0; border-radius: 8px; background: #0E7C86; color: #FFFFFF; font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer">저장</button>
|
||||
<sc-if value="{{ saved }}" hint-placeholder-val="{{ false }}">
|
||||
<span role="status" style="display: inline-flex; align-items: center; gap: 6px; color: #067647; font-weight: 500">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"></polyline></svg>
|
||||
<span>저장했습니다. 새로 여는 쓰기 화면부터 들어갑니다.</span>
|
||||
</span>
|
||||
</sc-if>
|
||||
</div>
|
||||
|
||||
<hr style="width: 100%; height: 1px; margin: 0; border: 0; background: #EEF0F3">
|
||||
|
||||
<section aria-labelledby="sig-preview-title" style="display: flex; flex-direction: column; gap: 12px">
|
||||
<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px">
|
||||
<h2 id="sig-preview-title" style="margin: 0; font-size: 14px; font-weight: 700">미리 보기</h2>
|
||||
<div role="group" aria-label="미리 볼 메일" style="display: inline-flex; gap: 2px; padding: 2px; border-radius: 8px; background: #F2F4F7">
|
||||
<button type="button" class="seg" aria-pressed="{{ newPressed }}" onClick="{{ showNew }}" style="min-height: 36px; padding: 0 14px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer">새 메일</button>
|
||||
<button type="button" class="seg" aria-pressed="{{ replyPressed }}" onClick="{{ showReply }}" style="min-height: 36px; padding: 0 14px; border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer">답장</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="box-sizing: border-box; padding: 16px 20px 20px; border: 1px solid #E6E8EC; border-radius: 10px; background: #FFFFFF; font-family: 'Malgun Gothic', '맑은 고딕', 'Apple SD Gothic Neo', sans-serif; font-size: 14px; line-height: 1.75; color: #1F2733">
|
||||
<p style="margin: 0; color: #667085">(여기에 쓴 내용)</p>
|
||||
<p style="margin: 0"><br></p>
|
||||
<sc-if value="{{ showSignature }}" hint-placeholder-val="{{ true }}">
|
||||
<div>
|
||||
<p style="margin: 0"><strong>김아라</strong> · 인프라팀</p>
|
||||
<p style="margin: 0">ARA SYSTEM · [전화번호]</p>
|
||||
<p style="margin: 0"><a href="mailto:ara.kim@arasystem.it.kr">ara.kim@arasystem.it.kr</a></p>
|
||||
<p style="margin: 8px 0 0"><span role="img" aria-label="[회사 로고]" style="display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; width: {{ logoWidth }}px; height: {{ logoHeight }}px; border: 1px dashed #98A2B3; border-radius: 4px; color: #667085; font-family: Pretendard, -apple-system, 'Apple SD Gothic Neo', 'Malgun Gothic', system-ui, sans-serif; font-size: 12px">[회사 로고]</span></p>
|
||||
</div>
|
||||
</sc-if>
|
||||
<sc-if value="{{ isReplyPreview }}" hint-placeholder-val="{{ false }}">
|
||||
<blockquote style="margin: 24px 0 0; padding: 2px 0 2px 14px; border-left: 2px solid #D0D5DD; color: #4A5363">
|
||||
<div style="margin: 0 0 12px; font-size: 12.5px; line-height: 1.6">
|
||||
<p style="margin: 0; font-weight: 600">원본 메일</p>
|
||||
<table style="border-collapse: collapse; font-size: 12.5px; line-height: 1.6">
|
||||
<tbody>
|
||||
<tr><th scope="row" style="padding: 0 12px 0 0; text-align: left; vertical-align: top; font-weight: 400; color: #667085; white-space: nowrap">보낸 사람</th><td style="padding: 0">이도윤 <doyun.lee@arasystem.it.kr></td></tr>
|
||||
<tr><th scope="row" style="padding: 0 12px 0 0; text-align: left; vertical-align: top; font-weight: 400; color: #667085; white-space: nowrap">날짜</th><td style="padding: 0">2026. 10. 26. (월) 오전 10:42</td></tr>
|
||||
<tr><th scope="row" style="padding: 0 12px 0 0; text-align: left; vertical-align: top; font-weight: 400; color: #667085; white-space: nowrap">제목</th><td style="padding: 0">Re: 메일 서버 이전 일정 공유</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p style="margin: 0">김아라님, 안녕하세요.</p>
|
||||
<p style="margin: 0">말씀하신 대로 이번 주 금요일(10/30) 저녁 9시에 MX 레코드를 새 메일 서버로 전환하겠습니다.</p>
|
||||
</blockquote>
|
||||
</sc-if>
|
||||
</div>
|
||||
<p style="margin: 0; font-size: 12.5px; color: #667085">{{ previewNote }}</p>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-dc>
|
||||
<script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":900}}'>
|
||||
class Component extends DCLogic {
|
||||
state = { inNew: true, inReply: true, preview: 'new', saved: false, imageSize: 'medium' };
|
||||
|
||||
renderVals() {
|
||||
const s = this.state;
|
||||
// 그림 표시 크기 — 작게 · 보통 · 원본(올린 그림의 폭, 최대 600px). 시안은 로고 자리 상자로 보인다
|
||||
const LOGO_SIZES = { small: [96, 29], medium: [144, 43], original: [200, 60] };
|
||||
const [logoWidth, logoHeight] = LOGO_SIZES[s.imageSize] || LOGO_SIZES.medium;
|
||||
const isReply = s.preview === 'reply';
|
||||
const showSignature = isReply ? s.inReply : s.inNew;
|
||||
let previewNote = '새 메일은 본문 끝에 서명을 넣습니다.';
|
||||
if (isReply) previewNote = s.inReply ? '답장 · 전달은 인용한 원문 위에 서명을 넣습니다.' : '답장 · 전달에는 서명을 넣지 않습니다.';
|
||||
else if (!s.inNew) previewNote = '새 메일에는 서명을 넣지 않습니다.';
|
||||
const flag = (value) => (value ? 'true' : 'false');
|
||||
return {
|
||||
inNew: s.inNew,
|
||||
inReply: s.inReply,
|
||||
saved: s.saved,
|
||||
showSignature,
|
||||
isReplyPreview: isReply,
|
||||
newPressed: flag(!isReply),
|
||||
replyPressed: flag(isReply),
|
||||
previewNote,
|
||||
logoWidth,
|
||||
logoHeight,
|
||||
smallPressed: flag(s.imageSize === 'small'),
|
||||
mediumPressed: flag(s.imageSize === 'medium'),
|
||||
originalPressed: flag(s.imageSize === 'original'),
|
||||
sizeSmall: () => this.setState({ imageSize: 'small', saved: false }),
|
||||
sizeMedium: () => this.setState({ imageSize: 'medium', saved: false }),
|
||||
sizeOriginal: () => this.setState({ imageSize: 'original', saved: false }),
|
||||
toggleNew: () => this.setState({ inNew: !s.inNew, saved: false }),
|
||||
toggleReply: () => this.setState({ inReply: !s.inReply, saved: false }),
|
||||
showNew: () => this.setState({ preview: 'new' }),
|
||||
showReply: () => this.setState({ preview: 'reply' }),
|
||||
save: () => this.setState({ saved: true }),
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -11,11 +11,14 @@
|
||||
"States.dc.html": { "x": 0, "y": 1020, "w": 1440, "h": 1040, "title": "오류 · 빈 상태 · 피드백" },
|
||||
"MainList.dc.html": { "x": 1520, "y": 1020, "w": 1440, "h": 900, "title": "메일함 · 목록 보기", "expand": "fill", "is_interactive": true },
|
||||
"MainListRead.dc.html": { "x": 3040, "y": 1020, "w": 1440, "h": 900, "title": "목록 보기 · 메일 읽기", "expand": "fill", "is_interactive": true },
|
||||
"ComposeEditor.dc.html": { "x": 4560, "y": 0, "w": 1440, "h": 3576, "title": "메일 쓰기 · 편집기 상태" }
|
||||
"ComposeEditor.dc.html": { "x": 4560, "y": 0, "w": 1440, "h": 3576, "title": "메일 쓰기 · 편집기 상태" },
|
||||
"Settings.dc.html": { "x": 0, "y": 2480, "w": 1440, "h": 900, "title": "설정 · 메일 서명", "expand": "fill", "is_interactive": true },
|
||||
"ComposeAssist.dc.html": { "x": 1520, "y": 2480, "w": 1440, "h": 1400, "title": "메일 쓰기 · 임시 저장 · 자동 완성 · 서명" }
|
||||
},
|
||||
"order": ["Main.dc.html", "Login.dc.html", "Compose.dc.html", "States.dc.html", "MainList.dc.html", "MainListRead.dc.html", "ComposeEditor.dc.html"],
|
||||
"order": ["Main.dc.html", "Login.dc.html", "Compose.dc.html", "States.dc.html", "MainList.dc.html", "MainListRead.dc.html", "ComposeEditor.dc.html", "Settings.dc.html", "ComposeAssist.dc.html"],
|
||||
"notes": {
|
||||
"flow": { "x": 0, "y": -300, "text": "arasystem 웹메일 — 1단계 화면 (로그인 → 메일함 → 쓰기)", "kind": "title1", "maxW": 4480 }
|
||||
"flow": { "x": 0, "y": -300, "text": "arasystem 웹메일 — 1단계 화면 (로그인 → 메일함 → 쓰기)", "kind": "title1", "maxW": 4480 },
|
||||
"phase2": { "x": 0, "y": 2180, "text": "2단계 화면 — 임시 저장 · 받는 사람 자동 완성 · 서명 (2026-10-27 확정)", "kind": "title1", "maxW": 2960 }
|
||||
},
|
||||
"designSystems": []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user