Groo Design

Tag Group

여러 메타 정보(카테고리 이름 · 자산 · 시각 · 거리 · 개수 · 금액)를 " · " 로 이어 한 줄로 보이는 글줄 — "식비 · 신한카드 · 오후 2:10". 읽기만 한다. 대상의 상태 · 분류 라벨은 Badge, 고르는 값은 Chip 이다.

구조는 당근 SEED Tag Group(Apache-2.0)를 따른다 — 항목(글 + 아이콘 하나) · 구분 " · ", 크기 셋(t2 · t3 · t4), 항목마다 톤 · 굵기, 줄바꿈 또는 한 줄 말줄임. 값은 groo 토큰이고, SEED 와 다른 자리는 맨 아래 "SEED 와 다른 점" 에 적었다(2026-10-03 사용자 결정). groo 에 처음 두는 컴포넌트다 — DESIGN.md Caption 절의 "닉네임 · 시간" 메타 줄과 List 줄의 설명 줄이 이것이다.

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

9:41
가계부
10월 2일 (금)
  • 스타벅스 강남역점카페, 현대카드 M, 오후 2:10−5,600원
  • 넷플릭스예정구독, 현대카드 M, 10월 18일−17,000원
  • 점심 식사식비, 신한카드, 오후 12:40−12,000원
  • 교통 정기권연체 3교통, 국민 체크카드, 3/12회−62,000원
9:41
공지
이번 주
  • 10월 전사 워크숍 안내인사팀, 10월 2일, 조회 12
  • 연말 정산 서류 제출재무팀, 9월 30일, 조회 48
  • 사내 동호회 모집총무팀, 9월 28일, 조회 7
9:41
카드
현대카드 M신용단종결제일 14일, 연회비 2만원, 포인트형
혜택
커피 10% 할인전월 30만원 이상, 할인형, 연회비 2만원
10월 거래
  • 스타벅스 강남역점카페, 현대카드 M, 오후 2:10−5,600원
  • 점심 식사식비, 신한카드, 오후 12:40−12,000원
9:41
가계부
10월 2일 (금)
  • 스타벅스 강남역점카페, 현대카드 M, 오후 2:10−5,600원
  • 넷플릭스예정구독, 현대카드 M, 10월 18일−17,000원
  • 점심 식사식비, 신한카드, 오후 12:40−12,000원
  • 교통 정기권연체 3교통, 국민 체크카드, 3/12회−62,000원
9:41
공지
이번 주
  • 10월 전사 워크숍 안내인사팀, 10월 2일, 조회 12
  • 연말 정산 서류 제출재무팀, 9월 30일, 조회 48
  • 사내 동호회 모집총무팀, 9월 28일, 조회 7
9:41
카드
현대카드 M신용단종결제일 14일, 연회비 2만원, 포인트형
혜택
커피 10% 할인전월 30만원 이상, 할인형, 연회비 2만원
10월 거래
  • 스타벅스 강남역점카페, 현대카드 M, 오후 2:10−5,600원
  • 점심 식사식비, 신한카드, 오후 12:40−12,000원
가계부 줄 · 공지 · 카드 상세의 메타 줄 — 라이트 · 다크

직접 골라 보기

크기 · 항목 수 · 항목마다 톤 · 굵기 · 아이콘 · 줄바꿈 · 말줄임과 폭을 고르면 스펙대로 그린 줄과 그 코드, 보조 기술이 읽는 글이 바뀐다.

폭 240
식비, 신한카드 Deep Dream 체크(1234), 오후 2:10
보조 기술이 읽는 글: “식비, 신한카드 Deep Dream 체크(1234), 오후 2:10”
크기 size
항목 수
앞세울 항목
아이콘(넷째 항목 — 조회)
넘칠 때
폭
모드
브랜드
import { TagGroup, TagGroupItem } from "@/components/ui/tag-group"

<TagGroup>
  <TagGroupItem>식비</TagGroupItem>
  <TagGroupItem>신한카드 Deep Dream 체크(1234)</TagGroupItem>
  <TagGroupItem>오후 2:10</TagGroupItem>
</TagGroup>

Anatomy

조회 12, 인사팀, 10월 2일
ⓐ Itemⓑ Iconⓒ Separator
3배로 그렸다(t2) — 구분 “ · ” 는 글자다. 앞 공백이 줄이 안 바뀌는 공백이라 앞 항목에 붙는다
항목(아이콘 + 글) · 구분 " · "
부위설명
ⓐ Item항목 — 글 하나. 6 ~ 10자.
ⓑ Icon아이콘 — 항목의 앞 또는 뒤 하나. 없어도 된다.
ⓒ Separator구분 " · " — 글자다(점 그림이 아니다). 앞 항목에 붙는다.

부위

부위설명
root묶음 — 항목을 " · " 로 잇는다. 줄바꿈하거나(기본) 한 줄에서 항목마다 말줄임한다
item항목 — 글 + 아이콘 하나(앞 또는 뒤)
label항목 글 — 한 줄 말줄임이면 각자 끝을 "…" 로, 첫 글자 + "…" 까지만 준다
icon항목 아이콘 — 앞(prefix) 또는 뒤(suffix) 하나만. 항목 글자색을 따른다
separator구분 " · " — 보이기만 한다(보조 기술에 숨긴다)
srSeparator보이지 않는 ", " — 보조 기술이 항목을 끊어 읽게 구분 자리에 둔다

Properties

Size

t2 12 / 16 (기본) · t3 13 / 18 · t4 14 / 19. 아이콘은 12 · 13 · 14 로 글자에 맞추고 글과 사이 2. 크기는 묶음에 하나다 — 한 줄 안에서 섞지 않는다. 글은 글자 크기 설정을 따른다.

t2 12 / 16 (기본)아이콘 12 · 아이콘과 글 사이 2
식비, 신한카드, 오후 2:10, 조회 12
t3 13 / 18아이콘 13 · 아이콘과 글 사이 2
식비, 신한카드, 오후 2:10, 조회 12
t4 14 / 19아이콘 14 · 아이콘과 글 사이 2
식비, 신한카드, 오후 2:10, 조회 12

크기는 묶음에 하나 — 한 줄 안에서 섞지 않는다. 글은 글자 크기 설정을 따른다

크기 — t2 · t3 · t4

크기

size항목 글자아이콘구분 글자 크기설명
t2 (기본)text-t2 12px / 16px — 12 / 16 — 글자 크기 설정을 따른다12pxtext-t2 12px / 16px12 / 16 — 기본. 목록 줄의 설명 줄 · 카드의 메타
t3text-t3 13px / 18px — 13 / 18 — 글자 크기 설정을 따른다13px — 글자 크기에 맞춘 값(SEED) — Iconography 의 16 · 20 · 24 밖text-t3 13px / 18px13 / 18 — 목록 설명이 13 인 자리 · 상세 머리
t4text-t4 14px / 19px — 14 / 19 — 글자 크기 설정을 따른다14pxtext-t4 14px / 19px14 / 19 — 상세 본문 위 · 넓은 화면

공통

부위속성값비고
item아이콘과 글 사이spacing-x0_5 2px아이콘 ↔ 글
icon아이콘 색currentColor항목 글자색 — 뜻이 있는 아이콘(갈래 = 분할 · 눈 = 조회)은 그 항목의 읽을 글(srLabel — "분할 2건")이 뜻을 말한다. 아이콘 자신은 aria-hidden
separator구분 글자 · 앞 공백은 줄이 안 바뀌는 공백(U+00A0) · 가운뎃점(U+00B7) · 뒤 공백 — 앞 항목에 붙어 줄 끝에 남는다. 2px 점 · "•" 를 쓰지 않는다
separator구분 색color-fg-disabled #8A91A0 · 다크 #838997글보다 한 단계 흐리다(흰 바탕 3.16 · 다크 4.13 — 장식, 보조 기술에 숨김)
separator구분 굵기400
srSeparator읽는 구분, 보이지 않는 글(sr-only) — 화면 읽기 프로그램이 "식비, 신한카드, 오후 2:10" 처럼 끊어 읽는다. 앱은 묶음 하나의 의미 노드에 항목을 ", " 로 이어 붙인다

Tone · Weight

톤과 굵기는 항목마다 고른다. 기본은 흐린 글자(neutralSubtle — fg-neutral-subtle) · 400 이고, 금액 · 핵심 수치처럼 앞세울 항목은 되도록 하나만 neutral(본문 글자) · bold 로 둔다 — 여럿을 진하게 하면 앞세움이 사라진다(SEED 는 항목마다 톤 · 굵기를 조합하게 열어 둔다). brand 는 아껴 쓴다. 구분 " · " 는 톤과 관계없이 늘 fg-disabled 로 글보다 한 단계 흐리다.

regular 400bold 700
neutralSubtle흐린 글자(기본)12,000원12,000원
neutral본문 글자12,000원12,000원
brand브랜드 글자12,000원12,000원
금액 하나만 진하게12,000원, 식비, 오후 2:10
라이트구분 “ · ” 는 톤과 관계없이 늘 fg-disabled — 글보다 한 단계 흐리다
regular 400bold 700
neutralSubtle흐린 글자(기본)12,000원12,000원
neutral본문 글자12,000원12,000원
brand브랜드 글자12,000원12,000원
금액 하나만 진하게12,000원, 식비, 오후 2:10
다크구분 “ · ” 는 톤과 관계없이 늘 fg-disabled — 글보다 한 단계 흐리다
톤 셋 · 굵기 둘 — 금액 하나만 진하게

톤

tone항목 글자색설명
neutralSubtle (기본)color-fg-neutral-subtle #62697A · 다크 #A2A8B7 — 흰 바탕 5.50 · 다크 6.09, 회색 바탕 5.09 · 6.89흐린 글자 — 기본. 대부분의 메타
neutralcolor-fg-neutral #1A1F2E · 다크 #F5F6FA — 16.41 · 13.42본문 글자 — 금액 · 핵심 수치처럼 앞세울 항목
brandcolor-fg-brand HR #075B3C · Desk #0147AD — Desk 8.38 · 6.10 · HR 8.17 · 6.07브랜드 글자 — 아껴 쓴다(내 항목 표시처럼 브랜드와 닿는 자리)

굵기

weight항목 굵기설명
regular (기본)400400 — 기본
bold700700 — 앞세울 항목 하나(금액)

Icon

아이콘은 항목의 앞(prefix) 또는 뒤(suffix)에 하나만 — 앞뒤 모두 두지 않는다. 글자색을 따른다. 갈래(분할) · 눈(조회)처럼 뜻이 있는 아이콘은 그 항목의 읽을 글(srLabel — "분할 2건" · "조회 12")이 뜻을 말한다.

분할 2건, 조회 12보조 기술이 읽는 글: “분할 2건, 조회 12”
앞 아이콘 prefixIcon항목에 하나만 — 앞뒤 모두 두지 않는다. 뜻은 읽을 글(srLabel)이 말한다
분할 2건, 조회 12보조 기술이 읽는 글: “분할 2건, 조회 12”
뒤 아이콘 suffixIcon항목에 하나만 — 앞뒤 모두 두지 않는다. 뜻은 읽을 글(srLabel)이 말한다
앞 아이콘 · 뒤 아이콘 — 분할 2 · 조회 12

Overflow

값넘칠 때
wrap (기본)낱말 단위로 줄을 바꾼다(v114) — 구분은 앞 항목에 붙어 줄 끝에 남고, 다음 줄은 항목으로 시작한다. 아이콘은 붙은 낱말과 한 줄에 남는다(앞 아이콘은 첫 낱말, 뒤 아이콘은 마지막 낱말과 줄바꿈 없이 묶는다 — NBSP 만으로는 아이콘 앞뒤가 줄바꿈 자리가 된다)
truncate한 줄 — 항목 글이 각자 말줄임(…)한다. 줄어드는 정도를 항목마다 정한다(shrink — 0 은 줄지 않고, 1 이상은 넘친 폭을 '글 폭 × shrink' 비율로 나눠 함께 준다). 줄어드는 항목도 첫 글자 + "…"(2.1em) 까지만 준다

말줄임하면 정보를 읽기 어려워지는 자리(가게 이름 · 주소)는 줄바꿈이 낫다. 목록 줄처럼 높이가 늘면 안 되는 자리만 truncate 로 두고, 꼭 보여야 할 항목(금액)은 shrink={0} 이다. 말줄임으로 줄이는 것은 이름 항목(카테고리 · 계좌 · 태그)뿐이다 — 잘리면 뜻이 없는 항목(금액 · 시각 · 주기 문장)은 줄이지 않고, 줄이 모자라면 항목째 다음 줄로 넘긴다("연회비 1,…" · 앞 두 낱말만 남은 주기는 쓰지 않는다).

shrink 는 차례가 아니다 — 브라우저 · Flutter 모두 넘친 폭을 줄어드는 항목에 '글 폭 × shrink' 비율로 나눠 한꺼번에 줄인다. 수가 클수록, 글이 길수록 많이 줄 뿐 큰 수의 항목이 다 줄어든 뒤에 다음 항목이 줄지는 않는다. 그래서 줄어드는 항목에는 최소 폭이 있다 — 첫 글자 + "…" 가 남는 2.1em(t3 100% 에서 27.3). 그보다 짧은 항목(두 글자 이하)은 넓히지 않고 글 폭 그대로다. 최소 폭이 없으면 좁은 줄에서 짧은 시각 · 개수까지 함께 줄어 글자 조각("오" 6.7px)만 남았다. 모든 항목이 최소 폭까지 줄어도 넘치면 줄 끝이 말줄임 없이 잘린다(200% · 폭 260 에서 21) — 꼭 보일 항목은 shrink={0} 으로 앞에 둔다(2026-10-17 사용자 결정 — 03-E 결정 5 B. 기본을 "줄지 않음" 으로 · SEED 그대로는 고르지 않았다).

교통, 신한카드 Deep Dream 체크(1234), 오후 2:10
wrap — 줄바꿈(기본)낱말 단위로 바꾼다 — 구분은 앞 줄 끝에 남고, 다음 줄은 항목으로 시작한다
교통, 신한카드 Deep Dream 체크(1234), 오후 2:10
truncate — 한 줄 말줄임항목 글이 각자 말줄임 — 구분은 줄지 않는다
교통, 신한카드 Deep Dream 체크(1234), 오후 2:10
shrink — 줄어드는 정도0 은 줄지 않고 1 이상은 글 폭 × shrink 비율로 함께 준다 — 긴 자산 이름만 줄었다
간식 · 디저트 모음 아주 긴 카테고리 이름, 지어낸카드 체크카드 개인(1234), 오후 2:10, 분할 2건
최소 폭 — 첫 글자 + …모두 shrink 1 이어도 항목마다 첫 글자 + "…"(2.1em)는 남는다 — 글자 조각만 남지 않는다

분홍 점선 — 폭 200. 말줄임해도 글 전체는 보조 기술이 읽는다

줄바꿈 · 한 줄 말줄임 · 줄어드는 정도 · 최소 폭

줄바꿈 · 말줄임

overflow넘칠 때항목 줄어듦label 최소 너비구분 줄어듦설명
wrap (기본)줄바꿈 — 낱말 단위 — word-break keep-all + overflow-wrap break-word(v114) — 항목 사이 · 항목 안 띄어쓰기에서 줄을 바꾸고, 한 줄보다 긴 낱말만 칸 끝에서 끊는다. 앱은 공용 글자 위젯의 이음 문자(U+2060)———넘치면 낱말 단위로 줄을 바꾼다 — 기본
truncate말줄임 — 한 줄 — 묶음은 한 줄(inline-flex · max-width 100%) — 넘치면 항목 글이 각자 말줄임(…), 구분은 줄지 않는다1 — 줄어드는 정도 — 0 은 줄지 않는다. 1 이상인 항목은 넘친 폭을 '글 폭 × shrink' 비율로 나눠 함께 준다(flex-shrink — 차례대로가 아니다. 수가 클수록 · 글이 길수록 많이 준다). 금액처럼 꼭 보일 항목은 0. 글 전체는 보조 기술이 읽는다2.1em — 줄어드는 항목도 첫 글자 + "…" 는 남긴다 — t2 25.2 · t3 27.3 · t4 29.4(100%), em 이라 글자 크기를 따라 커진다. 글이 이보다 짧은 항목(두 글자 이하)은 넓히지 않고 글 폭 그대로다. 아이콘은 이 폭 밖이라 늘 보인다. 모든 항목이 최소 폭까지 줄어도 넘치면 줄 끝이 말줄임 없이 잘린다(200% · 폭 260 에서 21). SEED 에 없는 값 — 기본을 '줄지 않음' 으로(A) · SEED 그대로(C)는 고르지 않았다(2026-10-17 사용자 결정 — 03-E 결정 5 B)0한 줄 — 넘치면 항목마다 말줄임(첫 글자 + … 까지), 항목마다 줄어드는 정도(0 = 줄지 않음)를 정할 수 있다

State

상태는 enabled 하나다 — 누르지 않는다. 막힌 줄 안에 있으면 그 줄의 규칙(List 의 비활성 — 모든 글 fg-disabled)을 따른다. 끝낸 줄(끝낸 할 일 — 줄은 막히지 않고 누를 수 있다) 안도 항목 글을 모두 fg-disabled 로 둔다 — 톤 · 굵기와 상관없이, 구분 " · " 는 원래 fg-disabled 그대로다(2026-10-25 I-10 앱 PTagTone.disabled, 같은 줄의 배지는 Badge 의 "끝낸 항목 안").

Guidelines

메타 정보는 Tag Group

시간 · 개수 · 길이 · 거리 · 금액 · 자산 같은 메타 정보는 Tag Group 이다. 대상의 상태 · 분류(예정 · 승인 · 연체)는 Badge 다(SEED Image Frame — "Badge 는 상태나 분류를 표현할 때만, 시간 · 개수 · 길이 같은 메타 정보에는 쓰지 않는다"). 한 줄에 둘이 함께 있으면 배지는 제목 옆, Tag Group 은 설명 줄이다.

  • 넷플릭스예정구독, 현대카드 M, 10월 18일−17,000원
  • 스타벅스 강남역점카페, 현대카드 M, 오후 2:10−5,600원
이렇게 — 상태(예정)는 제목 옆 배지, 메타(분류 · 자산 · 날짜)는 설명 줄 Tag Group
  • 넷플릭스구독현대카드 M10월 18일−17,000원
  • 스타벅스 강남역점카페, 현대카드 M, 결제 완료−5,600원
이렇게 하지 않는다 — 메타를 배지로 · 상태를 메타 줄에 — 무엇이 상태인지 갈리지 않는다
제목 옆 배지 · 설명 줄 Tag Group

짧게 — 조사 · 접속어를 빼고

항목은 6 ~ 10자로, 조사 · 접속어 · 단위의 군말을 뺀다("신한카드로 결제함" 이 아니라 "신한카드"). 문장이 되면 Tag Group 이 아니라 설명 글이다. 같은 자리의 항목은 화면마다 같은 순서다(가계부 줄 — 분류 · 자산 · 시각).

식비, 신한카드, 오후 2:10
이렇게 — 6 ~ 10자 · 조사와 군말을 뺐다 — 화면마다 같은 순서(분류 · 자산 · 시각)
식비로 분류됨, 신한카드로 결제함, 오후 2시 10분에 결제했어요
이렇게 하지 않는다 — 항목이 문장이 됐다 — 길어져 잘리고 읽기 어렵다. 문장은 설명 글이다
짧은 항목 · 문장이 된 항목

구분은 " · " 글자

항목 사이는 글자 " · "(가운뎃점 앞뒤 띄어쓰기)다 — 2px 점 그림 · "•" · "|" · 띄어쓰기만으로 가르지 않는다. 구분은 글보다 한 단계 흐린 fg-disabled 다.

500m, 역삼동, 3분 전500m, 역삼동, 3분 전
이렇게 — 글자 " · " — 앞뒤 띄어쓰기, 글보다 한 단계 흐리게(fg-disabled). 글자 크기를 따라간다
500m역삼동3분 전500m역삼동3분 전
이렇게 하지 않는다 — 2px 점 그림 — 글자가 커져도 그대로이고 화면마다 크기 · 색이 갈린다
500m역삼동3분 전500m역삼동3분 전
이렇게 하지 않는다 — "•" · "|" — 구분이 글보다 무거워 항목처럼 보인다
" · " 글자 · 2px 점 · "•"

한 묶음은 한 크기

크기는 묶음에 하나다 — 항목마다 크기를 바꾸지 않는다. 강조는 톤 · 굵기로 한다.

12,000원, 식비, 오후 2:10
이렇게 — 한 크기 — 금액은 톤 · 굵기로 앞세운다
12,000원 · 식비 · 오후 2:10
이렇게 하지 않는다 — 항목마다 크기를 바꿨다 — 글줄이 들쭉날쭉하고 높이가 흔들린다
한 크기 · 섞인 크기

끊어 읽는다

구분 " · " 는 보조 기술에 숨기고, 그 자리에 보이지 않는 ", " 를 둔다 — 화면 읽기 프로그램이 "식비, 신한카드, 오후 2:10" 으로 끊어 읽는다("식비신한카드오후 2:10" 처럼 붙지 않는다). 아이콘이 뜻을 가진 항목은 읽을 글을 따로 준다("분할 2건" · "조회 12").

인사팀, 10월 2일, 조회 12보조 기술이 읽는 글: “인사팀, 10월 2일, 조회 12”
이렇게 — 구분 자리에 보이지 않는 ", " · 아이콘 항목은 읽을 글("조회 12")
인사팀, 10월 2일, 조회 12보조 기술이 읽는 글: “인사팀10월 2일12”
이렇게 하지 않는다 — 구분을 숨기기만 했다 — 항목이 붙어 읽히고 숫자만 남는다
보조 기술이 읽는 글 — 항목마다 쉼표

쓰는 자리

자리크기 · 넘침
List 줄의 설명 줄(거래 · 할 일 · 메모 · 이체)t3 · truncate(줄 높이 유지) — 금액 같은 꼭 보일 항목은 줄지 않게
카드 · 상세 머리의 메타(카드 종류 · 혜택 · 공지 날짜 · 조회)t2 · wrap
작성자 · 시각("김민수 · 3분 전")t2 · wrap

코드

레시피 recipes/shadcn/components/ui/tag-group.tsx 를 쓴다 — TagGroup · TagGroupItem. TagGroup 은 size("t2" 기본 · "t3" · "t4") · truncate(기본 false = 줄바꿈)와 항목의 기본 tone · weight 를 받고, 항목 사이에 " · "(보조 기술에는 ", ")를 스스로 넣는다 — 빈 항목(null · false · "")은 건너뛴다. TagGroupItem 은 tone("neutralSubtle" · "neutral" · "brand") · weight("regular" · "bold") · prefixIcon 또는 suffixIcon(하나만) · shrink(truncate 일 때 줄어드는 정도, 기본 1 — 0 은 줄지 않는다) · srLabel(보조 기술이 읽을 글 — 주면 보이는 글 · 아이콘은 숨긴다)을 받는다. 아래 미리보기는 스펙 값으로 그린 모습이다.

목록 줄의 설명 — 한 줄

식비, 신한카드, 오후 2:10
가계부 줄 — 식비 · 신한카드 · 오후 2:10
import { TagGroup, TagGroupItem } from "@/components/ui/tag-group"

<TagGroup size="t3" truncate>
  <TagGroupItem>{tx.category}</TagGroupItem>
  <TagGroupItem>{tx.assetName}</TagGroupItem>
  <TagGroupItem shrink={0}>{formatTime(tx.at)}</TagGroupItem>
</TagGroup>

앞세울 항목 · 아이콘

전월 30만원 이상, 할인형, 연회비 2만원인사팀, 10월 2일, 조회 12
카드 혜택 조건 — 전월 30만원 이상 · 할인형 / 공지 — 인사팀 · 10월 2일 · 조회 12
import { Eye } from "lucide-react"

<TagGroup>
  <TagGroupItem tone="neutral" weight="bold">전월 30만원 이상</TagGroupItem>
  <TagGroupItem>할인형</TagGroupItem>
  <TagGroupItem>연회비 2만원</TagGroupItem>
</TagGroup>

<TagGroup>
  <TagGroupItem>인사팀</TagGroupItem>
  <TagGroupItem>10월 2일</TagGroupItem>
  <TagGroupItem prefixIcon={<Eye />} srLabel="조회 12">12</TagGroupItem>
</TagGroup>

줄어드는 정도

교통, 신한카드 Deep Dream 체크(1234), 오후 2:10
분홍 칸 — 폭 220
좁은 폭 — 긴 자산 이름만 줄어든다
<TagGroup size="t3" truncate>
  <TagGroupItem shrink={0}>교통</TagGroupItem>
  <TagGroupItem shrink={2}>신한카드 Deep Dream 체크(1234)</TagGroupItem>
  <TagGroupItem shrink={0}>오후 2:10</TagGroupItem>
</TagGroup>

Behavior

인터랙션동작
누르기 · 호버 · 키보드없다 — 포커스가 서지 않는다. 줄이 눌리면 그 줄의 동작이다
폭이 좁음(wrap)낱말 단위로 줄을 바꾼다 — 구분은 앞 줄 끝에 남는다
폭이 좁음(truncate)한 줄 그대로, 줄어드는 항목이 '글 폭 × shrink' 비율로 함께 말줄임 — 첫 글자 + "…"(2.1em)에서 멈춘다. 구분 · shrink={0} 항목은 줄지 않는다. 모두 최소 폭이어도 넘치면 줄 끝이 잘린다
글자 크기 설정글이 커진다(wrap 이면 줄이 늘고, truncate 면 더 일찍 말줄임)

Accessibility

기준검증
WCAG 1.4.3 Color contrast(글자 ≥ 4.5:1)기본 fg-neutral-subtle 흰 바탕 5.50 · 다크 6.09, 회색 바탕 5.09 · 6.89 ✓(SEED 의 3.42 가 아니다). neutral 16.41 · 13.42, brand Desk 8.38 · 6.10 · HR 8.17 · 6.07 ✓. 구분 " · " fg-disabled 3.16 · 4.13 은 장식이다(보조 기술에 숨김)
WCAG 1.3.1 Info and Relationships항목 사이에 보이지 않는 ", " — 항목이 붙어 읽히지 않는다 ✓
WCAG 1.4.1 Use of color앞세운 항목은 색과 함께 굵기로도 다르다
WCAG 1.4.4 Resize text글이 커지고 줄바꿈 · 말줄임으로 넘치지 않는다 ✓
WCAG 2.5.8 Target Size — Minimum(AA ≥ 24×24)해당 없음 — 누르지 않는다
WCAG 2.5.5 Target Size — Enhanced(AAA ≥ 44×44)해당 없음 — 누르지 않는다
ARIA묶음 <span> · 역할 없음(목록 역할을 주지 않는다 — "목록, 항목 3개" 를 줄마다 읽지 않게). 구분 aria-hidden, 보이지 않는 ", " 는 sr-only 글. 아이콘 aria-hidden, srLabel 이 있으면 보이는 글을 숨기고 그 글을 읽는다. 말줄임해도 글 전체를 읽는다. 앱은 묶음을 의미 노드 하나로 합쳐 항목을 ", " 로 잇는다

Do / Don't

✅ Do

  • 메타 정보를 " · " 로 이어 짧게.
  • 앞세울 항목은 되도록 하나만 진하게.
  • 한 묶음은 한 크기.
  • 항목마다 끊어 읽게.

❌ Don't

  • 2px 점 · "•" · "|" 로 가르기.
  • 항목을 문장으로 · 조사를 붙여 길게.
  • 상태 · 분류를 Tag Group 에 — 배지다.
  • 영어 · 코드값 항목("Day 2 of 3" · "9:00 AM").

Specification

tag-group.yaml 의 규칙을 하나도 빼지 않고 조건마다 그린다 — 웹 · 앱이 Tag Group 을 만들 때 이 값을 그대로 쓴다. 조건이 없는 Base 가 모든 조합에 걸리고, 뒤의 규칙이 앞의 같은 값을 덮는다.

Base

부위상태속성값
itemenabled아이콘과 글 사이gapspacing-x0_52px아이콘 ↔ 글
iconenabled아이콘 색colorcurrentColor항목 글자색 — 뜻이 있는 아이콘(갈래 = 분할 · 눈 = 조회)은 그 항목의 읽을 글(srLabel — "분할 2건")이 뜻을 말한다. 아이콘 자신은 aria-hidden
separatorenabled구분 색foregroundfg-disabled#8A91A0다크 #838997글보다 한 단계 흐리다(흰 바탕 3.16 · 다크 4.13 — 장식, 보조 기술에 숨김)
구분 굵기fontWeight400
구분 글자glyph·앞 공백은 줄이 안 바뀌는 공백(U+00A0) · 가운뎃점(U+00B7) · 뒤 공백 — 앞 항목에 붙어 줄 끝에 남는다. 2px 점 · "•" 를 쓰지 않는다
srSeparatorenabled읽는 구분glyph,보이지 않는 글(sr-only) — 화면 읽기 프로그램이 "식비, 신한카드, 오후 2:10" 처럼 끊어 읽는다. 앱은 묶음 하나의 의미 노드에 항목을 ", " 로 이어 붙인다

size=t2

부위상태속성값
itemenabled항목 글자typographytext-t212px / 16px12 / 16 — 글자 크기 설정을 따른다
iconenabled아이콘size12px
separatorenabled구분 글자 크기typographytext-t212px / 16px

size=t3

부위상태속성값
itemenabled항목 글자typographytext-t313px / 18px13 / 18 — 글자 크기 설정을 따른다
iconenabled아이콘size13px글자 크기에 맞춘 값(SEED) — Iconography 의 16 · 20 · 24 밖
separatorenabled구분 글자 크기typographytext-t313px / 18px

size=t4

부위상태속성값
itemenabled항목 글자typographytext-t414px / 19px14 / 19 — 글자 크기 설정을 따른다
iconenabled아이콘size14px
separatorenabled구분 글자 크기typographytext-t414px / 19px

tone=neutralSubtle

부위상태속성값
itemenabled항목 글자색foregroundfg-neutral-subtle#62697A다크 #A2A8B7흰 바탕 5.50 · 다크 6.09, 회색 바탕 5.09 · 6.89

tone=neutral

부위상태속성값
itemenabled항목 글자색foregroundfg-neutral#1A1F2E다크 #F5F6FA16.41 · 13.42

tone=brand

부위상태속성값
itemenabled항목 글자색foregroundfg-brandDesk#0147AD다크 #7AA9F6HR#075B3C다크 #2ABE84Desk 8.38 · 6.10 · HR 8.17 · 6.07

weight=regular

부위상태속성값
itemenabled항목 굵기fontWeight400

weight=bold

부위상태속성값
itemenabled항목 굵기fontWeight700

overflow=wrap

부위상태속성값
rootenabled넘칠 때overflowX줄바꿈 — 낱말 단위word-break keep-all + overflow-wrap break-word(v114) — 항목 사이 · 항목 안 띄어쓰기에서 줄을 바꾸고, 한 줄보다 긴 낱말만 칸 끝에서 끊는다. 앱은 공용 글자 위젯의 이음 문자(U+2060)

overflow=truncate

부위상태속성값
rootenabled넘칠 때overflowX말줄임 — 한 줄묶음은 한 줄(inline-flex · max-width 100%) — 넘치면 항목 글이 각자 말줄임(…), 구분은 줄지 않는다
itemenabled항목 줄어듦shrink1줄어드는 정도 — 0 은 줄지 않는다. 1 이상인 항목은 넘친 폭을 '글 폭 × shrink' 비율로 나눠 함께 준다(flex-shrink — 차례대로가 아니다. 수가 클수록 · 글이 길수록 많이 준다). 금액처럼 꼭 보일 항목은 0. 글 전체는 보조 기술이 읽는다
labelenabled최소 너비minWidth2.1em줄어드는 항목도 첫 글자 + "…" 는 남긴다 — t2 25.2 · t3 27.3 · t4 29.4(100%), em 이라 글자 크기를 따라 커진다. 글이 이보다 짧은 항목(두 글자 이하)은 넓히지 않고 글 폭 그대로다. 아이콘은 이 폭 밖이라 늘 보인다. 모든 항목이 최소 폭까지 줄어도 넘치면 줄 끝이 말줄임 없이 잘린다(200% · 폭 260 에서 21). SEED 에 없는 값 — 기본을 '줄지 않음' 으로(A) · SEED 그대로(C)는 고르지 않았다(2026-10-17 사용자 결정 — 03-E 결정 5 B)
separatorenabled구분 줄어듦shrink0

SEED 와 다른 점

  • 기본 글자가 4.5:1 을 넘는다 — 기본 톤은 groo fg-neutral-subtle(흰 바탕 5.50:1)이다. SEED fg.neutral-subtle(#868b94)은 3.42:1 이다.
  • 구분 색은 fg-disabled — SEED palette gray-600 의 역할 짝(글보다 한 단계 흐리다).
  • 낱말 단위 줄바꿈 · 구분은 앞 줄 끝에 — SEED 웹은 한국어를 음절에서 끊고("3시 / 간 전") 구분 " · " 가 다음 줄 첫머리에 남는다. groo 는 v114(keep-all + break-word)로 낱말 사이에서만 끊고, 구분 앞 공백을 줄이 안 바뀌는 공백으로 둔다.
  • 끊어 읽는다 — SEED 는 구분을 숨기기만 해 "500m서초4동3분 전" 처럼 붙어 읽히고, 예제의 aria-label(span)은 무시된다. groo 는 보이지 않는 ", " 와 항목의 srLabel 을 둔다.
  • 구분 기호는 " · " 하나 — SEED 는 separator 로 바꿀 수 있다.
  • 줄어드는 항목의 최소 폭 — 한 줄 말줄임에서 항목은 첫 글자 + "…"(2.1em) 까지만 준다. SEED 는 최소 폭이 없어 좁은 줄에서 글자 조각만 남는다(2026-10-17 사용자 결정 — 03-E 결정 5 B).

Migration notes

2026-10-30 — 끝낸 줄 안

구현 검수(I-10)에서 앱 ds 가 먼저 만든 PTagTone.disabled 를 State 에 한 줄로 적었다 — 끝낸 줄 안의 Tag Group 은 모든 항목 글이 fg-disabled. 값 · 토큰 변경 없음(tag-group.yaml 은 그대로). 옛 스펙은 tag-group.history/v-pre-cleanup-1030.md.

2026-10-22 — 앞세울 항목은 되도록 하나

"앞세울 항목 하나만"(b1dfc58 — 10-03 비교 페이지에 없다)을 까닭을 붙인 권장 "되도록 하나 — 여럿을 진하게 하면 앞세움이 사라진다" 로 낮췄다(남은 규칙 R4). 사용자 결정 — https://claude.ai/artifact/Mag1tEv51MdQHdy1o8hY3L. 값 변경 없음.

2026-10-17 — 줄어드는 항목의 최소 폭 · shrink 문장(03-E 결정 5 B)

구현 조사에서 모든 항목이 기본 shrink 1 · 최소 폭 0 이면 폭 200 에서 짧은 시각 · 분할이 18.8 · 16.6px(200% 에서 21 · 19)의 글자 조각이 되는 것을 찾았다. 사용자가 비교 페이지에서 "줄어드는 항목도 첫 글자 + … 까지만"(B)을 골랐다 — tag-group.yaml 의 label.minWidth 2.1em. 같은 페이지가 바로잡은 대로 shrink 문장 "수가 클수록 먼저" 를 "글 폭 × shrink 비율로 함께" 로 고쳤다(브라우저는 차례대로 줄이지 않는다). 레시피 TagGroupItem 은 항목 칸에 최소 폭(2.1em + 아이콘 · 사이, 두 글자 이하면 글 폭)을 준다 — 글 칸(overflow hidden)에 주면 항목의 최소 크기로 올라가지 않아 줄 전체가 줄지 않는다. 웹 ds TagGroup 도 같게, 앱은 항목을 ConstrainedBox(minWidth: 첫 글자 + … 폭 + 아이콘)(글이 더 짧으면 글 폭)로. 지금 Desk 화면은 Tag Group 을 아직 쓰지 않는다. 옛 스펙은 tag-group.history/v-pre-03e-03b.*.

2026-10-03 — 새로 둔다(SEED Tag Group)

사용자가 비교 페이지의 "따라오는 것" 으로 정했다 — 메타 줄은 Tag Group(항목 사이 " · " 글자, 12/16 기본 · 13/18 · 14/19, 글자 fg-neutral-subtle, 구분 fg-disabled, 넘치면 낱말 단위 줄바꿈 또는 한 줄 말줄임, 낭독은 항목마다 끊어). 웹 2px 점 · HR "•" 는 걷는다. DESIGN.md Caption 절의 메타 줄 규칙("닉네임 + · + 시간")은 이 스펙을 가리킨다.

제품은 앱 적용 단계에서 옮긴다(2026-10-03 조사).

  • 메타 줄 구분이 세 가지 — Desk 웹은 2 × 2 점 그림(shared/ui/groo/ledger.tsx:639-652 LedgerRowSep · 할 일 TodoPage.tsx:789-795, --border-strong 3.72 · 4.80), Desk 앱은 " · " 글자 합치기(features/expense/presentation/widgets/expense_row.dart:199-209 — 할 일만 2px 점 todo_screen.dart:1266-1282), HR 은 "•"(admin-notice/ui/NoticeList.tsx:61 · 63 · admin-holiday/ui/HolidayList.tsx:69, 3.07 · 3.96).
  • 웹의 글자 "·" 세 벌 — 코드 86줄 · 39파일과 번역 177행에 " · " · "·"(StatsPage.tsx:1786) · &nbsp;·(ExpensePage.tsx:2196)가 섞였다.
  • 웹 · 앱 항목이 다르다 — 가계부 줄이 웹은 분류 · 자산 · 시각, 앱은 분류 · 자산 · 할부 N개월이다. 앱 적용 때 한 순서로 맞춘다.
  • 아이콘 + 숫자가 숫자만 읽힘 — 분할 개수(웹 entities/expense/ui/expense-row.tsx:86-103)는 "2" 로만, HR 공지 조회수(눈 아이콘 + 숫자)는 아이콘 이름이 없다 → srLabel("분할 2건" · "조회 12").
  • 영어 표기 — HR 일정 칩 "Day 2 of 3 •" · "9:00 AM"(calendar/ui/month-view/month-event-badge.tsx:118-133 · agenda-view/agenda-event-card.tsx:85-88) → "2/3일째" · "오전 9:00"(International Design v106).

이 페이지