Groo Design

Snackbar

화면 아래에 잠깐 떴다 사라지는 띠(토스트) — 방금 한 일의 결과("거래를 저장했어요."), 뒤에서 끝난 일, 다시 하면 되는 가벼운 실패를 알린다. 조치해야 끝나는 오류 · 계속 보여야 할 경고 · 결정은 여기 두지 않는다 — 그 자리의 Callout · 페이지의 Page Banner · Result Section · Alert Dialog 다.

구조는 당근 SEED Snackbar(Apache-2.0)를 따른다 — 짙은 띠 · 아이콘(성공 · 실패에만) · 글 · 액션 하나, 화면 아래 가운데에 한 번에 하나. 값은 groo 토큰이고, SEED 와 다른 자리는 맨 아래 "SEED 와 다른 점" 에 적었다(2026-10-02 사용자 결정). 옛 Sonner(토스트) 스펙을 대신한다.

수치 원본은 snackbar.yaml이다. 수치 표 자리([표: …])와 그림 자리([그림: …])는 사이트가 그 파일로 그린다 — GitHub 에서는 그 파일 · 그림 코드로 가는 링크로 보인다.

9:41
가계부
10월 2일 (금)−19,050원
점점심 식사식비, 현대카드 M−12,000원
스스타벅스카페, 현대카드 M−5,600원
지지하철교통, 국민 체크카드−1,450원
월월급수입, 토스뱅크 통장+3,200,000원
거래를 삭제했어요.되돌리기
라이트
거래를 저장했어요.
거래를 삭제했어요.되돌리기
관심 종목에 넣지 못했어요. 다시 시도해주세요.다시 시도
9:41
가계부
10월 2일 (금)−19,050원
점점심 식사식비, 현대카드 M−12,000원
스스타벅스카페, 현대카드 M−5,600원
지지하철교통, 국민 체크카드−1,450원
월월급수입, 토스뱅크 통장+3,200,000원
거래를 삭제했어요.되돌리기
다크
거래를 저장했어요.
거래를 삭제했어요.되돌리기
관심 종목에 넣지 못했어요. 다시 시도해주세요.다시 시도
거래 저장 · 삭제 되돌리기 · 관심 종목 실패 — 라이트 · 다크

직접 골라 보기

톤 · 액션 · 글 길이를 고르고 띄우면 스펙대로 그린 띠가 아래에서 뜨고, 시간이 지나면 사라진다. 마우스를 올리거나 키보드로 옮기면 멈춘다.

가계부
  • 점심 식사식비 · 생활비 카드−12,000원
  • 골목커피카페 · 생활비 카드−5,600원
  • 지하철교통 · 교통 체크카드−1,450원
띠 없음 — 띄우기를 누른다
톤 tone
액션 action
글
시간액션이 없으면 4초, 있으면 6초. 띄우기를 다시 누르면 지금 띠를 바로 바꾼다 — 액션이 달린 띠는 끝날 때까지 지키고 새 띠는 그 뒤에 뜬다.
모드
브랜드
import { useSnackbar } from "@/components/ui/snackbar"

const snackbar = useSnackbar()

snackbar.show({
  message: "거래를 삭제했어요.",
  action: { label: "되돌리기", onClick: undo },
})

Anatomy

미리 낸 돈 중 32,000원이 계좌로 돌아왔어요.잔액 고치기
탭 바 · 플로팅 버튼 · 바닥 버튼
ⓐ Regionⓑ Containerⓒ Iconⓓ Messageⓔ Action
1.5배로 그렸다 — 두 줄이면 아이콘 · 액션은 띠 가운데에 선다. 보조 기술용 닫기는 키보드 초점이 올 때만 보인다
띠는 아이콘 · 글 · 액션으로, 화면 아래 자리에 하나
부위설명
ⓐ Region자리 — 화면 아래 가운데. 탭 바 · 플로팅 버튼 · 바닥 버튼 위 8.
ⓑ Container띠 — 짙은 바탕(다크는 밝은 띠) · 최대 464.
ⓒ Icon아이콘 — 성공(체크) · 실패(느낌표)에만.
ⓓ Message글 — 무엇이 됐는지 먼저. 줄이지 않는다.
ⓔ Action액션 — 하나, 동작 이름("되돌리기"). 누르면 닫힌다.

부위

부위설명
region자리 — 화면 아래 가운데. 탭 바 · 플로팅 버튼 · 바닥 버튼을 피해 그 위에 선다
root띠 — 짙은 바탕(다크는 밝은 띠), 한 번에 하나
icon아이콘 — 성공 · 실패에만
content글과 액션 — 양 끝에 놓는다
message글 — 무엇이 됐는지 먼저, 줄이지 않는다
action액션 — 하나, 동작 이름(되돌리기 · 잔액 고치기)
closeButton보조 기술용 닫기 — 보이지 않고, 키보드 초점이 오면 띠 오른쪽 끝에 보인다
focusRing키보드 포커스 링(웹)

Properties

띠

최소 44 · 여백 10 + 글 좌우 6(글은 띠 가장자리에서 16) · 모서리 8 · 그림자 없음. 글 14 / 19, 아이콘 24, 액션 14 · 700. 폭은 화면에서 좌우 8 을 뺀 만큼이고 최대 464 — 넓은 화면에서는 가운데에 선다. 글이 길면 줄을 바꾸고 자르지 않는다 — 두 줄 안에서 끝나게 쓴다.

거래를 삭제했어요.되돌리기
아이콘 없음 · 액션 — 분홍 칸은 누르는 영역(글 + 좌우 8 × 44) — 글은 띠 가장자리에서 16
관심 종목에 넣었어요.
아이콘 24 — 글은 띠 가장자리에서 40
미리 낸 돈 중 32,000원이 계좌로 돌아왔어요. 잔액이 맞는지 확인해 주세요.잔액 고치기
실제 크기(폰 360 · 띠 328) — 글이 길면 줄을 바꾸고 자르지 않는다. 아이콘 · 액션은 띠 가운데
상태 — 실제 크기
거래를 삭제했어요.되돌리기
띠 포커스 — 안쪽 4
거래를 삭제했어요.되돌리기
액션 포커스 — 바깥 2 · 모서리 4
거래를 삭제했어요.되돌리기
닫기 포커스 — 키보드 초점이 오면 X 16 · 상자 44(위 · 아래 · 오른쪽 -10), 안쪽 4 · 모서리 8
거래를 삭제했어요.되돌리기
액션 누름 — 글만 2px 거리 축소
  • 최소 44 · 여백 10 + 글 좌우 6 · 모서리 8 · 그림자 없음
  • 글 14 / 19 · 400 · 액션 14 · 700 · 글과 액션은 양 끝(사이 적어도 10)
  • 폭은 자리 폭(화면 − 좌우 8 × 2), 최대 464
띠의 여백 · 글 · 아이콘 · 액션

공통

부위속성값비고
region좌우 여백spacing-x2 8px화면 끝과 8 — 안전 영역이 있으면 그만큼 더
region아래 여백spacing-x2 8px아래 8 + 안전 영역 — 탭 바 · 플로팅 버튼 · 바닥 버튼이 있으면 그 위 8(안전 영역과 둘 중 큰 쪽 — 탭 바는 안전 영역을 품고 있다). 화면 키보드가 올라와 있으면 키보드 바로 위 8 — 웹 폰 브라우저도 보이는 화면의 아래 끝을 잰다(2026-10-15 사용자 결정 — 구현 세션 질문 Q-003-1)
regionkeyboardGapspacing-x2 8px화면 키보드 위 끝 ↔ 띠 아래 끝 — 키보드도 피할 자리 하나다(안전 영역 · 탭 바 · 바닥 버튼과 넷 중 가장 위)
regionoffsetDurationmotion-duration-d4 200ms피할 자리(탭 바 · 바닥 버튼 · 키보드)가 바뀌어 띠가 옮겨 갈 때 — 모션 줄이기면 바로(SEED snackbar.region.offsetDuration)
regionoffsetEasingmotion-ease-easing cubic-bezier(0.35, 0, 0.35, 1)SEED snackbar.region.offsetTimingFunction
regionz-index400z-snackbar — specs/z-index.md L6. 시트 · 대화상자 · 확인창 위
root너비100%자리 폭 — 최대 464, 넓으면 가운데
root최대 너비464px
root최소 높이44px
root여백spacing-x2_5 10px
root모서리radius-r2 8px
root배경color-bg-neutral-inverted #1A1F2E · 다크 #F5F6FA다크에서는 밝은 띠
root그림자none그림자 없이 면 색으로 뜬다(SEED · Elevation)
root보이는 시간4000ms액션이 있으면 6000ms. 마우스 · 손가락 · 키보드 초점이 머무는 동안 멈추고, 떠나면 처음부터 다시 센다
icon아이콘24pxlucide 선 아이콘 — 체크(circle-check) · 느낌표(circle-alert). 오른쪽 여백 2 를 이 칸 안에 둬 그림은 22 다(SEED 와 같다 — 글은 띠 가장자리에서 40)
icon오른쪽 여백spacing-x0_5 2px칸 안쪽 — 칸을 넓히지 않는다
content좌우 여백spacing-x1_5 6px글은 띠 가장자리에서 16(아이콘이 있으면 40)
content간격spacing-x2_5 10px글과 액션은 양 끝 — 사이는 적어도 10
message글자text-t4 14px / 19px단어 단위 줄바꿈(v114) — 줄 수를 자르지 않는다(2026-09-22). 두 줄 안에서 끝나게 쓴다
message굵기400
message글자·아이콘color-fg-neutral-inverted #FFFFFF · 다크 #242938
action글자text-t4 14px / 19px
action굵기700
action글자·아이콘color-fg-brand-inverted HR #2ABE84 · Desk #7AA9F6반전 짝(v115) — 짙은 띠 위 Desk 6.90 · HR 6.88, 다크의 밝은 띠 위 7.76 · 7.56
action터치 영역글 + 좌우 8 × 44띠 높이 안에서 위아래로 넓힌다
action모서리radius-r1 4px바탕이 없어 초점 링에만 보인다
closeButton크기44px평소에는 보이지 않는다(보조 기술은 읽는다) — 키보드 초점이 오면 띠 오른쪽 끝에 X 16 으로 보인다
closeButton아이콘 크기16px
closeButton색color-fg-neutral-inverted #FFFFFF · 다크 #242938
closeButton모서리radius-r2 8px바탕이 없어 초점 링에만 보인다
closeButton바깥 여백위 · 아래 · 오른쪽 −10띠 여백(10) 안으로 들어와 띠 높이를 44 로 둔다

Tone

neutral(기본)은 아이콘이 없다. 성공을 눈에 띄게 알릴 때만 positive(체크), 가볍게 실패했을 때 critical(느낌표) — 아이콘 색만 바뀐다. 짙은 띠 위에서 보이게 아이콘 · 액션은 반전 짝 색(fg-*-inverted)이다.

거래를 저장했어요.
neutral(기본) — 아이콘 없음
관심 종목에 넣었어요.
positive — fg-positive-inverted #25C062
계좌번호를 복사하지 못했어요.
critical — fg-critical-inverted #FF8477
거래를 삭제했어요.되돌리기
Desk 액션 — fg-brand-inverted #7AA9F6
휴가 신청을 취소했어요.되돌리기
HR 액션 — fg-brand-inverted #2ABE84
라이트 — 짙은 띠bg-neutral-inverted #1A1F2E
거래를 저장했어요.
neutral(기본) — 아이콘 없음
관심 종목에 넣었어요.
positive — fg-positive-inverted #167F3F
계좌번호를 복사하지 못했어요.
critical — fg-critical-inverted #D72323
거래를 삭제했어요.되돌리기
Desk 액션 — fg-brand-inverted #0147AD
휴가 신청을 취소했어요.되돌리기
HR 액션 — fg-brand-inverted #075B3C
다크 — 밝은 띠bg-neutral-inverted #F5F6FA
톤 셋 — 아이콘 없음 · 체크 · 느낌표

톤

toneicon 색설명
neutral (기본)—결과 · 안내 — 아이콘 없음
positivecolor-fg-positive-inverted #25C062 · 다크 #167F3F — 반전 짝(v115) — 짙은 띠 위 6.87, 다크의 밝은 띠 위 4.70성공을 눈에 띄게 알릴 때 — 체크 아이콘
criticalcolor-fg-critical-inverted #FF8477 · 다크 #D72323 — 반전 짝(v115) — 짙은 띠 위 6.89, 다크의 밝은 띠 위 4.68가볍게 실패했을 때(다시 하면 되는 일) — 느낌표 아이콘

State

상태모습
enabled보임
pressed액션 — 글만 2px 거리 축소
focused웹 — 키보드 포커스에만 띠 글자색 링. 띠 · 닫기는 안쪽 4, 액션은 바깥 2 — 어느 링이든 띠 위에 그린다(페이지 위로 나가면 보이지 않는다)

상태

상태action 글자·아이콘action 배율action 축소 시간action 축소 곡선링 두께링 간격링 색액션 링 간격
enabled 보임color-fg-brand-inverted HR #2ABE84 · Desk #7AA9F6 — 반전 짝(v115) — 짙은 띠 위 Desk 6.90 · HR 6.88, 다크의 밝은 띠 위 7.76 · 7.56———————
pressed 액션 누름 — 2px 거리 축소color-fg-brand-inverted HR #2ABE84 · Desk #7AA9F6 — 반전 짝(v115) — 짙은 띠 위 Desk 6.90 · HR 6.88, 다크의 밝은 띠 위 7.76 · 7.562px 거리 축소 — 글만 준다 — 모션 줄이기면 하지 않는다motion-duration-pressed-scale 150msmotion-ease-pressed-scale cubic-bezier(0, 0, 0.15, 1)————
focused 웹 — 키보드 포커스에만 링(띠 · 액션 · 닫기)color-fg-brand-inverted HR #2ABE84 · Desk #7AA9F6 — 반전 짝(v115) — 짙은 띠 위 Desk 6.90 · HR 6.88, 다크의 밝은 띠 위 7.76 · 7.56———2px-4px — 띠 · 닫기 — 안쪽 4. 링이 띠 글자색이라 바깥(페이지 위)에 그리면 보이지 않는다color-fg-neutral-inverted #FFFFFF · 다크 #242938 — 띠 글자색 — 브랜드 링은 짙은 띠 위에서 Desk 1.96 이라 3:1 에 못 미친다2px — 액션 — 바깥 2. 띠 여백 안이라 띠 위에 그려진다

모션

전환시간곡선대상비고
나타남motion-duration-d3 150msmotion-ease-enter cubic-bezier(0, 0, 0.15, 1)scale 0.8 → 1, opacity 0 → 1가운데를 기준점으로 — 모션 줄이기면 투명도만(v104)
사라짐motion-duration-d2 100msmotion-ease-exit cubic-bezier(0.35, 0, 1, 1)scale → 0.8, opacity → 0
새 것으로 바꿈motion-duration-d2 100msmotion-ease-exit cubic-bezier(0.35, 0, 1, 1)지금 것 사라짐 → 새 것 나타남한 번에 하나 — 새 것이 오면 지금 것을 바로 바꾼다. 지금 것에 액션이 있으면 끝날 때까지 지키고 새 것은 그 뒤에(기다리는 것은 하나 — 2026-10-22 1B)

Guidelines

무엇으로 알리나 — 상황 → 고를 것

알리는 부품 다섯(Snackbar · Callout · Page Banner · Result Section · Alert Dialog)을 고르는 표는 여기 한 벌이다 — Callout · Page Banner · Help Bubble · Alert Dialog 문서는 자기 줄만 두고 이 표로 링크한다(2026-10-22 사용자 결정 3B — https://claude.ai/artifact/NuEPiLRH2fJidXdKzcDsCX). 나누는 법(일로 나눈다)은 2026-10-02 결정 그대로다.

먼저 묻는다 — 사용자가 지금 답해야 하나? 그렇다면 Alert Dialog. 아니면 얼마나 오래 보여야 하나(잠깐 · 조치할 때까지 · 상태가 풀릴 때까지)와 무엇에 걸린 일인가(방금 한 일 · 그 기능 · 페이지 전체 · 그 영역)로 고른다.

이런 일쓰는 것
방금 한 일의 결과(저장 · 삭제 · 복사 · 옮김)Snackbar — 되돌릴 수 있으면 "되돌리기"
뒤에서 끝난 일(내보내기 · 동기화)Snackbar
다시 하면 되는 가벼운 실패(관심 종목에 넣지 못함)Snackbar critical + "다시 시도"(켜고 끄는 단추의 실패는 되돌린 뒤 이 띠 — Toggle 20A)
시트 · 대화상자가 열린 채 결과를 봐야 함(저장 실패 · 계산 결과)그 안 Callout — 폼 맨 위, 창은 연 채로
시트 · 대화상자를 닫으며 끝나는 일(저장하고 닫힘)닫힌 뒤 Snackbar
입력값 하나가 틀림Field 의 오류 문구(칸 아래)
저장 · 제출이 실패함폼 맨 위 Callout critical — 폼은 연 채로
그 기능 · 내용 가까이의 팁 · 제약 · 주의Callout — 그 내용 바로 위
페이지 전체의 상태(연결 끊김 · 만료 예정 · 새 버전)Page Banner — 머리 바로 아래, 한 화면에 하나
화면 · 영역이 비었음 · 불러오지 못함 · 끝남그 자리 Result Section(못 불러왔으면 + "다시 시도")
되돌릴 수 없는 결정 · 꼭 알아야 할 일Alert Dialog — 답할 때까지 닫히지 않는다

다섯 부품 견주기

SnackbarCalloutPage BannerResult SectionAlert Dialog
알리는 것방금 한 일의 결과 · 가벼운 실패그 기능의 팁 · 제약 · 주의, 그 자리의 오류페이지 전체의 상태비어 있음 · 불러오기 실패 · 완료되돌릴 수 없는 결정 · 꼭 알아야 할 일
자리화면 아래 가운데(탭 바 · 키보드 위)본문 안, 그 내용 바로 위 · 폼 맨 위머리 바로 아래화면이나 그 영역 가운데화면 가운데, 딤 위
폭화면 폭에서 좌우를 남기고, 넓으면 최대 폭콘텐츠 폭화면 폭 전체놓인 자리확인창 최대 폭
범위그 일 하나그 기능 · 내용(로컬)페이지 전체(글로벌)그 화면 · 영역그 일 하나
머무는 시간잠깐 — 액션이 있으면 조금 더, 머무는 동안 멈춤조치할 때까지상태가 풀릴 때까지상태가 바뀔 때까지답할 때까지
수한 번에 하나필요한 만큼(쌓지 않는다)한 화면에 하나영역마다 하나하나
닫기시간 · 액션 · 보조 기술용 닫기한 번 보면 되는 안내만(경고 · 오류는 못 닫음)한 번 보면 되는 안내만(경고 · 오류는 못 닫음)없음(상태가 바뀌면 걷힘)버튼으로만 — 바깥은 무시 · Esc 는 취소
누를 것액션 하나(동작 이름)링크 · 또는 상자 전체버튼 하나 · 또는 띠 전체해결 하나 + 보조 하나버튼 둘(알릴 때 하나)
스크롤떠 있음함께 움직임붙일 수 있음(화면마다)함께 움직임떠 있음(모달)
사용자 응답없어도 됨없어도 됨없어도 됨없어도 됨(버튼은 고를 수 있음)꼭 답해야 함

수치(폭 · 시간 · 쌓임)는 각 부품의 YAML 이다 — 이 표는 고르는 법만 적는다. 입력칸의 오류(Field)와 몰라도 되는 설명(Help Bubble)은 이 표 밖 — 각 문서의 표가 맡는다.

방금 한 일의 결과 · 가벼운 실패Snackbar
거래를 삭제했어요.되돌리기
입력값이 틀림Field 오류(칸 아래)
예: 5,600원
금액을 입력해 주세요.
그 자리의 안내 · 주의 · 저장 실패Callout

총액이 바뀌어 분할 합계와 1,200원 달라요.

페이지 전체의 상태Page Banner
연결 끊김 증권 연결 키가 만료돼 시세를 받지 못해요.다시 연결
비어 있음 · 불러오기 실패 · 완료Result Section
거래를 불러오지 못했어요

잠시 뒤 다시 시도해 주세요.

되돌릴 수 없는 결정Alert Dialog
거래를 삭제할까요?
삭제한 거래는 되돌릴 수 없어요.
스낵바는 결과 · 가벼운 실패 — 조치가 필요한 오류는 그 자리에

오류는 자리에서

모든 실패를 한곳에서 스낵바로 띄우지 않는다 — 서버가 보낸 글 · 영어 · 코드가 그대로 나가고, 같은 실패가 둘 · 넷씩 뜬다. 각 화면이 실패한 자리에서 알린다: 불러오기 실패는 Result Section, 저장 실패는 폼 맨 위 Callout, 칸 오류는 칸 아래. 스낵바는 그 자리에 둘 곳이 없는 가벼운 실패에만 쓴다.

9:41
가계부
거래를 불러오지 못했어요

잠시 뒤 다시 시도해 주세요.

불러오기 실패그 자리 Result Section
9:41
가계부
10월 2일 (금)−19,050원
점점심 식사식비, 현대카드 M−12,000원
스스타벅스카페, 현대카드 M−5,600원
지지하철교통, 국민 체크카드−1,450원
거래 추가

저장하지 못했어요. 입력한 내용은 그대로 있어요. 잠시 뒤 다시 저장해 주세요.

12,000원
식비 · 점심
저장 실패폼 맨 위 Callout — 입력은 그대로
이렇게 — 불러오기 실패는 그 자리에 Result Section + 다시 시도, 저장 실패는 폼을 연 채 맨 위 Callout — 무엇이 안 됐고 무엇을 하면 되는지 그 자리에서 보인다
9:41
가계부
내역이 없어요
Request failed with status code 500
거래를 불러오지 못했어요.
전역 오류 토스트띠 둘 · 서버 글 · 빈 목록
이렇게 하지 않는다 — 모든 실패를 한곳에서 토스트로 — 서버가 보낸 영어가 그대로 나가고, 화면이 같은 실패를 또 띄운다. 목록은 비어 보여 실패를 숨긴다
오류는 자리에서 — 전역 토스트를 두지 않는다

자리 — 화면 아래 가운데

어느 폭이든 화면 아래 가운데다. 탭 바(Bottom Navigation) · 떠 있는 버튼(Floating Action Button) · 바닥 고정 버튼이 있으면 그 위 8 에 서고, 안전 영역(홈 표시줄)을 피한다. 화면 키보드가 올라와 있으면 키보드 바로 위 8 에 선다 — 탭 바 · 바닥 버튼이 키보드 뒤로 가도 띠는 보인다. 웹도 폰 브라우저에서 같다(키보드가 화면을 줄이지 않아도 보이는 화면의 아래 끝을 재어 피할 자리에 더한다). 2026-10-15 사용자 결정 — 구현 세션 질문 Q-003-1. 시트 · 대화상자가 열려 있어도 그 위에 뜬다(z L6). 다만 시트 · 대화상자에서 한 일은 창이 열린 채인지 닫히며 끝나는지로 가른다(2026-10-02 사용자 결정 그대로 — 2026-10-22 사용자 결정 2B 로 상황을 풀어 썼다, https://claude.ai/artifact/NuEPiLRH2fJidXdKzcDsCX).

시트 · 대화상자에서 한 일알리는 자리
창이 열린 채 결과를 봐야 함(저장 실패 · 계산 결과)그 안 Callout — 폼 맨 위, 창은 연 채로
창을 닫으며 끝나는 일(저장하고 닫힘)닫힌 뒤 Snackbar
칸 하나가 틀림칸 아래 Field 오류

창이 열린 채 그 안의 결과를 스낵바로 띄우지 않는다 — 시트 위의 띠를 누르면 시트가 바깥 누름으로 닫히고 액션이 먹지 않는다.

9:41
가계부
10월 2일 (금)−19,050원
점점심 식사식비, 현대카드 M−12,000원
스스타벅스카페, 현대카드 M−5,600원
지지하철교통, 국민 체크카드−1,450원
월월급수입, 토스뱅크 통장+3,200,000원
거래를 삭제했어요.되돌리기
폰 — 탭 바 위 8분홍은 자리의 여백 — 좌우 8 · 아래 8. 띠 폭은 화면 − 16. 아래는 안전 영역과 피할 자리(탭 바 · 플로팅 버튼 · 바닥 버튼) 중 큰 쪽 위 8 — 탭 바는 안전 영역을 품고 있다.
9:41
관심 종목
숲길
점점심 식사식비, 현대카드 M−12,000원
스스타벅스카페, 현대카드 M−5,600원
지지하철교통, 국민 체크카드−1,450원
월월급수입, 토스뱅크 통장+3,200,000원
관심 종목에 넣지 못했어요. 다시 시도해주세요.다시 시도
화면 키보드 — 키보드 바로 위 8키보드도 피할 자리다 — 탭 바가 키보드 뒤로 가도 띠는 키보드 위 8 에 선다. 웹도 폰 브라우저에서 같다(보이는 화면의 아래 끝을 잰다). 자리가 옮겨 갈 때는 200ms easing.
desk.groo.app
가계부
10월 2일 (금)−19,050원
점점심 식사식비, 현대카드 M−12,000원
스스타벅스카페, 현대카드 M−5,600원
거래를 삭제했어요.되돌리기
데스크톱 — 아래 가운데넓은 화면에서는 최대 464 로 가운데에 선다 · 아래 8
폰은 탭 바 위 · 화면 키보드 위 · 데스크톱은 아래 가운데 최대 464

시간 · 한 번에 하나

액션이 없으면 4초, 있으면 6초. 마우스를 올리거나, 손가락으로 누르고 있거나, 키보드 초점이 들어오면 멈추고, 떠나면 처음부터 다시 센다. 한 번에 하나만 — 새 띠가 오면 지금 띠를 바로 바꾼다(쌓지 않는다). 다만 지금 띠에 액션(되돌리기 · 다시 시도)이 있으면 그 띠는 끝날 때까지(시간 · 액션 · 닫기) 지키고, 새 띠는 그 뒤에 뜬다 — 그 경우만 줄을 세운다(SEED React strategy: "queued"). 기다리는 띠는 하나다 — 그 사이 또 오면 마지막 것만 남는다. 되돌리기 6초(사용자 결정)가 다음 결과에 잘리지 않고, 연달아 저장하는 흔한 경우(액션 없는 결과끼리)는 늦어지지 않는다(2026-10-22 사용자 결정 1B — https://claude.ai/artifact/NuEPiLRH2fJidXdKzcDsCX). 되돌리기 같은 액션은 스낵바에만 두지 않는다 — 시간이 지나면 사라지므로 같은 일을 할 다른 길(목록 · 상세)이 있어야 한다.

액션 없음
보임 4초
0초2초4초6초8초10초12초
액션 있음("되돌리기")
보임 6초
0초2초4초6초8초10초12초
마우스 · 손가락 · 키보드 초점이 머무르면 — 멈췄다가, 떠나면 처음부터
2초멈춤다시 4초
0초2초4초6초8초10초12초
새 띠가 오면 — 지금 띠를 바로 바꾼다
지금 띠새 띠 4초
0초2초4초6초8초10초12초
지금 띠에 액션이 있으면 — 끝날 때까지 지키고 새 띠는 그 뒤에
되돌리기 6초새 띠 4초
0초2초4초6초8초10초12초
머무름이 끝나면 남은 시간이 아니라 처음부터 다시 센다. 한 번에 하나 — 새 띠가 오면 지금 띠가 100ms 로 사라지고 새 띠가 150ms 로 나타난다. 지금 띠에 액션(되돌리기 · 다시 시도)이 있으면 그 띠가 끝난 뒤에 새 띠가 뜬다. 되돌리기 같은 액션은 같은 일을 할 다른 길(목록 · 상세)도 둔다.
시간 — 4초 · 액션 6초 · 머무는 동안 멈춤

글

해요체 문장에 마침표(Writing v106) — 무엇이 됐는지 먼저: "거래를 저장했어요." · "거래를 삭제하지 못했어요."(액션 [다시 시도] 가 있으면 한 문장 — 버튼과 같은 말을 되풀이하지 않고, 폰에서 두 줄이 되지 않는다) · 액션이 없으면 "관심 종목에 넣지 못했어요. 잠시 뒤 다시 시도해주세요." 시스템 말("처리가 완료되었습니다") · "실패" 로 끝나는 말 · 서버가 보낸 글 · 영어 · 코드를 쓰지 않는다. 액션은 구체적인 동작 이름 한두 마디("되돌리기" · "잔액 고치기") — "확인" · "취소" 로 뭉뚱그리지 않는다.

큰 글자에서 글이 좁아지는 것은 이 쓰기 규칙으로 막는다 — 글은 두 줄 안, 액션은 한두 마디. 띠 모양은 SEED 와 같다(액션은 줄지 않고 글이 남은 폭에서 줄을 바꾼다). 규칙을 어긴 긴 글 · 긴 액션이 오면 200% 에서 글이 한두 글자씩 세로로 쌓여 띠가 화면을 덮는다 — 문구 검토에서 막는다. 영어 로케일은 액션이 길어지기 쉬우니("Try again" · "Fix balance") 번역 문구도 같은 규칙으로 본다(2026-10-17 사용자 결정 — 03-F 2B, https://claude.ai/artifact/F5SKUbGEWDG82F7B5RRjQB — 추천 2A "글 칸 반 폭 아래로 줄지 않음 · 액션 아래 줄" 이 아니다).

거래를 저장했어요.
거래를 삭제했어요.되돌리기
관심 종목에 넣지 못했어요. 다시 시도해주세요.다시 시도
이렇게 — 무엇이 됐는지 먼저, 해요체 문장에 마침표 — 액션은 "되돌리기" 처럼 동작 이름
처리가 완료되었습니다
거래가 삭제되었습니다.확인
로드 실패
이렇게 하지 않는다 — 시스템 말 · "실패" 로 끝나는 말 · 마침표 없음 · "확인" 액션 — 무엇이 됐는지, 무엇을 하면 되는지 알 수 없다
글 — 결과 먼저 · 마침표 · 액션은 동작 이름

코드

레시피 recipes/shadcn/components/ui/snackbar.tsx 를 쓴다. 앱 맨 위에 SnackbarProvider 를 한 번 두고, 띄울 때는 useSnackbar() 의 show 를 부른다. 탭 바 · 바닥 버튼처럼 띠가 피해야 할 것은 SnackbarAvoidOverlap 으로 감싼다. 아래 미리보기는 스펙 값으로 그린 모습이다.

결과 알리기

가계부
    10월 2일 (금)
  • 스타벅스카페 · 현대카드 M−5,600원
  • 지하철교통 · 국민 체크카드−1,450원
  • 월급수입 · 토스뱅크 통장+3,200,000원

저장하면 띠가 4초 동안 뜬다 — 마우스를 올리거나 Tab 으로 띠에 들어가면 멈추고, 떠나면 처음부터 센다.

import { useSnackbar } from "@/components/ui/snackbar"

const snackbar = useSnackbar()

await saveTransaction(draft)
snackbar.show({ message: "거래를 저장했어요." })

되돌리기 — 액션이 있으면 6초

가계부
    10월 2일 (금)
  • 점심 식사식비 · 현대카드 M−12,000원
  • 스타벅스카페 · 현대카드 M−5,600원
  • 지하철교통 · 국민 체크카드−1,450원
  • 월급수입 · 토스뱅크 통장+3,200,000원

휴지통을 누르면 거래가 빠지고 띠가 6초 동안 뜬다(액션이 있으면 6초). 되돌리기를 누르면 그 자리로 돌아오고 띠는 닫힌다. 관심 종목 넣기가 실패하면 띠에 다시 시도가 달린다(6초).

snackbar.show({
  message: "거래를 삭제했어요.",
  action: { label: "되돌리기", onClick: () => restoreTransaction(id) },
})

// 가볍게 실패 — 다시 하면 되는 일만. 저장 · 불러오기 실패는 그 자리에서 알린다.
// 켜고 끄는 단추(관심 등록)는 되돌린 뒤 같은 요청을 다시 보내는 "다시 시도" 를 단다(Toggle 20A)
snackbar.show({
  tone: "critical",
  message: "관심 종목에 넣지 못했어요. 다시 시도해주세요.",
  action: { label: "다시 시도", onClick: () => setWatched(stock.id, true) },
})

피할 자리 — 탭 바 · 바닥 버튼

import { SnackbarAvoidOverlap, SnackbarProvider } from "@/components/ui/snackbar"

<SnackbarProvider>
  <App />
  <SnackbarAvoidOverlap>
    <TabBar />
  </SnackbarAvoidOverlap>
</SnackbarProvider>

Behavior

인터랙션동작
나타남150ms 로 가운데에서 커지며 나타난다(모션 줄이기면 투명도만). 초점은 옮기지 않는다
시간4초 · 액션이 있으면 6초 뒤 100ms 로 사라진다
마우스를 올림 · 손가락으로 누르고 있음 · 키보드 초점멈춘다 — 떠나면 처음부터 다시 센다
새 띠가 옴지금 띠를 바로 바꾼다 — 한 번에 하나. 지금 띠에 액션이 있으면 그 띠가 끝날 때까지 기다렸다 뜬다(기다리는 띠는 하나 — 마지막 것만)
액션 누르기액션을 하고 닫는다
Tab띠 안에서는 띠 → 액션 → 보조 기술용 닫기(초점이 오면 보인다). 웹은 페이지 마지막 칸 다음이 띠다. 앱은 화면의 Tab 순서가 띠에 닿지 않는다(띠가 시트 · 대화상자 위, 화면 밖에 그려진다) — 스크린 리더는 훑기로 닿고, 액션은 다른 길이 있다(위 "시간 · 한 번에 하나"). 모달이 열린 동안은 웹도 닿지 않는다 — 그 안에서 한 일의 결과는 그 안 Callout 이다(Q-003-2)
화면 키보드가 올라옴 · 내려감띠가 키보드 바로 위 8 로 옮겨 가고, 내려가면 원래 자리로 — 자리가 옮겨 갈 때는 200ms easing(모션 줄이기면 바로). 피할 자리(탭 바 · 바닥 버튼)와 둘 중 위쪽
Esc · 밀기 · 글 누르기닫히지 않는다 — 닫기 버튼 · 시간 · 액션으로만
띠 안에 초점이 있을 때 닫힘초점은 띠에 들어오기 전 자리로 돌아간다
시트 · 대화상자가 열린 동안그 위에 그린다. 띠를 눌러도 그 창은 닫히지 않는다(바깥 누르기가 아니다). 창이 열린 채 봐야 할 결과는 그 안 Callout, 창을 닫으며 끝나는 일은 닫힌 뒤 스낵바

Accessibility

기준검증
WCAG 1.4.3 Color contrast(글자 ≥ 4.5:1)글 fg-neutral-inverted 띠(bg-neutral-inverted) 위 16.41 · 다크 13.42, 액션 fg-brand-inverted Desk 6.90 · 7.76 · HR 6.88 · 7.56 ✓
WCAG 1.4.11 Non-text contrast(≥ 3:1)아이콘 fg-positive-inverted 6.87 · 4.70, fg-critical-inverted 6.89 · 4.68, 띠 면 페이지 위 16.41 · 13.42 ✓. 포커스 링은 띠 글자색으로 띠 위에 그린다 ✓
WCAG 2.2.1 Timing adjustable머무는 동안 멈추고 떠나면 처음부터. 액션은 6초 — 같은 일을 할 다른 길을 둔다 ✓
WCAG 2.5.8 Target Size — Minimum(AA ≥ 24×24)액션 글 + 좌우 8 × 44 ✓
WCAG 2.5.5 Target Size — Enhanced(AAA ≥ 44×44)액션 높이 44 ✓ · 폭은 글에 따라 ⚠
WCAG 4.1.3 Status messages자리는 aria-live="polite", 띠는 role="status" + aria-atomic="true" — 초점을 옮기지 않고 읽힌다. 조치가 필요한 오류는 스낵바가 아니라 자리에서(role="alert")
ARIA아이콘은 장식(aria-hidden) — 성공 · 실패는 글이 말한다. 사라지는 동안은 aria-hidden

Do / Don't

✅ Do

  • 방금 한 일의 결과를 한 문장으로 — "거래를 저장했어요."
  • 되돌릴 수 있는 삭제에 "되돌리기" — 그리고 다른 길도 둔다. 되돌리기가 달린 띠는 다음 결과에 밀리지 않는다.
  • 시트를 연 채 결과를 봐야 하면 그 안 Callout, 닫으며 끝나면 닫힌 뒤 스낵바.
  • 탭 바 · 바닥 버튼은 SnackbarAvoidOverlap 으로 피한다.

❌ Don't

  • 모든 실패를 한곳에서 스낵바로 — 서버 글 그대로 · 중복.
  • 조치가 필요한 오류 · 계속 보여야 할 경고를 스낵바에.
  • 띠를 여러 장 쌓기.
  • 시트 · 대화상자가 열린 채 그 안의 결과를 스낵바로 — 띠를 누르면 시트가 닫히고 액션이 먹지 않는다(그 안 Callout).
  • "확인" 액션.

Specification

snackbar.yaml 의 규칙을 하나도 빼지 않고 조건마다 그린다 — 웹 · 앱이 Snackbar 를 만들 때 이 값을 그대로 쓴다. 조건이 없는 Base 가 모든 조합에 걸리고, 뒤의 규칙이 앞의 같은 값을 덮는다. 상태는 enabled 에서 바뀌는 값만 적었다.

Base

부위상태속성값
regionenabled좌우 여백paddingXspacing-x28px화면 끝과 8 — 안전 영역이 있으면 그만큼 더
아래 여백paddingBottomspacing-x28px아래 8 + 안전 영역 — 탭 바 · 플로팅 버튼 · 바닥 버튼이 있으면 그 위 8(안전 영역과 둘 중 큰 쪽 — 탭 바는 안전 영역을 품고 있다). 화면 키보드가 올라와 있으면 키보드 바로 위 8 — 웹 폰 브라우저도 보이는 화면의 아래 끝을 잰다(2026-10-15 사용자 결정 — 구현 세션 질문 Q-003-1)
z-indexzIndex400z-snackbar — specs/z-index.md L6. 시트 · 대화상자 · 확인창 위
keyboardGapkeyboardGapspacing-x28px화면 키보드 위 끝 ↔ 띠 아래 끝 — 키보드도 피할 자리 하나다(안전 영역 · 탭 바 · 바닥 버튼과 넷 중 가장 위)
offsetDurationoffsetDurationmotion-duration-d4200ms피할 자리(탭 바 · 바닥 버튼 · 키보드)가 바뀌어 띠가 옮겨 갈 때 — 모션 줄이기면 바로(SEED snackbar.region.offsetDuration)
offsetEasingoffsetEasingmotion-ease-easingcubic-bezier(0.35, 0, 0.35, 1)SEED snackbar.region.offsetTimingFunction
rootenabled최소 높이minHeight44px
너비width100%자리 폭 — 최대 464, 넓으면 가운데
최대 너비maxWidth464px
여백paddingspacing-x2_510px
모서리radiusradius-r28px
배경backgroundbg-neutral-inverted#1A1F2E다크 #F5F6FA다크에서는 밝은 띠
그림자shadownone그림자 없이 면 색으로 뜬다(SEED · Elevation)
보이는 시간duration4000ms액션이 있으면 6000ms. 마우스 · 손가락 · 키보드 초점이 머무는 동안 멈추고, 떠나면 처음부터 다시 센다
iconenabled아이콘size24pxlucide 선 아이콘 — 체크(circle-check) · 느낌표(circle-alert). 오른쪽 여백 2 를 이 칸 안에 둬 그림은 22 다(SEED 와 같다 — 글은 띠 가장자리에서 40)
오른쪽 여백paddingRightspacing-x0_52px칸 안쪽 — 칸을 넓히지 않는다
contentenabled좌우 여백paddingXspacing-x1_56px글은 띠 가장자리에서 16(아이콘이 있으면 40)
간격gapspacing-x2_510px글과 액션은 양 끝 — 사이는 적어도 10
messageenabled글자·아이콘foregroundfg-neutral-inverted#FFFFFF다크 #242938
글자typographytext-t414px / 19px단어 단위 줄바꿈(v114) — 줄 수를 자르지 않는다(2026-09-22). 두 줄 안에서 끝나게 쓴다
굵기fontWeight400
actionenabled모서리radiusradius-r14px바탕이 없어 초점 링에만 보인다
글자·아이콘foregroundfg-brand-invertedDesk#7AA9F6다크 #0147ADHR#2ABE84다크 #075B3C반전 짝(v115) — 짙은 띠 위 Desk 6.90 · HR 6.88, 다크의 밝은 띠 위 7.76 · 7.56
글자typographytext-t414px / 19px
굵기fontWeight700
터치 영역touchTarget글 + 좌우 8 × 44띠 높이 안에서 위아래로 넓힌다
closeButtonenabled크기size44px평소에는 보이지 않는다(보조 기술은 읽는다) — 키보드 초점이 오면 띠 오른쪽 끝에 X 16 으로 보인다
아이콘 크기iconSize16px
바깥 여백margin위 · 아래 · 오른쪽 −10띠 여백(10) 안으로 들어와 띠 높이를 44 로 둔다
모서리radiusradius-r28px바탕이 없어 초점 링에만 보인다
색colorfg-neutral-inverted#FFFFFF다크 #242938
actionpressed배율scale2px 거리 축소글만 준다 — 모션 줄이기면 하지 않는다
축소 시간scaleDurationmotion-duration-pressed-scale150ms
축소 곡선scaleEasingmotion-ease-pressed-scalecubic-bezier(0, 0, 0.15, 1)
focusRingfocused링 두께width2px
링 색colorfg-neutral-inverted#FFFFFF다크 #242938띠 글자색 — 브랜드 링은 짙은 띠 위에서 Desk 1.96 이라 3:1 에 못 미친다
링 간격offset-4px띠 · 닫기 — 안쪽 4. 링이 띠 글자색이라 바깥(페이지 위)에 그리면 보이지 않는다
액션 링 간격actionOffset2px액션 — 바깥 2. 띠 여백 안이라 띠 위에 그려진다

tone=positive

부위상태속성값
iconenabled색colorfg-positive-inverted#25C062다크 #167F3F반전 짝(v115) — 짙은 띠 위 6.87, 다크의 밝은 띠 위 4.70

tone=critical

부위상태속성값
iconenabled색colorfg-critical-inverted#FF8477다크 #D72323반전 짝(v115) — 짙은 띠 위 6.89, 다크의 밝은 띠 위 4.68

SEED 와 다른 점

  • 아이콘 · 액션 색은 반전 짝 역할(v115 — fg-positive-inverted · fg-critical-inverted · fg-brand-inverted) — SEED 는 밝은 바탕용 색을 그대로 써 짙은 띠 위에서 대비가 모자란다(다크 아이콘 2.5:1 · 액션 2.67:1).
  • 액션이 있으면 6초(사용자 결정 2026-10-02) — SEED 는 늘 4초.
  • 글은 문장이면 마침표(Writing v106) — SEED 는 한 문장이면 뺀다.
  • 모션 줄이기면 투명도만(v104) — SEED 는 그대로 돈다.
  • 보조 기술용 닫기는 키보드 초점이 오면 보인다 — SEED 는 안 보이는 채로 Tab 이 선다.
  • 포커스 링은 띠 글자색 — groo 브랜드 링은 짙은 띠 위에서 3:1 에 못 미친다.
  • 아이콘은 lucide 선 아이콘(v106).
  • z-index 는 specs/z-index.md 의 L6(z-snackbar 400).
  • 띠 안에서 닫히면 초점을 돌려준다 — 띠에 들어오기 전 자리로. SEED 는 body 로 떨어뜨려 키보드 사용자가 처음부터 다시 찾아야 한다.
  • 화면 키보드가 있으면 키보드 바로 위 8(사용자 결정 2026-10-15) — SEED 는 키보드를 말하지 않는다.
  • 아래 자리는 안전 영역과 피할 자리 중 큰 쪽 — SEED 는 둘을 더해, 안전 영역을 품은 탭 바 위에서는 그만큼 더 뜬다.
  • 새 띠는 바로 바꾸고, 액션이 달린 띠만 지킨다 — SEED 디자인 문서는 늘 큐("현재 표시 중인 항목이 사라진 후 순차적으로"), SEED React 는 기본이 바로 바꿈(immediate)이고 strategy: "queued" 를 띠마다 고른다. groo 는 액션(되돌리기 · 다시 시도)이 있는 띠가 떠 있을 때만 줄을 세운다(2026-10-22 사용자 결정 1B — https://claude.ai/artifact/NuEPiLRH2fJidXdKzcDsCX).

Migration notes

2026-10-22 — 액션 띠는 지킨다 · 알림 표는 한 벌 · 시트 안 결과 셋

사용자가 알리고 기다리는 것 정리 페이지에서 모두 추천 안으로 정했다.

  • 새 띠(1B) — 바로 바꾸되, 지금 띠에 액션(되돌리기 · 다시 시도)이 있으면 끝날 때까지 지키고 새 띠는 뒤에(기다리는 띠는 하나 — 마지막 것만). 10-02 비교 페이지는 두 안 모두 "바로 바꾼다(SEED React 기본)" 로 그렸고 바꾸기 ↔ 줄 세우기는 묻지 않았다(따라오는 것). 레시피 snackbar.tsx 의 상태(떠 있는 띠 하나 + 기다리는 것 하나)에 조건 하나를 더했다 · 사이트 데모 · 시간 그림 · yaml 모션 비고. 제품(웹 ds snackbar.tsx · 앱 p_snackbar.dart)은 머지된 코드라 구현 지시로 고친다.
  • 시트 · 대화상자 안 결과(2B) — 결정(그 안 Callout · 스낵바는 닫힌 뒤)은 그대로, 상황 셋의 표로 풀어 썼다(열린 채 → Callout · 닫으며 → 닫힌 뒤 스낵바 · 칸 하나 → 칸 아래).
  • "무엇으로 알리나" 표(3B) — 다섯 문서에 따로 있던 표를 이 문서 한 벌(상황 → 고를 것 + 다섯 부품 견주기)로 모으고, Callout · Page Banner · Help Bubble · Alert Dialog 는 자기 줄만 두고 링크한다. Page Banner ↔ Callout 표에 SEED 의 "용도" · "Sticky" 두 줄을 더했다. 값 변경 없음.

2026-10-15 — 키보드 위 자리 · 앱의 Tab

구현 세션 질문 두 가지를 정했다.

  • 화면 키보드가 올라와 있으면 키보드 바로 위 8(사용자 결정 — Q-003-1). 앱은 이미 그렇다. 웹은 position: fixed; bottom 만 써서 폰 브라우저에서 띠가 키보드 뒤로 갔다 — 보이는 화면(visualViewport)의 아래 끝을 재어 피할 자리에 더한다(레시피). 키보드가 있을 때 화면 위쪽에 띄우는 안 · 키보드가 내려간 뒤에 띄우는 안은 고르지 않았다.
  • 앱의 화면 Tab 은 띠에 닿지 않는다(정리 — Q-003-2). 띠는 화면 밖(시트 · 대화상자 위)에 그려진다. 액션은 다른 길이 있어야 하고("시간 · 한 번에 하나"), 시트 · 대화상자 안의 결과는 그 안 Callout 이라("자리") 키보드로 띠에 닿지 못해도 잃는 일이 없다. Behavior 의 Tab 줄에 적었다.
  • 자리가 옮겨 갈 때의 200ms easing 을 YAML(region.offsetDuration · offsetEasing)에 적었다 — 웹 · 앱이 이미 같은 값을 쓰고 SEED snackbar.region.offsetDuration 과 같다.

2026-10-02 — SEED Snackbar 로 새로 둔다(옛 Sonner 를 대신)

사용자가 비교 페이지에서 정했다 — 알림을 일로 나누고(결과 · 가벼운 실패만 스낵바), 오류는 자리에서 알리고(전역 오류 토스트를 걷는다), SEED 모양 + 반전 짝 색, 아래 가운데, 액션이 있으면 6초, 마침표는 v106 그대로. 옛 Sonner(흰 카드 · 그림자 · 아이콘 넷 · 글 16/600 · 위 가운데 · 3장 쌓기)는 걷었다 — 옛 스펙은 sonner.history/v-pre-seed-feedback.*. 2026-09-22 의 "글은 자르지 않는다" 는 그대로 둔다.

제품은 앱 적용 단계에서 옮긴다(2026-10-02 조사 — Desk 웹 · HR 은 크로미움에 띄워 쟀고, Desk 앱은 위젯 테스트로 쟀다).

  • Desk 웹 — sonner 37곳(위 가운데) + 손으로 만든 토스트 2(반복 거래 · 별빛, 아래 가운데 · 역할 없음). 전역 오류 토스트가 서버 글을 그대로(11곳은 화면이 또 띄운다). 시트가 열린 동안 띠를 누르면 시트가 닫히고 액션이 먹지 않는다. 키보드 초점에서 멈추지 않는다. 더치페이 "송금 요청을 보냈어요" 는 아무것도 보내지 않는다.
  • Desk 앱 — showPSnackBar 36(아래). 전역 오류 스낵바(값을 바꾸는 요청만, 영어 대체 문구 "Server error"), 높이를 줄인 시트 4곳에서 띠가 시트 뒤에 그려져 안 보인다, 대화상자 위로는 딤 아래. 액션 스낵바가 스크린리더가 켜져도 6초 뒤 사라진다.
  • HR 웹 — sonner 46(위 가운데, 앱 테마가 아니라 OS 테마, 스타일 클래스가 먹지 않는다). 전역 오류 토스트가 GET 까지 · 재시도마다(실패 한 번에 최대 4), 19곳은 화면이 또 띄운다. 저장 성공을 알리지 않는 화면이 많다(30파일).

이 페이지