Files
arasystem/docs/design/webmail
ttipo 1868665592 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>
2026-10-27 19:21:52 +09:00
..

웹메일 디자인 원본 (1·2단계)

확정된 디자인 캔버스의 원본이다. 화면 구현의 기준으로 쓴다.

  • 캔버스: https://claude.ai/artifact/WJvVsKvXepxn3p75CGJAr2 (확정본: 2026-10-27, 버전 19)
  • 화면: Login(로그인) · Main(분할 보기: 메일함·목록·본문) · MainList(목록 보기: 게시판형 표) · MainListRead(목록 보기에서 연 메일) · Compose(메일 쓰기 — 서식 편집기) · ComposeEditor(메일 쓰기 · 편집기 상태: 포커스·툴바·메뉴·팝오버·인용·이미지 첨부) · States(오류·빈 상태·피드백 모음) · 2단계: Settings(설정 · 메일 서명) · ComposeAssist(메일 쓰기 · 임시 저장 · 받는 사람 자동 완성 · 서명) — 아래 "2단계"
  • 파일 형식은 캔버스 전용(<x-dc> 마크업 + DCLogic 클래스)이다. 그대로 쓰지 말고 구조·간격·색·문구의 기준으로만 본다. Compose 의 툴바·메뉴는 눌러 볼 수 있는 시안이다 — 버튼 상태만 바뀌고 본문 글자에 서식이 입혀지지는 않는다.

캔버스 안의 자산 주소

캔버스는 자산을 /_blob/<id> 로 참조한다. 저장소에서는 아래 파일에 대응한다.

캔버스 주소 저장소 파일 용도
/_blob/16067b9aa5137abf808e3dbef30c42e0 Pretendard Variable (npm pretendard 패키지로 자체 호스팅) 전체 글꼴
/_blob/2b9ef4349333debc969432c859eaf1bf frontend/src/assets/brand/logo-ara-white.png 왼쪽 앱 레일 로고(가로 48px)
/_blob/3a2f4115a8f90207faa7d3a51cd9aec2 frontend/src/assets/brand/logo-arasystem-white.png 로그인 브랜드 패널 로고(가로 240px)

로고 원본은 docs/brand/logo_arasystem_white.png 다. 흰 로고라 어두운 브랜드 바탕(#0B3640) 위에만 둔다.

디자인 원칙 (사용자 확정)

  • 안 읽음 점·개수 알약·코드 태그 같은 뱃지를 쓰지 않는다 — 굵은 글자와 평범한 숫자로 구분한다.
  • 왼쪽 전역 앱 레일(메일·캘린더·파일·ERP·주소록·설정)에 모듈을 계속 붙인다. 지금은 메일만 동작한다.
  • 정보 밀도가 높은 데스크톱 화면 — 기본 13px. 목록에 본문 미리보기를 넣지 않는다.
    • 분할 보기 행: 2줄(보낸 사람·시간 / 제목+첨부 클립), 약 50px
    • 목록 보기 행: 1줄 표, 38px. 칸 = 별 32 · 보낸 사람 168 · 제목(나머지) · 날짜 84 · 크기 64 (px, 칸 사이 12). 폭 1100px 미만에서 크기 칸 숨김, 600px 미만에서 보낸 사람·날짜 축소, 더 좁으면 가로 스크롤. 캔버스는 파서 제약 때문에 grid 로 그렸지만 구현은 실제 <table> 로 한다.
  • 클릭 영역은 44px 이 기본이다. 아래만 밀도를 위한 의도된 예외다(사용자 확정).
    • 목록 표의 별 버튼(폭 32px) · "분할 | 목록" 전환(바깥 36px)
    • 메일 쓰기 편집기(2026-10-27): 툴바 아이콘 버튼 40×44(새로고침·이전/다음 버튼과 같은 크기) · 메뉴 항목 높이 40(메일함 항목과 같다) · 색 견본 칸 40×40 · 표 고르기 격자 칸 22(간격 3, 키보드는 화살표)
  • 보기 방식: 목록 머리의 "분할 | 목록" 전환. 선택은 사용자별로 기억한다.
  • 콘텐츠 열(읽기·쓰기 공통): 최대 폭 800px, 좌우 여백 32px, 위 20px·아래 36px, 본문 글줄 최대 680px, 영역 안 왼쪽 정렬. 분할 보기 읽기·목록 보기 읽기·쓰기 세 곳이 같은 값을 쓰고, 툴바 첫 아이콘도 같은 32px 선에서 시작한다.
  • 브랜드 컬러 "바다 청록": 바탕 #0B3640, 강조 #0E7C86. 파생 색은 각 화면 원본의 인라인 스타일을 따른다.

메일 쓰기 (2026-10-27 확정 — Compose · ComposeEditor)

위에서부터 머리(제목·닫기) → 받는 사람(→ 참조·숨은참조) → 제목 → 본문 툴바 → 본문 → 첨부 → 보내기 줄이다. 모두 콘텐츠 열 안에 있다. 첨부 안내문은 "파일당 최대 20MB · 합계 25MB · 최대 20개 · 문서, 이미지, 압축 파일" 이다(용량은 서버 값, 개수는 계약 상수).

글자 입력칸 포커스 — 한 가지 규칙

항목 값
대상 받는 사람 · 참조 · 숨은참조 · 제목 · 본문 편집기
위치 그 칸의 아래 hairline 자리. 본문은 편집 영역 아래(첨부 영역 위)
두께 · 색 2px --color-brand(#0E7C86). 1px 선의 색을 바꾸고 안쪽 그림자 1px 를 더한다 — 높이가 변하지 않는다
모서리 없음(곧은 선)
범위 행 전체 폭 — 원래 hairline 과 같은 길이(콘텐츠 열, 최대 800px). 이름표 아래까지 이어진다
언제 글자 입력 요소(input·편집 영역)에 포커스가 있을 때. 마우스로 눌러도 보인다(:focus)
대비 흰 바탕 4.9:1 · 원래 선 #EEF0F3 4.3:1 · 오류 띠 #FEF3F2 4.5:1 (모두 3:1 이상)
  • 버튼 고리와의 관계: 같은 색·같은 2px 이고 모양만 다르다. 누르는 것(버튼·링크)은 전역 :focus-visible 고리(바깥 2px, 버튼 모서리를 따른다), 쓰는 곳은 선이다. 행 안의 버튼(받는 사람 토큰 ✕ · "참조 · 숨은참조")에 포커스가 가면 고리만 보이고 행의 선은 회색 그대로다 — 한 번에 하나만 보인다.

  • 테두리가 있는 입력칸(링크 팝오버·로그인)은 상자가 있으므로 버튼처럼 고리를 쓴다.

  • 구현(tokens.css 변수):

    .compose-field:has(:is(input, .ProseMirror):focus) {
      border-bottom-color: var(--color-brand);
      box-shadow: inset 0 calc(var(--border-width) * -1) 0 var(--color-brand);
    }
    .compose-field :is(input, .ProseMirror):focus-visible { outline: none; }
    

    .compose-field 는 받는 사람·참조·숨은참조 행, 제목 행, 본문 편집 영역에 붙인다. 편집 영역이 아래 hairline 을 가지므로 첨부 영역의 위 선은 없앤다.

본문 서식 편집기 (TipTap)

  • 툴바: 한 줄 · 높이 52(위아래 4) · 왼쪽 여백 20 + 버튼 안 12 → 첫 아이콘이 32px 선. 버튼 사이 2, 묶음 사이 세로선 1×20 #E6E8EC(좌우 4).

    • 아이콘 버튼 40×44 · 모서리 8 · 아이콘 16(선 1.75) · #344054. 글꼴 108×44 · 글자 크기 56×44(글자 + ▾).
    • 상태: 올림 #F2F4F7 · 켜짐(aria-pressed) #E3F2F3 + 안쪽 1px #0E7C86 + 아이콘 #0A5F67(옅은 바탕만으로는 3:1 이 안 돼 선을 둔다) · 비활성 50% · 포커스는 전역 고리 · 메뉴 열림(aria-expanded)은 올림과 같은 바탕.
    • role="toolbar" — Tab 한 번에 들어가 화살표로 옮긴다. 본문에서 Alt+F10 → 툴바, Esc → 본문.
  • 툴바 기능(800px): 실행 취소 · 다시 실행 | 글꼴 ▾ · 글자 크기 ▾ | 굵게 · 기울임 · 밑줄 | 글자 색 · 배경 색 | 글머리 목록 · 번호 목록 | 링크 | 더보기

  • 더보기(늘): 취소선 | 왼쪽 · 가운데 · 오른쪽 정렬 | 내어쓰기 · 들여쓰기 | 인용 · 표 넣기 › · 가로줄 | 서식 지우기

    • 항목 높이 40 · 아이콘 16 · 이름 · 단축키(12px #667085) · 켜진 것은 오른쪽 ✓. 값을 고르는 것(글꼴·크기·색·표)은 › 로 한 단계 더 연다.
    • 단축키: 굵게 Ctrl+B · 기울임 Ctrl+I · 밑줄 Ctrl+U · 취소선 Ctrl+Shift+S · 글머리 Ctrl+Shift+8 · 번호 Ctrl+Shift+7 · 정렬 Ctrl+Shift+L/E/R · 내어쓰기 Ctrl+[ · 들여쓰기 Ctrl+] · 인용 Ctrl+Shift+B · 링크 Ctrl+K · 서식 지우기 Ctrl+\ · 실행 취소 Ctrl+Z · 다시 실행 Ctrl+Y
    • 맥은 Ctrl 대신 ⌘ 이고 표기도 기호로 보인다(⌘B · ⇧⌘S). 다시 실행은 맥 관례대로 ⇧⌘Z 로 적는다(⌘Y 도 된다). 내어쓰기 · 들여쓰기 · 서식 지우기는 할 일이 없어도 키를 삼킨다 — 맥의 ⌘[ 가 브라우저 "뒤로"가 되어 쓰던 메일을 잃지 않게 (2026-10-27 구현하며 정함).
  • 좁은 폭: 툴바는 줄을 바꾸지 않는다. 묶음째 아래 순서로 더보기에 옮기고, 숨은 묶음은 더보기 맨 위에 툴바 순서대로 들어간다. 더보기 단추에 숫자를 달지 않는다.

    1. 실행 취소 · 다시 실행 — 쓰기 칸 734px 미만 (Ctrl+Z · Ctrl+Y 는 그대로)
    2. 글꼴 · 글자 크기 — 639px 미만
    3. 글자 색 · 배경 색 — 460px 미만
    4. 링크 — 365px 미만 (주소를 붙여 넣으면 저절로 링크가 된다)
    5. 글머리 · 번호 목록 — 312px 미만

    굵게 · 기울임 · 밑줄과 더보기는 늘 남는다. 폭은 지금 크기로 셈한 참고값이다 — 구현은 툴바의 실제 폭을 재어(ResizeObserver) 이 순서로 넘긴다. Compose 보드의 좁은 폭 메뉴는 색 · 목록을 취소선 뒤에 그렸지만, 이 문서의 순서(숨은 묶음 전부를 맨 위에)가 기준이다 — 구현도 이 순서다. 휴대폰에서는 더보기 메뉴가 화면 높이에 맞춰 안에서 스크롤된다.

  • 글꼴: 맑은 고딕(기본) · 굴림 · 돋움 · 바탕 | Arial · Verdana · Georgia · Times New Roman · Courier New. 목록의 이름은 그 글꼴로 보인다.

    • 본문 기본 글꼴은 맑은 고딕 스택 'Malgun Gothic', '맑은 고딕', 'Apple SD Gothic Neo', sans-serif 다 — 편집기 안 모양을 받는 사람이 보는 모양과 같게 한다. 화면 UI 는 Pretendard 그대로다. 맥에서는 Apple SD 산돌고딕 Neo 로 보인다.
    • "맑은 고딕(기본)"을 고르면 글꼴 지정을 지운다.
  • 글자 크기(px): 12 · 13 · 14(기본) · 16 · 18 · 20 · 24 · 32. 제목 스타일(제목 1·2·3)은 두지 않는다. 고른 글자의 크기가 섞이면 "–".

  • 색 팔레트(8색씩 · 견본 칸 40×40, 보이는 색 26 · 고른 색에 ✓ · 고른 색 이름을 글자로도 보인다):

    • 글자 색: 기본 #1F2733 · 회색 #667085 · 빨강 #B42318 · 주황 #B54708 · 초록 #067647 · 청록 #0E7C86 · 파랑 #175CD3 · 보라 #6941C6 — 모두 흰 바탕 4.5:1 이상. "기본"은 글자 색을 지운다.
    • 배경 색: 없음 · 노랑 #FFF1A8 · 주황 #FDE4CC · 분홍 #FBDCE3 · 초록 #D9F2DF · 하늘 #D6E8FB · 보라 #E9E0FA · 회색 #E9EBEF — 본문 글자(#1F2733)가 10:1 이상 남는다. "없음"은 배경 색을 지운다.
  • 붙여 넣은 글 · 원문 인용의 서식: 보낼 수 있는 형식(계약 2절 "서식 본문")만 받고 나머지는 버린다 — 색 이름(red) · Calibri 같은 서식은 기본 모양으로 보인다. 편집기에 보이는 모양이 곧 받는 사람이 보는 모양이다 (2026-10-27 구현하며 정함). 보이지 않을 만큼 작은 글자(8px 미만)와 거의 투명한 글자 색(알파 0.3 미만)도 그 서식을 버린다 — 그렇게 숨긴 글은 드러난다. 바탕과 같은 색(흰 바탕 위 흰 글자 등)은 바탕을 알 수 없어 막지 않는다 (2026-10-27 사용자 확정).

  • 링크 팝오버(폭 300): 주소 · 표시할 글자(비우면 주소). 새 링크는 [취소] [넣기], 이미 있는 링크는 [링크 빼기] … [취소] [적용]. Enter = 적용, Esc = 닫고 본문으로. 주소는 http(s) · mailto 만 받는다.

  • 표 넣기(더보기 ›): 8열 × 6행 격자에서 고른다("3행 × 4열"). 표 안의 행·열 추가·삭제는 다음 단계.

  • 메뉴·팝오버 공통: 흰 바탕 · 테두리 #E6E8EC · 모서리 10 · 그림자 --shadow-toast · 툴바 아래 선 바로 밑에서 연다. Esc 로 닫는다.

  • 빈 본문: 안내 문구 "내용을 입력하세요" · #667085(4.9:1). 커서는 문구 앞에 선다.

  • 문단: 문단 사이 여백은 0 — Enter 한 번이 한 줄이다(지금 textarea 와 같다). 줄 간격은 1.75 이고, 보내는 본문도 같은 값이다 (감싸는 div 의 line-height — 받는 사람이 편집기와 같은 모양으로 본다, 2026-10-27 구현하며 정함). 여러 칸 띄어쓰기 · 줄 앞 공백도 받는 쪽에서 그대로 보이게 보낸다. 탭은 다음 8칸 자리까지의 공백이 된다(편집 영역의 탭 간격과 같다, 2026-10-27).

답장 · 전달의 원문 인용

  • 원문은 인용 막대(왼쪽 2px #D0D5DD · 막대와 글 사이 14) 안에 둔다. 원문 글은 #4A5363, 내 글과 24 띄운다.
  • 머리는 답장 · 전달 모두 "원본 메일"(12.5px 굵게)이고, 그 아래에 항목 이름(#667085) · 값 표를 둔다.
    • 답장: 보낸 사람 · 날짜 · 제목 — 커서는 맨 위 첫 줄
    • 전달: 보낸 사람 · 날짜 · 받는 사람 · 참조 · 제목 — 커서는 받는 사람 칸
  • 막대는 회색이다 — 2px 브랜드색 선은 포커스 표시라 겹치지 않게 한다. 툴바의 "인용"도 같은 막대를 머리 없이 쓴다.
  • 초안이 한도(제목 255자 · 본문 텍스트 100,000자 · 서식 본문 500,000자 — 계약 2절)를 넘으면 인용을 줄이고 인용 끝에 "(원문이 길어 이하 생략)"을 둔다(2026-10-26 구현하며 정함 — 캔버스에는 그리지 않았다).
    • 처음 맞출 때 내 글 몫으로 한도의 5%를 남긴다. 보내기 직전에 다시 재서 넘으면 인용을 더 줄이고, 편집기에도 줄인 모양을 보인다(실행 취소로 되돌릴 수 있다).
    • 내 글만으로 넘으면 보내지 않는다 — 본문 아래(첨부 위)에 받는 사람 오류와 같은 빨간 띠로 알리고 본문에 초점을 준다. 제목이 255자를 넘으면 제목 아래에 같은 띠를 둔다 (2026-10-27 구현하며 정함).
    • 본문 띠의 문구는 전용 코드 MAIL_007("본문이 너무 길어 보낼 수 없습니다. 내용을 줄인 뒤 다시 보내 주세요.")다 — 서버가 같은 코드를 돌려줘도 같은 띠를 보인다. 제목 띠는 VAL_001 그대로다 (제목 칸은 255자에서 더 입력되지 않는다, 2026-10-27 사용자 확정).
  • 원문이 서버의 읽기 한도에서 잘렸으면(isBodyTruncated) 클라이언트가 줄이지 않았어도 인용 끝에 같은 생략 표시를 둔다.
  • 인용할 원문은 읽기 화면과 같은 규칙으로 고른다 — HTML 이 없거나 공백뿐이면 글자 본문(textBody)이다. 인용은 그림을 빼므로, 그림을 빼고 남는 글자가 없으면(그림만 있는 뉴스레터 — 그림을 감싼 레이아웃 표 포함) 그때도 글자 본문으로 인용한다 (2026-10-27 리뷰 반영).
  • 내가 보낸 메일에 답장하면 받는 사람은 그 메일의 받는 사람이다 — 답장은 원래 받는 사람, 전체 답장은 원래 받는 사람과 참조(둘 다 나는 뺀다). 나에게만 보낸 메일이면 나에게 답장한다 (2026-10-27 사용자 확정 — 전에는 받는 사람 칸이 비었다). 이때 회신 주소(Reply-To)는 보지 않는다. 받는 사람 없이 참조만 있던 메일이면 답장은 나에게, 전체 답장은 나에게 + 원래 참조로 간다.

나가기 전 확인 (2026-10-27 사용자 확정 — 캔버스에는 아직 없다)

  • 쓰기 화면을 연 뒤 받는 사람 · 제목 · 본문 · 첨부를 바꿨으면, 화면을 떠나기 전에 묻는다 — 답장 · 전달로 처음 채운 내용은 "바꿈"이 아니다.
    • 앱 안 이동(앱 레일 · 메일함 · 뒤로/앞으로 · 쓰기 화면의 취소 · 닫기 ✕)은 확인 대화상자를 띄운다 — 세션 만료 대화상자와 같은 모양이다. 제목 "보내지 않은 메일이 있습니다", 글 "이 화면을 나가면 쓰던 내용이 사라집니다.", 단추 [계속 쓰기](처음 초점 · Esc 와 같다) [나가기]. 단추는 오른쪽 정렬이고, 계속 쓰기는 채운 기본 단추 · 나가기는 "취소"와 같은 보조 단추다. 계속 쓰기를 고르면 주소와 방문 기록이 그대로다.
    • "바꿈"에는 아직 주소 칩이 되지 않은 받는 사람 입력 글자, 첨부 목록의 모든 변화(사전 검사에 걸린 파일 포함)도 든다. 지운 · 실행 취소로 처음 모양에 돌아오면 바꾸지 않은 것으로 본다. 방문 기록(뒤로 · 앞으로)으로 쓰기 화면끼리 옮겨 갈 때도 묻는다 (쓰기 화면에서는 메일함 패널의 "메일 쓰기"가 "메일 쓰는 중"으로 바뀌어 눌리지 않는다).
    • 대화상자가 떠 있는 동안 세션이 끝나면 대화상자를 닫고 그 이동을 취소한다(세션 만료 대화상자가 그 뒤에 뜬다).
    • 알려진 한계(vue-router): 뒤로 가기로 연 확인 창이 떠 있는 동안 주소창에는 가려던 주소가 보인다(계속 쓰기를 고르면 돌아온다). 그 사이 뒤로 가기를 두 번 누르면 방문 기록이 한 칸 어긋날 수 있다.
    • 탭 닫기 · 새로고침 · 다른 사이트로 가기는 브라우저 기본 확인창을 띄운다(문구는 브라우저가 정한다).
  • 보낸 뒤와 세션이 끝났을 때(로그아웃 · 만료 · 다른 탭의 로그아웃)는 묻지 않는다 — 세션 만료 대화상자와 겹치지 않는다.
  • 보내는 중에도 묻지 않는다 — 이미 보내기를 눌렀기 때문이다(Gmail 과 같다). 보내는 중에 화면을 떠나면 결과는 알림으로만 알린다: 성공은 평소의 성공 알림, 실패는 그 오류의 사전 문구 알림이다(받는 사람 · 첨부 · 본문 길이 오류처럼 평소 칸 아래에 보이던 것도). 떠난 화면이나 새로 연 쓰기 화면은 그 결과로 바뀌지 않는다 (2026-10-27 리뷰 반영). 단 보내는 중에 탭을 닫거나 새로고침하면 브라우저 기본 확인창은 뜬다 — 요청이 끊길 수 있고 결과를 알릴 화면이 남지 않기 때문이다.
  • 맥의 ⌘[ 를 본문 밖에서 눌러 브라우저 "뒤로"가 되어도 이 확인에 걸린다.
  • 2단계(임시 저장)부터는 저장된 채로는 묻지 않는다 — 저장하지 못한 내용이 있을 때만 이 확인을 띄우고 제목 · 글이 바뀐다 (아래 "2단계 › 임시 저장"). 단추 · 키 · 묻지 않는 경우는 그대로다.

본문 이미지 → 첨부 파일

  • 본문에는 이미지를 넣지 않는다(사용자 확정). 툴바에 이미지 버튼이 없다. 서명 그림만 예외다 (아래 "2단계 › 서명").
  • 본문에 붙여 넣거나(Ctrl+V) 끌어다 놓은 이미지는 첨부 파일로 올린다. 끌어다 놓은 다른 파일도 첨부로 올린다(쓰기 화면 어디에 놓아도 같다). 한도는 첨부와 같다 — 넘치면 첨부 목록에 실패로 보인다(States 의 "첨부 업로드").
    • 클립보드에 글이 함께 있으면 글을 붙여 넣는다 — 워드 · 엑셀에서 복사하면 고른 부분의 그림이 글과 함께 따라오기 때문이다. 글 없이 파일만 있을 때 첨부로 돌린다 (2026-10-27 구현하며 정함 — 캔버스 시안은 그림이 있으면 늘 첨부로 돌린다).
    • 이름 없이 붙여 넣은 그림은 "붙여넣은 이미지 N.확장자"로 올린다. 원래 이름이 있는 파일은 그 이름 그대로다.
  • 끌어다 놓는 동안 본문 위에 점선 덮개(2px #0E7C86 점선 · 바탕 #F3F8F8)와 "놓으면 첨부 파일로 올립니다"를 보인다. 쓰기 화면이 떠 있으면 파일은 창 어디(앱 레일 위 포함)에 놓아도 첨부로 받고, 덮개도 파일이 창 위에 있는 동안 보인다 — 받지 않는 곳에 놓으면 브라우저가 그 파일을 열어 쓰던 메일을 잃기 때문이다 (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 — 캔버스에는 아직 없다)

  • 찾지 못한 첨부(보관 시간이 지난 업로드·지워진 원본)는 실패로 표시하고, 전달 원본에는 "빼기"만 둔다(다시 올릴 수 없다).
  • 없는 메일함·메일(주소창에 남은 옛 id 등)에는 "다시 시도" 대신 "받은편지함으로"·"목록으로"를 둔다. "다시 시도"는 메일 서버 장애처럼 다시 해 보면 나아질 수 있는 오류에만 쓴다.
  • 읽기 화면의 본문 안내(2026-10-27 사용자 확정) — "외부 이미지를 차단했습니다"와 같은 모양(아이콘 alert-circle)의 안내 줄을 본문 위에 둔다. 순서는 생략 → 잘림 → 외부 이미지 차단이다. "표시할 수 없음"을 보일 때는 잘림 안내를 숨기고, 공백뿐인 글자 본문은 없는 것으로 본다:
    • 서버가 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). 화살표는 끝에서 처음으로 돌고, 마우스를 올린 줄이 골라진다. 초성 · 자모만 친 글자는 서버에 묻지 않는다(받아 둔 목록에서만 거른다).