보이는 것을 정할 때 읽는 문서

디자인 가이드

“남은 시간만 보여 주지 말고 날짜가 포함된 마감 시각을 같이 적는다” 같은 기준이 여기 있습니다. 본문 최대 폭 1280px 도 여기서 정해졌습니다.

13,507자 · 시스템이 만든 그대로입니다

사람이 손댄 곳 2군데
  • · 문서와 화면 목록은 손대지 않았습니다. 이 사례에서 사람이 한 일은 수정 요청을 적어 보낸 것과, 검토가 되물은 것에 답한 것뿐입니다.
  • · 아래 ‘고쳐 가는 과정’의 요청문·검토문은 실제로 오간 원문입니다. 줄이거나 다듬지 않았습니다.

DESIGN CONTRACT V1

동네 필라테스 예약과 대기 순번 디자인 가이드

공정한 대기 순서와 처리 근거를 가장 먼저 보여주는 차분한 운영형 UI다. 회원 화면은 카카오톡·문자 링크에서 바로 행동할 수 있도록 한 화면에 하나의 주요 행동만 강조한다. 원장 화면은 현재 정원과 처리 필요 상태를 먼저 요약하고, 취소·대기 제안·회원 응답·원장 최종 예약 승인·회원권 이력을 시간순으로 연결한다. 장식적인 필라테스 이미지보다 상태, 마감 시각, 기록의 정확성을 우선한다.

공정한 대기 순번 · 차분한 신뢰감 · 모바일 예약 · 명확한 마감 시각 · 처리 필요 우선 · 시간순 이력 · 개인정보 최소 노출 · 원장 최종 예약 승인

레이아웃
Mobile first
기본 글꼴
Pretendard Variable
조사 출처
8곳

COLOR SYSTEM

컬러 시스템

각 토큰의 실제 색상과 사용 맥락의 본문 대비를 보여 줍니다. AA 기준은 4.5:1입니다.

#F7F8F6

Canvas

15.59:1 · AA

전체 페이지 배경

#FFFFFF

Surface

16.61:1 · AA

카드, 입력 영역, 모달과 상세 패널 배경

#18201E

Text Primary

15.59:1 · AA

제목, 본문, 핵심 수치

#53615D

Text Secondary

6.09:1 · AA

보조 설명, 시각과 메타데이터

#D6DEDB

Border

12.13:1 · AA

카드 구분선, 입력 테두리, 표 구분선

#176B5B

Primary

2.60:1 · 큰 글자용

예약, 대기 신청, 수락하고 승인 요청, 저장 등 주요 행동

#0F574A

Primary Strong

1.96:1 · 큰 글자용

주요 버튼 hover·pressed 상태

#E7F3F0

Primary Soft

14.62:1 · AA

선택 상태, 대기 순번 요약, 차분한 강조 배경

#245EA8

Info

2.56:1 · 큰 글자용

수락 대기, 안내, 링크와 정보성 배지

#EAF2FC

Info Soft

14.72:1 · AA

정보성 알림과 수락 대기 배경

#237A45

Success

3.12:1 · 큰 글자용

예약 확정, 출석, 발송 성공, 처리 완료

#EAF6EE

Success Soft

14.96:1 · AA

성공 알림과 예약 확정 배경

#8A4B08

Warning

2.44:1 · 큰 글자용

승인 대기, 12시간 이내 취소, 보류, 마감 임박

#FFF4E5

Warning Soft

15.29:1 · AA

원장 확인 필요와 마감 임박 알림 배경

#B42318

Danger

2.53:1 · 큰 글자용

노쇼, 오류, 문자 실패, 취소와 반려 같은 파괴적 행동

#FDECEC

Danger Soft

14.54:1 · AA

오류와 위험 알림 배경

#155EEF

Focus

3.07:1 · 큰 글자용

키보드 초점 표시

#AAB5B1

Disabled

1.98:1 · 큰 글자용

비활성 배경과 테두리 전용이며 작은 글자색으로 사용하지 않음

TYPOGRAPHY

한글 타이포그래피

제목 · -0.025em

흙에서 완성까지, 한눈에

본문 · -0.01em

작품의 현재 단계와 선반 위치를 기록하고, 다음 가마에 넣을 작품을 빠르게 확인합니다.

가마 02 · 1,250°C · 8–11시간

SPACING & RADIUS

간격과 형태

4px
8px
12px
16px
20px
24px
32px
40px
48px
64px
80px
sm
6px
md
10px
lg
16px
full
9999px

RESPONSIVE LAYOUT

그리드와 화면 전략

회원은 카카오톡 등에 공유된 링크를 휴대폰에서 열고 휴대폰 본인 확인, 예약, 취소, 대기 신청, 빈자리 수락을 수행한다. 원장도 프런트 직원 없이 수업 사이에 휴대폰으로 핵심 처리를 할 가능성이 높으므로 좁은 화면에서 모든 조회와 승인이 가능해야 한다. lg 이상에서는 원장용 표, 타임라인, 상세 패널을 동시에 보여주는 12열 레이아웃으로 확장한다.

모바일 · 4

데스크톱 · 12

sm
480px
md
768px
lg
1024px
xl
1440px
최대 폭
1280px

COMPONENTS

컴포넌트와 상태

계약 토큰을 적용한 버튼·입력·카드 견본과 구현 규칙입니다.

버튼

입력 상태

물레컵 3점

초벌 대기

2번 선반 · 1칸
예상 완료 9월 18일

AppShell

member · owner · default · loading · unauthorized

회원 화면은 최대 560px 단일 열과 하단 주요 행동을 사용한다. 원장 화면은 모바일에서 단일 열, lg 이상에서 좌측 내비게이션과 최대 1280px 본문을 사용한다. 권한이 없으면 운영 데이터가 잠깐이라도 노출되지 않게 한다.

TopNavigation

member-simple · owner-global · detail-back · default · scrolled

회원용 링크 화면은 스튜디오명과 뒤로가기만 제공한다. 원장용은 수업 현황, 회원 기록을 주요 메뉴로 두고 수업 등록과 회원 등록은 관련 화면 안의 행동으로 제공한다.

Button

primary · secondary · tertiary · danger · icon · default · hover · focus · pressed · loading · disabled

높이는 기본 48px, 조밀한 원장 표 안에서는 40px로 한다. 모바일 주요 버튼은 가로 폭을 채운다. 저장·수락 요청 중에는 중복 클릭을 막고 동작형 문구와 진행 표시를 함께 보여준다.

StatusBadge

neutral · info · success · warning · danger · 대기 중 · 수락 대기 · 대기 수락 만료 · 승인 대기 · 예약 확정 · 취소 완료 · 출석 · 지각 출석 · 노쇼 · 보류 · 휴강 · 오류

색상과 함께 상태 문구와 아이콘을 표시한다. 예약 확정, 수락 대기, 승인 대기를 같은 색이나 같은 문구로 표현하지 않는다.

ClassCard

member · owner · compact · 예약 가능 · 마감 · 대기 가능 · 예약 확정 · 대기 중 · 수락 대기 · 승인 대기 · 휴강 · 신청 종료

날짜, 시작·종료 시각, 수업명, 정원, 확정 인원 또는 잔여석, 대기 상태를 표시한다. 회원용 카드는 현재 가능한 다음 행동 하나를 명확히 제공하고, 원장용 카드는 처리 필요 상태와 마감 시각을 우선 표시한다.

CapacitySummary

member · owner · available · full · offering · held · over-capacity-error

회원에게는 정원과 잔여석 또는 마감 상태만 제공한다. 원장에게는 정원, 예약 확정, 승인 대기 좌석, 즉시 배정 가능한 좌석, 대기 인원을 분리해 표시한다.

DateNavigator

day-strip · calendar-popover · owner-day-control · default · selected · today · disabled

회원 화면에서는 가로 스크롤 날짜 목록과 날짜 선택 팝오버를 함께 제공한다. 원장 화면에서는 이전 날짜, 오늘, 다음 날짜를 고정 순서로 배치하고 선택 날짜를 전체 표기로 보여준다.

FilterChipGroup

single-select · multi-select · default · selected · focus · disabled

원장 현황의 전체, 처리 필요, 대기 있음, 빈자리 있음, 승인 대기, 수업 완료 필터에 사용한다. 선택 여부를 색상뿐 아니라 체크 아이콘과 aria-pressed로 전달한다.

WaitlistPosition

summary · detail · owner-row · 대기 중 · 수락 대기 · 승인 대기 · 대기 수락 만료 · 대기 취소 · 예약 확정

회원에게 현재 내 대기 순번, 전체 대기 인원, 대기 신청 시각만 표시한다. 다른 회원의 이름, 연락처, 신청 시각, 응답 결과는 노출하지 않는다. 원장용은 변경 불가능한 등록 순번과 처리 상태를 추가한다.

CountdownDeadline

member-offer · owner-urgent · compact · active · three-minutes-left · one-minute-left · expired · server-syncing

날짜가 포함된 응답 마감 절대 시각을 먼저 표시하고 남은 시간을 보조로 표시한다. 서버 시각을 기준으로 계산하며 마감 시 즉시 수락 버튼을 비활성화하고 현재 상태를 다시 조회한다. 스크린 리더에는 초마다 알리지 않는다.

PhoneAuthForm

phone-entry · code-entry · default · sending · sent · invalid · expired · rate-limited · verified · unregistered

휴대폰 번호와 인증번호는 눈에 보이는 라벨을 둔다. 인증번호는 숫자 키패드와 autocomplete one-time-code를 지원한다. 남은 시간, 재전송 가능 시각, 실패 이유를 텍스트로 표시하고 인증 후 저장된 진입 주소로 복귀한다.

FormField

text · phone · number · date · time · select · radio · textarea · switch · default · focus · filled · error · disabled · read-only

라벨, 필수 여부, 도움말, 오류 문구를 고정된 순서로 배치한다. 오류 시 색상 외에 오류 아이콘과 구체적인 수정 방법을 표시한다. 날짜와 시각은 같은 시간대 기준이며 화면에는 날짜를 포함한 절대 시각을 사용한다.

BottomActionBar

single-primary · primary-secondary · destructive-confirm · default · loading · disabled

회원 모바일 화면에서 주요 행동을 화면 하단 안전 영역 위에 고정한다. 본문 마지막 공간을 확보해 콘텐츠를 가리지 않는다. 취소처럼 되돌리기 어려운 행동은 마지막 확인 단계에서만 danger 스타일을 사용한다.

ConfirmationDialog

reservation · waitlist · cancellation · approval · rejection · correction · open · submitting · error

대상 수업, 적용될 상태 변화, 회원권 횟수 영향, 후속 대기 처리 여부를 요약한다. 파괴적 행동의 취소 버튼은 먼저, 실행 버튼은 뒤에 배치한다. 모바일에서는 하단 시트, md 이상에서는 대화상자를 사용한다.

ResponsiveDataList

table · card-list · master-detail · loading · populated · empty · error

lg 이상에서는 실제 table 요소와 고정 헤더를 사용한다. 좁은 화면에서는 각 행을 제목·상태·핵심 수치·주요 행동을 가진 카드로 바꾸며 가로 스크롤에 핵심 처리를 의존하지 않는다.

Timeline

class-activity · membership-history · correction-history · default · filtered · corrected · error-event

기본은 최신 기록부터 표시하고 처음부터 보기 전환을 제공한다. 각 이벤트에 발생 시각, 주체, 행동, 상태 변경, 변경 전후 값, 사유, 영향 범위, 후속 처리, 원본 이력 연결을 표시한다.

ApprovalPanel

vacancy-approval · exception-review · 승인 대기 · approved · rejected · expired · processing

회원, 마스킹된 휴대폰 번호, 수업, 회원권 잔여 횟수와 만료일, 중복 예약 여부, 대기 신청 시각, 수락 시각, 승인 대기 좌석, 서버가 제공한 보류 만료 시각을 표시한다. 승인과 반려 모두 결과와 사유를 기록한다.

AttendanceControl

single-member · class-bulk · 미처리 · 출석 · 지각 출석 · 노쇼 · 보류

출석 상태를 서로 배타적인 선택으로 제공한다. 노쇼 확정에는 회원권 영향과 사유를 확인하고, 변경 시 기존 기록을 덮어쓰지 않고 조정 이력을 생성한다.

NotificationStatus

auth-sms · vacancy-sms · 요청 · 발송 성공 · 실패 · 재시도 · 최종 실패

메시지 ID, 요청 시각, 발송 시각, 전달 상태, 실패 코드, 재시도 횟수를 원장 상세에서 확인하게 한다. 재발송 또는 다음 대기 회원 전환은 확정된 운영 정책이 없으므로 자동 행동으로 추정하지 않는다.

FeedbackMessage

inline · banner · toast · full-page-result · success · info · warning · error

예약·취소·수락처럼 상태가 바뀌는 작업은 토스트만 사용하지 말고 화면 본문에도 결과를 남긴다. 오류에는 현재 처리 상태, 재시도 가능 여부, 이미 처리된 시각을 구체적으로 표시한다.

SkeletonAndEmptyState

card · list · table · timeline · empty · loading · no-data · filtered-empty · failed

로딩 중 기존 수치를 0으로 표시하지 않는다. 빈 상태는 데이터가 없는 경우와 필터 결과가 없는 경우를 구분하고, 가능한 다음 행동을 하나만 제공한다.

APPLICATION

업계 조사와 화면별 적용

· 카카오톡이나 문자 링크로 진입한 회원은 휴대폰 본인 확인 후 홈이 아니라 원래 요청한 수업·내 예약·빈자리 수락 화면으로 돌아가야 한다.

· 회원은 다른 대기 회원의 정보보다 현재 내 대기 순번, 전체 대기 인원, 대기 신청 시각, 현재 상태를 확인할 때 대기 운영 기준을 이해하기 쉽다.

· 빈자리 수락 화면은 남은 시간만 보여주지 않고 날짜가 포함된 응답 마감 절대 시각을 함께 표시해야 한다.

· 수업 시작 2시간 전까지는 1시간, 그 이후에는 10분의 응답 시간을 적용한다. 조사 자료의 다른 시간 예시는 채택하지 않는다.

· 조사 자료에는 회원 수락 후 자동 확정 사례가 있으나, 제품 정본에 따라 회원 수락 후 승인 대기로 전환하고 원장이 최종 승인해야 예약 확정으로 표시한다.

· 원장 화면은 현재 상태 요약, 예약자·대기열, 처리 필요 항목, 시간순 이력을 분리하되 같은 수업 안에서 서로 이동할 수 있어야 한다.

· 회원권 횟수의 예외 처리와 오류 수정은 기존 기록을 덮어쓰지 않고 원본 이력에 연결된 예외 복구 또는 조정 이력을 추가하는 방식으로 표현한다.

· 문자 발송 요청과 실제 전달 결과는 다를 수 있으므로 원장 화면에서 요청, 발송 성공, 실패, 재시도, 최종 실패를 서로 다른 상태로 보여줘야 한다.

· 확인 필요: 승인 대기 좌석의 보류 만료 시간, 문자 실패 후 재발송 기준, 일반 예약의 회원권 부족 처리, 회원권 실제 차감 시점은 확정 전까지 서버가 제공하는 상태와 시각을 그대로 표시하고 UI가 임의로 판단하지 않는다.

member

대기 상세 전용 화면이다. 상단에 수업명과 날짜·시각, 이어서 상태 배지, 현재 내 대기 순번, 전체 대기 인원, 대기 신청 시각을 큰 수치로 표시한다. 수락 대기이면 응답 마감 절대 시각과 남은 시간을 보여주고 vacancy-accept로 이동한다. 승인 대기이면 좌석이 임시 보류 중이며 원장 최종 예약 승인을 기다린다는 문구를 표시한다. 다른 회원 정보는 표시하지 않는다.

class

상단 고정 요약에 날짜·시각, 수업명, 정원, 예약 확정, 승인 대기 좌석, 대기 인원, 현재 문제를 표시한다. 본문은 처리 필요, 예약자, 대기열, 전체 이력 탭으로 구성한다. 전체 이력은 취소 사유 제출, 무료 취소 마감 시각 판정, 횟수 차감, 예외 복구, 대기 제안, 문자 결과, 회원 응답, 원장 승인·반려, 출석 상태, 오류 수정을 시간순으로 묶는다. 각 수정 이벤트에서 원본 이력과 MS3로 이동할 수 있게 한다.

member-phone-auth

최대 480px 단일 열로 구성한다. 첫 단계는 휴대폰 번호와 인증번호 받기, 두 번째 단계는 마스킹된 번호, 인증번호, 만료까지 남은 시간, 재전송 가능 시각, 번호 변경으로 구성한다. 등록되지 않은 번호는 원장에게 회원 등록을 요청하라는 안내를 표시한다. 인증 완료 후 카카오톡 예약 링크, 내 예약 또는 빈자리 수락 등 처음 요청한 주소로 복귀한다.

member-class-list

상단에 스튜디오명, 날짜 선택, 내 예약 이동을 배치한다. 날짜별 수업 카드는 시작·종료 시각, 수업명, 정원, 잔여석 또는 마감, 대기 가능 상태, 무료 취소 마감 시각 요약을 표시한다. 자리가 있으면 예약하기, 만석이면 대기 신청, 이미 예약했으면 예약 상세 보기, 이미 대기 중이면 현재 대기 순번 보기를 제공한다. 저장 직전 자리가 사라지면 대기 신청으로 전환할 수 있도록 현재 상태를 다시 보여준다.

member-reservations

예약 확정, 대기 중, 처리 완료의 세 구역 또는 탭으로 구성한다. 카드마다 수업 일시, 수업명, 상태, 무료 취소 마감 시각을 표시한다. 대기 카드는 현재 내 대기 순번과 전체 대기 인원을 표시하고, 수락 대기는 응답 마감 시각, 승인 대기는 원장 확인 중임을 표시한다. 취소는 사유 필수 선택, 필요 시 상세 내용, 예상 횟수 처리, 최종 확인 순서로 진행한다.

vacancy-accept

문자 링크의 제안 건과 회원을 확인한 뒤 수업명, 날짜·시각, 우선 제안된 빈자리, 응답 마감 절대 시각, 남은 시간, 회원권 상태를 표시한다. 주요 버튼은 수락하고 승인 요청, 보조 버튼은 이번 자리는 거절하기로 한다. 수락 직후 버튼을 잠그고 서버에서 유효성·정원·중복 요청을 다시 확인한다. 성공하면 승인 대기를 표시하며 예약 확정이라고 표현하지 않는다. 만료·이미 처리·다른 기기 처리 상태에는 처리 시각과 현재 결과를 보여주고 수락을 다시 실행하지 않는다.

owner-class-status

상단에 날짜 이동과 전체, 처리 필요, 대기 있음, 빈자리 있음, 승인 대기 필터를 둔다. 수업은 시간순으로 표시하되 처리 필요 필터에서는 응답 마감 임박, 승인 대기, 빈자리와 대기 동시 존재, 문자 실패, 출결 관리 미처리 순으로 강조한다. 각 항목에 정원, 예약 확정, 승인 대기 좌석, 대기 인원, 현재 제안 상태와 마감 시각을 표시한다. lg 이상은 표, 좁은 화면은 카드 목록이며 수업 선택 시 class로 이동한다.

owner-member-records

상단 검색은 회원 이름과 마스킹된 휴대폰 번호를 지원한다. 회원 상세에 횟수제 회원권의 총 횟수, 잔여 횟수, 시작일, 만료일, 회원권 이력 합계 일치 여부를 요약한다. 하단은 회원권 이력, 취소·예외, 출결 관리·노쇼 탭으로 나누고 각 기록에서 관련 class 화면으로 이동한다. 횟수 변경은 원본 이력을 삭제하지 않고 조정 또는 예외 복구로 추가한다.

MS1

수업명, 날짜, 시작·종료 시각, 정원, 예약 가능 상태, 대기 신청 가능 상태를 입력한다. 정원은 5~15명으로 제한하고 현재 예약 확정 인원보다 작게 줄일 수 없다. 무료 취소 마감 시각은 시작 12시간 전으로 자동 계산해 읽기 전용으로 보여준다. 진행 중인 대기 제안이 있을 때 시간이나 정원을 바꾸면 영향을 받는 제안, 좌석, 마감 시각을 저장 전에 요약한다.

MS2

최상단에 승인 대기 좌석과 서버가 제공한 보류 만료 시각을 강조한다. 회원명, 마스킹된 휴대폰 번호, 수업, 대기 순번, 대기 신청 시각, 문자 발송 결과, 수락 시각, 회원권 잔여 횟수·만료일, 동일 시간 예약 여부, 취소·노쇼 참고 기록을 표시한다. 주요 행동은 승인하고 예약 확정, 보조 위험 행동은 반려하고 다음 대기 회원 처리로 둔다. 반려 사유는 필수이며 결과는 회원 화면과 시간순 이력에 반영한다.

MS3

중복 예약, 대기 순서 누락, 잘못된 취소·노쇼·회원권 횟수 처리를 유형과 기간으로 검색한다. 왼쪽 또는 상단에 문제 기록, 오른쪽 또는 하단에 원본 이력, 연결 기록, 변경 전후 값을 표시한다. 수정은 원본 삭제가 아니라 새 조정 이력을 만드는 방식이며 수정 사유, 처리자, 처리 시각, 회원 알림 여부를 필수로 남긴다. 저장 전 좌석, 대기 상태, 회원권 잔여 횟수에 미치는 영향을 요약한다.

MS4

회원 정보와 횟수제 회원권 정보를 두 구역으로 나눈다. 회원 이름, 휴대폰 번호, 회원권 상품명, 총 횟수, 잔여 횟수, 시작일, 만료일을 입력한다. 같은 스튜디오의 동일 휴대폰 번호가 있으면 중복 후보를 보여주고 저장을 막는다. 잔여 횟수가 총 횟수보다 크거나 만료일이 시작일보다 빠르면 필드 단위 오류를 표시한다. 저장 결과에는 등록 처리자와 등록 시각을 보여준다.

에셋 원칙
가정: 서비스 브랜드명과 로고가 확정되지 않았으므로 초기 구현은 스튜디오명을 텍스트 워드마크로 표시한다. · 아이콘은 하나의 SVG 선형 아이콘 세트로 통일하고 기본 20px, 주요 상태 24px, 선 두께 1.75~2px를 사용한다. · 예약 확정, 수락 대기, 승인 대기, 경고, 오류, 출석, 노쇼 상태별 아이콘을 준비하며 색상 없이도 의미를 구분한다. · 회원 사진과 다른 회원을 연상시키는 아바타는 사용하지 않는다. · 장식용 필라테스 사진은 첫 개발에 필요하지 않다. 빈 상태는 단순 아이콘과 다음 행동 문구로 구성한다. · 문자 템플릿에는 스튜디오명, 수업 날짜·시각, 수업명, 응답 마감 절대 시각, 만료되는 수락 링크, 원장 최종 예약 승인 안내를 포함한다. · 웹 앱 아이콘과 파비콘은 Primary 색상의 단순 캘린더·순번 조합 심벌을 임시 자산으로 사용하며 브랜드 확정 후 교체 가능하게 한다.

ACCESSIBILITY

접근성과 모션

  • · KWCAG 2.2와 WCAG 2.1 AA를 기준으로 일반 텍스트 명도 대비 4.5:1 이상, 큰 텍스트와 핵심 UI 그래픽은 3:1 이상을 확보한다.
  • · 예약 확정, 수락 대기, 승인 대기, 노쇼, 오류 상태는 색상만으로 구분하지 않고 문구와 아이콘을 함께 사용한다.
  • · 모든 터치 대상은 최소 44×44px로 만들고 인접한 주요 행동 사이에 최소 8px 간격을 둔다.
  • · 키보드 초점은 2px Focus 색상 외곽선과 2px 간격으로 명확히 표시하며 논리적인 탭 순서를 유지한다.
  • · 입력 필드에는 placeholder와 별도로 항상 보이는 라벨을 제공하고 오류 문구를 해당 필드와 프로그램 방식으로 연결한다.
  • · 제출 오류가 여러 개면 화면 상단에 오류 요약을 제공하고 각 오류 필드로 이동할 수 있게 한다.
  • · 응답 마감 타이머는 초마다 aria-live로 읽지 않는다. 3분, 1분, 만료 등 의미 있는 변화만 알리고 절대 마감 시각은 항상 텍스트로 제공한다.
  • · 상태 변경과 저장 결과는 aria-live polite로 알리되 오류와 만료처럼 즉시 행동이 필요한 경우에는 assertive 사용을 제한적으로 적용한다.
  • · 모달과 하단 시트는 열릴 때 초점을 내부로 이동하고, 닫힐 때 실행 버튼으로 돌려보내며, 열린 동안 배경에 초점이 이동하지 않게 한다.
  • · 원장용 표는 caption, thead, th, scope를 사용하고 모바일 카드로 전환돼도 각 값의 라벨을 생략하지 않는다.
  • · 휴대폰 번호는 회원 화면에 본인의 마스킹 번호만 표시하고, 다른 회원의 이름·휴대폰 번호·취소 사유·회원권 상태를 노출하지 않는다.
  • · 모션 감소 설정이 켜지면 카운트다운 강조 애니메이션, 카드 이동, 자동 스크롤을 제거하고 즉시 상태 전환으로 대체한다.

기본 전환 180ms cubic-bezier(0.2, 0, 0, 1) · 모션 감소 설정 지원 · 다크모드 not_planned

EVIDENCE

조사 출처

기계 판독 디자인 계약 보기
{
  "version": 1,
  "direction": "공정한 대기 순서와 처리 근거를 가장 먼저 보여주는 차분한 운영형 UI다. 회원 화면은 카카오톡·문자 링크에서 바로 행동할 수 있도록 한 화면에 하나의 주요 행동만 강조한다. 원장 화면은 현재 정원과 처리 필요 상태를 먼저 요약하고, 취소·대기 제안·회원 응답·원장 최종 예약 승인·회원권 이력을 시간순으로 연결한다. 장식적인 필라테스 이미지보다 상태, 마감 시각, 기록의 정확성을 우선한다.",
  "keywords": [
    "공정한 대기 순번",
    "차분한 신뢰감",
    "모바일 예약",
    "명확한 마감 시각",
    "처리 필요 우선",
    "시간순 이력",
    "개인정보 최소 노출",
    "원장 최종 예약 승인"
  ],
  "industryFindings": [
    "카카오톡이나 문자 링크로 진입한 회원은 휴대폰 본인 확인 후 홈이 아니라 원래 요청한 수업·내 예약·빈자리 수락 화면으로 돌아가야 한다.",
    "회원은 다른 대기 회원의 정보보다 현재 내 대기 순번, 전체 대기 인원, 대기 신청 시각, 현재 상태를 확인할 때 대기 운영 기준을 이해하기 쉽다.",
    "빈자리 수락 화면은 남은 시간만 보여주지 않고 날짜가 포함된 응답 마감 절대 시각을 함께 표시해야 한다.",
    "수업 시작 2시간 전까지는 1시간, 그 이후에는 10분의 응답 시간을 적용한다. 조사 자료의 다른 시간 예시는 채택하지 않는다.",
    "조사 자료에는 회원 수락 후 자동 확정 사례가 있으나, 제품 정본에 따라 회원 수락 후 승인 대기로 전환하고 원장이 최종 승인해야 예약 확정으로 표시한다.",
    "원장 화면은 현재 상태 요약, 예약자·대기열, 처리 필요 항목, 시간순 이력을 분리하되 같은 수업 안에서 서로 이동할 수 있어야 한다.",
    "회원권 횟수의 예외 처리와 오류 수정은 기존 기록을 덮어쓰지 않고 원본 이력에 연결된 예외 복구 또는 조정 이력을 추가하는 방식으로 표현한다.",
    "문자 발송 요청과 실제 전달 결과는 다를 수 있으므로 원장 화면에서 요청, 발송 성공, 실패, 재시도, 최종 실패를 서로 다른 상태로 보여줘야 한다.",
    "확인 필요: 승인 대기 좌석의 보류 만료 시간, 문자 실패 후 재발송 기준, 일반 예약의 회원권 부족 처리, 회원권 실제 차감 시점은 확정 전까지 서버가 제공하는 상태와 시각을 그대로 표시하고 UI가 임의로 판단하지 않는다."
  ],
  "layoutMode": "mobile_first",
  "layoutRationale": "회원은 카카오톡 등에 공유된 링크를 휴대폰에서 열고 휴대폰 본인 확인, 예약, 취소, 대기 신청, 빈자리 수락을 수행한다. 원장도 프런트 직원 없이 수업 사이에 휴대폰으로 핵심 처리를 할 가능성이 높으므로 좁은 화면에서 모든 조회와 승인이 가능해야 한다. lg 이상에서는 원장용 표, 타임라인, 상세 패널을 동시에 보여주는 12열 레이아웃으로 확장한다.",
  "typography": {
    "primaryFont": "Pretendard Variable",
    "fallback": [
      "Pretendard",
      "Apple SD Gothic Neo",
      "Noto Sans KR",
      "Malgun Gothic",
      "sans-serif"
    ],
    "scriptFallbacks": {
      "Jpan": [
        "Noto Sans JP",
        "Yu Gothic",
        "system-ui",
        "sans-serif"
      ],
      "Kore": [
        "Pretendard",
        "Noto Sans KR",
        "system-ui",
        "sans-serif"
      ],
      "Latn": [
        "Inter",
        "system-ui",
        "sans-serif"
      ]
    },
    "bodyLetterSpacing": "-0.01em",
    "headingLetterSpacing": "-0.025em",
    "bodyLineHeight": 1.6
  },
  "colors": [
    {
      "name": "Canvas",
      "value": "#F7F8F6",
      "usage": "전체 페이지 배경"
    },
    {
      "name": "Surface",
      "value": "#FFFFFF",
      "usage": "카드, 입력 영역, 모달과 상세 패널 배경"
    },
    {
      "name": "Text Primary",
      "value": "#18201E",
      "usage": "제목, 본문, 핵심 수치"
    },
    {
      "name": "Text Secondary",
      "value": "#53615D",
      "usage": "보조 설명, 시각과 메타데이터"
    },
    {
      "name": "Border",
      "value": "#D6DEDB",
      "usage": "카드 구분선, 입력 테두리, 표 구분선"
    },
    {
      "name": "Primary",
      "value": "#176B5B",
      "usage": "예약, 대기 신청, 수락하고 승인 요청, 저장 등 주요 행동"
    },
    {
      "name": "Primary Strong",
      "value": "#0F574A",
      "usage": "주요 버튼 hover·pressed 상태"
    },
    {
      "name": "Primary Soft",
      "value": "#E7F3F0",
      "usage": "선택 상태, 대기 순번 요약, 차분한 강조 배경"
    },
    {
      "name": "Info",
      "value": "#245EA8",
      "usage": "수락 대기, 안내, 링크와 정보성 배지"
    },
    {
      "name": "Info Soft",
      "value": "#EAF2FC",
      "usage": "정보성 알림과 수락 대기 배경"
    },
    {
      "name": "Success",
      "value": "#237A45",
      "usage": "예약 확정, 출석, 발송 성공, 처리 완료"
    },
    {
      "name": "Success Soft",
      "value": "#EAF6EE",
      "usage": "성공 알림과 예약 확정 배경"
    },
    {
      "name": "Warning",
      "value": "#8A4B08",
      "usage": "승인 대기, 12시간 이내 취소, 보류, 마감 임박"
    },
    {
      "name": "Warning Soft",
      "value": "#FFF4E5",
      "usage": "원장 확인 필요와 마감 임박 알림 배경"
    },
    {
      "name": "Danger",
      "value": "#B42318",
      "usage": "노쇼, 오류, 문자 실패, 취소와 반려 같은 파괴적 행동"
    },
    {
      "name": "Danger Soft",
      "value": "#FDECEC",
      "usage": "오류와 위험 알림 배경"
    },
    {
      "name": "Focus",
      "value": "#155EEF",
      "usage": "키보드 초점 표시"
    },
    {
      "name": "Disabled",
      "value": "#AAB5B1",
      "usage": "비활성 배경과 테두리 전용이며 작은 글자색으로 사용하지 않음"
    }
  ],
  "breakpoints": {
    "sm": 480,
    "md": 768,
    "lg": 1024,
    "xl": 1440
  },
  "grid": {
    "baseUnit": 4,
    "mobileColumns": 4,
    "desktopColumns": 12,
    "maxContentWidth": 1280
  },
  "spacing": [
    4,
    8,
    12,
    16,
    20,
    24,
    32,
    40,
    48,
    64,
    80
  ],
  "radius": {
    "sm": 6,
    "md": 10,
    "lg": 16,
    "full": 9999
  },
  "components": [
    {
      "name": "AppShell",
      "variants": [
        "member",
        "owner"
      ],
      "states": [
        "default",
        "loading",
        "unauthorized"
      ],
      "guidance": "회원 화면은 최대 560px 단일 열과 하단 주요 행동을 사용한다. 원장 화면은 모바일에서 단일 열, lg 이상에서 좌측 내비게이션과 최대 1280px 본문을 사용한다. 권한이 없으면 운영 데이터가 잠깐이라도 노출되지 않게 한다."
    },
    {
      "name": "TopNavigation",
      "variants": [
        "member-simple",
        "owner-global",
        "detail-back"
      ],
      "states": [
        "default",
        "scrolled"
      ],
      "guidance": "회원용 링크 화면은 스튜디오명과 뒤로가기만 제공한다. 원장용은 수업 현황, 회원 기록을 주요 메뉴로 두고 수업 등록과 회원 등록은 관련 화면 안의 행동으로 제공한다."
    },
    {
      "name": "Button",
      "variants": [
        "primary",
        "secondary",
        "tertiary",
        "danger",
        "icon"
      ],
      "states": [
        "default",
        "hover",
        "focus",
        "pressed",
        "loading",
        "disabled"
      ],
      "guidance": "높이는 기본 48px, 조밀한 원장 표 안에서는 40px로 한다. 모바일 주요 버튼은 가로 폭을 채운다. 저장·수락 요청 중에는 중복 클릭을 막고 동작형 문구와 진행 표시를 함께 보여준다."
    },
    {
      "name": "StatusBadge",
      "variants": [
        "neutral",
        "info",
        "success",
        "warning",
        "danger"
      ],
      "states": [
        "대기 중",
        "수락 대기",
        "대기 수락 만료",
        "승인 대기",
        "예약 확정",
        "취소 완료",
        "출석",
        "지각 출석",
        "노쇼",
        "보류",
        "휴강",
        "오류"
      ],
      "guidance": "색상과 함께 상태 문구와 아이콘을 표시한다. 예약 확정, 수락 대기, 승인 대기를 같은 색이나 같은 문구로 표현하지 않는다."
    },
    {
      "name": "ClassCard",
      "variants": [
        "member",
        "owner",
        "compact"
      ],
      "states": [
        "예약 가능",
        "마감",
        "대기 가능",
        "예약 확정",
        "대기 중",
        "수락 대기",
        "승인 대기",
        "휴강",
        "신청 종료"
      ],
      "guidance": "날짜, 시작·종료 시각, 수업명, 정원, 확정 인원 또는 잔여석, 대기 상태를 표시한다. 회원용 카드는 현재 가능한 다음 행동 하나를 명확히 제공하고, 원장용 카드는 처리 필요 상태와 마감 시각을 우선 표시한다."
    },
    {
      "name": "CapacitySummary",
      "variants": [
        "member",
        "owner"
      ],
      "states": [
        "available",
        "full",
        "offering",
        "held",
        "over-capacity-error"
      ],
      "guidance": "회원에게는 정원과 잔여석 또는 마감 상태만 제공한다. 원장에게는 정원, 예약 확정, 승인 대기 좌석, 즉시 배정 가능한 좌석, 대기 인원을 분리해 표시한다."
    },
    {
      "name": "DateNavigator",
      "variants": [
        "day-strip",
        "calendar-popover",
        "owner-day-control"
      ],
      "states": [
        "default",
        "selected",
        "today",
        "disabled"
      ],
      "guidance": "회원 화면에서는 가로 스크롤 날짜 목록과 날짜 선택 팝오버를 함께 제공한다. 원장 화면에서는 이전 날짜, 오늘, 다음 날짜를 고정 순서로 배치하고 선택 날짜를 전체 표기로 보여준다."
    },
    {
      "name": "FilterChipGroup",
      "variants": [
        "single-select",
        "multi-select"
      ],
      "states": [
        "default",
        "selected",
        "focus",
        "disabled"
      ],
      "guidance": "원장 현황의 전체, 처리 필요, 대기 있음, 빈자리 있음, 승인 대기, 수업 완료 필터에 사용한다. 선택 여부를 색상뿐 아니라 체크 아이콘과 aria-pressed로 전달한다."
    },
    {
      "name": "WaitlistPosition",
      "variants": [
        "summary",
        "detail",
        "owner-row"
      ],
      "states": [
        "대기 중",
        "수락 대기",
        "승인 대기",
        "대기 수락 만료",
        "대기 취소",
        "예약 확정"
      ],
      "guidance": "회원에게 현재 내 대기 순번, 전체 대기 인원, 대기 신청 시각만 표시한다. 다른 회원의 이름, 연락처, 신청 시각, 응답 결과는 노출하지 않는다. 원장용은 변경 불가능한 등록 순번과 처리 상태를 추가한다."
    },
    {
      "name": "CountdownDeadline",
      "variants": [
        "member-offer",
        "owner-urgent",
        "compact"
      ],
      "states": [
        "active",
        "three-minutes-left",
        "one-minute-left",
        "expired",
        "server-syncing"
      ],
      "guidance": "날짜가 포함된 응답 마감 절대 시각을 먼저 표시하고 남은 시간을 보조로 표시한다. 서버 시각을 기준으로 계산하며 마감 시 즉시 수락 버튼을 비활성화하고 현재 상태를 다시 조회한다. 스크린 리더에는 초마다 알리지 않는다."
    },
    {
      "name": "PhoneAuthForm",
      "variants": [
        "phone-entry",
        "code-entry"
      ],
      "states": [
        "default",
        "sending",
        "sent",
        "invalid",
        "expired",
        "rate-limited",
        "verified",
        "unregistered"
      ],
      "guidance": "휴대폰 번호와 인증번호는 눈에 보이는 라벨을 둔다. 인증번호는 숫자 키패드와 autocomplete one-time-code를 지원한다. 남은 시간, 재전송 가능 시각, 실패 이유를 텍스트로 표시하고 인증 후 저장된 진입 주소로 복귀한다."
    },
    {
      "name": "FormField",
      "variants": [
        "text",
        "phone",
        "number",
        "date",
        "time",
        "select",
        "radio",
        "textarea",
        "switch"
      ],
      "states": [
        "default",
        "focus",
        "filled",
        "error",
        "disabled",
        "read-only"
      ],
      "guidance": "라벨, 필수 여부, 도움말, 오류 문구를 고정된 순서로 배치한다. 오류 시 색상 외에 오류 아이콘과 구체적인 수정 방법을 표시한다. 날짜와 시각은 같은 시간대 기준이며 화면에는 날짜를 포함한 절대 시각을 사용한다."
    },
    {
      "name": "BottomActionBar",
      "variants": [
        "single-primary",
        "primary-secondary",
        "destructive-confirm"
      ],
      "states": [
        "default",
        "loading",
        "disabled"
      ],
      "guidance": "회원 모바일 화면에서 주요 행동을 화면 하단 안전 영역 위에 고정한다. 본문 마지막 공간을 확보해 콘텐츠를 가리지 않는다. 취소처럼 되돌리기 어려운 행동은 마지막 확인 단계에서만 danger 스타일을 사용한다."
    },
    {
      "name": "ConfirmationDialog",
      "variants": [
        "reservation",
        "waitlist",
        "cancellation",
        "approval",
        "rejection",
        "correction"
      ],
      "states": [
        "open",
        "submitting",
        "error"
      ],
      "guidance": "대상 수업, 적용될 상태 변화, 회원권 횟수 영향, 후속 대기 처리 여부를 요약한다. 파괴적 행동의 취소 버튼은 먼저, 실행 버튼은 뒤에 배치한다. 모바일에서는 하단 시트, md 이상에서는 대화상자를 사용한다."
    },
    {
      "name": "ResponsiveDataList",
      "variants": [
        "table",
        "card-list",
        "master-detail"
      ],
      "states": [
        "loading",
        "populated",
        "empty",
        "error"
      ],
      "guidance": "lg 이상에서는 실제 table 요소와 고정 헤더를 사용한다. 좁은 화면에서는 각 행을 제목·상태·핵심 수치·주요 행동을 가진 카드로 바꾸며 가로 스크롤에 핵심 처리를 의존하지 않는다."
    },
    {
      "name": "Timeline",
      "variants": [
        "class-activity",
        "membership-history",
        "correction-history"
      ],
      "states": [
        "default",
        "filtered",
        "corrected",
        "error-event"
      ],
      "guidance": "기본은 최신 기록부터 표시하고 처음부터 보기 전환을 제공한다. 각 이벤트에 발생 시각, 주체, 행동, 상태 변경, 변경 전후 값, 사유, 영향 범위, 후속 처리, 원본 이력 연결을 표시한다."
    },
    {
      "name": "ApprovalPanel",
      "variants": [
        "vacancy-approval",
        "exception-review"
      ],
      "states": [
        "승인 대기",
        "approved",
        "rejected",
        "expired",
        "processing"
      ],
      "guidance": "회원, 마스킹된 휴대폰 번호, 수업, 회원권 잔여 횟수와 만료일, 중복 예약 여부, 대기 신청 시각, 수락 시각, 승인 대기 좌석, 서버가 제공한 보류 만료 시각을 표시한다. 승인과 반려 모두 결과와 사유를 기록한다."
    },
    {
      "name": "AttendanceControl",
      "variants": [
        "single-member",
        "class-bulk"
      ],
      "states": [
        "미처리",
        "출석",
        "지각 출석",
        "노쇼",
        "보류"
      ],
      "guidance": "출석 상태를 서로 배타적인 선택으로 제공한다. 노쇼 확정에는 회원권 영향과 사유를 확인하고, 변경 시 기존 기록을 덮어쓰지 않고 조정 이력을 생성한다."
    },
    {
      "name": "NotificationStatus",
      "variants": [
        "auth-sms",
        "vacancy-sms"
      ],
      "states": [
        "요청",
        "발송 성공",
        "실패",
        "재시도",
        "최종 실패"
      ],
      "guidance": "메시지 ID, 요청 시각, 발송 시각, 전달 상태, 실패 코드, 재시도 횟수를 원장 상세에서 확인하게 한다. 재발송 또는 다음 대기 회원 전환은 확정된 운영 정책이 없으므로 자동 행동으로 추정하지 않는다."
    },
    {
      "name": "FeedbackMessage",
      "variants": [
        "inline",
        "banner",
        "toast",
        "full-page-result"
      ],
      "states": [
        "success",
        "info",
        "warning",
        "error"
      ],
      "guidance": "예약·취소·수락처럼 상태가 바뀌는 작업은 토스트만 사용하지 말고 화면 본문에도 결과를 남긴다. 오류에는 현재 처리 상태, 재시도 가능 여부, 이미 처리된 시각을 구체적으로 표시한다."
    },
    {
      "name": "SkeletonAndEmptyState",
      "variants": [
        "card",
        "list",
        "table",
        "timeline",
        "empty"
      ],
      "states": [
        "loading",
        "no-data",
        "filtered-empty",
        "failed"
      ],
      "guidance": "로딩 중 기존 수치를 0으로 표시하지 않는다. 빈 상태는 데이터가 없는 경우와 필터 결과가 없는 경우를 구분하고, 가능한 다음 행동을 하나만 제공한다."
    }
  ],
  "accessibility": [
    "KWCAG 2.2와 WCAG 2.1 AA를 기준으로 일반 텍스트 명도 대비 4.5:1 이상, 큰 텍스트와 핵심 UI 그래픽은 3:1 이상을 확보한다.",
    "예약 확정, 수락 대기, 승인 대기, 노쇼, 오류 상태는 색상만으로 구분하지 않고 문구와 아이콘을 함께 사용한다.",
    "모든 터치 대상은 최소 44×44px로 만들고 인접한 주요 행동 사이에 최소 8px 간격을 둔다.",
    "키보드 초점은 2px Focus 색상 외곽선과 2px 간격으로 명확히 표시하며 논리적인 탭 순서를 유지한다.",
    "입력 필드에는 placeholder와 별도로 항상 보이는 라벨을 제공하고 오류 문구를 해당 필드와 프로그램 방식으로 연결한다.",
    "제출 오류가 여러 개면 화면 상단에 오류 요약을 제공하고 각 오류 필드로 이동할 수 있게 한다.",
    "응답 마감 타이머는 초마다 aria-live로 읽지 않는다. 3분, 1분, 만료 등 의미 있는 변화만 알리고 절대 마감 시각은 항상 텍스트로 제공한다.",
    "상태 변경과 저장 결과는 aria-live polite로 알리되 오류와 만료처럼 즉시 행동이 필요한 경우에는 assertive 사용을 제한적으로 적용한다.",
    "모달과 하단 시트는 열릴 때 초점을 내부로 이동하고, 닫힐 때 실행 버튼으로 돌려보내며, 열린 동안 배경에 초점이 이동하지 않게 한다.",
    "원장용 표는 caption, thead, th, scope를 사용하고 모바일 카드로 전환돼도 각 값의 라벨을 생략하지 않는다.",
    "휴대폰 번호는 회원 화면에 본인의 마스킹 번호만 표시하고, 다른 회원의 이름·휴대폰 번호·취소 사유·회원권 상태를 노출하지 않는다.",
    "모션 감소 설정이 켜지면 카운트다운 강조 애니메이션, 카드 이동, 자동 스크롤을 제거하고 즉시 상태 전환으로 대체한다."
  ],
  "motion": {
    "durationMs": 180,
    "easing": "cubic-bezier(0.2, 0, 0, 1)",
    "reducedMotion": true
  },
  "darkMode": "not_planned",
  "screenGuidance": [
    {
      "screenId": "member",
      "guidance": "대기 상세 전용 화면이다. 상단에 수업명과 날짜·시각, 이어서 상태 배지, 현재 내 대기 순번, 전체 대기 인원, 대기 신청 시각을 큰 수치로 표시한다. 수락 대기이면 응답 마감 절대 시각과 남은 시간을 보여주고 vacancy-accept로 이동한다. 승인 대기이면 좌석이 임시 보류 중이며 원장 최종 예약 승인을 기다린다는 문구를 표시한다. 다른 회원 정보는 표시하지 않는다."
    },
    {
      "screenId": "class",
      "guidance": "상단 고정 요약에 날짜·시각, 수업명, 정원, 예약 확정, 승인 대기 좌석, 대기 인원, 현재 문제를 표시한다. 본문은 처리 필요, 예약자, 대기열, 전체 이력 탭으로 구성한다. 전체 이력은 취소 사유 제출, 무료 취소 마감 시각 판정, 횟수 차감, 예외 복구, 대기 제안, 문자 결과, 회원 응답, 원장 승인·반려, 출석 상태, 오류 수정을 시간순으로 묶는다. 각 수정 이벤트에서 원본 이력과 MS3로 이동할 수 있게 한다."
    },
    {
      "screenId": "member-phone-auth",
      "guidance": "최대 480px 단일 열로 구성한다. 첫 단계는 휴대폰 번호와 인증번호 받기, 두 번째 단계는 마스킹된 번호, 인증번호, 만료까지 남은 시간, 재전송 가능 시각, 번호 변경으로 구성한다. 등록되지 않은 번호는 원장에게 회원 등록을 요청하라는 안내를 표시한다. 인증 완료 후 카카오톡 예약 링크, 내 예약 또는 빈자리 수락 등 처음 요청한 주소로 복귀한다."
    },
    {
      "screenId": "member-class-list",
      "guidance": "상단에 스튜디오명, 날짜 선택, 내 예약 이동을 배치한다. 날짜별 수업 카드는 시작·종료 시각, 수업명, 정원, 잔여석 또는 마감, 대기 가능 상태, 무료 취소 마감 시각 요약을 표시한다. 자리가 있으면 예약하기, 만석이면 대기 신청, 이미 예약했으면 예약 상세 보기, 이미 대기 중이면 현재 대기 순번 보기를 제공한다. 저장 직전 자리가 사라지면 대기 신청으로 전환할 수 있도록 현재 상태를 다시 보여준다."
    },
    {
      "screenId": "member-reservations",
      "guidance": "예약 확정, 대기 중, 처리 완료의 세 구역 또는 탭으로 구성한다. 카드마다 수업 일시, 수업명, 상태, 무료 취소 마감 시각을 표시한다. 대기 카드는 현재 내 대기 순번과 전체 대기 인원을 표시하고, 수락 대기는 응답 마감 시각, 승인 대기는 원장 확인 중임을 표시한다. 취소는 사유 필수 선택, 필요 시 상세 내용, 예상 횟수 처리, 최종 확인 순서로 진행한다."
    },
    {
      "screenId": "vacancy-accept",
      "guidance": "문자 링크의 제안 건과 회원을 확인한 뒤 수업명, 날짜·시각, 우선 제안된 빈자리, 응답 마감 절대 시각, 남은 시간, 회원권 상태를 표시한다. 주요 버튼은 수락하고 승인 요청, 보조 버튼은 이번 자리는 거절하기로 한다. 수락 직후 버튼을 잠그고 서버에서 유효성·정원·중복 요청을 다시 확인한다. 성공하면 승인 대기를 표시하며 예약 확정이라고 표현하지 않는다. 만료·이미 처리·다른 기기 처리 상태에는 처리 시각과 현재 결과를 보여주고 수락을 다시 실행하지 않는다."
    },
    {
      "screenId": "owner-class-status",
      "guidance": "상단에 날짜 이동과 전체, 처리 필요, 대기 있음, 빈자리 있음, 승인 대기 필터를 둔다. 수업은 시간순으로 표시하되 처리 필요 필터에서는 응답 마감 임박, 승인 대기, 빈자리와 대기 동시 존재, 문자 실패, 출결 관리 미처리 순으로 강조한다. 각 항목에 정원, 예약 확정, 승인 대기 좌석, 대기 인원, 현재 제안 상태와 마감 시각을 표시한다. lg 이상은 표, 좁은 화면은 카드 목록이며 수업 선택 시 class로 이동한다."
    },
    {
      "screenId": "owner-member-records",
      "guidance": "상단 검색은 회원 이름과 마스킹된 휴대폰 번호를 지원한다. 회원 상세에 횟수제 회원권의 총 횟수, 잔여 횟수, 시작일, 만료일, 회원권 이력 합계 일치 여부를 요약한다. 하단은 회원권 이력, 취소·예외, 출결 관리·노쇼 탭으로 나누고 각 기록에서 관련 class 화면으로 이동한다. 횟수 변경은 원본 이력을 삭제하지 않고 조정 또는 예외 복구로 추가한다."
    },
    {
      "screenId": "MS1",
      "guidance": "수업명, 날짜, 시작·종료 시각, 정원, 예약 가능 상태, 대기 신청 가능 상태를 입력한다. 정원은 5~15명으로 제한하고 현재 예약 확정 인원보다 작게 줄일 수 없다. 무료 취소 마감 시각은 시작 12시간 전으로 자동 계산해 읽기 전용으로 보여준다. 진행 중인 대기 제안이 있을 때 시간이나 정원을 바꾸면 영향을 받는 제안, 좌석, 마감 시각을 저장 전에 요약한다."
    },
    {
      "screenId": "MS2",
      "guidance": "최상단에 승인 대기 좌석과 서버가 제공한 보류 만료 시각을 강조한다. 회원명, 마스킹된 휴대폰 번호, 수업, 대기 순번, 대기 신청 시각, 문자 발송 결과, 수락 시각, 회원권 잔여 횟수·만료일, 동일 시간 예약 여부, 취소·노쇼 참고 기록을 표시한다. 주요 행동은 승인하고 예약 확정, 보조 위험 행동은 반려하고 다음 대기 회원 처리로 둔다. 반려 사유는 필수이며 결과는 회원 화면과 시간순 이력에 반영한다."
    },
    {
      "screenId": "MS3",
      "guidance": "중복 예약, 대기 순서 누락, 잘못된 취소·노쇼·회원권 횟수 처리를 유형과 기간으로 검색한다. 왼쪽 또는 상단에 문제 기록, 오른쪽 또는 하단에 원본 이력, 연결 기록, 변경 전후 값을 표시한다. 수정은 원본 삭제가 아니라 새 조정 이력을 만드는 방식이며 수정 사유, 처리자, 처리 시각, 회원 알림 여부를 필수로 남긴다. 저장 전 좌석, 대기 상태, 회원권 잔여 횟수에 미치는 영향을 요약한다."
    },
    {
      "screenId": "MS4",
      "guidance": "회원 정보와 횟수제 회원권 정보를 두 구역으로 나눈다. 회원 이름, 휴대폰 번호, 회원권 상품명, 총 횟수, 잔여 횟수, 시작일, 만료일을 입력한다. 같은 스튜디오의 동일 휴대폰 번호가 있으면 중복 후보를 보여주고 저장을 막는다. 잔여 횟수가 총 횟수보다 크거나 만료일이 시작일보다 빠르면 필드 단위 오류를 표시한다. 저장 결과에는 등록 처리자와 등록 시각을 보여준다."
    }
  ],
  "assets": [
    "가정: 서비스 브랜드명과 로고가 확정되지 않았으므로 초기 구현은 스튜디오명을 텍스트 워드마크로 표시한다.",
    "아이콘은 하나의 SVG 선형 아이콘 세트로 통일하고 기본 20px, 주요 상태 24px, 선 두께 1.75~2px를 사용한다.",
    "예약 확정, 수락 대기, 승인 대기, 경고, 오류, 출석, 노쇼 상태별 아이콘을 준비하며 색상 없이도 의미를 구분한다.",
    "회원 사진과 다른 회원을 연상시키는 아바타는 사용하지 않는다.",
    "장식용 필라테스 사진은 첫 개발에 필요하지 않다. 빈 상태는 단순 아이콘과 다음 행동 문구로 구성한다.",
    "문자 템플릿에는 스튜디오명, 수업 날짜·시각, 수업명, 응답 마감 절대 시각, 만료되는 수락 링크, 원장 최종 예약 승인 안내를 포함한다.",
    "웹 앱 아이콘과 파비콘은 Primary 색상의 단순 캘린더·순번 조합 심벌을 임시 자산으로 사용하며 브랜드 확정 후 교체 가능하게 한다."
  ],
  "sources": [
    {
      "title": "이용자의 예약하는 방법 : 네이버 예약주문 이용자 고객센터",
      "url": "https://help.naver.com/service/11713/contents/3751?lang=ko&osType=COMMONOS",
      "note": "모바일 예약 진입, 예약 상태 확인, 행동 중심 화면 구성의 비교 근거로 사용했다."
    },
    {
      "title": "카카오톡 예약하기 파트너센터 - 카카오비즈니스",
      "url": "https://business.kakao.com/info/booking/",
      "note": "카카오톡에서 예약 링크로 진입하는 국내 사용 흐름과 사업자용 예약 관리 구조의 비교 근거로 사용했다."
    },
    {
      "title": "서울특별시 공공서비스예약",
      "url": "https://yeyak.seoul.go.kr/web/reservation/selectReservView.do?rsv_svc_id=S240709135735601003",
      "note": "날짜·시간·정원·예약 상태를 함께 제시하는 예약 정보 구조의 비교 근거로 사용했다."
    },
    {
      "title": "식당 웨이팅 관리 시스템 고르는 법 | 꼭 확인할 3가지",
      "url": "https://biz.catchtable.co.kr/n/knowhow/waiting-guide",
      "note": "순차 대기 안내와 운영자가 확인해야 할 웨이팅 상태의 비교 근거로 사용했다."
    },
    {
      "title": "그룹수업 예약 프로그램 | 클래스G",
      "url": "https://classg.kr/",
      "note": "필라테스·요가 그룹수업 예약 서비스의 정보 구성과 수업 단위 운영 화면을 비교하는 참고 자료로 사용했다."
    },
    {
      "title": "예약/주문 환불 기준 설정 방법 : 네이버 예약주문 사업자 고객센터",
      "url": "https://help.naver.com/service/11712/contents/7824?lang=ko&osType=COMMONOS",
      "note": "취소 기준과 처리 결과를 운영자 화면에서 명시하는 방식의 비교 근거로 사용했다. 실제 12시간 기준은 제품 정본을 적용했다."
    },
    {
      "title": "개인정보 포털",
      "url": "https://www.privacy.go.kr/front/per/iass/impct/impactAssessmentResultContentsView.do",
      "note": "개인정보 최소 노출과 운영 화면의 휴대폰 번호 마스킹 원칙을 검토하는 참고 자료로 사용했다."
    },
    {
      "title": "스마트플레이스",
      "url": "https://new.smartplace.naver.com/introduction/smartplace",
      "note": "사업자가 예약 현황과 처리 필요 항목을 확인하는 운영 화면의 비교 근거로 사용했다."
    }
  ]
}
디자인 가이드 원문 전체 보기

UI/UX 디자인 가이드

1. 디자인 방향

공정한 대기 순서와 처리 근거를 가장 먼저 보여주는 차분한 운영형 UI다. 회원 화면은 카카오톡·문자 링크에서 바로 행동할 수 있도록 한 화면에 하나의 주요 행동만 강조한다. 원장 화면은 현재 정원과 처리 필요 상태를 먼저 요약하고, 취소·대기 제안·회원 응답·원장 최종 예약 승인·회원권 이력을 시간순으로 연결한다. 장식적인 필라테스 이미지보다 상태, 마감 시각, 기록의 정확성을 우선한다.

무드 키워드: 공정한 대기 순번 · 차분한 신뢰감 · 모바일 예약 · 명확한 마감 시각 · 처리 필요 우선 · 시간순 이력 · 개인정보 최소 노출 · 원장 최종 예약 승인

업계 조사에서 반영한 점

  • 카카오톡이나 문자 링크로 진입한 회원은 휴대폰 본인 확인 후 홈이 아니라 원래 요청한 수업·내 예약·빈자리 수락 화면으로 돌아가야 한다.
  • 회원은 다른 대기 회원의 정보보다 현재 내 대기 순번, 전체 대기 인원, 대기 신청 시각, 현재 상태를 확인할 때 대기 운영 기준을 이해하기 쉽다.
  • 빈자리 수락 화면은 남은 시간만 보여주지 않고 날짜가 포함된 응답 마감 절대 시각을 함께 표시해야 한다.
  • 수업 시작 2시간 전까지는 1시간, 그 이후에는 10분의 응답 시간을 적용한다. 조사 자료의 다른 시간 예시는 채택하지 않는다.
  • 조사 자료에는 회원 수락 후 자동 확정 사례가 있으나, 제품 정본에 따라 회원 수락 후 승인 대기로 전환하고 원장이 최종 승인해야 예약 확정으로 표시한다.
  • 원장 화면은 현재 상태 요약, 예약자·대기열, 처리 필요 항목, 시간순 이력을 분리하되 같은 수업 안에서 서로 이동할 수 있어야 한다.
  • 회원권 횟수의 예외 처리와 오류 수정은 기존 기록을 덮어쓰지 않고 원본 이력에 연결된 예외 복구 또는 조정 이력을 추가하는 방식으로 표현한다.
  • 문자 발송 요청과 실제 전달 결과는 다를 수 있으므로 원장 화면에서 요청, 발송 성공, 실패, 재시도, 최종 실패를 서로 다른 상태로 보여줘야 한다.
  • 확인 필요: 승인 대기 좌석의 보류 만료 시간, 문자 실패 후 재발송 기준, 일반 예약의 회원권 부족 처리, 회원권 실제 차감 시점은 확정 전까지 서버가 제공하는 상태와 시각을 그대로 표시하고 UI가 임의로 판단하지 않는다.

2. 레이아웃 전략

  • 방식: Mobile first
  • 근거: 회원은 카카오톡 등에 공유된 링크를 휴대폰에서 열고 휴대폰 본인 확인, 예약, 취소, 대기 신청, 빈자리 수락을 수행한다. 원장도 프런트 직원 없이 수업 사이에 휴대폰으로 핵심 처리를 할 가능성이 높으므로 좁은 화면에서 모든 조회와 승인이 가능해야 한다. lg 이상에서는 원장용 표, 타임라인, 상세 패널을 동시에 보여주는 12열 레이아웃으로 확장한다.
  • 좁은 화면에서도 핵심 조회·입력·처리를 제거하지 않습니다.
  • 최대 콘텐츠 폭: 1280px
  • 그리드: 모바일 4열 / 데스크톱 12열 / 기본 단위 4px
  • Breakpoint: sm 480px, md 768px, lg 1024px, xl 1440px

3. 컬러 시스템

토큰용도
Canvas#F7F8F6전체 페이지 배경
Surface#FFFFFF카드, 입력 영역, 모달과 상세 패널 배경
Text Primary#18201E제목, 본문, 핵심 수치
Text Secondary#53615D보조 설명, 시각과 메타데이터
Border#D6DEDB카드 구분선, 입력 테두리, 표 구분선
Primary#176B5B예약, 대기 신청, 수락하고 승인 요청, 저장 등 주요 행동
Primary Strong#0F574A주요 버튼 hover·pressed 상태
Primary Soft#E7F3F0선택 상태, 대기 순번 요약, 차분한 강조 배경
Info#245EA8수락 대기, 안내, 링크와 정보성 배지
Info Soft#EAF2FC정보성 알림과 수락 대기 배경
Success#237A45예약 확정, 출석, 발송 성공, 처리 완료
Success Soft#EAF6EE성공 알림과 예약 확정 배경
Warning#8A4B08승인 대기, 12시간 이내 취소, 보류, 마감 임박
Warning Soft#FFF4E5원장 확인 필요와 마감 임박 알림 배경
Danger#B42318노쇼, 오류, 문자 실패, 취소와 반려 같은 파괴적 행동
Danger Soft#FDECEC오류와 위험 알림 배경
Focus#155EEF키보드 초점 표시
Disabled#AAB5B1비활성 배경과 테두리 전용이며 작은 글자색으로 사용하지 않음

상태는 색상만으로 구분하지 않고 아이콘·문구·테두리를 함께 사용합니다.

4. 타이포그래피

  • 한글 기본: Pretendard Variable
  • 대체 글꼴: Pretendard, Apple SD Gothic Neo, Noto Sans KR, Malgun Gothic, sans-serif
  • 본문 자간: -0.01em
  • 제목 자간: -0.025em
  • 본문 행간: 1.6

5. 간격·형태

  • 간격: 4px, 8px, 12px, 16px, 20px, 24px, 32px, 40px, 48px, 64px, 80px
  • 모서리: sm 6px, md 10px, lg 16px, full 9999px

6. 컴포넌트와 상태

AppShell

  • 변형: member, owner
  • 상태: default, loading, unauthorized
  • 적용: 회원 화면은 최대 560px 단일 열과 하단 주요 행동을 사용한다. 원장 화면은 모바일에서 단일 열, lg 이상에서 좌측 내비게이션과 최대 1280px 본문을 사용한다. 권한이 없으면 운영 데이터가 잠깐이라도 노출되지 않게 한다.

TopNavigation

  • 변형: member-simple, owner-global, detail-back
  • 상태: default, scrolled
  • 적용: 회원용 링크 화면은 스튜디오명과 뒤로가기만 제공한다. 원장용은 수업 현황, 회원 기록을 주요 메뉴로 두고 수업 등록과 회원 등록은 관련 화면 안의 행동으로 제공한다.

Button

  • 변형: primary, secondary, tertiary, danger, icon
  • 상태: default, hover, focus, pressed, loading, disabled
  • 적용: 높이는 기본 48px, 조밀한 원장 표 안에서는 40px로 한다. 모바일 주요 버튼은 가로 폭을 채운다. 저장·수락 요청 중에는 중복 클릭을 막고 동작형 문구와 진행 표시를 함께 보여준다.

StatusBadge

  • 변형: neutral, info, success, warning, danger
  • 상태: 대기 중, 수락 대기, 대기 수락 만료, 승인 대기, 예약 확정, 취소 완료, 출석, 지각 출석, 노쇼, 보류, 휴강, 오류
  • 적용: 색상과 함께 상태 문구와 아이콘을 표시한다. 예약 확정, 수락 대기, 승인 대기를 같은 색이나 같은 문구로 표현하지 않는다.

ClassCard

  • 변형: member, owner, compact
  • 상태: 예약 가능, 마감, 대기 가능, 예약 확정, 대기 중, 수락 대기, 승인 대기, 휴강, 신청 종료
  • 적용: 날짜, 시작·종료 시각, 수업명, 정원, 확정 인원 또는 잔여석, 대기 상태를 표시한다. 회원용 카드는 현재 가능한 다음 행동 하나를 명확히 제공하고, 원장용 카드는 처리 필요 상태와 마감 시각을 우선 표시한다.

CapacitySummary

  • 변형: member, owner
  • 상태: available, full, offering, held, over-capacity-error
  • 적용: 회원에게는 정원과 잔여석 또는 마감 상태만 제공한다. 원장에게는 정원, 예약 확정, 승인 대기 좌석, 즉시 배정 가능한 좌석, 대기 인원을 분리해 표시한다.

DateNavigator

  • 변형: day-strip, calendar-popover, owner-day-control
  • 상태: default, selected, today, disabled
  • 적용: 회원 화면에서는 가로 스크롤 날짜 목록과 날짜 선택 팝오버를 함께 제공한다. 원장 화면에서는 이전 날짜, 오늘, 다음 날짜를 고정 순서로 배치하고 선택 날짜를 전체 표기로 보여준다.

FilterChipGroup

  • 변형: single-select, multi-select
  • 상태: default, selected, focus, disabled
  • 적용: 원장 현황의 전체, 처리 필요, 대기 있음, 빈자리 있음, 승인 대기, 수업 완료 필터에 사용한다. 선택 여부를 색상뿐 아니라 체크 아이콘과 aria-pressed로 전달한다.

WaitlistPosition

  • 변형: summary, detail, owner-row
  • 상태: 대기 중, 수락 대기, 승인 대기, 대기 수락 만료, 대기 취소, 예약 확정
  • 적용: 회원에게 현재 내 대기 순번, 전체 대기 인원, 대기 신청 시각만 표시한다. 다른 회원의 이름, 연락처, 신청 시각, 응답 결과는 노출하지 않는다. 원장용은 변경 불가능한 등록 순번과 처리 상태를 추가한다.

CountdownDeadline

  • 변형: member-offer, owner-urgent, compact
  • 상태: active, three-minutes-left, one-minute-left, expired, server-syncing
  • 적용: 날짜가 포함된 응답 마감 절대 시각을 먼저 표시하고 남은 시간을 보조로 표시한다. 서버 시각을 기준으로 계산하며 마감 시 즉시 수락 버튼을 비활성화하고 현재 상태를 다시 조회한다. 스크린 리더에는 초마다 알리지 않는다.

PhoneAuthForm

  • 변형: phone-entry, code-entry
  • 상태: default, sending, sent, invalid, expired, rate-limited, verified, unregistered
  • 적용: 휴대폰 번호와 인증번호는 눈에 보이는 라벨을 둔다. 인증번호는 숫자 키패드와 autocomplete one-time-code를 지원한다. 남은 시간, 재전송 가능 시각, 실패 이유를 텍스트로 표시하고 인증 후 저장된 진입 주소로 복귀한다.

FormField

  • 변형: text, phone, number, date, time, select, radio, textarea, switch
  • 상태: default, focus, filled, error, disabled, read-only
  • 적용: 라벨, 필수 여부, 도움말, 오류 문구를 고정된 순서로 배치한다. 오류 시 색상 외에 오류 아이콘과 구체적인 수정 방법을 표시한다. 날짜와 시각은 같은 시간대 기준이며 화면에는 날짜를 포함한 절대 시각을 사용한다.

BottomActionBar

  • 변형: single-primary, primary-secondary, destructive-confirm
  • 상태: default, loading, disabled
  • 적용: 회원 모바일 화면에서 주요 행동을 화면 하단 안전 영역 위에 고정한다. 본문 마지막 공간을 확보해 콘텐츠를 가리지 않는다. 취소처럼 되돌리기 어려운 행동은 마지막 확인 단계에서만 danger 스타일을 사용한다.

ConfirmationDialog

  • 변형: reservation, waitlist, cancellation, approval, rejection, correction
  • 상태: open, submitting, error
  • 적용: 대상 수업, 적용될 상태 변화, 회원권 횟수 영향, 후속 대기 처리 여부를 요약한다. 파괴적 행동의 취소 버튼은 먼저, 실행 버튼은 뒤에 배치한다. 모바일에서는 하단 시트, md 이상에서는 대화상자를 사용한다.

ResponsiveDataList

  • 변형: table, card-list, master-detail
  • 상태: loading, populated, empty, error
  • 적용: lg 이상에서는 실제 table 요소와 고정 헤더를 사용한다. 좁은 화면에서는 각 행을 제목·상태·핵심 수치·주요 행동을 가진 카드로 바꾸며 가로 스크롤에 핵심 처리를 의존하지 않는다.

Timeline

  • 변형: class-activity, membership-history, correction-history
  • 상태: default, filtered, corrected, error-event
  • 적용: 기본은 최신 기록부터 표시하고 처음부터 보기 전환을 제공한다. 각 이벤트에 발생 시각, 주체, 행동, 상태 변경, 변경 전후 값, 사유, 영향 범위, 후속 처리, 원본 이력 연결을 표시한다.

ApprovalPanel

  • 변형: vacancy-approval, exception-review
  • 상태: 승인 대기, approved, rejected, expired, processing
  • 적용: 회원, 마스킹된 휴대폰 번호, 수업, 회원권 잔여 횟수와 만료일, 중복 예약 여부, 대기 신청 시각, 수락 시각, 승인 대기 좌석, 서버가 제공한 보류 만료 시각을 표시한다. 승인과 반려 모두 결과와 사유를 기록한다.

AttendanceControl

  • 변형: single-member, class-bulk
  • 상태: 미처리, 출석, 지각 출석, 노쇼, 보류
  • 적용: 출석 상태를 서로 배타적인 선택으로 제공한다. 노쇼 확정에는 회원권 영향과 사유를 확인하고, 변경 시 기존 기록을 덮어쓰지 않고 조정 이력을 생성한다.

NotificationStatus

  • 변형: auth-sms, vacancy-sms
  • 상태: 요청, 발송 성공, 실패, 재시도, 최종 실패
  • 적용: 메시지 ID, 요청 시각, 발송 시각, 전달 상태, 실패 코드, 재시도 횟수를 원장 상세에서 확인하게 한다. 재발송 또는 다음 대기 회원 전환은 확정된 운영 정책이 없으므로 자동 행동으로 추정하지 않는다.

FeedbackMessage

  • 변형: inline, banner, toast, full-page-result
  • 상태: success, info, warning, error
  • 적용: 예약·취소·수락처럼 상태가 바뀌는 작업은 토스트만 사용하지 말고 화면 본문에도 결과를 남긴다. 오류에는 현재 처리 상태, 재시도 가능 여부, 이미 처리된 시각을 구체적으로 표시한다.

SkeletonAndEmptyState

  • 변형: card, list, table, timeline, empty
  • 상태: loading, no-data, filtered-empty, failed
  • 적용: 로딩 중 기존 수치를 0으로 표시하지 않는다. 빈 상태는 데이터가 없는 경우와 필터 결과가 없는 경우를 구분하고, 가능한 다음 행동을 하나만 제공한다.

7. 화면별 적용

member · 회원 화면

대기 상세 전용 화면이다. 상단에 수업명과 날짜·시각, 이어서 상태 배지, 현재 내 대기 순번, 전체 대기 인원, 대기 신청 시각을 큰 수치로 표시한다. 수락 대기이면 응답 마감 절대 시각과 남은 시간을 보여주고 vacancy-accept로 이동한다. 승인 대기이면 좌석이 임시 보류 중이며 원장 최종 예약 승인을 기다린다는 문구를 표시한다. 다른 회원 정보는 표시하지 않는다.

class · 수업별 화면

상단 고정 요약에 날짜·시각, 수업명, 정원, 예약 확정, 승인 대기 좌석, 대기 인원, 현재 문제를 표시한다. 본문은 처리 필요, 예약자, 대기열, 전체 이력 탭으로 구성한다. 전체 이력은 취소 사유 제출, 무료 취소 마감 시각 판정, 횟수 차감, 예외 복구, 대기 제안, 문자 결과, 회원 응답, 원장 승인·반려, 출석 상태, 오류 수정을 시간순으로 묶는다. 각 수정 이벤트에서 원본 이력과 MS3로 이동할 수 있게 한다.

member-phone-auth · 회원용 휴대폰 인증 화면

최대 480px 단일 열로 구성한다. 첫 단계는 휴대폰 번호와 인증번호 받기, 두 번째 단계는 마스킹된 번호, 인증번호, 만료까지 남은 시간, 재전송 가능 시각, 번호 변경으로 구성한다. 등록되지 않은 번호는 원장에게 회원 등록을 요청하라는 안내를 표시한다. 인증 완료 후 카카오톡 예약 링크, 내 예약 또는 빈자리 수락 등 처음 요청한 주소로 복귀한다.

member-class-list · 회원용 수업 목록·예약·대기 신청 화면

상단에 스튜디오명, 날짜 선택, 내 예약 이동을 배치한다. 날짜별 수업 카드는 시작·종료 시각, 수업명, 정원, 잔여석 또는 마감, 대기 가능 상태, 무료 취소 마감 시각 요약을 표시한다. 자리가 있으면 예약하기, 만석이면 대기 신청, 이미 예약했으면 예약 상세 보기, 이미 대기 중이면 현재 대기 순번 보기를 제공한다. 저장 직전 자리가 사라지면 대기 신청으로 전환할 수 있도록 현재 상태를 다시 보여준다.

member-reservations · 회원용 내 예약·대기 순번·취소 화면

예약 확정, 대기 중, 처리 완료의 세 구역 또는 탭으로 구성한다. 카드마다 수업 일시, 수업명, 상태, 무료 취소 마감 시각을 표시한다. 대기 카드는 현재 내 대기 순번과 전체 대기 인원을 표시하고, 수락 대기는 응답 마감 시각, 승인 대기는 원장 확인 중임을 표시한다. 취소는 사유 필수 선택, 필요 시 상세 내용, 예상 횟수 처리, 최종 확인 순서로 진행한다.

vacancy-accept · 문자 링크에서 여는 빈자리 수락 화면

문자 링크의 제안 건과 회원을 확인한 뒤 수업명, 날짜·시각, 우선 제안된 빈자리, 응답 마감 절대 시각, 남은 시간, 회원권 상태를 표시한다. 주요 버튼은 수락하고 승인 요청, 보조 버튼은 이번 자리는 거절하기로 한다. 수락 직후 버튼을 잠그고 서버에서 유효성·정원·중복 요청을 다시 확인한다. 성공하면 승인 대기를 표시하며 예약 확정이라고 표현하지 않는다. 만료·이미 처리·다른 기기 처리 상태에는 처리 시각과 현재 결과를 보여주고 수락을 다시 실행하지 않는다.

owner-class-status · 원장용 날짜별 수업·예약 인원·대기 현황 화면

상단에 날짜 이동과 전체, 처리 필요, 대기 있음, 빈자리 있음, 승인 대기 필터를 둔다. 수업은 시간순으로 표시하되 처리 필요 필터에서는 응답 마감 임박, 승인 대기, 빈자리와 대기 동시 존재, 문자 실패, 출결 관리 미처리 순으로 강조한다. 각 항목에 정원, 예약 확정, 승인 대기 좌석, 대기 인원, 현재 제안 상태와 마감 시각을 표시한다. lg 이상은 표, 좁은 화면은 카드 목록이며 수업 선택 시 class로 이동한다.

owner-member-records · 원장용 회원별 회원권 횟수·취소 예외·노쇼 기록 화면

상단 검색은 회원 이름과 마스킹된 휴대폰 번호를 지원한다. 회원 상세에 횟수제 회원권의 총 횟수, 잔여 횟수, 시작일, 만료일, 회원권 이력 합계 일치 여부를 요약한다. 하단은 회원권 이력, 취소·예외, 출결 관리·노쇼 탭으로 나누고 각 기록에서 관련 class 화면으로 이동한다. 횟수 변경은 원본 이력을 삭제하지 않고 조정 또는 예외 복구로 추가한다.

MS1 · 원장용 수업 등록·수정 화면

수업명, 날짜, 시작·종료 시각, 정원, 예약 가능 상태, 대기 신청 가능 상태를 입력한다. 정원은 5~15명으로 제한하고 현재 예약 확정 인원보다 작게 줄일 수 없다. 무료 취소 마감 시각은 시작 12시간 전으로 자동 계산해 읽기 전용으로 보여준다. 진행 중인 대기 제안이 있을 때 시간이나 정원을 바꾸면 영향을 받는 제안, 좌석, 마감 시각을 저장 전에 요약한다.

MS2 · 원장용 빈자리 수락 승인 화면

최상단에 승인 대기 좌석과 서버가 제공한 보류 만료 시각을 강조한다. 회원명, 마스킹된 휴대폰 번호, 수업, 대기 순번, 대기 신청 시각, 문자 발송 결과, 수락 시각, 회원권 잔여 횟수·만료일, 동일 시간 예약 여부, 취소·노쇼 참고 기록을 표시한다. 주요 행동은 승인하고 예약 확정, 보조 위험 행동은 반려하고 다음 대기 회원 처리로 둔다. 반려 사유는 필수이며 결과는 회원 화면과 시간순 이력에 반영한다.

MS3 · 원장용 오류 수정·조정 이력 화면

중복 예약, 대기 순서 누락, 잘못된 취소·노쇼·회원권 횟수 처리를 유형과 기간으로 검색한다. 왼쪽 또는 상단에 문제 기록, 오른쪽 또는 하단에 원본 이력, 연결 기록, 변경 전후 값을 표시한다. 수정은 원본 삭제가 아니라 새 조정 이력을 만드는 방식이며 수정 사유, 처리자, 처리 시각, 회원 알림 여부를 필수로 남긴다. 저장 전 좌석, 대기 상태, 회원권 잔여 횟수에 미치는 영향을 요약한다.

MS4 · 원장용 회원·회원권 초기 등록 화면

회원 정보와 횟수제 회원권 정보를 두 구역으로 나눈다. 회원 이름, 휴대폰 번호, 회원권 상품명, 총 횟수, 잔여 횟수, 시작일, 만료일을 입력한다. 같은 스튜디오의 동일 휴대폰 번호가 있으면 중복 후보를 보여주고 저장을 막는다. 잔여 횟수가 총 횟수보다 크거나 만료일이 시작일보다 빠르면 필드 단위 오류를 표시한다. 저장 결과에는 등록 처리자와 등록 시각을 보여준다.

8. 에셋과 모션

  • 가정: 서비스 브랜드명과 로고가 확정되지 않았으므로 초기 구현은 스튜디오명을 텍스트 워드마크로 표시한다.
  • 아이콘은 하나의 SVG 선형 아이콘 세트로 통일하고 기본 20px, 주요 상태 24px, 선 두께 1.75~2px를 사용한다.
  • 예약 확정, 수락 대기, 승인 대기, 경고, 오류, 출석, 노쇼 상태별 아이콘을 준비하며 색상 없이도 의미를 구분한다.
  • 회원 사진과 다른 회원을 연상시키는 아바타는 사용하지 않는다.
  • 장식용 필라테스 사진은 첫 개발에 필요하지 않다. 빈 상태는 단순 아이콘과 다음 행동 문구로 구성한다.
  • 문자 템플릿에는 스튜디오명, 수업 날짜·시각, 수업명, 응답 마감 절대 시각, 만료되는 수락 링크, 원장 최종 예약 승인 안내를 포함한다.
  • 웹 앱 아이콘과 파비콘은 Primary 색상의 단순 캘린더·순번 조합 심벌을 임시 자산으로 사용하며 브랜드 확정 후 교체 가능하게 한다.
  • 기본 전환: 180ms cubic-bezier(0.2, 0, 0, 1)
  • prefers-reduced-motion 사용자는 불필요한 움직임을 제거합니다.
  • 다크모드: 초기 범위에서 제외

9. 접근성

  • KWCAG 2.2와 WCAG 2.1 AA를 기준으로 일반 텍스트 명도 대비 4.5:1 이상, 큰 텍스트와 핵심 UI 그래픽은 3:1 이상을 확보한다.
  • 예약 확정, 수락 대기, 승인 대기, 노쇼, 오류 상태는 색상만으로 구분하지 않고 문구와 아이콘을 함께 사용한다.
  • 모든 터치 대상은 최소 44×44px로 만들고 인접한 주요 행동 사이에 최소 8px 간격을 둔다.
  • 키보드 초점은 2px Focus 색상 외곽선과 2px 간격으로 명확히 표시하며 논리적인 탭 순서를 유지한다.
  • 입력 필드에는 placeholder와 별도로 항상 보이는 라벨을 제공하고 오류 문구를 해당 필드와 프로그램 방식으로 연결한다.
  • 제출 오류가 여러 개면 화면 상단에 오류 요약을 제공하고 각 오류 필드로 이동할 수 있게 한다.
  • 응답 마감 타이머는 초마다 aria-live로 읽지 않는다. 3분, 1분, 만료 등 의미 있는 변화만 알리고 절대 마감 시각은 항상 텍스트로 제공한다.
  • 상태 변경과 저장 결과는 aria-live polite로 알리되 오류와 만료처럼 즉시 행동이 필요한 경우에는 assertive 사용을 제한적으로 적용한다.
  • 모달과 하단 시트는 열릴 때 초점을 내부로 이동하고, 닫힐 때 실행 버튼으로 돌려보내며, 열린 동안 배경에 초점이 이동하지 않게 한다.
  • 원장용 표는 caption, thead, th, scope를 사용하고 모바일 카드로 전환돼도 각 값의 라벨을 생략하지 않는다.
  • 휴대폰 번호는 회원 화면에 본인의 마스킹 번호만 표시하고, 다른 회원의 이름·휴대폰 번호·취소 사유·회원권 상태를 노출하지 않는다.
  • 모션 감소 설정이 켜지면 카운트다운 강조 애니메이션, 카드 이동, 자동 스크롤을 제거하고 즉시 상태 전환으로 대체한다.

10. 구현 체크리스트

  • 디자인 토큰을 CSS 변수 또는 Tailwind theme에 한 번만 정의합니다.
  • Pretendard와 지정 자간이 모든 한글 화면에 적용되는지 확인합니다.
  • 선택한 레이아웃 전략과 breakpoint가 화면마다 달라지지 않게 합니다.
  • 버튼·입력·표·대화상자의 focus, disabled, error 상태를 확인합니다.
  • 모바일과 데스크톱에서 핵심 사용자 흐름을 각각 끝까지 확인합니다.

조사 출처

디자인 가이드 — 동네 필라테스 예약과 대기 순번 | Prometheon