diff --git a/.qa/issue-410/after/nav-active-blue-1280.png b/.qa/issue-410/after/nav-active-blue-1280.png new file mode 100644 index 0000000..6c1797b Binary files /dev/null and b/.qa/issue-410/after/nav-active-blue-1280.png differ diff --git a/.qa/issue-410/after/nav-active-blue-390.png b/.qa/issue-410/after/nav-active-blue-390.png new file mode 100644 index 0000000..af805c2 Binary files /dev/null and b/.qa/issue-410/after/nav-active-blue-390.png differ diff --git a/.qa/issue-414/after/admin-desktop.png b/.qa/issue-414/after/admin-desktop.png new file mode 100644 index 0000000..6ba94ca Binary files /dev/null and b/.qa/issue-414/after/admin-desktop.png differ diff --git a/.qa/issue-414/after/admin-mobile.png b/.qa/issue-414/after/admin-mobile.png new file mode 100644 index 0000000..ae65cfb Binary files /dev/null and b/.qa/issue-414/after/admin-mobile.png differ diff --git a/.qa/issue-414/after/admin-tablet.png b/.qa/issue-414/after/admin-tablet.png new file mode 100644 index 0000000..d39248a Binary files /dev/null and b/.qa/issue-414/after/admin-tablet.png differ diff --git a/.qa/issue-414/after/ai-desktop.png b/.qa/issue-414/after/ai-desktop.png new file mode 100644 index 0000000..888c985 Binary files /dev/null and b/.qa/issue-414/after/ai-desktop.png differ diff --git a/.qa/issue-414/after/ai-mobile.png b/.qa/issue-414/after/ai-mobile.png new file mode 100644 index 0000000..b4bd591 Binary files /dev/null and b/.qa/issue-414/after/ai-mobile.png differ diff --git a/.qa/issue-414/after/ai-tablet.png b/.qa/issue-414/after/ai-tablet.png new file mode 100644 index 0000000..8448f38 Binary files /dev/null and b/.qa/issue-414/after/ai-tablet.png differ diff --git a/.qa/issue-414/after/attendance-desktop.png b/.qa/issue-414/after/attendance-desktop.png new file mode 100644 index 0000000..4ab02a8 Binary files /dev/null and b/.qa/issue-414/after/attendance-desktop.png differ diff --git a/.qa/issue-414/after/attendance-mobile.png b/.qa/issue-414/after/attendance-mobile.png new file mode 100644 index 0000000..39d5c5a Binary files /dev/null and b/.qa/issue-414/after/attendance-mobile.png differ diff --git a/.qa/issue-414/after/attendance-tablet.png b/.qa/issue-414/after/attendance-tablet.png new file mode 100644 index 0000000..c19286c Binary files /dev/null and b/.qa/issue-414/after/attendance-tablet.png differ diff --git a/.qa/issue-414/after/calendar-desktop.png b/.qa/issue-414/after/calendar-desktop.png new file mode 100644 index 0000000..6379c6b Binary files /dev/null and b/.qa/issue-414/after/calendar-desktop.png differ diff --git a/.qa/issue-414/after/calendar-mobile.png b/.qa/issue-414/after/calendar-mobile.png new file mode 100644 index 0000000..4d25295 Binary files /dev/null and b/.qa/issue-414/after/calendar-mobile.png differ diff --git a/.qa/issue-414/after/calendar-tablet.png b/.qa/issue-414/after/calendar-tablet.png new file mode 100644 index 0000000..e62b3ef Binary files /dev/null and b/.qa/issue-414/after/calendar-tablet.png differ diff --git a/.qa/issue-414/after/chat-desktop.png b/.qa/issue-414/after/chat-desktop.png new file mode 100644 index 0000000..6e843a2 Binary files /dev/null and b/.qa/issue-414/after/chat-desktop.png differ diff --git a/.qa/issue-414/after/chat-mobile.png b/.qa/issue-414/after/chat-mobile.png new file mode 100644 index 0000000..32c0b38 Binary files /dev/null and b/.qa/issue-414/after/chat-mobile.png differ diff --git a/.qa/issue-414/after/chat-tablet.png b/.qa/issue-414/after/chat-tablet.png new file mode 100644 index 0000000..5716111 Binary files /dev/null and b/.qa/issue-414/after/chat-tablet.png differ diff --git a/.qa/issue-414/after/drive-desktop.png b/.qa/issue-414/after/drive-desktop.png new file mode 100644 index 0000000..3e0d62e Binary files /dev/null and b/.qa/issue-414/after/drive-desktop.png differ diff --git a/.qa/issue-414/after/drive-mobile.png b/.qa/issue-414/after/drive-mobile.png new file mode 100644 index 0000000..519e368 Binary files /dev/null and b/.qa/issue-414/after/drive-mobile.png differ diff --git a/.qa/issue-414/after/drive-tablet.png b/.qa/issue-414/after/drive-tablet.png new file mode 100644 index 0000000..f19fa5a Binary files /dev/null and b/.qa/issue-414/after/drive-tablet.png differ diff --git a/.qa/issue-414/after/home-desktop.png b/.qa/issue-414/after/home-desktop.png new file mode 100644 index 0000000..4220286 Binary files /dev/null and b/.qa/issue-414/after/home-desktop.png differ diff --git a/.qa/issue-414/after/home-mobile.png b/.qa/issue-414/after/home-mobile.png new file mode 100644 index 0000000..aeff37c Binary files /dev/null and b/.qa/issue-414/after/home-mobile.png differ diff --git a/.qa/issue-414/after/home-tablet.png b/.qa/issue-414/after/home-tablet.png new file mode 100644 index 0000000..f00202b Binary files /dev/null and b/.qa/issue-414/after/home-tablet.png differ diff --git a/.qa/issue-414/after/light-calendar-desktop.png b/.qa/issue-414/after/light-calendar-desktop.png new file mode 100644 index 0000000..05585b0 Binary files /dev/null and b/.qa/issue-414/after/light-calendar-desktop.png differ diff --git a/.qa/issue-414/after/light-home-desktop.png b/.qa/issue-414/after/light-home-desktop.png new file mode 100644 index 0000000..7426cf3 Binary files /dev/null and b/.qa/issue-414/after/light-home-desktop.png differ diff --git a/.qa/issue-414/after/light-login-desktop.png b/.qa/issue-414/after/light-login-desktop.png new file mode 100644 index 0000000..4945be2 Binary files /dev/null and b/.qa/issue-414/after/light-login-desktop.png differ diff --git a/.qa/issue-414/after/login-desktop.png b/.qa/issue-414/after/login-desktop.png new file mode 100644 index 0000000..8d105ff Binary files /dev/null and b/.qa/issue-414/after/login-desktop.png differ diff --git a/.qa/issue-414/after/login-mobile.png b/.qa/issue-414/after/login-mobile.png new file mode 100644 index 0000000..d4d556e Binary files /dev/null and b/.qa/issue-414/after/login-mobile.png differ diff --git a/.qa/issue-414/after/login-tablet.png b/.qa/issue-414/after/login-tablet.png new file mode 100644 index 0000000..44ca484 Binary files /dev/null and b/.qa/issue-414/after/login-tablet.png differ diff --git a/.qa/issue-414/after/members-desktop.png b/.qa/issue-414/after/members-desktop.png new file mode 100644 index 0000000..3e17c5a Binary files /dev/null and b/.qa/issue-414/after/members-desktop.png differ diff --git a/.qa/issue-414/after/members-mobile.png b/.qa/issue-414/after/members-mobile.png new file mode 100644 index 0000000..7fcfa79 Binary files /dev/null and b/.qa/issue-414/after/members-mobile.png differ diff --git a/.qa/issue-414/after/members-tablet.png b/.qa/issue-414/after/members-tablet.png new file mode 100644 index 0000000..e975b38 Binary files /dev/null and b/.qa/issue-414/after/members-tablet.png differ diff --git a/.qa/issue-414/after/metadata.json b/.qa/issue-414/after/metadata.json new file mode 100644 index 0000000..c83d69a --- /dev/null +++ b/.qa/issue-414/after/metadata.json @@ -0,0 +1,639 @@ +{ + "capturedAt": "2026-08-22T02:46:41.542Z", + "source": "issue-414-after", + "sourceCommit": "753febc17546ca4bdd7c3525f53e43fc719f7de1", + "viewports": [ + { + "name": "mobile", + "width": 390, + "height": 844 + }, + { + "name": "tablet", + "width": 768, + "height": 1024 + }, + { + "name": "desktop", + "width": 1280, + "height": 900 + } + ], + "routes": [ + { + "name": "home", + "path": "/", + "token": "mock-token-1" + }, + { + "name": "chat", + "path": "/chat", + "token": "mock-token-1" + }, + { + "name": "calendar", + "path": "/calendar", + "token": "mock-token-1" + }, + { + "name": "attendance", + "path": "/attendance", + "token": "mock-token-1" + }, + { + "name": "work-schedules", + "path": "/work-schedules", + "token": "mock-token-1" + }, + { + "name": "drive", + "path": "/drive", + "token": "mock-token-1" + }, + { + "name": "ai", + "path": "/ai", + "token": "mock-token-1" + }, + { + "name": "members", + "path": "/members", + "token": "mock-token-1" + }, + { + "name": "my-page", + "path": "/my-page", + "token": "mock-token-1" + }, + { + "name": "team-management", + "path": "/team-management", + "token": "mock-token-2" + }, + { + "name": "admin", + "path": "/admin", + "token": "mock-token-1" + }, + { + "name": "login", + "path": "/login" + }, + { + "name": "register", + "path": "/register" + }, + { + "name": "verify-email", + "path": "/verify-email" + } + ], + "results": [ + { + "name": "home", + "requestedPath": "/", + "role": "ADMIN", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/", + "scrollWidth": 390, + "scrollHeight": 1661, + "bodyText": "WORKSPACE\n\n홈\n09:13\n오늘은 휴무입니다\n오늘 근무가 종료되어 예정 시간과 함께 비교할 수 있습니다.\n휴무일에도 출근 기록이 있습니다\n\n오늘은 휴무일로 설정되어 있지만 실제 출퇴근 기록이 남아 있습니다.\n\n출근은 220.69 대역 IP에서만 가능합니다.\n오전 9:02 - 오후 6:15\n출근 내역 초기화\n오늘 일정\n\n오늘 등록된 일정이 없습니다\n\n캘린더 보기\n# General\n김\n김리더\n모두 좋은 아침입니다!\n오전 10:45\n박\n박팀장\n좋은 아침이에요 :)\n오전 10:55\n채팅 열기\n오늘 할 일\n주간 회의 안건 정리\n높음\n10:00 오전 까지\n완료 처리\n정산 시트 점검\n높음\n8:00 오후 까지\n완료됨\n출퇴근 누락자 확인\n보통\n6:30 오후 까지\n완료 처리", + "durationMs": 1857 + }, + { + "name": "chat", + "requestedPath": "/chat", + "role": "ADMIN", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/chat", + "scrollWidth": 390, + "scrollHeight": 985, + "bodyText": "WORKSPACE\n\n채팅\n대화 목록\n\n대화할 채널이나 대상을 먼저 선택한 뒤 대화방으로 들어갑니다.\n\n채널\n# 전체 공지\n안녕하세요!\n# 디자인팀\n디자인 피드백 부탁드려요\n# 개발팀\nPR 리뷰 요청드립니다\n개인 대화\n최\n최개발\n1팀\n• 자리 비움\n박\n박팀장\n2팀\n• 자리 비움\n이\n이멤버\n3팀\n• 자리 비움", + "durationMs": 1744 + }, + { + "name": "calendar", + "requestedPath": "/calendar", + "role": "ADMIN", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/calendar", + "scrollWidth": 390, + "scrollHeight": 1424, + "bodyText": "WORKSPACE\n\n캘린더\n오늘\n2026년 8월\n월\n주\n일\n목록\n일\n\t\n월\n\t\n화\n\t\n수\n\t\n목\n\t\n금\n\t\n토\n\n\n26일\n\t\n27일\n\t\n28일\n\t\n29일\n\t\n30일\n\t\n31일\n\t\n1일\n\n\n2일\n\t\n3일\n\t\n4일\n\t\n5일\n\t\n6일\n\t\n7일\n\t\n8일\n\n\n9일\n\t\n10일\n\t\n11일\n\t\n12일\n\t\n13일\n\t\n14일\n\t\n15일\n\n\n16일\n\t\n17일\n\t\n18일\n\t\n19일\n\t\n20일\n\t\n21일\n\t\n22일\n오전 10시\n주간 회의 안건 정리\n오후 6:30\n출퇴근 누락자 확인\n\n\n23일\n오후 2시\n신입 팀 공지 업로드\n\t\n24일\n\t\n25일\n\t\n26일\n\t\n27일\n\t\n28일\n\t\n29일\n\n\n30일\n\t\n31일\n\t\n1일\n\t\n2일\n\t\n3일\n\t\n4일\n\t\n5일\n내 할일\n팀 할일\n일정\n할일\n마감 시간\n:\n마감 날짜\n중요도\n높음\n보통\n낮음\n추가\n오늘의 할일\n주간 회의 안건 정리", + "durationMs": 1833 + }, + { + "name": "attendance", + "requestedPath": "/attendance", + "role": "ADMIN", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/attendance", + "scrollWidth": 390, + "scrollHeight": 1367, + "bodyText": "WORKSPACE\n\n출퇴근\n\nATTENDANCE · 2026-08-22\n\n출석 관리\n\n오늘의 출석 현황과 확인이 필요한 기록을 한 곳에서 관리합니다.\n\nCSV 내보내기\n2026-08-22\n오늘\n이번 주\n날짜 선택\n전체 기록\n3\n2026-08-22\n처리 필요\n2\n근무 중 기록\n근무 중\n2\n현재 진행 중\n퇴근 완료\n1\n완료 기록\n\nOPERATIONS FIRST\n\n처리 필요\n2건이 먼저 표시됩니다.\n멤버 검색\n전체\n근무 중\n퇴근 완료\n\nATTENDANCE RECORDS\n\n2026-08-22 기록\n3명\n박\n박팀장\n2026-08-22\n근무 중\n이\n이멤버\n2026-08-22\n근무 중\n김\n김리더\n2026-08-22\n퇴근 완료", + "durationMs": 1771 + }, + { + "name": "work-schedules", + "requestedPath": "/work-schedules", + "role": "ADMIN", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/work-schedules", + "scrollWidth": 390, + "scrollHeight": 2558, + "bodyText": "WORKSPACE\n\n근무 일정\n\n반복 근무와 날짜별 근무 일정을 같은 캘린더에서 보고 바로 관리할 수 있습니다.\n\n날짜 클릭으로 개별 일정을 추가하고, 역할 범위에 따라 다른 사람 일정도 함께 확인합니다.\n근무 일정 캘린더\n\n날짜를 눌러 개인 근무 일정을 추가하고, 역할 범위에 따라 다른 사람 근무 일정도 함께 확인합니다.\n\n전체\n팀별\n개인\n내 반복 일정\n공유 반복 일정\n날짜별 추가 일정\n팀 공유 일정\n날짜별 일정 추가\n오늘\n2026년 8월\n월\n목록\n일\n\t\n월\n\t\n화\n\t\n수\n\t\n목\n\t\n금\n\t\n토\n\n\n26일\n\t\n27일\n08:30\n이멤버\n09:00\n김리더\n10:00\n박팀장\n\t\n28일\n09:00\n김리더\n\t\n29일\n08:30\n이멤버\n\t\n30일\n09:00\n김리더\n10:00\n박팀장\n\t\n31일\n08:30\n이멤버\n09:00\n김리더\n22:00\n최개발\n\t\n1일", + "durationMs": 1804 + }, + { + "name": "drive", + "requestedPath": "/drive", + "role": "ADMIN", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/drive", + "scrollWidth": 390, + "scrollHeight": 2014, + "bodyText": "WORKSPACE\n\n드라이브\n\nSHARED LIBRARY\n\n모든 멤버가 함께 쓰는 공용 문서함입니다. 업로드한 파일은 팀 전체가 바로 확인할 수 있습니다.\n\n전체 멤버 공유\n공용 파일 업로드\n총 파일\n3개\n사용 용량\n1.2 MB\n최근 업로드\n3월 18일 오후 8:00\n팀 공유 라이브러리\n빠른 공유 업로드\n\n회의록, 산출물, 참고 자료를 올리면 일반 멤버를 포함한 팀 전체가 바로 같은 파일을 확인합니다.\n\n새 공유 파일 추가\n현재 사용자\n김리더\n\n일반 멤버, 팀장, 관리자 모두 같은 공유 드라이브를 사용합니다.\n\n업로드 참여자\n3명\n대표 업로더\n이멤버\n파일 라이브러리\n\n이름, 업로더, 업로드 시점을 함께 보여줘서 바로 찾을 수 있게 정리했습니다.\n\n회의록_0318.docx\n이멤버\n3월 18일 오후 8:00\n50 KB\n디자인 시안 v2.fig\n박", + "durationMs": 1775 + }, + { + "name": "ai", + "requestedPath": "/ai", + "role": "ADMIN", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/ai", + "scrollWidth": 390, + "scrollHeight": 964, + "bodyText": "WORKSPACE\n\nAI\n\n공유 문서를 바탕으로 답변하는 팀 어시스턴트입니다.\n\n안녕하세요! 저는 yANUs AI입니다. 파일 드라이브에 공유된 문서를 바탕으로 질문에 답변해 드립니다. 무엇을 도와드릴까요?\n\n추천 질문\n\n오늘 일정 요약해줘\n공유된 파일 목록 알려줘\n프로젝트 진행 상황 정리해줘", + "durationMs": 1762 + }, + { + "name": "members", + "requestedPath": "/members", + "role": "ADMIN", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/members", + "scrollWidth": 390, + "scrollHeight": 1732, + "bodyText": "WORKSPACE\n\n멤버\n\n멤버 상태와 역할을 한 곳에서 확인하고 관리합니다.\n\n관리자 전용\n멤버 초대\n팀\n전체 팀\n1팀\n2팀\n3팀\n역할\n전체 역할\n관리자\n팀장\n멤버\n전체 멤버 4명\n멤버 목록\n\n활성 멤버를 팀과 역할 기준으로 빠르게 확인할 수 있습니다.\n\n프로필\t팀\t역할\t상태\t관리\n\n김\n김리더\n\t1팀\t\n관리자\t\n활성\n\t\n관리 불가\n\n\n최\n최개발\n\t1팀\t멤버\t\n활성화\n\t\n\n\n박\n박팀장\n\t2팀\t팀장\t\n활성화\n\t\n\n\n이\n이멤버\n\t3팀\t멤버\t\n활성화\n\t\n팀별 멤버 수\n\n비활성 멤버는 집계에서 제외됩니다.\n\n1팀\n2\n2팀\n1\n3팀\n1\n역할 분포\n\n현재 활성 멤버 기준으로 역할 비중을 보여줍니다.\n\n관리자 1\n팀장 1\n멤버 2", + "durationMs": 1759 + }, + { + "name": "my-page", + "requestedPath": "/my-page", + "role": "ADMIN", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/my-page", + "scrollWidth": 390, + "scrollHeight": 1513, + "bodyText": "WORKSPACE\n\n마이페이지\n\nMY PAGE\n\n프로필, 알림, 테마, 정산, 보안 정보를 한 곳에서 관리하세요.\n\n다크 모드 사용 중\n선택한 테마는 브라우저에 저장되어 다음 방문에도 유지됩니다.\n프로필\n알림\n테마\n정산\n보안\n\nPROFILE\n\n내 계정과 소속 정보를 정리합니다.\n\n표시 이름, 역할, 팀 정보를 확인하고 개인 프로필을 안전하게 관리할 수 있습니다.\n\n계정 기본 정보\n프로필 정보\n김\n\n김리더\n\nADMIN · 1팀\n\n표시 이름\n역할\n팀\n저장", + "durationMs": 1818 + }, + { + "name": "team-management", + "requestedPath": "/team-management", + "role": "TEAM_LEAD", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/team-management", + "scrollWidth": 390, + "scrollHeight": 863, + "bodyText": "WORKSPACE\n\n팀 관리\n\n팀장은 같은 팀 멤버를 확인하고 팀 이동만 관리할 수 있습니다.\n\n2팀 멤버 1명\n팀 멤버 목록\n\n팀장은 같은 팀의 활성 일반 멤버만 다른 팀으로 이동할 수 있습니다.\n\n역할 변경, 상태 변경, 퇴출은 관리자만 가능합니다.\n\n이름\t이메일\t현재 팀\t역할\t상태\t팀 변경\n\n\n표시할 멤버가 없습니다.\n\n검색 조건을 바꾸거나 멤버 상태를 다시 확인해 주세요.", + "durationMs": 1800 + }, + { + "name": "admin", + "requestedPath": "/admin", + "role": "ADMIN", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/admin", + "scrollWidth": 390, + "scrollHeight": 3783, + "bodyText": "WORKSPACE\n\n관리자\n\n출근 현황과 멤버 상태를 한 곳에서 관리합니다.\n\nCSV 내보내기\n출근 현황\n멤버 관리\n팀 관리\n감사 로그\n지각비 정산\n운영 설정\n활성 멤버\n4명\n\n현재 운영 중인 전체 인원\n\n활성 팀\n3개\n\n근무 일정을 관리 중인 팀 수\n\n오늘 기록\n3건\n\n출근 또는 퇴근 기록이 남은 인원\n\n오늘 미기록\n1명\n\n확인 필요한 인원, 퇴근 1명 완료\n\n팀원 출근 현황\n2026-08-22\n2\n근무 중\n1\n퇴근\n2\n미출근\n박\n박팀장\n2팀\n근무 중\n09:45 ~\n이\n이멤버\n3팀\n근무 중\n09:00 ~\nOPERATIONS\n출퇴근 예외 처리\n\n총무와 팀장이 오늘 운영 이슈를 한 화면에서 보고, 메모와 처리 상태를 바로 남길 수 있습니다.\n\n오늘 미퇴근자 일괄 처리 (1)\n처리 대기\n3건\n\n2026-08-22 기준으로 아직 판단이 필요한 예외", + "durationMs": 1833 + }, + { + "name": "login", + "requestedPath": "/login", + "role": "PUBLIC", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/login", + "scrollWidth": 390, + "scrollHeight": 844, + "bodyText": "yANUs\n동아리 그룹웨어\n이메일\n비밀번호\n로그인\n아직 계정이 없으신가요? 회원가입", + "durationMs": 1718 + }, + { + "name": "register", + "requestedPath": "/register", + "role": "PUBLIC", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/register", + "scrollWidth": 390, + "scrollHeight": 924, + "bodyText": "yANUs\n새 계정을 만들어 시작해 보세요\n이름\n이메일\n팀\n회원가입 시 모든 신규 사용자는 신입 팀으로 자동 배정됩니다.\n비밀번호\n비밀번호 확인\n회원가입\n이미 계정이 있으신가요? 로그인", + "durationMs": 1734 + }, + { + "name": "verify-email", + "requestedPath": "/verify-email", + "role": "PUBLIC", + "viewport": "mobile", + "viewportWidth": 390, + "viewportHeight": 844, + "path": "/verify-email", + "scrollWidth": 390, + "scrollHeight": 1044, + "bodyText": "yANUs\n이메일 인증\n이메일을 확인해 주세요\n\n회원가입이 거의 끝났습니다.\n메일로 받은 인증 코드를 입력해야 로그인할 수 있습니다.\n\n인증 코드\n인증 확인\n메일을 받지 못하셨나요?\n\n아래 이메일로 인증 코드를 다시 받을 수 있습니다.\n\n이메일\n인증 메일 다시 보내기\n이미 인증을 마치셨나요? 로그인", + "durationMs": 1738 + }, + { + "name": "home", + "requestedPath": "/", + "role": "ADMIN", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/", + "scrollWidth": 768, + "scrollHeight": 1648, + "bodyText": "WORKSPACE\n\n홈\n09:13\n오늘은 휴무입니다\n오늘 근무가 종료되어 예정 시간과 함께 비교할 수 있습니다.\n휴무일에도 출근 기록이 있습니다\n\n오늘은 휴무일로 설정되어 있지만 실제 출퇴근 기록이 남아 있습니다.\n\n출근은 220.69 대역 IP에서만 가능합니다.\n오전 9:02 - 오후 6:15\n출근 내역 초기화\n오늘 일정\n\n오늘 등록된 일정이 없습니다\n\n캘린더 보기\n# General\n김\n김리더\n모두 좋은 아침입니다!\n오전 10:45\n박\n박팀장\n좋은 아침이에요 :)\n오전 10:55\n채팅 열기\n오늘 할 일\n주간 회의 안건 정리\n높음\n10:00 오전 까지\n완료 처리\n정산 시트 점검\n높음\n8:00 오후 까지\n완료됨\n출퇴근 누락자 확인\n보통\n6:30 오후 까지\n완료 처리", + "durationMs": 1802 + }, + { + "name": "chat", + "requestedPath": "/chat", + "role": "ADMIN", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/chat", + "scrollWidth": 768, + "scrollHeight": 1124, + "bodyText": "WORKSPACE\n\n채팅\n대화 목록\n\n대화할 채널이나 대상을 먼저 선택한 뒤 대화방으로 들어갑니다.\n\n채널\n# 전체 공지\n안녕하세요!\n# 디자인팀\n디자인 피드백 부탁드려요\n# 개발팀\nPR 리뷰 요청드립니다\n개인 대화\n최\n최개발\n1팀\n• 자리 비움\n박\n박팀장\n2팀\n• 자리 비움\n이\n이멤버\n3팀\n• 자리 비움", + "durationMs": 1768 + }, + { + "name": "calendar", + "requestedPath": "/calendar", + "role": "ADMIN", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/calendar", + "scrollWidth": 768, + "scrollHeight": 1709, + "bodyText": "WORKSPACE\n\n캘린더\n오늘\n2026년 8월\n월\n주\n일\n목록\n일\n\t\n월\n\t\n화\n\t\n수\n\t\n목\n\t\n금\n\t\n토\n\n\n26일\n\t\n27일\n\t\n28일\n\t\n29일\n\t\n30일\n\t\n31일\n\t\n1일\n\n\n2일\n\t\n3일\n\t\n4일\n\t\n5일\n\t\n6일\n\t\n7일\n\t\n8일\n\n\n9일\n\t\n10일\n\t\n11일\n\t\n12일\n\t\n13일\n\t\n14일\n\t\n15일\n\n\n16일\n\t\n17일\n\t\n18일\n\t\n19일\n\t\n20일\n\t\n21일\n\t\n22일\n오전 10시\n주간 회의 안건 정리\n오후 6:30\n출퇴근 누락자 확인\n\n\n23일\n오후 2시\n신입 팀 공지 업로드\n\t\n24일\n\t\n25일\n\t\n26일\n\t\n27일\n\t\n28일\n\t\n29일\n\n\n30일\n\t\n31일\n\t\n1일\n\t\n2일\n\t\n3일\n\t\n4일\n\t\n5일\n내 할일\n팀 할일\n일정\n할일\n마감 시간\n:\n마감 날짜\n중요도\n높음\n보통\n낮음\n추가\n오늘의 할일\n주간 회의 안건 정리", + "durationMs": 1846 + }, + { + "name": "attendance", + "requestedPath": "/attendance", + "role": "ADMIN", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/attendance", + "scrollWidth": 768, + "scrollHeight": 1087, + "bodyText": "WORKSPACE\n\n출퇴근\n\nATTENDANCE · 2026-08-22\n\n출석 관리\n\n오늘의 출석 현황과 확인이 필요한 기록을 한 곳에서 관리합니다.\n\nCSV 내보내기\n2026-08-22\n오늘\n이번 주\n날짜 선택\n전체 기록\n3\n2026-08-22\n처리 필요\n2\n근무 중 기록\n근무 중\n2\n현재 진행 중\n퇴근 완료\n1\n완료 기록\n\nOPERATIONS FIRST\n\n처리 필요\n2건이 먼저 표시됩니다.\n멤버 검색\n전체\n근무 중\n퇴근 완료\n\nATTENDANCE RECORDS\n\n2026-08-22 기록\n3명\n박\n박팀장\n2026-08-22\n출근\n09:45\n퇴근\n미기록\n근무 중\n이\n이멤버\n2026-08-22\n출근\n09:00\n퇴근\n미기록\n근무 중\n김\n김리더\n2026-08-22\n출근\n09:02\n퇴근\n18:15\n퇴근 완료", + "durationMs": 1782 + }, + { + "name": "work-schedules", + "requestedPath": "/work-schedules", + "role": "ADMIN", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/work-schedules", + "scrollWidth": 768, + "scrollHeight": 2240, + "bodyText": "WORKSPACE\n\n근무 일정\n\n반복 근무와 날짜별 근무 일정을 같은 캘린더에서 보고 바로 관리할 수 있습니다.\n\n날짜 클릭으로 개별 일정을 추가하고, 역할 범위에 따라 다른 사람 일정도 함께 확인합니다.\n근무 일정 캘린더\n\n날짜를 눌러 개인 근무 일정을 추가하고, 역할 범위에 따라 다른 사람 근무 일정도 함께 확인합니다.\n\n전체\n팀별\n개인\n내 반복 일정\n공유 반복 일정\n날짜별 추가 일정\n팀 공유 일정\n날짜별 일정 추가\n오늘\n2026년 8월\n월\n목록\n일\n\t\n월\n\t\n화\n\t\n수\n\t\n목\n\t\n금\n\t\n토\n\n\n26일\n\t\n27일\n08:30\n이멤버\n09:00\n김리더\n10:00\n박팀장\n\t\n28일\n09:00\n김리더\n\t\n29일\n08:30\n이멤버\n\t\n30일\n09:00\n김리더\n10:00\n박팀장\n\t\n31일\n08:30\n이멤버\n09:00\n김리더\n22:00\n최개발\n\t\n1일", + "durationMs": 1795 + }, + { + "name": "drive", + "requestedPath": "/drive", + "role": "ADMIN", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/drive", + "scrollWidth": 768, + "scrollHeight": 1498, + "bodyText": "WORKSPACE\n\n드라이브\n\nSHARED LIBRARY\n\n모든 멤버가 함께 쓰는 공용 문서함입니다. 업로드한 파일은 팀 전체가 바로 확인할 수 있습니다.\n\n전체 멤버 공유\n공용 파일 업로드\n총 파일\n3개\n사용 용량\n1.2 MB\n최근 업로드\n3월 18일 오후 8:00\n팀 공유 라이브러리\n빠른 공유 업로드\n\n회의록, 산출물, 참고 자료를 올리면 일반 멤버를 포함한 팀 전체가 바로 같은 파일을 확인합니다.\n\n새 공유 파일 추가\n현재 사용자\n김리더\n\n일반 멤버, 팀장, 관리자 모두 같은 공유 드라이브를 사용합니다.\n\n업로드 참여자\n3명\n대표 업로더\n이멤버\n파일 라이브러리\n\n이름, 업로더, 업로드 시점을 함께 보여줘서 바로 찾을 수 있게 정리했습니다.\n\n회의록_0318.docx\n이멤버\n3월 18일 오후 8:00\n50 KB\n디자인 시안 v2.fig\n박", + "durationMs": 1791 + }, + { + "name": "ai", + "requestedPath": "/ai", + "role": "ADMIN", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/ai", + "scrollWidth": 768, + "scrollHeight": 1024, + "bodyText": "WORKSPACE\n\nAI\n\n공유 문서를 바탕으로 답변하는 팀 어시스턴트입니다.\n\n안녕하세요! 저는 yANUs AI입니다. 파일 드라이브에 공유된 문서를 바탕으로 질문에 답변해 드립니다. 무엇을 도와드릴까요?\n\n추천 질문\n\n오늘 일정 요약해줘\n공유된 파일 목록 알려줘\n프로젝트 진행 상황 정리해줘", + "durationMs": 1776 + }, + { + "name": "members", + "requestedPath": "/members", + "role": "ADMIN", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/members", + "scrollWidth": 768, + "scrollHeight": 1702, + "bodyText": "WORKSPACE\n\n멤버\n\n멤버 상태와 역할을 한 곳에서 확인하고 관리합니다.\n\n관리자 전용\n멤버 초대\n팀\n전체 팀\n1팀\n2팀\n3팀\n역할\n전체 역할\n관리자\n팀장\n멤버\n전체 멤버 4명\n멤버 목록\n\n활성 멤버를 팀과 역할 기준으로 빠르게 확인할 수 있습니다.\n\n프로필\t팀\t역할\t상태\t관리\n\n김\n김리더\n\t1팀\t\n관리자\t\n활성\n\t\n관리 불가\n\n\n최\n최개발\n\t1팀\t멤버\t\n활성화\n\t\n\n\n박\n박팀장\n\t2팀\t팀장\t\n활성화\n\t\n\n\n이\n이멤버\n\t3팀\t멤버\t\n활성화\n\t\n팀별 멤버 수\n\n비활성 멤버는 집계에서 제외됩니다.\n\n1팀\n2\n2팀\n1\n3팀\n1\n역할 분포\n\n현재 활성 멤버 기준으로 역할 비중을 보여줍니다.\n\n관리자 1\n팀장 1\n멤버 2", + "durationMs": 1833 + }, + { + "name": "my-page", + "requestedPath": "/my-page", + "role": "ADMIN", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/my-page", + "scrollWidth": 768, + "scrollHeight": 1333, + "bodyText": "WORKSPACE\n\n마이페이지\n\nMY PAGE\n\n프로필, 알림, 테마, 정산, 보안 정보를 한 곳에서 관리하세요.\n\n다크 모드 사용 중\n선택한 테마는 브라우저에 저장되어 다음 방문에도 유지됩니다.\n프로필\n알림\n테마\n정산\n보안\n\nPROFILE\n\n내 계정과 소속 정보를 정리합니다.\n\n표시 이름, 역할, 팀 정보를 확인하고 개인 프로필을 안전하게 관리할 수 있습니다.\n\n계정 기본 정보\n프로필 정보\n김\n\n김리더\n\nADMIN · 1팀\n\n표시 이름\n역할\n팀\n저장", + "durationMs": 1785 + }, + { + "name": "team-management", + "requestedPath": "/team-management", + "role": "TEAM_LEAD", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/team-management", + "scrollWidth": 768, + "scrollHeight": 1024, + "bodyText": "WORKSPACE\n\n팀 관리\n\n팀장은 같은 팀 멤버를 확인하고 팀 이동만 관리할 수 있습니다.\n\n2팀 멤버 1명\n팀 멤버 목록\n\n팀장은 같은 팀의 활성 일반 멤버만 다른 팀으로 이동할 수 있습니다.\n\n역할 변경, 상태 변경, 퇴출은 관리자만 가능합니다.\n\n이름\t이메일\t현재 팀\t역할\t상태\t팀 변경\n\n\n표시할 멤버가 없습니다.\n\n검색 조건을 바꾸거나 멤버 상태를 다시 확인해 주세요.", + "durationMs": 1781 + }, + { + "name": "admin", + "requestedPath": "/admin", + "role": "ADMIN", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/admin", + "scrollWidth": 768, + "scrollHeight": 3157, + "bodyText": "WORKSPACE\n\n관리자\n\n출근 현황과 멤버 상태를 한 곳에서 관리합니다.\n\nCSV 내보내기\n출근 현황\n멤버 관리\n팀 관리\n감사 로그\n지각비 정산\n운영 설정\n활성 멤버\n4명\n\n현재 운영 중인 전체 인원\n\n활성 팀\n3개\n\n근무 일정을 관리 중인 팀 수\n\n오늘 기록\n3건\n\n출근 또는 퇴근 기록이 남은 인원\n\n오늘 미기록\n1명\n\n확인 필요한 인원, 퇴근 1명 완료\n\n팀원 출근 현황\n2026-08-22\n2\n근무 중\n1\n퇴근\n2\n미출근\n박\n박팀장\n2팀\n근무 중\n09:45 ~\n이\n이멤버\n3팀\n근무 중\n09:00 ~\nOPERATIONS\n출퇴근 예외 처리\n\n총무와 팀장이 오늘 운영 이슈를 한 화면에서 보고, 메모와 처리 상태를 바로 남길 수 있습니다.\n\n오늘 미퇴근자 일괄 처리 (1)\n처리 대기\n3건\n\n2026-08-22 기준으로 아직 판단이 필요한 예외", + "durationMs": 1898 + }, + { + "name": "login", + "requestedPath": "/login", + "role": "PUBLIC", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/login", + "scrollWidth": 768, + "scrollHeight": 1024, + "bodyText": "yANUs\n동아리 그룹웨어\n이메일\n비밀번호\n로그인\n아직 계정이 없으신가요? 회원가입", + "durationMs": 1748 + }, + { + "name": "register", + "requestedPath": "/register", + "role": "PUBLIC", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/register", + "scrollWidth": 768, + "scrollHeight": 1024, + "bodyText": "yANUs\n새 계정을 만들어 시작해 보세요\n이름\n이메일\n팀\n회원가입 시 모든 신규 사용자는 신입 팀으로 자동 배정됩니다.\n비밀번호\n비밀번호 확인\n회원가입\n이미 계정이 있으신가요? 로그인", + "durationMs": 1737 + }, + { + "name": "verify-email", + "requestedPath": "/verify-email", + "role": "PUBLIC", + "viewport": "tablet", + "viewportWidth": 768, + "viewportHeight": 1024, + "path": "/verify-email", + "scrollWidth": 768, + "scrollHeight": 1024, + "bodyText": "yANUs\n이메일 인증\n이메일을 확인해 주세요\n\n회원가입이 거의 끝났습니다.\n메일로 받은 인증 코드를 입력해야 로그인할 수 있습니다.\n\n인증 코드\n인증 확인\n메일을 받지 못하셨나요?\n\n아래 이메일로 인증 코드를 다시 받을 수 있습니다.\n\n이메일\n인증 메일 다시 보내기\n이미 인증을 마치셨나요? 로그인", + "durationMs": 1745 + }, + { + "name": "home", + "requestedPath": "/", + "role": "ADMIN", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/", + "scrollWidth": 1280, + "scrollHeight": 903, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n홈\n09:13\n오늘은 휴무입니다\n오늘 근무가 종료되어 예정 시간과 함께 비교할 수 있습니다.\n휴무일에도 출근 기록이 있습니다\n\n오늘은 휴무일로 설정되어 있지만 실제 출퇴근 기록이 남아 있습니다.\n\n출근은 220.69 대역 IP에서만 가능합니다.\n오전 9:02 - 오후 6:15\n출근 내역 초기화\n오늘 일정\n\n오늘 등록된 일정이 없습니다\n\n캘린더 보기\n# General\n김\n김리더\n모두 좋은 아침입니다!\n오전 10:46\n박\n박팀장\n좋은 아침이에요 :)\n오전 10:56\n채팅 열기\n오늘 할 일\n주간 회의 안건 정리\n높음\n10:00 오전 까지\n완료 처리\n정산 시트 점검\n높음\n8:00 오후 까지\n완료됨\n출퇴근 누락자 확인\n", + "durationMs": 1819 + }, + { + "name": "chat", + "requestedPath": "/chat", + "role": "ADMIN", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/chat", + "scrollWidth": 1280, + "scrollHeight": 900, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n채팅\n대화 목록\n\n대화할 채널이나 대상을 먼저 선택한 뒤 대화방으로 들어갑니다.\n\n채널\n# 전체 공지\n안녕하세요!\n# 디자인팀\n디자인 피드백 부탁드려요\n# 개발팀\nPR 리뷰 요청드립니다\n개인 대화\n최\n최개발\n1팀\n• 자리 비움\n박\n박팀장\n2팀\n• 자리 비움\n이\n이멤버\n3팀\n• 자리 비움\n# 전체 공지\n23명 참여 중\n⋮\n김\n김리더\n오전 10:46\n\n모두 좋은 아침입니다!\n\n박\n박팀장\n오전 10:56\n\n좋은 아침이에요 :)\n\n보내기", + "durationMs": 1778 + }, + { + "name": "calendar", + "requestedPath": "/calendar", + "role": "ADMIN", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/calendar", + "scrollWidth": 1280, + "scrollHeight": 951, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n캘린더\n오늘\n2026년 8월\n월\n주\n일\n목록\n일\n\t\n월\n\t\n화\n\t\n수\n\t\n목\n\t\n금\n\t\n토\n\n\n26일\n\t\n27일\n\t\n28일\n\t\n29일\n\t\n30일\n\t\n31일\n\t\n1일\n\n\n2일\n\t\n3일\n\t\n4일\n\t\n5일\n\t\n6일\n\t\n7일\n\t\n8일\n\n\n9일\n\t\n10일\n\t\n11일\n\t\n12일\n\t\n13일\n\t\n14일\n\t\n15일\n\n\n16일\n\t\n17일\n\t\n18일\n\t\n19일\n\t\n20일\n\t\n21일\n\t\n22일\n오전 10시\n주간 회의 안건 정리\n오후 6:30\n출퇴근 누락자 확인\n\n\n23일\n오후 2시\n신입 팀 공지 업로드\n\t\n24일\n\t\n25일\n\t\n26일\n\t\n27일\n\t\n28일\n\t\n29일\n\n\n30일\n\t\n31일\n\t\n1일\n\t\n2일\n\t\n3일\n\t\n4일\n\t\n5일\n", + "durationMs": 1857 + }, + { + "name": "attendance", + "requestedPath": "/attendance", + "role": "ADMIN", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/attendance", + "scrollWidth": 1280, + "scrollHeight": 904, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n출퇴근\n\nATTENDANCE · 2026-08-22\n\n출석 관리\n\n오늘의 출석 현황과 확인이 필요한 기록을 한 곳에서 관리합니다.\n\nCSV 내보내기\n2026-08-22\n오늘\n이번 주\n날짜 선택\n전체 기록\n3\n2026-08-22\n처리 필요\n2\n근무 중 기록\n근무 중\n2\n현재 진행 중\n퇴근 완료\n1\n완료 기록\n\nOPERATIONS FIRST\n\n처리 필요\n2건이 먼저 표시됩니다.\n멤버 검색\n전체\n근무 중\n퇴근 완료\n\nATTENDANCE RECORDS\n\n2026-08-22 기록\n3명\n박\n박팀장\n2026-08-22\n출근\n09:45\n퇴근\n미기록\n근무 중\n이\n이멤버\n2026-08-22\n출근\n09:00\n퇴근\n미기록\n근무 중\n", + "durationMs": 1832 + }, + { + "name": "work-schedules", + "requestedPath": "/work-schedules", + "role": "ADMIN", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/work-schedules", + "scrollWidth": 1280, + "scrollHeight": 2129, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n근무 일정\n\n반복 근무와 날짜별 근무 일정을 같은 캘린더에서 보고 바로 관리할 수 있습니다.\n\n날짜 클릭으로 개별 일정을 추가하고, 역할 범위에 따라 다른 사람 일정도 함께 확인합니다.\n근무 일정 캘린더\n\n날짜를 눌러 개인 근무 일정을 추가하고, 역할 범위에 따라 다른 사람 근무 일정도 함께 확인합니다.\n\n전체\n팀별\n개인\n내 반복 일정\n공유 반복 일정\n날짜별 추가 일정\n팀 공유 일정\n날짜별 일정 추가\n오늘\n2026년 8월\n월\n목록\n일\n\t\n월\n\t\n화\n\t\n수\n\t\n목\n\t\n금\n\t\n토\n\n\n26일\n\t\n27일\n08:30\n이멤버\n09:00\n김리더\n10:00\n박팀장\n\t\n28일\n09:00\n김리더\n\t\n29일\n08:30\n이멤버\n\t\n", + "durationMs": 1852 + }, + { + "name": "drive", + "requestedPath": "/drive", + "role": "ADMIN", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/drive", + "scrollWidth": 1280, + "scrollHeight": 911, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n드라이브\n\nSHARED LIBRARY\n\n모든 멤버가 함께 쓰는 공용 문서함입니다. 업로드한 파일은 팀 전체가 바로 확인할 수 있습니다.\n\n전체 멤버 공유\n공용 파일 업로드\n총 파일\n3개\n사용 용량\n1.2 MB\n최근 업로드\n3월 18일 오후 8:00\n팀 공유 라이브러리\n빠른 공유 업로드\n\n회의록, 산출물, 참고 자료를 올리면 일반 멤버를 포함한 팀 전체가 바로 같은 파일을 확인합니다.\n\n새 공유 파일 추가\n현재 사용자\n김리더\n\n일반 멤버, 팀장, 관리자 모두 같은 공유 드라이브를 사용합니다.\n\n업로드 참여자\n3명\n대표 업로더\n이멤버\n파일 라이브러리\n\n이름, 업로더, 업로드 시점을 함께 보여줘서 바로 찾을 수 있게", + "durationMs": 1787 + }, + { + "name": "ai", + "requestedPath": "/ai", + "role": "ADMIN", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/ai", + "scrollWidth": 1280, + "scrollHeight": 900, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\nAI\n\n공유 문서를 바탕으로 답변하는 팀 어시스턴트입니다.\n\n안녕하세요! 저는 yANUs AI입니다. 파일 드라이브에 공유된 문서를 바탕으로 질문에 답변해 드립니다. 무엇을 도와드릴까요?\n\n추천 질문\n\n오늘 일정 요약해줘\n공유된 파일 목록 알려줘\n프로젝트 진행 상황 정리해줘", + "durationMs": 1771 + }, + { + "name": "members", + "requestedPath": "/members", + "role": "ADMIN", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/members", + "scrollWidth": 1280, + "scrollHeight": 1550, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n멤버\n\n멤버 상태와 역할을 한 곳에서 확인하고 관리합니다.\n\n관리자 전용\n멤버 초대\n팀\n전체 팀\n1팀\n2팀\n3팀\n역할\n전체 역할\n관리자\n팀장\n멤버\n전체 멤버 4명\n멤버 목록\n\n활성 멤버를 팀과 역할 기준으로 빠르게 확인할 수 있습니다.\n\n프로필\t팀\t역할\t상태\t관리\n\n김\n김리더\n\t1팀\t\n관리자\t\n활성\n\t\n관리 불가\n\n\n최\n최개발\n\t1팀\t멤버\t\n활성화\n\t\n\n\n박\n박팀장\n\t2팀\t팀장\t\n활성화\n\t\n\n\n이\n이멤버\n\t3팀\t멤버\t\n활성화\n\t\n팀별 멤버 수\n\n비활성 멤버는 집계에서 제외됩니다.\n\n1팀\n2\n2팀\n1\n3팀\n1\n역할 분포\n\n현재 활성 멤버 기준으로 역할 비중을 보여줍니다.\n\n관리자 1\n팀장 1\n멤버 2", + "durationMs": 1865 + }, + { + "name": "my-page", + "requestedPath": "/my-page", + "role": "ADMIN", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/my-page", + "scrollWidth": 1280, + "scrollHeight": 1047, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n마이페이지\n\nMY PAGE\n\n프로필, 알림, 테마, 정산, 보안 정보를 한 곳에서 관리하세요.\n\n다크 모드 사용 중\n선택한 테마는 브라우저에 저장되어 다음 방문에도 유지됩니다.\n프로필\n알림\n테마\n정산\n보안\n\nPROFILE\n\n내 계정과 소속 정보를 정리합니다.\n\n표시 이름, 역할, 팀 정보를 확인하고 개인 프로필을 안전하게 관리할 수 있습니다.\n\n계정 기본 정보\n프로필 정보\n김\n\n김리더\n\nADMIN · 1팀\n\n표시 이름\n역할\n팀\n저장", + "durationMs": 1816 + }, + { + "name": "team-management", + "requestedPath": "/team-management", + "role": "TEAM_LEAD", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/team-management", + "scrollWidth": 1280, + "scrollHeight": 900, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n팀 관리\n박\n박팀장\nTEAM_LEAD\n로그아웃\n\nWORKSPACE\n\n팀 관리\n\n팀장은 같은 팀 멤버를 확인하고 팀 이동만 관리할 수 있습니다.\n\n2팀 멤버 1명\n팀 멤버 목록\n\n팀장은 같은 팀의 활성 일반 멤버만 다른 팀으로 이동할 수 있습니다.\n\n역할 변경, 상태 변경, 퇴출은 관리자만 가능합니다.\n\n이름\t이메일\t현재 팀\t역할\t상태\t팀 변경\n\n\n표시할 멤버가 없습니다.\n\n검색 조건을 바꾸거나 멤버 상태를 다시 확인해 주세요.", + "durationMs": 1777 + }, + { + "name": "admin", + "requestedPath": "/admin", + "role": "ADMIN", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/admin", + "scrollWidth": 1280, + "scrollHeight": 2089, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n관리자\n\n출근 현황과 멤버 상태를 한 곳에서 관리합니다.\n\nCSV 내보내기\n출근 현황\n멤버 관리\n팀 관리\n감사 로그\n지각비 정산\n운영 설정\n활성 멤버\n4명\n\n현재 운영 중인 전체 인원\n\n활성 팀\n3개\n\n근무 일정을 관리 중인 팀 수\n\n오늘 기록\n3건\n\n출근 또는 퇴근 기록이 남은 인원\n\n오늘 미기록\n1명\n\n확인 필요한 인원, 퇴근 1명 완료\n\n팀원 출근 현황\n2026-08-22\n2\n근무 중\n1\n퇴근\n2\n미출근\n박\n박팀장\n2팀\n근무 중\n09:45 ~\n이\n이멤버\n3팀\n근무 중\n09:00 ~\nOPERATIONS\n출퇴근 예외 처리\n\n총무와 팀장이 오늘 운영 이슈를 한 화면에서 보고, 메모와 처리 상태를 바로 남길 수 ", + "durationMs": 1889 + }, + { + "name": "login", + "requestedPath": "/login", + "role": "PUBLIC", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/login", + "scrollWidth": 1280, + "scrollHeight": 900, + "bodyText": "yANUs\n동아리 그룹웨어\n이메일\n비밀번호\n로그인\n아직 계정이 없으신가요? 회원가입", + "durationMs": 1760 + }, + { + "name": "register", + "requestedPath": "/register", + "role": "PUBLIC", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/register", + "scrollWidth": 1280, + "scrollHeight": 992, + "bodyText": "yANUs\n새 계정을 만들어 시작해 보세요\n이름\n이메일\n팀\n회원가입 시 모든 신규 사용자는 신입 팀으로 자동 배정됩니다.\n비밀번호\n비밀번호 확인\n회원가입\n이미 계정이 있으신가요? 로그인", + "durationMs": 1758 + }, + { + "name": "verify-email", + "requestedPath": "/verify-email", + "role": "PUBLIC", + "viewport": "desktop", + "viewportWidth": 1280, + "viewportHeight": 900, + "path": "/verify-email", + "scrollWidth": 1280, + "scrollHeight": 1058, + "bodyText": "yANUs\n이메일 인증\n이메일을 확인해 주세요\n\n회원가입이 거의 끝났습니다.\n메일로 받은 인증 코드를 입력해야 로그인할 수 있습니다.\n\n인증 코드\n인증 확인\n메일을 받지 못하셨나요?\n\n아래 이메일로 인증 코드를 다시 받을 수 있습니다.\n\n이메일\n인증 메일 다시 보내기\n이미 인증을 마치셨나요? 로그인", + "durationMs": 1778 + } + ] +} \ No newline at end of file diff --git a/.qa/issue-414/after/my-page-desktop.png b/.qa/issue-414/after/my-page-desktop.png new file mode 100644 index 0000000..8932e2f Binary files /dev/null and b/.qa/issue-414/after/my-page-desktop.png differ diff --git a/.qa/issue-414/after/my-page-mobile.png b/.qa/issue-414/after/my-page-mobile.png new file mode 100644 index 0000000..c5bd862 Binary files /dev/null and b/.qa/issue-414/after/my-page-mobile.png differ diff --git a/.qa/issue-414/after/my-page-tablet.png b/.qa/issue-414/after/my-page-tablet.png new file mode 100644 index 0000000..2cc5549 Binary files /dev/null and b/.qa/issue-414/after/my-page-tablet.png differ diff --git a/.qa/issue-414/after/register-desktop.png b/.qa/issue-414/after/register-desktop.png new file mode 100644 index 0000000..4c2cc79 Binary files /dev/null and b/.qa/issue-414/after/register-desktop.png differ diff --git a/.qa/issue-414/after/register-mobile.png b/.qa/issue-414/after/register-mobile.png new file mode 100644 index 0000000..976ac00 Binary files /dev/null and b/.qa/issue-414/after/register-mobile.png differ diff --git a/.qa/issue-414/after/register-tablet.png b/.qa/issue-414/after/register-tablet.png new file mode 100644 index 0000000..378501b Binary files /dev/null and b/.qa/issue-414/after/register-tablet.png differ diff --git a/.qa/issue-414/after/team-management-desktop.png b/.qa/issue-414/after/team-management-desktop.png new file mode 100644 index 0000000..2939c53 Binary files /dev/null and b/.qa/issue-414/after/team-management-desktop.png differ diff --git a/.qa/issue-414/after/team-management-mobile.png b/.qa/issue-414/after/team-management-mobile.png new file mode 100644 index 0000000..19a8570 Binary files /dev/null and b/.qa/issue-414/after/team-management-mobile.png differ diff --git a/.qa/issue-414/after/team-management-tablet.png b/.qa/issue-414/after/team-management-tablet.png new file mode 100644 index 0000000..4a5142e Binary files /dev/null and b/.qa/issue-414/after/team-management-tablet.png differ diff --git a/.qa/issue-414/after/verify-email-desktop.png b/.qa/issue-414/after/verify-email-desktop.png new file mode 100644 index 0000000..655c321 Binary files /dev/null and b/.qa/issue-414/after/verify-email-desktop.png differ diff --git a/.qa/issue-414/after/verify-email-mobile.png b/.qa/issue-414/after/verify-email-mobile.png new file mode 100644 index 0000000..d9195ef Binary files /dev/null and b/.qa/issue-414/after/verify-email-mobile.png differ diff --git a/.qa/issue-414/after/verify-email-tablet.png b/.qa/issue-414/after/verify-email-tablet.png new file mode 100644 index 0000000..27976c1 Binary files /dev/null and b/.qa/issue-414/after/verify-email-tablet.png differ diff --git a/.qa/issue-414/after/work-schedules-desktop.png b/.qa/issue-414/after/work-schedules-desktop.png new file mode 100644 index 0000000..4d83ad5 Binary files /dev/null and b/.qa/issue-414/after/work-schedules-desktop.png differ diff --git a/.qa/issue-414/after/work-schedules-mobile.png b/.qa/issue-414/after/work-schedules-mobile.png new file mode 100644 index 0000000..cfe8e5c Binary files /dev/null and b/.qa/issue-414/after/work-schedules-mobile.png differ diff --git a/.qa/issue-414/after/work-schedules-tablet.png b/.qa/issue-414/after/work-schedules-tablet.png new file mode 100644 index 0000000..874c53e Binary files /dev/null and b/.qa/issue-414/after/work-schedules-tablet.png differ diff --git a/.qa/issue-414/before/admin-desktop.png b/.qa/issue-414/before/admin-desktop.png new file mode 100644 index 0000000..28116d8 Binary files /dev/null and b/.qa/issue-414/before/admin-desktop.png differ diff --git a/.qa/issue-414/before/admin-mobile.png b/.qa/issue-414/before/admin-mobile.png new file mode 100644 index 0000000..d2519d9 Binary files /dev/null and b/.qa/issue-414/before/admin-mobile.png differ diff --git a/.qa/issue-414/before/admin-tablet.png b/.qa/issue-414/before/admin-tablet.png new file mode 100644 index 0000000..d4ca26d Binary files /dev/null and b/.qa/issue-414/before/admin-tablet.png differ diff --git a/.qa/issue-414/before/ai-desktop.png b/.qa/issue-414/before/ai-desktop.png new file mode 100644 index 0000000..b74b38c Binary files /dev/null and b/.qa/issue-414/before/ai-desktop.png differ diff --git a/.qa/issue-414/before/ai-mobile.png b/.qa/issue-414/before/ai-mobile.png new file mode 100644 index 0000000..f17fcaf Binary files /dev/null and b/.qa/issue-414/before/ai-mobile.png differ diff --git a/.qa/issue-414/before/ai-tablet.png b/.qa/issue-414/before/ai-tablet.png new file mode 100644 index 0000000..b4d9b59 Binary files /dev/null and b/.qa/issue-414/before/ai-tablet.png differ diff --git a/.qa/issue-414/before/attendance-desktop.png b/.qa/issue-414/before/attendance-desktop.png new file mode 100644 index 0000000..f5475ed Binary files /dev/null and b/.qa/issue-414/before/attendance-desktop.png differ diff --git a/.qa/issue-414/before/attendance-mobile.png b/.qa/issue-414/before/attendance-mobile.png new file mode 100644 index 0000000..9f96111 Binary files /dev/null and b/.qa/issue-414/before/attendance-mobile.png differ diff --git a/.qa/issue-414/before/attendance-tablet.png b/.qa/issue-414/before/attendance-tablet.png new file mode 100644 index 0000000..20faf62 Binary files /dev/null and b/.qa/issue-414/before/attendance-tablet.png differ diff --git a/.qa/issue-414/before/calendar-desktop.png b/.qa/issue-414/before/calendar-desktop.png new file mode 100644 index 0000000..9644d62 Binary files /dev/null and b/.qa/issue-414/before/calendar-desktop.png differ diff --git a/.qa/issue-414/before/calendar-mobile.png b/.qa/issue-414/before/calendar-mobile.png new file mode 100644 index 0000000..49efac5 Binary files /dev/null and b/.qa/issue-414/before/calendar-mobile.png differ diff --git a/.qa/issue-414/before/calendar-tablet.png b/.qa/issue-414/before/calendar-tablet.png new file mode 100644 index 0000000..6303b37 Binary files /dev/null and b/.qa/issue-414/before/calendar-tablet.png differ diff --git a/.qa/issue-414/before/chat-desktop.png b/.qa/issue-414/before/chat-desktop.png new file mode 100644 index 0000000..57ca3a6 Binary files /dev/null and b/.qa/issue-414/before/chat-desktop.png differ diff --git a/.qa/issue-414/before/chat-mobile.png b/.qa/issue-414/before/chat-mobile.png new file mode 100644 index 0000000..2dc9bff Binary files /dev/null and b/.qa/issue-414/before/chat-mobile.png differ diff --git a/.qa/issue-414/before/chat-tablet.png b/.qa/issue-414/before/chat-tablet.png new file mode 100644 index 0000000..d2fd19e Binary files /dev/null and b/.qa/issue-414/before/chat-tablet.png differ diff --git a/.qa/issue-414/before/drive-desktop.png b/.qa/issue-414/before/drive-desktop.png new file mode 100644 index 0000000..00c598f Binary files /dev/null and b/.qa/issue-414/before/drive-desktop.png differ diff --git a/.qa/issue-414/before/drive-mobile.png b/.qa/issue-414/before/drive-mobile.png new file mode 100644 index 0000000..cef9d73 Binary files /dev/null and b/.qa/issue-414/before/drive-mobile.png differ diff --git a/.qa/issue-414/before/drive-tablet.png b/.qa/issue-414/before/drive-tablet.png new file mode 100644 index 0000000..eee75be Binary files /dev/null and b/.qa/issue-414/before/drive-tablet.png differ diff --git a/.qa/issue-414/before/home-desktop.png b/.qa/issue-414/before/home-desktop.png new file mode 100644 index 0000000..1b9f440 Binary files /dev/null and b/.qa/issue-414/before/home-desktop.png differ diff --git a/.qa/issue-414/before/home-mobile.png b/.qa/issue-414/before/home-mobile.png new file mode 100644 index 0000000..5118231 Binary files /dev/null and b/.qa/issue-414/before/home-mobile.png differ diff --git a/.qa/issue-414/before/home-tablet.png b/.qa/issue-414/before/home-tablet.png new file mode 100644 index 0000000..724b133 Binary files /dev/null and b/.qa/issue-414/before/home-tablet.png differ diff --git a/.qa/issue-414/before/login-desktop.png b/.qa/issue-414/before/login-desktop.png new file mode 100644 index 0000000..0c71d55 Binary files /dev/null and b/.qa/issue-414/before/login-desktop.png differ diff --git a/.qa/issue-414/before/login-mobile.png b/.qa/issue-414/before/login-mobile.png new file mode 100644 index 0000000..f368ee4 Binary files /dev/null and b/.qa/issue-414/before/login-mobile.png differ diff --git a/.qa/issue-414/before/login-tablet.png b/.qa/issue-414/before/login-tablet.png new file mode 100644 index 0000000..243e94a Binary files /dev/null and b/.qa/issue-414/before/login-tablet.png differ diff --git a/.qa/issue-414/before/members-desktop.png b/.qa/issue-414/before/members-desktop.png new file mode 100644 index 0000000..4a53f05 Binary files /dev/null and b/.qa/issue-414/before/members-desktop.png differ diff --git a/.qa/issue-414/before/members-mobile.png b/.qa/issue-414/before/members-mobile.png new file mode 100644 index 0000000..ea13e8d Binary files /dev/null and b/.qa/issue-414/before/members-mobile.png differ diff --git a/.qa/issue-414/before/members-tablet.png b/.qa/issue-414/before/members-tablet.png new file mode 100644 index 0000000..f9016b4 Binary files /dev/null and b/.qa/issue-414/before/members-tablet.png differ diff --git a/.qa/issue-414/before/metadata.json b/.qa/issue-414/before/metadata.json new file mode 100644 index 0000000..6555e4b --- /dev/null +++ b/.qa/issue-414/before/metadata.json @@ -0,0 +1,510 @@ +{ + "capturedAt": "2026-08-22T02:09:25.883Z", + "source": "develop-before-app-wide-redesign", + "results": [ + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/", + "scrollWidth": 390, + "scrollHeight": 1573, + "viewportWidth": 390, + "bodyText": "WORKSPACE\n\n홈\n09:13\n오늘은 휴무입니다\n오늘 근무가 종료되어 예정 시간과 함께 비교할 수 있습니다.\n휴무일에도 출근 기록이 있습니다\n\n오늘은 휴무일로 설정되어 있지만 실제 출퇴근 기록이 남아 있습니다.\n\n출근은 220.69 대역 IP에서만 가능합니다.\n오전 9:02 - 오후 6:15\n출근 내역 초기화\n오늘 일정\n\n오늘 등록된 일정이 없습니다\n\n캘린더 보기\n# General\n김\n김리더\n모두 좋은 아침입니다!\n오전 1", + "route": "/", + "name": "home", + "viewport": "mobile", + "durationMs": 1836 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/chat", + "scrollWidth": 390, + "scrollHeight": 893, + "viewportWidth": 390, + "bodyText": "WORKSPACE\n\n채팅\n대화 목록\n\n대화할 채널이나 대상을 먼저 선택한 뒤 대화방으로 들어갑니다.\n\n채널\n# 전체 공지\n안녕하세요!\n# 디자인팀\n디자인 피드백 부탁드려요\n# 개발팀\nPR 리뷰 요청드립니다\n개인 대화\n최\n최개발\n1팀\n• 자리 비움\n박\n박팀장\n2팀\n• 자리 비움\n이\n이멤버\n3팀\n• 자리 비움", + "route": "/chat", + "name": "chat", + "viewport": "mobile", + "durationMs": 1790 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/calendar", + "scrollWidth": 390, + "scrollHeight": 1331, + "viewportWidth": 390, + "bodyText": "WORKSPACE\n\n캘린더\n오늘\n2026년 8월\n월\n주\n일\n목록\n일\n\t\n월\n\t\n화\n\t\n수\n\t\n목\n\t\n금\n\t\n토\n\n\n26일\n\t\n27일\n\t\n28일\n\t\n29일\n\t\n30일\n\t\n31일\n\t\n1일\n\n\n2일\n\t\n3일\n\t\n4일\n\t\n5일\n\t\n6일\n\t\n7일\n\t\n8일\n\n\n9일\n\t\n10일\n\t\n11일\n\t\n12일\n\t\n13일\n\t\n14일\n\t\n15일\n\n\n16일\n\t\n17일\n\t\n18일\n\t\n19일\n\t\n20일\n\t\n21일\n\t\n22일\n오전 10시\n주간 회의 안건 정리\n", + "route": "/calendar", + "name": "calendar", + "viewport": "mobile", + "durationMs": 1836 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/attendance", + "scrollWidth": 390, + "scrollHeight": 1314, + "viewportWidth": 390, + "bodyText": "WORKSPACE\n\n출퇴근\n\nATTENDANCE · 2026-08-22\n\n출석 관리\n\n오늘의 출석 현황과 확인이 필요한 기록을 한 곳에서 관리합니다.\n\nCSV 내보내기\n2026-08-22\n오늘\n이번 주\n날짜 선택\n전체 기록\n3\n2026-08-22\n처리 필요\n2\n근무 중 기록\n근무 중\n2\n현재 진행 중\n퇴근 완료\n1\n완료 기록\n\nOPERATIONS FIRST\n\n처리 필요\n2건이 먼저 표시됩니다.\n멤버 검색\n전체\n근무 중\n퇴근 완", + "route": "/attendance", + "name": "attendance", + "viewport": "mobile", + "durationMs": 1780 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/work-schedules", + "scrollWidth": 390, + "scrollHeight": 2434, + "viewportWidth": 390, + "bodyText": "WORKSPACE\n\n근무 일정\n\n반복 근무와 날짜별 근무 일정을 같은 캘린더에서 보고 바로 관리할 수 있습니다.\n\n날짜 클릭으로 개별 일정을 추가하고, 역할 범위에 따라 다른 사람 일정도 함께 확인합니다.\n근무 일정 캘린더\n\n날짜를 눌러 개인 근무 일정을 추가하고, 역할 범위에 따라 다른 사람 근무 일정도 함께 확인합니다.\n\n전체\n팀별\n개인\n내 반복 일정\n공유 반복 일정\n날짜별 추가 일정\n팀 공유 일정\n날짜별 일정 추가\n오늘\n", + "route": "/work-schedules", + "name": "work-schedules", + "viewport": "mobile", + "durationMs": 1787 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/drive", + "scrollWidth": 390, + "scrollHeight": 1882, + "viewportWidth": 390, + "bodyText": "WORKSPACE\n\n드라이브\n\nSHARED LIBRARY\n\n모든 멤버가 함께 쓰는 공용 문서함입니다. 업로드한 파일은 팀 전체가 바로 확인할 수 있습니다.\n\n전체 멤버 공유\n공용 파일 업로드\n총 파일\n3개\n사용 용량\n1.2 MB\n최근 업로드\n3월 18일 오후 8:00\n팀 공유 라이브러리\n빠른 공유 업로드\n\n회의록, 산출물, 참고 자료를 올리면 일반 멤버를 포함한 팀 전체가 바로 같은 파일을 확인합니다.\n\n새 공유 파일 추가\n현", + "route": "/drive", + "name": "drive", + "viewport": "mobile", + "durationMs": 1825 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/ai", + "scrollWidth": 390, + "scrollHeight": 891, + "viewportWidth": 390, + "bodyText": "WORKSPACE\n\nAI\n\n공유 문서를 바탕으로 답변하는 팀 어시스턴트입니다.\n\n안녕하세요! 저는 yANUs AI입니다. 파일 드라이브에 공유된 문서를 바탕으로 질문에 답변해 드립니다. 무엇을 도와드릴까요?\n\n추천 질문\n\n오늘 일정 요약해줘\n공유된 파일 목록 알려줘\n프로젝트 진행 상황 정리해줘", + "route": "/ai", + "name": "ai", + "viewport": "mobile", + "durationMs": 1806 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/members", + "scrollWidth": 390, + "scrollHeight": 1633, + "viewportWidth": 390, + "bodyText": "WORKSPACE\n\n멤버\n\n멤버 상태와 역할을 한 곳에서 확인하고 관리합니다.\n\n관리자 전용\n멤버 초대\n팀\n전체 팀\n1팀\n2팀\n3팀\n역할\n전체 역할\n관리자\n팀장\n멤버\n전체 멤버 4명\n멤버 목록\n\n활성 멤버를 팀과 역할 기준으로 빠르게 확인할 수 있습니다.\n\n프로필\t팀\t역할\t상태\t관리\n\n김\n김리더\n\t1팀\t\n관리자\t\n활성\n\t\n관리 불가\n\n\n최\n최개발\n\t1팀\t멤버\t\n활성화\n\t\n\n\n박\n박팀장\n\t2팀\t팀장\t\n활성화\n\t\n\n\n이\n이멤버\n\t", + "route": "/members", + "name": "members", + "viewport": "mobile", + "durationMs": 1795 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/my-page", + "scrollWidth": 390, + "scrollHeight": 1408, + "viewportWidth": 390, + "bodyText": "WORKSPACE\n\n마이페이지\n\nMY PAGE\n\n프로필, 알림, 테마, 정산, 보안 정보를 한 곳에서 관리하세요.\n\n다크 모드 사용 중\n선택한 테마는 브라우저에 저장되어 다음 방문에도 유지됩니다.\n프로필\n알림\n테마\n정산\n보안\n\nPROFILE\n\n내 계정과 소속 정보를 정리합니다.\n\n표시 이름, 역할, 팀 정보를 확인하고 개인 프로필을 안전하게 관리할 수 있습니다.\n\n계정 기본 정보\n프로필 정보\n김\n\n김리더\n\nADMIN · 1팀\n", + "route": "/my-page", + "name": "my-page", + "viewport": "mobile", + "durationMs": 1841 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/", + "scrollWidth": 390, + "scrollHeight": 1573, + "viewportWidth": 390, + "bodyText": "WORKSPACE\n\n홈\n09:13\n오늘은 휴무입니다\n오늘 근무가 종료되어 예정 시간과 함께 비교할 수 있습니다.\n휴무일에도 출근 기록이 있습니다\n\n오늘은 휴무일로 설정되어 있지만 실제 출퇴근 기록이 남아 있습니다.\n\n출근은 220.69 대역 IP에서만 가능합니다.\n오전 9:02 - 오후 6:15\n출근 내역 초기화\n오늘 일정\n\n오늘 등록된 일정이 없습니다\n\n캘린더 보기\n# General\n김\n김리더\n모두 좋은 아침입니다!\n오전 1", + "route": "/team-management", + "name": "team-management", + "viewport": "mobile", + "durationMs": 1793 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/admin", + "scrollWidth": 390, + "scrollHeight": 3720, + "viewportWidth": 390, + "bodyText": "WORKSPACE\n\n관리자\n\n출근 현황과 멤버 상태를 한 곳에서 관리합니다.\n\nCSV 내보내기\n출근 현황\n멤버 관리\n팀 관리\n감사 로그\n지각비 정산\n운영 설정\n활성 멤버\n4명\n\n현재 운영 중인 전체 인원\n\n활성 팀\n3개\n\n근무 일정을 관리 중인 팀 수\n\n오늘 기록\n3건\n\n출근 또는 퇴근 기록이 남은 인원\n\n오늘 미기록\n1명\n\n확인 필요한 인원, 퇴근 1명 완료\n\n팀원 출근 현황\n2026-08-22\n2\n근무 중\n1\n퇴근\n2\n미출", + "route": "/admin", + "name": "admin", + "viewport": "mobile", + "durationMs": 1898 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/login", + "scrollWidth": 390, + "scrollHeight": 844, + "viewportWidth": 390, + "bodyText": "yANUs\n동아리 그룹웨어\n이메일\n비밀번호\n로그인\n아직 계정이 없으신가요? 회원가입", + "route": "/login", + "name": "login", + "viewport": "mobile", + "durationMs": 1845 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/register", + "scrollWidth": 390, + "scrollHeight": 904, + "viewportWidth": 390, + "bodyText": "yANUs\n새 계정을 만들어 시작해 보세요\n이름\n이메일\n팀\n회원가입 시 모든 신규 사용자는 신입 팀으로 자동 배정됩니다.\n비밀번호\n비밀번호 확인\n회원가입\n이미 계정이 있으신가요? 로그인", + "route": "/register", + "name": "register", + "viewport": "mobile", + "durationMs": 1841 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/verify-email", + "scrollWidth": 390, + "scrollHeight": 1056, + "viewportWidth": 390, + "bodyText": "yANUs\n이메일 인증\n이메일을 확인해 주세요\n\n회원가입이 거의 끝났습니다.\n메일로 받은 인증 코드를 입력해야 로그인할 수 있습니다.\n\n인증 코드\n인증 확인\n메일을 받지 못하셨나요?\n\n아래 이메일로 인증 코드를 다시 받을 수 있습니다.\n\n이메일\n인증 메일 다시 보내기\n이미 인증을 마치셨나요? 로그인", + "route": "/verify-email", + "name": "verify-email", + "viewport": "mobile", + "durationMs": 1808 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/", + "scrollWidth": 768, + "scrollHeight": 1607, + "viewportWidth": 768, + "bodyText": "WORKSPACE\n\n홈\n09:13\n오늘은 휴무입니다\n오늘 근무가 종료되어 예정 시간과 함께 비교할 수 있습니다.\n휴무일에도 출근 기록이 있습니다\n\n오늘은 휴무일로 설정되어 있지만 실제 출퇴근 기록이 남아 있습니다.\n\n출근은 220.69 대역 IP에서만 가능합니다.\n오전 9:02 - 오후 6:15\n출근 내역 초기화\n오늘 일정\n\n오늘 등록된 일정이 없습니다\n\n캘린더 보기\n# General\n김\n김리더\n모두 좋은 아침입니다!\n오전 1", + "route": "/", + "name": "home", + "viewport": "tablet", + "durationMs": 1868 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/chat", + "scrollWidth": 768, + "scrollHeight": 1086, + "viewportWidth": 768, + "bodyText": "WORKSPACE\n\n채팅\n대화 목록\n\n대화할 채널이나 대상을 먼저 선택한 뒤 대화방으로 들어갑니다.\n\n채널\n# 전체 공지\n안녕하세요!\n# 디자인팀\n디자인 피드백 부탁드려요\n# 개발팀\nPR 리뷰 요청드립니다\n개인 대화\n최\n최개발\n1팀\n• 자리 비움\n박\n박팀장\n2팀\n• 자리 비움\n이\n이멤버\n3팀\n• 자리 비움", + "route": "/chat", + "name": "chat", + "viewport": "tablet", + "durationMs": 1784 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/calendar", + "scrollWidth": 768, + "scrollHeight": 1622, + "viewportWidth": 768, + "bodyText": "WORKSPACE\n\n캘린더\n오늘\n2026년 8월\n월\n주\n일\n목록\n일\n\t\n월\n\t\n화\n\t\n수\n\t\n목\n\t\n금\n\t\n토\n\n\n26일\n\t\n27일\n\t\n28일\n\t\n29일\n\t\n30일\n\t\n31일\n\t\n1일\n\n\n2일\n\t\n3일\n\t\n4일\n\t\n5일\n\t\n6일\n\t\n7일\n\t\n8일\n\n\n9일\n\t\n10일\n\t\n11일\n\t\n12일\n\t\n13일\n\t\n14일\n\t\n15일\n\n\n16일\n\t\n17일\n\t\n18일\n\t\n19일\n\t\n20일\n\t\n21일\n\t\n22일\n오전 10시\n주간 회의 안건 정리\n", + "route": "/calendar", + "name": "calendar", + "viewport": "tablet", + "durationMs": 1874 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/attendance", + "scrollWidth": 768, + "scrollHeight": 1034, + "viewportWidth": 768, + "bodyText": "WORKSPACE\n\n출퇴근\n\nATTENDANCE · 2026-08-22\n\n출석 관리\n\n오늘의 출석 현황과 확인이 필요한 기록을 한 곳에서 관리합니다.\n\nCSV 내보내기\n2026-08-22\n오늘\n이번 주\n날짜 선택\n전체 기록\n3\n2026-08-22\n처리 필요\n2\n근무 중 기록\n근무 중\n2\n현재 진행 중\n퇴근 완료\n1\n완료 기록\n\nOPERATIONS FIRST\n\n처리 필요\n2건이 먼저 표시됩니다.\n멤버 검색\n전체\n근무 중\n퇴근 완", + "route": "/attendance", + "name": "attendance", + "viewport": "tablet", + "durationMs": 1854 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/work-schedules", + "scrollWidth": 768, + "scrollHeight": 2127, + "viewportWidth": 768, + "bodyText": "WORKSPACE\n\n근무 일정\n\n반복 근무와 날짜별 근무 일정을 같은 캘린더에서 보고 바로 관리할 수 있습니다.\n\n날짜 클릭으로 개별 일정을 추가하고, 역할 범위에 따라 다른 사람 일정도 함께 확인합니다.\n근무 일정 캘린더\n\n날짜를 눌러 개인 근무 일정을 추가하고, 역할 범위에 따라 다른 사람 근무 일정도 함께 확인합니다.\n\n전체\n팀별\n개인\n내 반복 일정\n공유 반복 일정\n날짜별 추가 일정\n팀 공유 일정\n날짜별 일정 추가\n오늘\n", + "route": "/work-schedules", + "name": "work-schedules", + "viewport": "tablet", + "durationMs": 1890 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/drive", + "scrollWidth": 768, + "scrollHeight": 1343, + "viewportWidth": 768, + "bodyText": "WORKSPACE\n\n드라이브\n\nSHARED LIBRARY\n\n모든 멤버가 함께 쓰는 공용 문서함입니다. 업로드한 파일은 팀 전체가 바로 확인할 수 있습니다.\n\n전체 멤버 공유\n공용 파일 업로드\n총 파일\n3개\n사용 용량\n1.2 MB\n최근 업로드\n3월 18일 오후 8:00\n팀 공유 라이브러리\n빠른 공유 업로드\n\n회의록, 산출물, 참고 자료를 올리면 일반 멤버를 포함한 팀 전체가 바로 같은 파일을 확인합니다.\n\n새 공유 파일 추가\n현", + "route": "/drive", + "name": "drive", + "viewport": "tablet", + "durationMs": 1827 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/ai", + "scrollWidth": 768, + "scrollHeight": 1024, + "viewportWidth": 768, + "bodyText": "WORKSPACE\n\nAI\n\n공유 문서를 바탕으로 답변하는 팀 어시스턴트입니다.\n\n안녕하세요! 저는 yANUs AI입니다. 파일 드라이브에 공유된 문서를 바탕으로 질문에 답변해 드립니다. 무엇을 도와드릴까요?\n\n추천 질문\n\n오늘 일정 요약해줘\n공유된 파일 목록 알려줘\n프로젝트 진행 상황 정리해줘", + "route": "/ai", + "name": "ai", + "viewport": "tablet", + "durationMs": 1780 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/members", + "scrollWidth": 768, + "scrollHeight": 1606, + "viewportWidth": 768, + "bodyText": "WORKSPACE\n\n멤버\n\n멤버 상태와 역할을 한 곳에서 확인하고 관리합니다.\n\n관리자 전용\n멤버 초대\n팀\n전체 팀\n1팀\n2팀\n3팀\n역할\n전체 역할\n관리자\n팀장\n멤버\n전체 멤버 4명\n멤버 목록\n\n활성 멤버를 팀과 역할 기준으로 빠르게 확인할 수 있습니다.\n\n프로필\t팀\t역할\t상태\t관리\n\n김\n김리더\n\t1팀\t\n관리자\t\n활성\n\t\n관리 불가\n\n\n최\n최개발\n\t1팀\t멤버\t\n활성화\n\t\n\n\n박\n박팀장\n\t2팀\t팀장\t\n활성화\n\t\n\n\n이\n이멤버\n\t", + "route": "/members", + "name": "members", + "viewport": "tablet", + "durationMs": 1851 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/my-page", + "scrollWidth": 768, + "scrollHeight": 1251, + "viewportWidth": 768, + "bodyText": "WORKSPACE\n\n마이페이지\n\nMY PAGE\n\n프로필, 알림, 테마, 정산, 보안 정보를 한 곳에서 관리하세요.\n\n다크 모드 사용 중\n선택한 테마는 브라우저에 저장되어 다음 방문에도 유지됩니다.\n프로필\n알림\n테마\n정산\n보안\n\nPROFILE\n\n내 계정과 소속 정보를 정리합니다.\n\n표시 이름, 역할, 팀 정보를 확인하고 개인 프로필을 안전하게 관리할 수 있습니다.\n\n계정 기본 정보\n프로필 정보\n김\n\n김리더\n\nADMIN · 1팀\n", + "route": "/my-page", + "name": "my-page", + "viewport": "tablet", + "durationMs": 1887 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/", + "scrollWidth": 768, + "scrollHeight": 1607, + "viewportWidth": 768, + "bodyText": "WORKSPACE\n\n홈\n09:13\n오늘은 휴무입니다\n오늘 근무가 종료되어 예정 시간과 함께 비교할 수 있습니다.\n휴무일에도 출근 기록이 있습니다\n\n오늘은 휴무일로 설정되어 있지만 실제 출퇴근 기록이 남아 있습니다.\n\n출근은 220.69 대역 IP에서만 가능합니다.\n오전 9:02 - 오후 6:15\n출근 내역 초기화\n오늘 일정\n\n오늘 등록된 일정이 없습니다\n\n캘린더 보기\n# General\n김\n김리더\n모두 좋은 아침입니다!\n오전 1", + "route": "/team-management", + "name": "team-management", + "viewport": "tablet", + "durationMs": 1932 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/admin", + "scrollWidth": 768, + "scrollHeight": 3123, + "viewportWidth": 768, + "bodyText": "WORKSPACE\n\n관리자\n\n출근 현황과 멤버 상태를 한 곳에서 관리합니다.\n\nCSV 내보내기\n출근 현황\n멤버 관리\n팀 관리\n감사 로그\n지각비 정산\n운영 설정\n활성 멤버\n4명\n\n현재 운영 중인 전체 인원\n\n활성 팀\n3개\n\n근무 일정을 관리 중인 팀 수\n\n오늘 기록\n3건\n\n출근 또는 퇴근 기록이 남은 인원\n\n오늘 미기록\n1명\n\n확인 필요한 인원, 퇴근 1명 완료\n\n팀원 출근 현황\n2026-08-22\n2\n근무 중\n1\n퇴근\n2\n미출", + "route": "/admin", + "name": "admin", + "viewport": "tablet", + "durationMs": 1915 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/login", + "scrollWidth": 768, + "scrollHeight": 1024, + "viewportWidth": 768, + "bodyText": "yANUs\n동아리 그룹웨어\n이메일\n비밀번호\n로그인\n아직 계정이 없으신가요? 회원가입", + "route": "/login", + "name": "login", + "viewport": "tablet", + "durationMs": 1914 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/register", + "scrollWidth": 768, + "scrollHeight": 1024, + "viewportWidth": 768, + "bodyText": "yANUs\n새 계정을 만들어 시작해 보세요\n이름\n이메일\n팀\n회원가입 시 모든 신규 사용자는 신입 팀으로 자동 배정됩니다.\n비밀번호\n비밀번호 확인\n회원가입\n이미 계정이 있으신가요? 로그인", + "route": "/register", + "name": "register", + "viewport": "tablet", + "durationMs": 1838 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/verify-email", + "scrollWidth": 768, + "scrollHeight": 1024, + "viewportWidth": 768, + "bodyText": "yANUs\n이메일 인증\n이메일을 확인해 주세요\n\n회원가입이 거의 끝났습니다.\n메일로 받은 인증 코드를 입력해야 로그인할 수 있습니다.\n\n인증 코드\n인증 확인\n메일을 받지 못하셨나요?\n\n아래 이메일로 인증 코드를 다시 받을 수 있습니다.\n\n이메일\n인증 메일 다시 보내기\n이미 인증을 마치셨나요? 로그인", + "route": "/verify-email", + "name": "verify-email", + "viewport": "tablet", + "durationMs": 1910 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/", + "scrollWidth": 1280, + "scrollHeight": 1021, + "viewportWidth": 1280, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n홈\n09:13\n오늘은 휴무입니다\n오늘 근무가 종료되어 예정 시간과 함께 비교할 수 있습니다.\n휴무일에도 출근 기록이 있습니다\n\n오늘은 휴무일로 설정되어 있지만 실제 출퇴근 기록이 남아 있습니다.\n\n출근은 220.69 대역 IP에서만 가능합니다.\n오전 9:02 - 오후 6:15\n출근 내역 초기화\n", + "route": "/", + "name": "home", + "viewport": "desktop", + "durationMs": 1907 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/chat", + "scrollWidth": 1280, + "scrollHeight": 900, + "viewportWidth": 1280, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n채팅\n대화 목록\n\n대화할 채널이나 대상을 먼저 선택한 뒤 대화방으로 들어갑니다.\n\n채널\n# 전체 공지\n안녕하세요!\n# 디자인팀\n디자인 피드백 부탁드려요\n# 개발팀\nPR 리뷰 요청드립니다\n개인 대화\n최\n최개발\n1팀\n• 자리 비움\n박\n박팀장\n2팀\n• 자리 비움\n이\n이멤버\n3팀\n• 자리 비움\n# 전체", + "route": "/chat", + "name": "chat", + "viewport": "desktop", + "durationMs": 1825 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/calendar", + "scrollWidth": 1280, + "scrollHeight": 955, + "viewportWidth": 1280, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n캘린더\n오늘\n2026년 8월\n월\n주\n일\n목록\n일\n\t\n월\n\t\n화\n\t\n수\n\t\n목\n\t\n금\n\t\n토\n\n\n26일\n\t\n27일\n\t\n28일\n\t\n29일\n\t\n30일\n\t\n31일\n\t\n1일\n\n\n2일\n\t\n3일\n\t\n4일\n\t\n5일\n\t\n6일\n\t\n7일\n\t\n8일\n\n\n9일\n\t\n10일\n\t\n11일\n\t\n12일\n\t\n13일\n\t\n14일\n\t\n1", + "route": "/calendar", + "name": "calendar", + "viewport": "desktop", + "durationMs": 1933 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/attendance", + "scrollWidth": 1280, + "scrollHeight": 900, + "viewportWidth": 1280, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n출퇴근\n\nATTENDANCE · 2026-08-22\n\n출석 관리\n\n오늘의 출석 현황과 확인이 필요한 기록을 한 곳에서 관리합니다.\n\nCSV 내보내기\n2026-08-22\n오늘\n이번 주\n날짜 선택\n전체 기록\n3\n2026-08-22\n처리 필요\n2\n근무 중 기록\n근무 중\n2\n현재 진행 중\n퇴근 완료\n1", + "route": "/attendance", + "name": "attendance", + "viewport": "desktop", + "durationMs": 1867 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/work-schedules", + "scrollWidth": 1280, + "scrollHeight": 2049, + "viewportWidth": 1280, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n근무 일정\n\n반복 근무와 날짜별 근무 일정을 같은 캘린더에서 보고 바로 관리할 수 있습니다.\n\n날짜 클릭으로 개별 일정을 추가하고, 역할 범위에 따라 다른 사람 일정도 함께 확인합니다.\n근무 일정 캘린더\n\n날짜를 눌러 개인 근무 일정을 추가하고, 역할 범위에 따라 다른 사람 근무 일정도 함께 확", + "route": "/work-schedules", + "name": "work-schedules", + "viewport": "desktop", + "durationMs": 1952 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/drive", + "scrollWidth": 1280, + "scrollHeight": 914, + "viewportWidth": 1280, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n드라이브\n\nSHARED LIBRARY\n\n모든 멤버가 함께 쓰는 공용 문서함입니다. 업로드한 파일은 팀 전체가 바로 확인할 수 있습니다.\n\n전체 멤버 공유\n공용 파일 업로드\n총 파일\n3개\n사용 용량\n1.2 MB\n최근 업로드\n3월 18일 오후 8:00\n팀 공유 라이브러리\n빠른 공유 업로드\n\n회의록,", + "route": "/drive", + "name": "drive", + "viewport": "desktop", + "durationMs": 1858 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/ai", + "scrollWidth": 1280, + "scrollHeight": 900, + "viewportWidth": 1280, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\nAI\n\n공유 문서를 바탕으로 답변하는 팀 어시스턴트입니다.\n\n안녕하세요! 저는 yANUs AI입니다. 파일 드라이브에 공유된 문서를 바탕으로 질문에 답변해 드립니다. 무엇을 도와드릴까요?\n\n추천 질문\n\n오늘 일정 요약해줘\n공유된 파일 목록 알려줘\n프로젝트 진행 상황 정리해줘", + "route": "/ai", + "name": "ai", + "viewport": "desktop", + "durationMs": 1785 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/members", + "scrollWidth": 1280, + "scrollHeight": 1503, + "viewportWidth": 1280, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n멤버\n\n멤버 상태와 역할을 한 곳에서 확인하고 관리합니다.\n\n관리자 전용\n멤버 초대\n팀\n전체 팀\n1팀\n2팀\n3팀\n역할\n전체 역할\n관리자\n팀장\n멤버\n전체 멤버 4명\n멤버 목록\n\n활성 멤버를 팀과 역할 기준으로 빠르게 확인할 수 있습니다.\n\n프로필\t팀\t역할\t상태\t관리\n\n김\n김리더\n\t1팀\t\n관리자\t\n", + "route": "/members", + "name": "members", + "viewport": "desktop", + "durationMs": 1877 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/my-page", + "scrollWidth": 1280, + "scrollHeight": 1017, + "viewportWidth": 1280, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n마이페이지\n\nMY PAGE\n\n프로필, 알림, 테마, 정산, 보안 정보를 한 곳에서 관리하세요.\n\n다크 모드 사용 중\n선택한 테마는 브라우저에 저장되어 다음 방문에도 유지됩니다.\n프로필\n알림\n테마\n정산\n보안\n\nPROFILE\n\n내 계정과 소속 정보를 정리합니다.\n\n표시 이름, 역할, 팀 정보를 확인", + "route": "/my-page", + "name": "my-page", + "viewport": "desktop", + "durationMs": 1853 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/", + "scrollWidth": 1280, + "scrollHeight": 1021, + "viewportWidth": 1280, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n홈\n09:13\n오늘은 휴무입니다\n오늘 근무가 종료되어 예정 시간과 함께 비교할 수 있습니다.\n휴무일에도 출근 기록이 있습니다\n\n오늘은 휴무일로 설정되어 있지만 실제 출퇴근 기록이 남아 있습니다.\n\n출근은 220.69 대역 IP에서만 가능합니다.\n오전 9:02 - 오후 6:15\n출근 내역 초기화\n", + "route": "/team-management", + "name": "team-management", + "viewport": "desktop", + "durationMs": 1849 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/admin", + "scrollWidth": 1280, + "scrollHeight": 2101, + "viewportWidth": 1280, + "bodyText": "yANUs\n홈\n채팅\n캘린더\n멤버\n출퇴근\n근무 일정\n드라이브\nAI\n마이페이지\n관리자\n김\n김리더\nADMIN\n로그아웃\n\nWORKSPACE\n\n관리자\n\n출근 현황과 멤버 상태를 한 곳에서 관리합니다.\n\nCSV 내보내기\n출근 현황\n멤버 관리\n팀 관리\n감사 로그\n지각비 정산\n운영 설정\n활성 멤버\n4명\n\n현재 운영 중인 전체 인원\n\n활성 팀\n3개\n\n근무 일정을 관리 중인 팀 수\n\n오늘 기록\n3건\n\n출근 또는 퇴근 기록이 남은 인원\n\n오늘 미", + "route": "/admin", + "name": "admin", + "viewport": "desktop", + "durationMs": 1898 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/login", + "scrollWidth": 1280, + "scrollHeight": 900, + "viewportWidth": 1280, + "bodyText": "yANUs\n동아리 그룹웨어\n이메일\n비밀번호\n로그인\n아직 계정이 없으신가요? 회원가입", + "route": "/login", + "name": "login", + "viewport": "desktop", + "durationMs": 1908 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/register", + "scrollWidth": 1280, + "scrollHeight": 971, + "viewportWidth": 1280, + "bodyText": "yANUs\n새 계정을 만들어 시작해 보세요\n이름\n이메일\n팀\n회원가입 시 모든 신규 사용자는 신입 팀으로 자동 배정됩니다.\n비밀번호\n비밀번호 확인\n회원가입\n이미 계정이 있으신가요? 로그인", + "route": "/register", + "name": "register", + "viewport": "desktop", + "durationMs": 1893 + }, + { + "title": "yANUs - 동아리 그룹웨어", + "path": "/verify-email", + "scrollWidth": 1280, + "scrollHeight": 1070, + "viewportWidth": 1280, + "bodyText": "yANUs\n이메일 인증\n이메일을 확인해 주세요\n\n회원가입이 거의 끝났습니다.\n메일로 받은 인증 코드를 입력해야 로그인할 수 있습니다.\n\n인증 코드\n인증 확인\n메일을 받지 못하셨나요?\n\n아래 이메일로 인증 코드를 다시 받을 수 있습니다.\n\n이메일\n인증 메일 다시 보내기\n이미 인증을 마치셨나요? 로그인", + "route": "/verify-email", + "name": "verify-email", + "viewport": "desktop", + "durationMs": 1945 + } + ] +} \ No newline at end of file diff --git a/.qa/issue-414/before/my-page-desktop.png b/.qa/issue-414/before/my-page-desktop.png new file mode 100644 index 0000000..4360a43 Binary files /dev/null and b/.qa/issue-414/before/my-page-desktop.png differ diff --git a/.qa/issue-414/before/my-page-mobile.png b/.qa/issue-414/before/my-page-mobile.png new file mode 100644 index 0000000..50a35f1 Binary files /dev/null and b/.qa/issue-414/before/my-page-mobile.png differ diff --git a/.qa/issue-414/before/my-page-tablet.png b/.qa/issue-414/before/my-page-tablet.png new file mode 100644 index 0000000..3b7071c Binary files /dev/null and b/.qa/issue-414/before/my-page-tablet.png differ diff --git a/.qa/issue-414/before/register-desktop.png b/.qa/issue-414/before/register-desktop.png new file mode 100644 index 0000000..785ab5f Binary files /dev/null and b/.qa/issue-414/before/register-desktop.png differ diff --git a/.qa/issue-414/before/register-mobile.png b/.qa/issue-414/before/register-mobile.png new file mode 100644 index 0000000..e7f96f0 Binary files /dev/null and b/.qa/issue-414/before/register-mobile.png differ diff --git a/.qa/issue-414/before/register-tablet.png b/.qa/issue-414/before/register-tablet.png new file mode 100644 index 0000000..e0e3693 Binary files /dev/null and b/.qa/issue-414/before/register-tablet.png differ diff --git a/.qa/issue-414/before/team-management-desktop.png b/.qa/issue-414/before/team-management-desktop.png new file mode 100644 index 0000000..441c1aa Binary files /dev/null and b/.qa/issue-414/before/team-management-desktop.png differ diff --git a/.qa/issue-414/before/team-management-mobile.png b/.qa/issue-414/before/team-management-mobile.png new file mode 100644 index 0000000..5118231 Binary files /dev/null and b/.qa/issue-414/before/team-management-mobile.png differ diff --git a/.qa/issue-414/before/team-management-tablet.png b/.qa/issue-414/before/team-management-tablet.png new file mode 100644 index 0000000..724b133 Binary files /dev/null and b/.qa/issue-414/before/team-management-tablet.png differ diff --git a/.qa/issue-414/before/verify-email-desktop.png b/.qa/issue-414/before/verify-email-desktop.png new file mode 100644 index 0000000..0d1698f Binary files /dev/null and b/.qa/issue-414/before/verify-email-desktop.png differ diff --git a/.qa/issue-414/before/verify-email-mobile.png b/.qa/issue-414/before/verify-email-mobile.png new file mode 100644 index 0000000..f56efc4 Binary files /dev/null and b/.qa/issue-414/before/verify-email-mobile.png differ diff --git a/.qa/issue-414/before/verify-email-tablet.png b/.qa/issue-414/before/verify-email-tablet.png new file mode 100644 index 0000000..7061821 Binary files /dev/null and b/.qa/issue-414/before/verify-email-tablet.png differ diff --git a/.qa/issue-414/before/work-schedules-desktop.png b/.qa/issue-414/before/work-schedules-desktop.png new file mode 100644 index 0000000..c62a7d1 Binary files /dev/null and b/.qa/issue-414/before/work-schedules-desktop.png differ diff --git a/.qa/issue-414/before/work-schedules-mobile.png b/.qa/issue-414/before/work-schedules-mobile.png new file mode 100644 index 0000000..61294e7 Binary files /dev/null and b/.qa/issue-414/before/work-schedules-mobile.png differ diff --git a/.qa/issue-414/before/work-schedules-tablet.png b/.qa/issue-414/before/work-schedules-tablet.png new file mode 100644 index 0000000..caf41b4 Binary files /dev/null and b/.qa/issue-414/before/work-schedules-tablet.png differ diff --git a/.qa/issue-414/capture-after.cjs b/.qa/issue-414/capture-after.cjs new file mode 100644 index 0000000..7d40847 --- /dev/null +++ b/.qa/issue-414/capture-after.cjs @@ -0,0 +1,88 @@ +const fs = require('fs') +const { chromium } = require('@playwright/test') + +const viewports = [ + { name: 'mobile', width: 390, height: 844 }, + { name: 'tablet', width: 768, height: 1024 }, + { name: 'desktop', width: 1280, height: 900 }, +] + +const routes = [ + { name: 'home', path: '/', token: 'mock-token-1' }, + { name: 'chat', path: '/chat', token: 'mock-token-1' }, + { name: 'calendar', path: '/calendar', token: 'mock-token-1' }, + { name: 'attendance', path: '/attendance', token: 'mock-token-1' }, + { name: 'work-schedules', path: '/work-schedules', token: 'mock-token-1' }, + { name: 'drive', path: '/drive', token: 'mock-token-1' }, + { name: 'ai', path: '/ai', token: 'mock-token-1' }, + { name: 'members', path: '/members', token: 'mock-token-1' }, + { name: 'my-page', path: '/my-page', token: 'mock-token-1' }, + { name: 'team-management', path: '/team-management', token: 'mock-token-2' }, + { name: 'admin', path: '/admin', token: 'mock-token-1' }, + { name: 'login', path: '/login' }, + { name: 'register', path: '/register' }, + { name: 'verify-email', path: '/verify-email' }, +] + +const sourceCommit = '753febc17546ca4bdd7c3525f53e43fc719f7de1' + +async function capture() { + const browser = await chromium.launch({ headless: true }) + const results = [] + + for (const viewport of viewports) { + for (const route of routes) { + const page = await browser.newPage({ viewport: { width: viewport.width, height: viewport.height } }) + const setup = route.token + ? 'localStorage.setItem("accessToken", "' + route.token + '"); localStorage.setItem("refreshToken", "refresh-' + (route.token === 'mock-token-2' ? '2' : '1') + '");' + : 'localStorage.removeItem("accessToken"); localStorage.removeItem("refreshToken");' + + await page.addInitScript({ content: setup + ' localStorage.setItem("yanus-theme", "dark");' }) + const started = Date.now() + await page.goto('http://127.0.0.1:5173' + route.path, { waitUntil: 'networkidle' }) + await page.waitForTimeout(500) + + const metrics = await page.evaluate(() => ({ + path: location.pathname, + scrollWidth: document.documentElement.scrollWidth, + scrollHeight: document.documentElement.scrollHeight, + bodyText: document.body.innerText.slice(0, 420), + })) + + await page.screenshot({ + path: '.qa/issue-414/after/' + route.name + '-' + viewport.name + '.png', + fullPage: true, + }) + + results.push({ + name: route.name, + requestedPath: route.path, + role: route.token === 'mock-token-2' ? 'TEAM_LEAD' : route.token ? 'ADMIN' : 'PUBLIC', + viewport: viewport.name, + viewportWidth: viewport.width, + viewportHeight: viewport.height, + ...metrics, + durationMs: Date.now() - started, + }) + + console.log(route.name + '/' + viewport.name + ' ' + metrics.path + ' width=' + metrics.scrollWidth + ' height=' + metrics.scrollHeight) + await page.close() + } + } + + fs.writeFileSync('.qa/issue-414/after/metadata.json', JSON.stringify({ + capturedAt: new Date().toISOString(), + source: 'issue-414-after', + sourceCommit, + viewports, + routes, + results, + }, null, 2)) + + await browser.close() +} + +capture().catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/DESIGN.md b/DESIGN.md index 699f29e..f625ae0 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -35,7 +35,7 @@ Elevation is expressed through background color layering rather than shadows. Th - **Lists**: Repository and file lists use full-width rows with 8px 16px padding, #30363D bottom border (1px). Hover highlights row to #161B22. Selected/active rows get a 2px left border in #F78166 (orange accent). - **Checkboxes**: 16x16px, #0D1117 background, 1px solid #30363D border, 3px radius. Checked state fills #2F81F7 with white checkmark SVG. Used prominently in task lists within issues and PRs. - **Tooltips**: #21262D background, #C9D1D9 text, 6px radius, 6px 10px padding, 12px font. Arrow-tipped, positioned above by default. 200ms delay on hover. Max-width 250px. -- **Navigation**: Top nav is #161B22 with 1px bottom border #21262D, 64px height. Tab navigation uses underline-style active indicator — 2px bottom border in #F78166 (orange) for active tab, #8B949E text for inactive. Sidebar nav uses #0D1117 background with hover highlight rows. +- **Navigation**: Top nav is #161B22 with 1px bottom border #21262D, 64px height. Tab navigation uses underline-style active indicator — 2px bottom border in #F78166 (orange) for active tab, #8B949E text for inactive. Sidebar nav uses #0D1117 background with hover highlight rows; the active item uses the primary blue (`#2F81F7`) for its 2px left rail and icon, with a restrained primary surface tint. Warning yellow is reserved for pending, draft, and caution states, not navigation selection. - **Search**: Prominent top-bar search with #0D1117 background, #30363D border, 6px radius. Activated state expands to full-width overlay with typeahead suggestions on #161B22 dropdown. Search shortcut / displayed as a muted kbd badge. ## Spacing @@ -63,6 +63,96 @@ Elevation is expressed through background color layering rather than shadows. Th - Don't animate transitions longer than 150ms — the interface should feel instant - Don't use the primary blue (#2F81F7) for large background fills — reserve it for interactive elements and links +## Issue #414 — App-wide redesign + +Issue #414 extends the Octo Code contract from the attendance surface to every route. The +redesign is a visual and interaction-system refactor: existing API calls, permission guards, +state ownership, route semantics, and user-visible data remain unchanged. + +### Route inventory + +Authenticated routes share one application shell: + +`/` dashboard, `/chat` chat, `/calendar` calendar and tasks, `/attendance` attendance, +`/work-schedules` work schedules, `/drive` drive, `/ai` AI chat, `/members` members, +`/my-page` profile/settings, `/team-management` team management, and `/admin` administration. + +Public routes use the same tokens without the authenticated shell: + +`/login`, `/register`, and `/verify-email`. + +### Shared surface contract + +- **App shell**: a 200px desktop sidebar, a 64px topbar, and a fixed bottom navigation at + narrow widths. The content region is capped at 1280px with `20–32px` gutters and always + reserves bottom-bar clearance on touch layouts. +- **Page header**: one eyebrow, one Korean page title, one concise description, and a right-side + action group. Header actions never compete with the page title on mobile. +- **Surface**: cards, tables, lists, forms, drawers, and modals use `#161B22`, a 1px + `#30363D` border, a maximum 6px radius, and layered backgrounds instead of blur or decorative + gradients. +- **Controls**: primary actions use Mona Blue or Growth Green only when the action is a merge/ + success operation. Secondary controls are bordered and transparent. Inputs are 36px high on + desktop and at least 44px high for touch-critical actions. +- **Data display**: dense information uses border-separated rows, compact metadata, and explicit + empty/loading/error states in the same region as the data. Tables scroll inside their surface; + the page itself never gains horizontal overflow. +- **Feedback**: every status includes text plus an icon, border, or layout cue. `#D29922` is + reserved for pending, draft, and caution feedback; it is never used to indicate navigation + selection. Errors use `#F85149`, success uses `#3FB950`, and informational selection uses + `#2F81F7`. +- **Overlays**: popovers use `#1C2128`, modals use `#21262D`, and the backdrop uses the Octo + overlay token. Functional overlays keep the 6px radius and provide labelled close/focus paths. + +### Page family rules + +- **Dashboard** prioritizes the current attendance action, then schedule, chat, and tasks in a + compact grid. Empty cards explain what the user can do next. +- **Chat, calendar, and work schedules** keep their existing interaction models, but use shared + toolbars, bordered panels, blue selection, and compact rows. FullCalendar's DOM remains a + vendor boundary and inherits the same tokens. +- **Attendance, members, team management, and admin** use the same table, search, filter, + status-badge, modal, and responsive row language. Role guards and data scope are unchanged. +- **Drive and AI chat** use repository-like lists and code-friendly message surfaces. Markdown + and code retain JetBrains Mono; conversational bubbles do not use purple gradients. +- **My Page** uses a narrow readable form column with section dividers, explicit save feedback, + and a separate danger zone. +- **Auth routes** use the base background, a bordered 6px form surface, restrained branding, + and one primary action. Decorative glass, blur, and full-page purple gradients are removed. + +### Responsive, theme, and accessibility rules + +- Reference widths are `390px`, `768px`, and `1280px`. At each width, `scrollWidth` must not + exceed the viewport width and all dense data must remain readable without clipped CJK text. +- Mobile layouts collapse by priority, not by shrinking every control. Tables become scrollable + regions or labelled rows, and fixed navigation always has at least `56px` of content clearance. +- Dark mode remains the default. The explicit `data-theme="light"` preference maps every surface, + border, text, state, and input token to a readable light alias; the system preference does not + silently override the user's stored theme. +- Korean headings use `text-wrap: pretty` where supported, body copy uses a readable line-height, + and no page relies on color alone. Every interactive element keeps a visible `:focus-visible` + ring and a minimum 36px target (44px for primary touch actions). +- Motion is limited to 120ms state transitions. `prefers-reduced-motion: reduce` disables + non-essential transitions and animated decoration. + +### Implementation boundary and accepted debt + +The app-wide layer owns tokens, shell geometry, shared surface language, state colors, responsive +guards, and cross-route visual overrides. Existing page CSS owns only route-specific composition +and vendor integration. API, Context, route guard, mock, and permission changes are out of scope. +The remaining FullCalendar vendor markup and existing bundle chunk-size warning are recorded as +accepted debt unless they block a route or accessibility condition. + +### Before / After evidence contract + +Before captures are taken from the same mock-authenticated route matrix before Issue #414 style +changes. After captures use the same route, role, viewport, browser, theme, and scroll conditions. +Each capture records the rendered commit SHA, viewport, `scrollWidth`, full-page `scrollHeight`, +and the visible state. The evidence set covers all 14 routes at `390×844`, `768×1024`, and +`1280×900`; protected `/team-management` is captured with a team-lead fixture and `/admin` with +an admin fixture. Representative screenshots are inspected at every breakpoint, with focused +interaction checks for auth, navigation, tables, filters, modals, forms, and feedback states. + ## Issue #410 — 출석 운영 화면 ### Information architecture @@ -165,3 +255,51 @@ After verification checklist: - [x] Member view shows one CTA, schedule chip, text timeline, personal records, and retry state. - [x] Keyboard focus, text status, contrast, touch target size, and mobile bottom clearance are checked in the browser. - [x] Fresh PNG signatures, dimensions, and final verification metadata were checked for all six After captures. + +### Navigation active-state follow-up + +The post-merge navigation polish was captured against source commit `fbf6ee2` after replacing the warning-yellow active rail/icon with the Octo primary blue token. The active item uses `rgba(47, 129, 247, 0.12)` as its surface tint, `#2F81F7` for the 2px left rail and icon, and keeps warning yellow reserved for caution states. + +| Capture | Viewport | Objective evidence | File | +| --- | --- | --- | --- | +| Home sidebar | `1280×900` | Active `홈` uses primary blue rail/icon and `scrollWidth=1280`. | `.qa/issue-410/after/nav-active-blue-1280.png` | +| Home bottom navigation | `390×844` | Active `홈` uses primary blue rail/icon and `scrollWidth=390`; no horizontal overflow. | `.qa/issue-410/after/nav-active-blue-390.png` | + +## Before / After evidence — #414 + +The app-wide baseline was captured from `develop` at `f35affdb5a30a9c05b25e9b22d92742b13abc1ef` +before Issue #414 style edits. The After set was captured on `2026-08-22` from rendered source +`753febc17546ca4bdd7c3525f53e43fc719f7de1`. Both sets use Chromium, `VITE_USE_MOCK=true`, +dark theme, full-page screenshots, and the same `390×844`, `768×1024`, and `1280×900` viewports. +The After set uses the admin fixture for authenticated general routes, the team-lead fixture for +`/team-management`, and no auth fixture for the public routes. + +### Before + +| Scope | Coverage | Objective evidence | File | +| --- | --- | --- | --- | +| Authenticated shell | 10 routes × 3 viewports | Existing shell and route CSS used mixed glass/gradient surfaces, large functional radii, and route-specific spacing. | `.qa/issue-414/before/metadata.json` | +| Public auth | 3 routes × 3 viewports | Login, register, and email verification shared the legacy decorative auth treatment. | `.qa/issue-414/before/login-desktop.png`, `.qa/issue-414/before/register-desktop.png`, `.qa/issue-414/before/verify-email-desktop.png` | +| Protected team management | 1 route × 3 viewports | Admin fixture redirected `/team-management` to `/`, so the team-lead surface had no valid baseline capture. | `.qa/issue-414/before/team-management-mobile.png` | +| Whole matrix | 42 captures | `scrollWidth` matched the viewport in the recorded baseline, but the evidence exposed route redirect coverage and inconsistent surface language. | `.qa/issue-414/before/metadata.json` | + +### After + +| Scope | Coverage | Objective evidence | File | +| --- | --- | --- | --- | +| Authenticated shell | 10 routes × 3 viewports | Sidebar active state is blue, surfaces use token borders and 6px functional radii, and mobile uses the fixed bottom bar with content clearance. | `.qa/issue-414/after/home-desktop.png`, `.qa/issue-414/after/home-mobile.png` | +| Chat, calendar, schedules | 3 routes × 3 viewports | Toolbars, selected rows, FullCalendar controls, message surfaces, and schedule legends use shared blue/info, warning, success, and error states. | `.qa/issue-414/after/chat-desktop.png`, `.qa/issue-414/after/calendar-desktop.png`, `.qa/issue-414/after/work-schedules-mobile.png` | +| Operations and data pages | 4 routes × 3 viewports | Attendance, members, team management, and admin tables use compact bordered rows, readable empty states, and semantic status colors. | `.qa/issue-414/after/attendance-desktop.png`, `.qa/issue-414/after/members-desktop.png`, `.qa/issue-414/after/team-management-desktop.png`, `.qa/issue-414/after/admin-mobile.png` | +| Drive and AI | 2 routes × 3 viewports | File lists, upload controls, AI messages, suggestions, and code-friendly surfaces no longer depend on purple gradients or blur. | `.qa/issue-414/after/drive-mobile.png`, `.qa/issue-414/after/ai-desktop.png` | +| My Page and public auth | 4 routes × 3 viewports | Settings sections, form controls, login, register, and email verification use the same surface and focus language. | `.qa/issue-414/after/my-page-mobile.png`, `.qa/issue-414/after/login-desktop.png`, `.qa/issue-414/after/register-desktop.png`, `.qa/issue-414/after/verify-email-mobile.png` | +| Whole matrix | 42 captures | All 14 requested routes rendered at the requested path; all 42 captures recorded `scrollWidth` equal to the viewport width. | `.qa/issue-414/after/metadata.json` | + +After verification checklist: + +- [x] All 14 routes render at `390px`, `768px`, and `1280px`. +- [x] `scrollWidth` does not exceed the viewport in any of the 42 After captures. +- [x] `/team-management` is captured with the team-lead fixture and no longer redirects to `/`. +- [x] Navigation selection uses primary blue; warning yellow remains reserved for caution/status. +- [x] Auth backgrounds, cards, fields, buttons, and public feedback states use the shared surface layer. +- [x] Explicit light theme was checked on home, calendar, and login at `1280×900`; all kept the viewport width. +- [x] Fresh PNG files, dimensions, route paths, roles, and scroll metrics are recorded in After metadata. diff --git a/src/index.css b/src/index.css index c3f5bec..3cbbb31 100644 --- a/src/index.css +++ b/src/index.css @@ -67,6 +67,8 @@ --ring-color: rgba(47, 129, 247, 0.45); --nav-hover: var(--surface); --nav-active: var(--surface); + --nav-active-indicator: var(--color-primary); + --nav-active-icon: var(--color-primary); --page-max-regular: 1200px; --page-max-wide: 1480px; --page-max-ultra: 1760px; @@ -180,3 +182,817 @@ svg, white-space: nowrap; border: 0; } + +:root { + --app-page-gutter: clamp(16px, 2.4vw, 32px); + --surface-hover: #1c2128; + --surface-subtle: rgba(255, 255, 255, 0.03); + --state-info-bg: rgba(47, 129, 247, 0.12); + --state-success-bg: rgba(63, 185, 80, 0.12); + --state-warning-bg: rgba(210, 153, 34, 0.14); + --state-error-bg: rgba(248, 81, 73, 0.12); +} + +:root[data-theme='light'] { + --surface-hover: #f6f8fa; + --surface-subtle: rgba(31, 35, 40, 0.04); + --state-info-bg: rgba(9, 105, 218, 0.1); + --state-success-bg: rgba(26, 127, 55, 0.1); + --state-warning-bg: rgba(154, 103, 0, 0.12); + --state-error-bg: rgba(207, 34, 46, 0.1); + --bg-soft: rgba(31, 35, 40, 0.04); + --bg-soft-strong: rgba(31, 35, 40, 0.08); + --bg-input: #ffffff; + --surface-muted: rgba(31, 35, 40, 0.04); + --bg-overlay: rgba(31, 35, 40, 0.45); + --surface-tint: rgba(9, 105, 218, 0.1); + --surface-tint-strong: rgba(9, 105, 218, 0.16); + --border-strong: #afb8c1; + --shadow-strong: 0 8px 24px rgba(31, 35, 40, 0.16); +} + +body { + overflow-x: hidden; + line-height: 1.5; +} + +#root { + overflow-x: clip; +} + +#root .layout { + background: var(--bg-dark); +} + +#root .sidebar { + background: var(--bg-sidebar); + border-color: var(--border-color); +} + +#root .logo-panel { + min-height: 64px; + padding: 12px 14px; +} + +#root .logo { + gap: 9px; +} + +#root .logo-img { + width: 32px; + height: 32px; +} + +#root .logo-copy strong { + font-family: var(--font-mono); + font-size: 0.88rem; + letter-spacing: -0.04em; +} + +#root .theme-toggle { + width: 32px; + height: 32px; + border-radius: var(--radius-xs); + background: transparent; +} + +#root .nav { + padding: 16px 10px; + gap: 2px; +} + +#root .nav-item { + min-height: 36px; + padding: 0 10px; + border-radius: var(--radius-xs); + gap: 10px; +} + +#root .nav-item.active, +#root .admin-nav-item.active { + color: var(--text-primary) !important; + background: var(--surface-tint) !important; + box-shadow: inset 2px 0 var(--color-primary); +} + +#root .nav-item.active svg, +#root .admin-nav-item.active svg { + color: var(--color-primary) !important; +} + +#root .sidebar-bottom { + padding: 12px; + background: var(--bg-sidebar); +} + +#root .sidebar-user { + padding: 10px; + border-radius: var(--radius-xs); + background: var(--surface); +} + +#root .sidebar-user-avatar { + width: 32px; + height: 32px; + border-radius: var(--radius-xs); + background: var(--surface-popover); + color: var(--color-primary); +} + +#root .main-content { + min-width: 0; + padding: 24px var(--app-page-gutter) 32px; + background: var(--bg-dark); +} + +#root .content-topbar { + min-height: 56px; + margin-bottom: 24px; + padding: 0 0 16px; + border-color: var(--border-color); +} + +#root .content-kicker, +#root :is(.drive-kicker, .settings-kicker, .page-eyebrow, .section-eyebrow) { + color: var(--text-muted); + font-family: var(--font-mono); + font-size: 0.72rem; + font-weight: 500; + letter-spacing: 0.08em; +} + +#root .content-topbar h1 { + font-size: 1.5rem; + font-weight: 600; +} + +#root .content-body, +#root :is(.dashboard, .chat-page, .calendar-page, .attendance-page, .work-schedules-page, + .drive-page, .ai-chat-page, .members-page, .settings-page, .team-management-page, .admin-page) { + min-width: 0; + width: 100%; +} + +#root :is(.dashboard, .chat-page, .calendar-page, .attendance-page, .work-schedules-page, + .drive-page, .ai-chat-page, .members-page, .settings-page, .team-management-page, .admin-page) { + max-width: var(--content-max-wide); + margin-inline: auto; +} + +#root .glass, +#root :is(.card, .chat-sidebar, .chat-main, .fullcalendar-wrapper, .tasks-sidebar, + .drive-content, .drive-side-panel, .drive-stat-card, .ai-chat-area, .table-section, + .stats-sidebar, .settings-nav, .settings-content, .team-management-panel, + .admin-tab-content, .admin-overview-card, .dashboard-detail-modal) { + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + background: var(--surface); + box-shadow: var(--shadow-soft); + backdrop-filter: none; +} + +#root :is(.card, .drive-stat-card, .admin-overview-card, .my-settlement-card):hover, +#root :is(.file-row, .task-item, .schedule-item, .channel-item, .dm-item):hover { + border-color: var(--border-strong); +} + +#root :is(input, textarea, select) { + min-height: 36px; + border: 1px solid var(--border-color); + border-radius: var(--radius-xs); + background: var(--bg-input); + color: var(--text-primary); +} + +#root :is(input, textarea, select):focus { + border-color: var(--color-primary); + outline: 2px solid var(--ring-color); + outline-offset: 0; +} + +#root :is(button, a, input, textarea, select) { + transition-duration: var(--motion-fast); +} + +#root :is(.view-all, .drive-access-badge, .file-meta, .file-size, .schedule-time, + .task-meta-row, .settings-section-eyebrow) { + color: var(--text-secondary); +} + +#root :is(.view-all, .drive-access-badge, a) { + color: var(--accent-purple-light); +} + +#root :is(.primary-btn, .login-btn, .register-btn, .upload-btn, .upload-cta, .send-btn, + .confirm-btn, .team-confirm-btn, .save-btn, .attendance-export-button, .filter-apply-btn, + .clockout-btn, .dashboard-primary-btn, .admin-create-team-btn) { + min-height: 36px; + border: 1px solid var(--color-primary); + border-radius: var(--radius-xs); + background: var(--color-primary); + color: var(--color-on-primary); + box-shadow: none; +} + +#root :is(.primary-btn, .login-btn, .register-btn, .upload-btn, .upload-cta, .send-btn, + .confirm-btn, .team-confirm-btn, .save-btn, .attendance-export-button, .filter-apply-btn, + .clockout-btn, .dashboard-primary-btn, .admin-create-team-btn):hover:not(:disabled) { + border-color: var(--color-primary-hover); + background: var(--color-primary-hover); +} + +#root :is(.secondary-btn, .dashboard-secondary-btn, .cancel-btn, .team-cancel-btn, + .download-btn, .delete-btn, .close-btn, .theme-toggle) { + border: 1px solid var(--border-color); + border-radius: var(--radius-xs); + background: transparent; + color: var(--text-secondary); +} + +#root :is(.secondary-btn, .dashboard-secondary-btn, .cancel-btn, .team-cancel-btn, + .download-btn, .delete-btn, .close-btn, .theme-toggle):hover { + border-color: var(--border-strong); + background: var(--surface-hover); + color: var(--text-primary); +} + +#root :is(.dashboard, .chat-page, .calendar-page, .attendance-page, .work-schedules-page, + .drive-page, .ai-chat-page, .members-page, .settings-page, .team-management-page, .admin-page) + :is(h1, h2, h3, h4) { + text-wrap: pretty; + letter-spacing: -0.02em; +} + +#root .dashboard-grid { + gap: 16px; +} + +#root .dashboard-grid .card { + padding: 20px; +} + +#root .clock-card, +#root .schedule-card, +#root .chat-preview, +#root .tasks-card { + min-height: 0; +} + +#root .clock-ring-btn.clickable:hover { + filter: brightness(1.08); +} + +#root :is(.clockout-btn, .clock-reset-btn) { + border-radius: var(--radius-xs); +} + +#root .schedule-item.purple, +#root .schedule-item { + border-left: 2px solid var(--color-primary); + border-radius: var(--radius-xs); + background: var(--surface-popover); +} + +#root .schedule-item.purple { + color: var(--text-primary); +} + +#root :is(.task-priority-badge, .task-deadline-badge, .task-done-badge, + .clock-schedule-pill, .attendance-alert-card) { + border-radius: var(--radius-xs); +} + +#root .attendance-alert-card.success, +#root .task-done-badge.done { + background: var(--state-success-bg); + border-color: color-mix(in srgb, var(--color-success) 35%, var(--border-color)); +} + +#root .attendance-alert-card.warning, +#root .task-deadline-badge.urgent { + background: var(--state-warning-bg); + border-color: color-mix(in srgb, var(--color-warning) 35%, var(--border-color)); +} + +#root .chat-page { + gap: 12px; +} + +#root .chat-sidebar, +#root .chat-main { + min-height: 0; + border-radius: var(--radius-sm); +} + +#root .chat-sidebar { + padding: 16px; +} + +#root :is(.search-wrap, .chat-input-area, .input-preview, .format-toolbar) { + border-color: var(--border-color); + border-radius: var(--radius-xs); + background: var(--surface-popover); +} + +#root :is(.channel-item, .dm-item) { + border-radius: var(--radius-xs); +} + +#root :is(.channel-item.active, .dm-item.active) { + border-left: 2px solid var(--color-primary); + background: var(--surface-tint); + color: var(--text-primary); +} + +#root .msg-content { + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + background: var(--surface-popover); +} + +#root .msg.own .msg-content { + border-color: var(--color-primary); + background: var(--state-info-bg); +} + +#root :is(.msg-markdown code, .code-block, .file-attachment) { + border-radius: var(--radius-xs); + background: var(--surface-popover); +} + +#root .send-btn { + min-width: 40px; +} + +#root :is(.calendar-page, .work-schedules-page) { + gap: 16px; +} + +#root :is(.fullcalendar-wrapper, .work-schedules-calendar-card, .work-schedules-editor-card, + .tasks-sidebar) { + border-radius: var(--radius-sm); + background: var(--surface); + box-shadow: var(--shadow-soft); +} + +#root .fullcalendar-wrapper { + --fc-border-color: var(--border-color); + --fc-page-bg-color: var(--surface); + --fc-neutral-bg-color: var(--surface-popover); + --fc-list-event-hover-bg-color: var(--surface-hover); + --fc-today-bg-color: var(--state-info-bg); +} + +#root .fullcalendar-wrapper :is(.fc-button-primary, .fc-button-primary:not(:disabled)) { + border-color: var(--color-primary); + border-radius: var(--radius-xs); + background: var(--color-primary); + color: var(--color-on-primary); +} + +#root .fullcalendar-wrapper :is(.fc-button-primary:hover, .fc-button-primary:focus) { + border-color: var(--color-primary-hover); + background: var(--color-primary-hover); +} + +#root .fullcalendar-wrapper .fc-daygrid-day.fc-day-today { + background: var(--state-info-bg); +} + +#root .fullcalendar-wrapper .fc-event { + border-radius: var(--radius-xs); + border-color: var(--color-primary); + background: var(--color-primary); +} + +#root :is(.tasks-tabs span.active, .scope-chip.active, .work-schedules-scope-group .active) { + border-color: var(--color-primary); + background: var(--state-info-bg); + color: var(--color-primary); +} + +#root :is(.task-item, .event-item, .work-schedules-detail-item) { + border-color: var(--border-color); + border-radius: var(--radius-xs); + background: transparent; +} + +#root :is(.edit-task-modal, .add-task-modal, .context-menu-modal, .work-schedules-modal, + .event-popup, .fc-popover) { + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + background: var(--surface-modal); + box-shadow: var(--shadow-strong); +} + +#root :is(.member-schedule-section, .member-today-card, .member-timeline-section, + .member-history-section, .operator-board, .table-section, .stats-sidebar, + .team-management-panel, .admin-tab-content, .settings-content) { + background: var(--surface); + border-color: var(--border-color); + border-radius: var(--radius-sm); + box-shadow: var(--shadow-soft); +} + +#root :is(.member-schedule-section, .table-section, .team-management-panel, .admin-tab-content) { + padding: 20px; +} + +#root :is(.filter-btns button, .attendance-filter-group button, .operator-filters button, + .role-btn, .admin-tab-btn, .settings-nav-item, .team-select-option) { + border: 1px solid transparent; + border-radius: var(--radius-xs); + background: transparent; + color: var(--text-secondary); +} + +#root :is(.filter-btns button.active, .attendance-filter-group button.active, + .operator-filters button.active, .role-btn.active, .admin-tab-btn.active, + .settings-nav-item.active, .team-select-option.selected) { + border-color: color-mix(in srgb, var(--color-primary) 40%, var(--border-color)); + background: var(--state-info-bg); + color: var(--color-primary); +} + +#root :is(.members-table, .team-management-table, .admin-table, .my-settlement-table) { + border-collapse: collapse; +} + +#root :is(.members-table th, .members-table td, .team-management-table th, + .team-management-table td, .admin-table th, .admin-table td, .my-settlement-table th, + .my-settlement-table td) { + border-color: var(--border-color); +} + +#root :is(.members-table tbody tr:hover td, .team-management-table tbody tr:hover td, + .admin-table tbody tr:hover td) { + background: var(--surface-hover); +} + +#root :is(.admin-badge, .status-badge, .team-chip, .team-tag, .role-tag, .role-pill, + .admin-team-tag, .settings-section-badge) { + border-radius: var(--radius-xs); +} + +#root :is(.team-member-avatar, .avatar, .profile-avatar, .big-avatar) { + background: var(--surface-popover); + color: var(--color-primary); +} + +#root :is(.team-member-avatar, .avatar, .profile-avatar, .big-avatar) { + border-radius: 50%; +} + +#root :is(.modal-overlay, .dashboard-modal-overlay, .link-modal-overlay, + .team-management-modal-overlay, .admin-modal-overlay, .edit-task-modal-overlay) { + background: var(--bg-overlay); + backdrop-filter: none; +} + +#root :is(.change-role-modal, .invite-modal, .team-management-modal, .admin-modal, + .dashboard-detail-modal, .link-modal) { + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + background: var(--surface-modal); + box-shadow: var(--shadow-strong); +} + +#root .drive-overview { + gap: 12px; +} + +#root :is(.drive-stat-card, .drive-side-panel, .drive-content, .ai-chat-area, + .suggestions) { + padding: 20px; +} + +#root :is(.file-row, .drive-side-stats > div) { + border-color: var(--border-color); +} + +#root .file-icon { + width: 36px; + height: 36px; + border-radius: var(--radius-xs); + background: var(--state-info-bg); + color: var(--color-primary); +} + +#root .file-row { + border-radius: var(--radius-xs); +} + +#root .ai-chat-area { + border-radius: var(--radius-sm); +} + +#root :is(.msg-bubble.user span, .msg-bubble.ai span) { + border-radius: var(--radius-sm); +} + +#root .msg-bubble.user span { + background: var(--state-info-bg); + color: var(--text-primary); + border: 1px solid var(--color-primary); +} + +#root .msg-bubble.ai span { + background: var(--surface-popover); + border-color: var(--border-color); +} + +#root :is(.suggestions button, .input-area input) { + border-radius: var(--radius-xs); +} + +#root .suggestions button { + border-color: var(--border-color); + background: var(--surface-popover); +} + +#root .suggestions button:hover { + border-color: var(--color-primary); + background: var(--state-info-bg); +} + +#root .drive-access-badge, +#root .drive-panel-badge { + border: 1px solid color-mix(in srgb, var(--color-primary) 35%, var(--border-color)); + border-radius: var(--radius-xs); + background: var(--state-info-bg); + color: var(--color-primary); +} + +#root .drive-stat-icon { + width: 36px; + height: 36px; + border-radius: var(--radius-xs); + background: var(--state-info-bg); + color: var(--color-primary); +} + +#root .drive-access-note { + border: 1px solid var(--border-color); + border-radius: var(--radius-xs); + background: var(--surface-popover); +} + +#root .drive-side-stats > div { + border: 1px solid var(--border-color); + border-radius: var(--radius-xs); + background: var(--surface-popover); +} + +#root .settings-summary-icon { + width: 36px; + height: 36px; + border-radius: var(--radius-xs); + background: var(--state-info-bg); + color: var(--color-primary); +} + +#root .settings-section-hero { + border-radius: var(--radius-xs); + background: var(--surface-popover); +} + +#root .settings-section-badge { + border: 1px solid color-mix(in srgb, var(--color-primary) 35%, var(--border-color)); + border-radius: var(--radius-xs); + background: var(--state-info-bg); + color: var(--color-primary); +} + +#root :is(.theme-option-card, .my-settlement-card, .appearance-note) { + border-radius: var(--radius-xs); + border-color: var(--border-color); + background: var(--surface-popover); +} + +#root .theme-option-card.active { + border-color: var(--color-primary); + background: var(--state-info-bg); +} + +#root :is(.member-avatar, .team-member-avatar) { + border: 1px solid color-mix(in srgb, var(--color-primary) 35%, var(--border-color)); + background: var(--surface-popover); + color: var(--color-primary); +} + +#root :is(.member-team-tag, .team-tag, .team-chip) { + border: 1px solid color-mix(in srgb, var(--color-primary) 30%, var(--border-color)); + border-radius: var(--radius-xs); + background: var(--state-info-bg); + color: var(--text-primary); +} + +#root :is(.member-role-tag.ADMIN, .role-tag.ADMIN, .role-pill.ADMIN) { + border-color: color-mix(in srgb, var(--color-primary) 35%, var(--border-color)); + background: var(--state-info-bg); + color: var(--color-primary); +} + +#root :is(.member-role-tag.TEAM_LEAD, .role-tag.TEAM_LEAD, .role-pill.TEAM_LEAD) { + border-color: color-mix(in srgb, var(--color-primary) 30%, var(--border-color)); + background: var(--state-info-bg); + color: var(--color-primary); +} + +#root :is(.member-role-tag.MEMBER, .role-tag.MEMBER, .role-pill.MEMBER) { + background: var(--surface-popover); + color: var(--text-secondary); +} + +#root .bar { + border-radius: var(--radius-xs) var(--radius-xs) 0 0; + background: var(--color-primary); +} + +#root .legend-chip { + border-radius: var(--radius-xs); +} + +#root .legend-chip.recurring-own, +#root .legend-chip.recurring-team, +#root .quick-add-btn { + background: var(--state-info-bg); + color: var(--color-primary); +} + +#root .legend-chip.date-own { + background: var(--state-warning-bg); + color: var(--color-warning); +} + +#root .legend-chip.date-team { + background: var(--state-success-bg); + color: var(--color-success); +} + +#root :is(.settings-nav, .settings-content) { + border-radius: var(--radius-sm); +} + +#root :is(.settings-section, .danger-zone, .settlement-empty-panel, .appearance-note) { + border-color: var(--border-color); + border-radius: var(--radius-xs); +} + +#root :is(.setting-input, .form-input, .form-select, .verify-email-input) { + border-radius: var(--radius-xs); + background: var(--bg-input); +} + +#root :is(.danger-zone, .danger-confirm-box) { + background: var(--state-error-bg); +} + +#root :is(.login-page, .register-page, .verify-email-page) { + min-height: 100vh; + background: var(--bg-dark); + background-image: none !important; +} + +#root .login-page::after, +#root .register-page::after, +#root .verify-email-page::after { + content: none; + display: none; +} + +#root :is(.login-card, .register-card, .verify-email-card) { + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + background: var(--surface); + box-shadow: var(--shadow-strong); + backdrop-filter: none; +} + +#root .login-card::before, +#root .register-card::before, +#root .verify-email-card::before { + content: none; + display: none; +} + +#root :is(.login-logo-title, .register-logo-title, .verify-email-logo-title) { + font-family: var(--font-mono); + color: var(--text-primary); + background: none; + -webkit-text-fill-color: var(--color-primary); +} + +#root :is(.login-btn, .register-btn, .verify-email-primary-link, .verify-email-resend-btn) { + min-height: 40px; + border-radius: var(--radius-xs); + background: var(--color-primary); + color: var(--color-on-primary); +} + +#root :is(.login-error, .register-error, .verify-email-feedback.error) { + border-color: var(--color-error); + background: var(--state-error-bg); +} + +#root :is(.verify-email-status-card, .verify-email-resend) { + border-color: var(--border-color); + border-radius: var(--radius-xs); + background: var(--surface-popover); +} + +@media (max-width: 900px) { + #root :is(.drive-layout, .members-content, .settings-layout, .work-schedules-layout) { + grid-template-columns: minmax(0, 1fr); + } + + #root :is(.drive-side-panel, .stats-sidebar, .settings-nav) { + width: 100%; + } + + #root :is(.attendance-header, .drive-header, .members-header, .settings-header, + .team-management-header, .admin-header) { + align-items: flex-start; + flex-wrap: wrap; + } +} + +@media (max-width: 768px) { + #root .main-content { + margin-bottom: 120px; + padding-inline: 14px; + } + + #root .content-topbar { + min-height: 48px; + } + + #root .content-topbar h1 { + font-size: 1.35rem; + } + + #root .dashboard-grid { + grid-template-columns: minmax(0, 1fr); + } + + #root :is(.dashboard-grid .clock-card, .dashboard-grid .schedule-card, + .dashboard-grid .chat-preview, .dashboard-grid .tasks-card) { + grid-column: auto; + } + + #root :is(.member-schedule-section, .table-section, .team-management-panel, + .admin-tab-content, .drive-content, .drive-side-panel, .ai-chat-area) { + padding: 16px; + } + + #root :is(.admin-overview-grid, .drive-overview) { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + #root :is(.members-table-wrap, .team-management-table-wrap, .admin-table-wrap, + .my-settlement-table-wrap) { + max-width: 100%; + overflow-x: auto; + } + + #root :is(.header-actions, .drive-header-actions, .admin-header-actions) { + width: 100%; + justify-content: flex-start; + } +} + +@media (max-width: 480px) { + #root .main-content { + padding-inline: 12px; + } + + #root :is(.admin-overview-grid, .drive-overview) { + grid-template-columns: minmax(0, 1fr); + } + + #root :is(.content-topbar, .attendance-header, .drive-header, .members-header, + .settings-header, .team-management-header, .admin-header) { + margin-bottom: 16px; + } + + #root :is(.attendance-export-button, .upload-btn, .upload-cta, .login-btn, + .register-btn, .save-btn, .send-btn) { + min-height: 40px; + } + + #root :is(.modal-overlay, .dashboard-modal-overlay, .link-modal-overlay, + .team-management-modal-overlay, .admin-modal-overlay, .edit-task-modal-overlay) { + padding: 12px; + } +} + +@media (prefers-reduced-motion: reduce) { + #root *, + #root *::before, + #root *::after { + scroll-behavior: auto !important; + transition-duration: 0.01ms !important; + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + } +} diff --git a/src/widgets/Layout/Layout.css b/src/widgets/Layout/Layout.css index 8e5ee58..c7f1c05 100644 --- a/src/widgets/Layout/Layout.css +++ b/src/widgets/Layout/Layout.css @@ -109,41 +109,41 @@ .nav-item:hover { color: var(--text-primary); - background: var(--nav-hover); background: var(--surface) !important; } .nav-item.active { color: var(--text-primary); - box-shadow: inset 2px 0 var(--color-warning); - background: var(--surface) !important; + box-shadow: inset 2px 0 var(--nav-active-indicator); + background: var(--surface-tint) !important; border-color: transparent; } .nav-item.active svg { - color: var(--color-warning); + color: var(--nav-active-icon); } .admin-nav-item { margin-top: 8px; border-top: 1px solid var(--border-color); padding-top: 14px; - color: var(--color-warning) !important; - opacity: 0.85; + color: var(--text-secondary) !important; } .admin-nav-item:hover { - opacity: 1; background: var(--surface) !important; - color: var(--color-warning) !important; + color: var(--text-primary) !important; } .admin-nav-item.active { - opacity: 1; - background: var(--surface) !important; + background: var(--surface-tint) !important; color: var(--text-primary) !important; } +.admin-nav-item.active svg { + color: var(--nav-active-icon); +} + .main-content { flex: 1; margin-left: var(--sidebar-width);