Progress
"얼마나 찼나" 를 보이는 막대 — 예산 · 카드 한도처럼 쓸수록 차는 것, 저축 목표 · 카드 실적처럼 모을수록 차는 것. 이름 · 오른쪽 글 · 막대 · 금액 줄이 한 묶음이다. 불러오기나 올리기 · 받기의 진행에는 쓰지 않는다 — 그건 Progress Circle 이다.
SEED 에는 선형 막대 컴포넌트가 없다 — Loading 패턴에 "Progress Bar" 라는 말만 있고 rootage · React · Figma 어디에도 없다(SEED 는 진행을 값 있는 Progress Circle 로 그린다). 그래서 groo 만의 부품이다 — 높이 하나(8) · 모서리 full · 색 하나(브랜드), 넘친 한도만 위험 색. 값은 groo 토큰이다(2026-10-03 사용자 결정). 옛 Progress 스펙(높이 2 · 4 · 8 · 진행 · 흐르는 막대 · 100% 에서 성공 색)을 대신한다.
수치 원본은 progress.yaml이다. 수치 표 자리([표: …])와 그림 자리([그림: …])는 사이트가 그 파일로 그린다 — GitHub 에서는 그 파일 · 그림 코드로 가는 링크로 보인다.
직접 골라 보기
한도 · 목표, 값과 목표, 놓인 면을 고르면 스펙대로 그린 막대와 그 코드가 바뀐다. 값을 옮기면 채움이 따라 찬다.
import { Progress } from "@/components/ui/progress"
<Progress label="식비 예산" value={352000} max={400000} />Anatomy
| 부위 | 설명 |
|---|---|
| ⓐ Label | 이름 — 무엇이 얼마나 찼나. |
| ⓑ Status | 오른쪽 글 — 비율 · "N원 초과" · "달성". |
| ⓒ Track | 트랙 — 막대 바탕. |
| ⓓ Fill | 채움 — 값만큼, 넘쳐도 끝까지만. |
| ⓔ Amount | 금액 줄 — "현재 / 목표". |
부위
| 부위 | 설명 |
|---|---|
root | 묶음 — 이름 줄 · 막대 · 금액 줄 |
header | 이름 줄 — 이름과 오른쪽 글을 양 끝에, 글자 바탕선 맞춤 |
label | 이름 — 무엇이 얼마나 찼나(식비 예산 · 여행 자금) |
status | 오른쪽 글 — 비율 · "N원 초과" · "달성" |
track | 트랙 — 막대 바탕(값이 0 이어도 보인다) |
fill | 채움 — 값만큼, 넘쳐도 끝까지만 |
amount | 금액 줄 — "현재 / 목표" |
Properties
막대 — 높이 하나 · 색 하나
높이 8 · 모서리 full, 트랙 bg-neutral-weak, 채움은 브랜드 글자색(fg-brand — 다크는 밝은 짝)이다. 화면의 요약 머리든 목록 줄이든 같다 — 크게 보일 것은 막대가 아니라 위의 금액(제목)이다. 위에 이름(14 · 500)과 오른쪽 글(13), 아래에 금액 줄(12 · fg-neutral-subtle)을 두고 사이는 6 이다. 이름과 오른쪽 글은 양 끝에 두고 사이는 적어도 8 — 이름이 길면 줄을 바꿔 오른쪽 글에 붙지 않는다. 오른쪽 글(+ 사이 8)이 이름의 가장 긴 낱말 자리도 남기지 못하면(큰 글자 · 긴 금액) 오른쪽 글을 이름 아래 오른쪽 끝으로 내린다 — 차례는 이름 → 오른쪽 글 → 막대이고, 오른쪽 글은 자르지 않는다. List 의 "큰 글자에서 값을 본문 아래로" 와 같은 결이다(2026-10-30 28-2 — 앱 통계 비교 막대 줄). 트랙이 페이지 바탕과 같은 색이라 흰 면(카드 · 시트) 위에 둔다.
큰 글자에서 글(이름 · 오른쪽 글 · 금액 줄)은 두 플랫폼 모두 글자 크기 설정을 따른다. 막대는 웹이 rem 이라 배율대로 커지고(200% 에서 16), 앱은 8 그대로다 — 같은 설정에서 웹 막대가 앱보다 굵다(2026-10-17 사용자 결정 — 03-E 결정 1 C, Chip 의 큰 글자와 같은 결정).
요약 머리든 목록 줄이든 같은 막대다 — 크게 보일 것은 막대가 아니라 위의 금액이다. 트랙이 페이지 바탕과 같은 색이라 흰 면(카드 · 시트) 위에 둔다(그림은 1.5배)
공통
| 부위 | 속성 | 값 | 비고 |
|---|---|---|---|
root | 간격 | spacing-x1_5 6px | 이름 줄 ↔ 막대 ↔ 금액 줄 6 |
header | 이름 ↔ 오른쪽 글 | spacing-x2 8px | 이름 ↔ 오른쪽 글 — 적어도 8. 이름이 길면 줄을 바꿔 오른쪽 글에 붙지 않는다(2026-10-08 — 전엔 레시피에만 있었다) |
label | 글자 | text-t4 14px / 19px | |
label | 굵기 | 500 | |
label | 글자·아이콘 | color-fg-neutral #1A1F2E · 다크 #F5F6FA | |
status | 글자 | text-t3 13px / 400 / 18px | 이름 줄 오른쪽 끝, 글자 바탕선 맞춤 — 숫자 폭을 같게(tabular-nums). 비율은 반올림한 정수("88%") |
status | 글자·아이콘 | color-fg-neutral-subtle #62697A · 다크 #A2A8B7 | |
track | 높이 | 8px | 웹은 rem 이라 글자 크기 설정의 배율대로 커진다(200% 에서 16). 앱은 8 그대로 — 글이 없는 상자라 OS 글자 크기를 따르지 않는다. 이름 · 오른쪽 글 · 금액 줄은 두 플랫폼 모두 글자 크기를 따른다(2026-10-17 사용자 결정 — 03-E 결정 1 C) |
track | 모서리 | radius-full 9999px | |
track | 배경 | color-bg-neutral-weak #F5F6FA · 다크 #353B4D | 흰 면 위 1.08 · 다크 1.30 — 장식(값은 채움이 보인다). 흰 면 위에 둔다 |
fill | 너비 | 값 ÷ 목표(최대 100%) | 넘쳐도 끝까지만 채운다. 값이 0 보다 크면 적어도 높이만큼(8) — 둥근 끝이 찌그러지지 않게 |
fill | 모서리 | radius-full 9999px | |
fill | 배경 | color-fg-brand HR #075B3C · Desk #0147AD | 브랜드 글자색 — 다크는 밝은 짝. 트랙과 Desk 7.76 · 다크 4.69, HR 7.56 · 4.67 |
fill | 전환 대상 | width | |
fill | 전환 시간 | motion-duration-d6 300ms | |
fill | 전환 곡선 | motion-ease-enter cubic-bezier(0, 0, 0.15, 1) | |
amount | 글자 | text-t2 12px / 400 / 16px | |
amount | 글자·아이콘 | color-fg-neutral-subtle #62697A · 다크 #A2A8B7 | |
amount | 숫자 폭 | tabular-nums | "350,000원 / 400,000원" — 현재 / 목표 |
Meaning — 한도 · 목표
| 값 | 쓰는 곳 | 100% 를 넘으면 |
|---|---|---|
limit (기본) | 예산 · 카드 한도(쓸수록 찬다) | 채움을 끝까지 + 위험 색(fg-critical) + 오른쪽 글 "N원 초과" |
goal | 저축 목표 · 카드 실적(모을수록 찬다) | 끝까지 + 오른쪽 글 "달성" — 색은 그대로 |
State
| 상태 | 모습 |
|---|---|
enabled | 0 ~ 100% — 채움 브랜드, 오른쪽 글 비율("88%") |
over | 한도를 넘음(limit) — 채움 끝까지 · 위험 색, 오른쪽 글 "20,000원 초과"(위험 색 · 700) |
reached | 목표에 닿음(goal) — 채움 끝까지, 오른쪽 글 "달성"(본문 색 · 700). 색은 바꾸지 않는다 |
enabled — 0 ~ 100% — 채움 브랜드, 오른쪽 글 비율 · 라이트 · 다크over — 한도를 넘음 — 끝까지 위험 색, "N원 초과" · 라이트 · 다크reached — 목표에 닿음 — 끝까지, 글 "달성" 만 · 라이트 · 다크상태
| meaning | over 한도를 넘음(limit) — 채움을 끝까지 + 위험 색 + "N원 초과" | reached 목표에 닿음(goal) — 글 "달성", 색은 그대로 |
|---|---|---|
limit | status 글자·아이콘 color-fg-critical #D72323 · 다크 #FF8477 — "20,000원 초과" — 흰 면 위 5.06 · 다크 6.08 · status 굵기 700 · fill 너비 100% — 끝까지 — 얼마나 넘었는지는 글이 말한다 · fill 배경 color-fg-critical #D72323 · 다크 #FF8477 — 트랙과 4.68 · 다크 4.68 | — |
goal | — | status 글자·아이콘 color-fg-neutral #1A1F2E · 다크 #F5F6FA — "달성" — 색을 바꾸지 않는다(사용자 결정) · status 굵기 700 · fill 너비 100% — 넘어도 끝까지만 — 색은 그대로 브랜드 |
모션
| 전환 | 시간 | 곡선 | 대상 | 비고 |
|---|---|---|---|---|
채움 | motion-duration-d6 300ms | motion-ease-enter cubic-bezier(0, 0, 0.15, 1) | width | 값이 바뀔 때만 — 처음 그릴 때는 움직이지 않는다. 모션 줄이기면 바로 |
Guidelines
막대는 미터다 — 기다림에 쓰지 않는다
막대는 범위가 정해진 값이 얼마나 찼는지를 보인다. 불러오는 동안 · 올리기 · 받기의 진행은 Progress Circle 이다(값을 모르면 도는 원, 알면 채우는 원). 값을 모른 채 흐르는 막대는 두지 않는다.
넘친 한도 — 끝까지 + "N원 초과"
쓴 돈이 한도를 넘으면 채움을 끝까지 칠하고 위험 색으로 바꾼다. 얼마나 넘었는지는 막대가 아니라 오른쪽 글이 말한다 — "20,000원 초과". 막대를 100% 너머로 늘이거나 넘친 만큼 다른 색 조각을 잇지 않는다.
목표에 닿으면 글자만
저축 · 실적이 목표에 닿으면 오른쪽 글을 "달성" 으로 바꾼다 — 막대 색은 브랜드 그대로다. 성공 색 · 축하 모양을 더하지 않는다. 넘어도(130%) 막대는 끝까지만 차고, 금액 줄이 실제 값을 보인다.
주의 구간 색은 없다
한도에 가까워져도(85% 같은) 색을 바꾸지 않는다 — 막대의 색은 브랜드 · 위험 둘뿐이다(사용자 결정). 가까워졌다는 알림은 사용자가 정한 예산 알림 기준이 알린다.
글
- 이름은 무엇의 막대인지 — "식비 예산" · "여행 자금" · "현대카드 M 전월 실적".
- 오른쪽 글은 반올림한 정수 비율 — "88%". 넘치면 "20,000원 초과", 닿으면 "달성". 마침표 없이.
- 금액 줄은 "현재 / 목표" — "350,000원 / 400,000원". 돈이 아닌 값은 그 단위로("6시간 / 8시간").
- 영어 · 코드값 · 카드사의 원색을 쓰지 않는다.
코드
레시피 recipes/shadcn/components/ui/progress.tsx 를 쓴다. 아래 미리보기는 스펙 값으로 그린 모습이다.
Progress— 이름 줄 · 막대 · 금액 줄 한 묶음.label(이름),value,max,meaning("limit"기본 ·"goal"),formatValue(기본"350,000원"꼴 — 원 단위).ProgressBar— 막대만(이름 · 글을 직접 그릴 때).value·max·meaning과 이름(aria-label) · 값 글(aria-valuetext)을 꼭 준다.- 막대는
role="meter"다 — 이름 "{이름} {목표} 중 {현재}", 값 글은 오른쪽 글과 같은 말. 보이는 이름 · 오른쪽 글 · 금액 줄은 보조 기술에 숨긴다(같은 말을 두 번 읽지 않게).
예산 — 한도
import { Progress } from "@/components/ui/progress"
<Progress label="식비 예산" value={350000} max={400000} />
{/* 넘치면 — 끝까지 위험 색, 오른쪽 "20,000원 초과" */}
<Progress label="교통 예산" value={120000} max={100000} />저축 목표 · 카드 실적 — 목표
<Progress meaning="goal" label="여행 자금" value={1200000} max={2000000} />
<Progress meaning="goal" label="현대카드 M 전월 실적" value={390000} max={300000} /> {/* "달성" — 막대는 끝까지 */}
{/* 돈이 아닌 값 — 단위를 바꾼다 */}
<Progress meaning="goal" label="오늘 근무" value={6} max={8} formatValue={(h) => `${h}시간`} />Behavior
| 인터랙션 | 동작 |
|---|---|
| 값이 바뀜 | 채움이 300ms 로 따라 찬다 — 처음 그릴 때는 움직이지 않는다 |
| 한도를 넘음 | 채움 끝까지 · 위험 색, 오른쪽 글 "N원 초과" |
| 목표에 닿음 | 채움 끝까지, 오른쪽 글 "달성" — 색은 그대로 |
| 모션 줄이기 | 채움이 바로 바뀐다 |
| 누르기 | 막대는 누르지 않는다 — 줄 전체가 상세로 가면 List 줄이 맡는다 |
Accessibility
| 기준 | 검증 |
|---|---|
| WCAG 1.4.3 Color contrast(글자 ≥ 4.5:1) | 이름 fg-neutral 흰 면 위 16.41 · 다크 13.42, 비율 · 금액 fg-neutral-subtle 5.50 · 6.09(떠 있는 면 5.27), "N원 초과" fg-critical 5.06 · 6.08 ✓ |
| WCAG 1.4.4 Resize text | 이름 · 오른쪽 글 · 금액 줄이 글자 크기 설정을 따른다 ✓ — 막대는 웹 rem(배율대로) · 앱 8 그대로 |
| WCAG 1.4.11 Non-text contrast(≥ 3:1) | 채움 : 트랙 Desk 7.76 · 다크 4.69, HR 7.56 · 4.67, 넘침 4.68 · 4.68 ✓. 트랙 : 바탕 1.08 · 1.30 — 장식(막대의 끝은 금액 줄이 말한다) |
| WCAG 1.4.1 Use of color | 넘침은 색과 함께 "N원 초과" 글, 달성은 글로만 ✓ |
| WCAG 4.1.2 Name, Role, Value | role="meter" + 이름 "식비 예산 400,000원 중 350,000원" + aria-valuemin 0 · aria-valuemax 목표 · aria-valuenow(목표를 넘으면 목표) + aria-valuetext("88%" · "20,000원 초과" · "달성") ✓ |
| WCAG 2.3.3 Animation from Interactions | 모션 줄이기면 채움이 바로 바뀐다 ✓ |
| WCAG 2.5.8 Target Size — Minimum(AA ≥ 24×24) | 누르는 것이 없다 — 해당 없음 |
| WCAG 2.5.5 Target Size — Enhanced(AAA ≥ 44×44) | 누르는 것이 없다 — 해당 없음 |
| ARIA | 보이는 글(이름 · 오른쪽 글 · 금액 줄)은 aria-hidden — 미터의 이름 · 값 글이 같은 말이다. 미터를 모르는 보조 기술에서도 이름 · 값 글은 읽힌다. 앱은 Semantics(label: 이름, value: 값 글) |
Do / Don't
✅ Do
- 막대 하나, 높이 8 · 브랜드 채움 — 요약 머리든 목록 줄이든.
- 넘친 한도는 끝까지 + 위험 색 + "N원 초과".
- 목표에 닿으면 "달성" 글자만.
- 보조 기술에는 미터로 — "식비 예산 400,000원 중 350,000원".
❌ Don't
- 높이를 자리마다 다르게(6 · 7 · 10 · 12 · 16).
- 주의 구간 주황 · 달성 초록 · 카드사 원색(장미 · 호박 · 초록).
- 다크에서 채움 색(
bg-brand-solid) — 트랙에 묻힌다(1.33:1). - 불러오기 · 올리기 진행을 막대로 · 값 모르는 흐르는 막대.
- 넘친 만큼 막대를 더 그리기.
Specification
progress.yaml 의 규칙을 하나도 빼지 않고 조건마다 그린다 — 웹 · 앱이 막대를 만들 때 이 값을 그대로 쓴다. 조건이 없는 Base 가 모든 조합에 걸리고, 뒤의 규칙이 앞의 같은 값을 덮는다. 상태는 enabled 에서 바뀌는 값만 적었다.
Base
| 부위 | 상태 | 속성 | 값 |
|---|---|---|---|
root | enabled | 간격gap | spacing-x1_56px이름 줄 ↔ 막대 ↔ 금액 줄 6 |
header | enabled | 이름 ↔ 오른쪽 글gap | spacing-x28px이름 ↔ 오른쪽 글 — 적어도 8. 이름이 길면 줄을 바꿔 오른쪽 글에 붙지 않는다(2026-10-08 — 전엔 레시피에만 있었다) |
label | enabled | 글자·아이콘foreground | fg-neutral#1A1F2E다크 #F5F6FA |
| 글자typography | text-t414px / 19px | ||
| 굵기fontWeight | 500 | ||
status | enabled | 글자·아이콘foreground | fg-neutral-subtle#62697A다크 #A2A8B7 |
| 글자typography | text-t313px / 18px / 400이름 줄 오른쪽 끝, 글자 바탕선 맞춤 — 숫자 폭을 같게(tabular-nums). 비율은 반올림한 정수("88%") | ||
track | enabled | 높이height | 8px웹은 rem 이라 글자 크기 설정의 배율대로 커진다(200% 에서 16). 앱은 8 그대로 — 글이 없는 상자라 OS 글자 크기를 따르지 않는다. 이름 · 오른쪽 글 · 금액 줄은 두 플랫폼 모두 글자 크기를 따른다(2026-10-17 사용자 결정 — 03-E 결정 1 C) |
| 모서리radius | radius-full9999px(알약) | ||
| 배경background | bg-neutral-weak#F5F6FA다크 #353B4D흰 면 위 1.08 · 다크 1.30 — 장식(값은 채움이 보인다). 흰 면 위에 둔다 | ||
fill | enabled | 너비width | 값 ÷ 목표(최대 100%)넘쳐도 끝까지만 채운다. 값이 0 보다 크면 적어도 높이만큼(8) — 둥근 끝이 찌그러지지 않게 |
| 모서리radius | radius-full9999px(알약) | ||
| 배경background | fg-brandDesk#0147AD다크 #7AA9F6HR#075B3C다크 #2ABE84브랜드 글자색 — 다크는 밝은 짝. 트랙과 Desk 7.76 · 다크 4.69, HR 7.56 · 4.67 | ||
| 전환 대상transitionProperty | width | ||
| 전환 시간transitionDuration | motion-duration-d6300ms | ||
| 전환 곡선transitionEasing | motion-ease-entercubic-bezier(0, 0, 0.15, 1) | ||
amount | enabled | 글자·아이콘foreground | fg-neutral-subtle#62697A다크 #A2A8B7 |
| 글자typography | text-t212px / 16px / 400 | ||
| 숫자 폭numerals | tabular-nums"350,000원 / 400,000원" — 현재 / 목표 |
meaning=limit
| 부위 | 상태 | 속성 | 값 |
|---|---|---|---|
status | over | 글자·아이콘foreground | fg-critical#D72323다크 #FF8477"20,000원 초과" — 흰 면 위 5.06 · 다크 6.08 |
| 굵기fontWeight | 700 | ||
fill | over | 너비width | 100%끝까지 — 얼마나 넘었는지는 글이 말한다 |
| 배경background | fg-critical#D72323다크 #FF8477트랙과 4.68 · 다크 4.68 |
meaning=goal
| 부위 | 상태 | 속성 | 값 |
|---|---|---|---|
status | reached | 글자·아이콘foreground | fg-neutral#1A1F2E다크 #F5F6FA"달성" — 색을 바꾸지 않는다(사용자 결정) |
| 굵기fontWeight | 700 | ||
fill | reached | 너비width | 100%넘어도 끝까지만 — 색은 그대로 브랜드 |
SEED 와 다른 점
- SEED 에는 선형 막대가 없다 — groo 만의 부품이다. SEED 가 진행에 쓰는 값 있는 Progress Circle(올리기 · 당겨서 새로 고침)은 groo 도 그대로 쓰고, 막대는 "얼마나 찼나" 를 보이는 미터로만 둔다.
- 미터는
role="meter"로 읽힌다 — 진행(progressbar)과 나눈다.
Migration notes
2026-10-30 — 오른쪽 글이 들어갈 자리가 없을 때
"막대 — 높이 하나 · 색 하나" 에 한 줄을 더했다 — 오른쪽 글이 이름의 가장 긴 낱말 자리도 못 남기면 이름 아래 오른쪽 끝으로 내린다(28-2 앱 _CompareBar 가 먼저 한 모양). 통계 비교 막대 줄(이름 | 막대 | 금액 한 줄)이 Progress 인지 Chart 인지는 정하지 않았다. 값 변경 없음. 옛 스펙은 progress.history/v-pre-cleanup-1030.md.
2026-10-17 — 큰 글자에서 막대(03-E 결정 1 C)
웹은 그대로(rem — 200% 에서 막대 16), 앱은 8 그대로다. 글이 상자를 넘지 않는다는 규칙 하나만 두 플랫폼이 같다 — 같은 설정에서 웹 막대가 앱보다 굵다. 고칠 것은 없다(웹 h-2 · 앱 8 고정이 이미 그렇다). 앱도 배율대로(A) · 두 플랫폼 px(B)는 고르지 않았다. 비교 페이지 https://claude.ai/artifact/FKYaqu7zAR5T2HVwFnx5oD · 옛 스펙 progress.history/v-pre-03e-03b.*.
2026-10-08 — 이름 ↔ 오른쪽 글 사이를 YAML 에
이름 줄 안의 이름 ↔ 오른쪽 글 사이 8 이 레시피(gap-x2)와 그 주석에만 있었다 — YAML 대로 만들면 사이가 0 이라, 이름이 길면 글이 오른쪽 글에 붙는다(desk-front #428). progress.yaml 에 이름 줄(header)과 그 사이($spacing-x2)를 적었다. 모습은 레시피 그대로다. 사용자 결정 — 비교 페이지 5.
2026-10-03 — 미터로 다시 둔다
사용자가 비교 페이지에서 정했다 — 색 하나 · 높이 하나(늘 브랜드 글자색, 넘친 예산만 위험 색 + "N원 초과"(끝까지 채움), 달성은 글자만, 높이 8, 트랙 bg-neutral-weak). 뜻에 따라 두 벌(주의 구간 · 달성 색) · 높이 둘(요약 10 · 줄 6)은 고르지 않았다. 옛 Progress(높이 2 · 4 · 8 · 진행 · 흐르는 막대 · 100% 에서 성공 색 · 브랜드 채움 색)는 걷었다 — 옛 스펙은 progress.history/v-pre-seed-loading.*. 진행(올리기 · 받기)은 값 있는 Progress Circle 24 로 옮긴다.
제품은 앱 적용 단계에서 옮긴다(2026-10-03 조사 — Desk 웹 · HR 은 크로미움에 띄워 쟀고, Desk 앱은 위젯 테스트로 쟀다).
- Desk 웹 — 손 막대 20여 곳의 높이가 6 · 7 · 8 · 10 · 12 이고 역할이 하나도 없다(낭독기에 값이 가지 않는다). 예산 막대(
shared/styles/groo.css:562-582— 안내 · 주의 · 위험 세 색, 채움 전환이 꺼져 있다groo.css:575), 예산 페이스(pages/budget/ui/BudgetPage.tsx:881— 다크에서 채움 색 그대로 1.5:1), 카드 사용(AssetPage.tsx:1176-1181— 다크에서 라이트 경고 · 위험 색 2.7 · 2.6), 저축(AssetPage.tsx:827-845·SavingGoalManager.tsx:267·SavingGoalAddDialog.tsx:311), 신용 한도(AssetDetailDialog.tsx:1336). 카드 실적은 Tailwind 원색 장미 · 호박 · 초록(70% 에서 바뀜)으로 트랙과 1.91 ~ 3.35:1, "130% 달성" 글 3.22:1(features/card-performance/ui/CardPerformanceBar.tsx:21-53). - Desk 앱 —
LinearProgressIndicator13곳 + 홈 손 막대 1(dashboard/dashboard_screen.dart:1404-1430— 의미 없음), 높이 6 · 8 · 10 · 12. 이름 없이 값 "50" 만 읽힌다. 카드 실적은 브랜드 → 성공 색(card/card_performance_bar.dart:79-81 · 115-120, 다크 2.51:1)으로 웹과 색 · 문턱이 다르다. 앱 업데이트 받기 막대(update/update_gate_screen.dart:304-309·settings/update_screen.dart:262)는 값 있는 원으로. - HR 웹 —
Progress래퍼가 값을 Radix 에 넘기지 않아 모든 막대가 '값 모름'으로 읽힌다(shared/ui/shadcn/progress.tsx:10-24). 승인률 · 오늘 근무 시간 2곳(vacation-application/ui/VacationRequestStatsItem.tsx:131·dashboard/ui/widgets/TodayWorkStatus/TodayWorkStatusContent.tsx:54-60— 초록 2.09 · 주황 2.72:1). - 앱 적용 때 화면마다 정할 자리 — 예산 페이스(오늘 표시 2 × 18 을 얹은 막대), 할 일 완료 · 더치페이 정산 · 분할 비율 막대(
TodoPage.tsx:600·DutchPayPage.tsx:937·TxDetailDialog.tsx:720)가 미터인지, 통계의 막대(차트라 이 막대가 아니다).
Progress Circle
작업이 진행 중임을 알리는 원 — 값을 모르면 호가 늘었다 줄며 돌고, 값을 알면 12시부터 값만큼 채운다. 섹션 하나를 새로 고칠 때 · 목록 끝을 더 불러올 때 · 구조를 미리 그릴 수 없는 화면을 기다릴 때 · 올리기 · 받기에 쓴다. 목록 · 카드처럼 구조가 보이는 자리를 처음 불러올 때는 Skeleton, 저장 버튼은 Button 의 로딩이다. 앱의 당겨서 새로 고침도 이 원이다(아래 "당겨서 새로 고침").
Quantity Picker
작은 정수를 한 단계씩 늘리고 줄이는 컨트롤 — 승인 필요 횟수(0 ~ 3) · 반복 간격 · 부여 시간(0 ~ 7시간)처럼 흔한 값이 열 단계 안쪽인 수를 받는다. 흔한 값이 더 멀거나 돈 · 소수면 Input 의 숫자 칸, 날짜 부분(1 ~ 31일)이나 띄엄띄엄 이름 붙은 값(할부)은 Select, 범위 안의 자리(임계값)는 Slider 다.