diff --git a/mobile/src/App.vue b/mobile/src/App.vue index eb8c6913..40053b46 100644 --- a/mobile/src/App.vue +++ b/mobile/src/App.vue @@ -1150,503 +1150,81 @@ - + diff --git a/mobile/src/data/auth.ts b/mobile/src/data/auth.ts new file mode 100644 index 00000000..aafc8d6c --- /dev/null +++ b/mobile/src/data/auth.ts @@ -0,0 +1,7 @@ +export const tokenKey = 'aihr_mobile_access_token'; + +export const clientIdKey = 'aihr_mobile_client_id'; + +export const phoneKey = 'aihr_mobile_phone'; + +export const phonePattern = /^1[3-9]\d{9}$/; diff --git a/mobile/src/data/home.ts b/mobile/src/data/home.ts new file mode 100644 index 00000000..32a9553f --- /dev/null +++ b/mobile/src/data/home.ts @@ -0,0 +1,127 @@ +import type { RoleHome, RoleKey, TabItem } from '../types'; + +export const employeeTabs: TabItem[] = [ + { label: '今日', icon: 'home', active: true }, + { label: '练', icon: 'graduation', active: false }, + { label: '问', icon: 'book', active: false }, + { label: '我', icon: 'user', active: false } +]; + +export const fallbackHomes: Record = { + user: { + role: 'user', + roleLabel: '员工端', + avatarTone: 'avatar-woman', + greeting: '早上好,王敏', + location: '星河湾一期 · 客服管家', + toolTitle: '学习与工具', + recommend: '本周推荐:催费沟通专项', + primary: { + badge: '重点训练', + title: '投诉接待三角色对练', + desc: '3分钟语音练习 · 完成后自动评分', + progressText: '1/1', + progress: 100, + cta: '开始训练', + icon: 'headset' + }, + review: { + title: '岗前SOP复习', + desc: '今日需完成 · 住宅投诉处理流程' + }, + tools: [ + { icon: 'mic', title: '每日一练', desc: '每日3分钟\n提升服务能力', tone: 'teal' }, + { icon: 'book-search', title: '查SOP', desc: '随时查找\n标准流程', tone: 'blue' }, + { icon: 'folder', title: '案例学习', desc: '优秀案例\n对标提升', tone: 'orange' }, + { icon: 'pen', title: '提交素材', desc: '记录工作场景\n供审核入库', tone: 'purple' } + ], + metrics: [ + { icon: 'bars', title: '完成', value: '6/10', desc: '今日任务进度', tone: 'teal', progress: 60 }, + { icon: 'target', title: '能力', value: '82', desc: '综合能力分', tone: 'blue', progress: 82 }, + { icon: 'clipboard', title: '待复盘', value: '2', desc: '待复盘任务', tone: 'orange', progress: 48 } + ], + tabs: [...employeeTabs] + }, + candidate: { + role: 'candidate', + roleLabel: '候选人端', + avatarTone: 'avatar-candidate', + greeting: '早上好,李娜', + location: '星河湾一期 · 客服管家候选人', + toolTitle: '面试准备', + recommend: '本周推荐:投诉接待基础', + primary: { + badge: '面试任务', + title: 'AI结构化面试', + desc: '8分钟问答 · 完成后生成面试记录', + progressText: '0/1', + progress: 22, + cta: '开始面试', + icon: 'briefcase' + }, + review: { + title: '岗位SOP预习', + desc: '今日需完成 · 客服接待基础流程' + }, + tools: [ + { icon: 'mic', title: '面试练习', desc: '模拟问答\n熟悉岗位', tone: 'teal' }, + { icon: 'book-search', title: '查岗位SOP', desc: '快速了解\n标准流程', tone: 'blue' }, + { icon: 'folder', title: '案例学习', desc: '典型场景\n提前预习', tone: 'orange' }, + { icon: 'upload', title: '补充资料', desc: '提交证书\n与经历', tone: 'purple' } + ], + metrics: [ + { icon: 'bars', title: '进度', value: '2/4', desc: '候选任务', tone: 'teal', progress: 50 }, + { icon: 'target', title: '匹配度', value: '86', desc: '岗位画像分', tone: 'blue', progress: 86 }, + { icon: 'clipboard', title: '待补充', value: '1', desc: '资料项', tone: 'orange', progress: 35 } + ], + tabs: [ + { label: '首页', icon: 'home', active: true }, + { label: '面试', icon: 'briefcase', active: false }, + { label: '知识', icon: 'book', active: false }, + { label: '我的', icon: 'user', active: false } + ] + }, + supervisor: { + role: 'supervisor', + roleLabel: '主管端', + avatarTone: 'avatar-man', + greeting: '早上好,李主管', + location: '星河湾一期 · 项目主管', + toolTitle: '快捷操作', + tools: [ + { icon: 'presentation', title: '指派训练', desc: '为员工分配训练任务', tone: 'teal' }, + { icon: 'target', title: '团队短板', desc: '查看短板分布\n与改进建议', tone: 'blue' }, + { icon: 'upload', title: '提交案例素材', desc: '上传案例素材\n供审核与沉淀', tone: 'orange' }, + { icon: 'book-search', title: '查SOP', desc: '快速搜索制度与\n标准流程', tone: 'purple' } + ], + tabs: [ + { label: '首页', icon: 'home', active: true }, + { label: '团队', icon: 'users', active: false }, + { label: '案例', icon: 'folder', active: false }, + { label: '我的', icon: 'user', active: false } + ], + team: { + title: '客服团队训练进度', + progressText: '12人已完成 · 3人待跟进', + progress: 80, + completionLabel: '完训率', + detailCta: '查看详情', + stats: [ + { icon: 'users', title: '完训率', value: '80%', tone: 'teal' }, + { icon: 'bars', title: '平均能力', value: '78', tone: 'teal' }, + { icon: 'warning', title: '高频短板', value: '3', tone: 'orange' } + ] + }, + todos: [ + { icon: 'presentation', title: '待复盘对练', desc: '查看对练记录,辅导与点评', count: 3, tone: 'teal' }, + { icon: 'folder', title: '待提交本周案例', desc: '提交优质案例素材,供审核入库', count: 1, tone: 'orange' }, + { icon: 'clipboard', title: '待指派专项', desc: '为低分或薄弱项员工指派训练专项', count: 2, tone: 'blue' } + ], + suggestion: { + icon: 'bulb', + title: '建议:给催费沟通低分员工指派专项', + desc: '基于团队短板分析,建议开展「催费沟通技巧」专项训练', + tone: 'amber' + } + } +}; diff --git a/mobile/src/data/icons.ts b/mobile/src/data/icons.ts new file mode 100644 index 00000000..a0d87abf --- /dev/null +++ b/mobile/src/data/icons.ts @@ -0,0 +1,97 @@ +import type { IconName } from '../types'; + +export const iconPaths: Record?]>> = { + bars: [ + ['rect', { x: 5, y: 14, width: 3, height: 5, rx: 1 }], + ['rect', { x: 11, y: 10, width: 3, height: 9, rx: 1 }], + ['rect', { x: 17, y: 5, width: 3, height: 14, rx: 1 }] + ], + book: [ + ['path', { d: 'M4 6.5A3.5 3.5 0 0 1 7.5 3H20v16H7.5A3.5 3.5 0 0 0 4 22V6.5Z' }], + ['path', { d: 'M4 19a3.5 3.5 0 0 1 3.5-3.5H20' }] + ], + 'book-search': [ + ['path', { d: 'M4 6.5A3.5 3.5 0 0 1 7.5 3H18v10' }], + ['path', { d: 'M4 19a3.5 3.5 0 0 1 3.5-3.5H13' }], + ['circle', { cx: 17, cy: 17, r: 3 }], + ['path', { d: 'm19.5 19.5 2 2' }] + ], + briefcase: [ + ['path', { d: 'M9 6V5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v1' }], + ['rect', { x: 4, y: 6, width: 16, height: 13, rx: 2 }], + ['path', { d: 'M4 11h16M10 11v2h4v-2' }] + ], + bulb: [ + ['path', { d: 'M9 18h6M10 22h4M8 14a6 6 0 1 1 8 0c-.8.7-1.2 1.6-1.3 2.5H9.3C9.2 15.6 8.8 14.7 8 14Z' }] + ], + 'chevron-down': [['path', { d: 'm6 9 6 6 6-6' }]], + 'chevron-right': [['path', { d: 'm9 5 7 7-7 7' }]], + clipboard: [ + ['rect', { x: 6, y: 5, width: 12, height: 16, rx: 2 }], + ['path', { d: 'M9 5a3 3 0 0 1 6 0M9 11h6M9 15h6' }] + ], + document: [ + ['path', { d: 'M7 3h7l4 4v14H7V3Z' }], + ['path', { d: 'M14 3v5h5M10 12h5M10 16h5' }] + ], + folder: [ + ['path', { d: 'M3 7h7l2 2h9v9.5A2.5 2.5 0 0 1 18.5 21h-13A2.5 2.5 0 0 1 3 18.5V7Z' }], + ['path', { d: 'M3 9.5h18' }] + ], + graduation: [ + ['path', { d: 'm3 8 9-4 9 4-9 4-9-4Z' }], + ['path', { d: 'M7 10.5V15c2.5 2 7.5 2 10 0v-4.5M21 8v5' }] + ], + headset: [ + ['path', { d: 'M4 14a8 8 0 0 1 16 0' }], + ['rect', { x: 3, y: 13, width: 4, height: 7, rx: 2 }], + ['rect', { x: 17, y: 13, width: 4, height: 7, rx: 2 }], + ['path', { d: 'M19 20c0 2-2 3-5 3h-2M13 23v-2h3' }] + ], + home: [ + ['path', { d: 'm3 11 9-8 9 8' }], + ['path', { d: 'M5 10.5V21h5v-6h4v6h5V10.5' }] + ], + 'map-pin': [ + ['path', { d: 'M12 22s7-6.1 7-12a7 7 0 0 0-14 0c0 5.9 7 12 7 12Z' }], + ['circle', { cx: 12, cy: 10, r: 2.5 }] + ], + megaphone: [ + ['path', { d: 'M4 12h4l10-5v10L8 12H4Z' }], + ['path', { d: 'M8 12v6a2 2 0 0 0 2 2h1' }] + ], + mic: [ + ['rect', { x: 9, y: 3, width: 6, height: 11, rx: 3 }], + ['path', { d: 'M5 11a7 7 0 0 0 14 0M12 18v4M8 22h8' }] + ], + pen: [ + ['path', { d: 'M4 20h4L19 9a2.8 2.8 0 0 0-4-4L4 16v4Z' }], + ['path', { d: 'm13.5 6.5 4 4' }] + ], + presentation: [ + ['rect', { x: 4, y: 4, width: 16, height: 12, rx: 2 }], + ['path', { d: 'M8 21h8M12 16v5M9 11l2 2 4-5' }] + ], + target: [ + ['circle', { cx: 12, cy: 12, r: 8 }], + ['circle', { cx: 12, cy: 12, r: 3 }], + ['path', { d: 'm16 8 4-4M20 4v4M20 4h-4' }] + ], + upload: [ + ['path', { d: 'M12 16V4M7 9l5-5 5 5' }], + ['path', { d: 'M5 16v4h14v-4' }] + ], + user: [ + ['circle', { cx: 12, cy: 8, r: 4 }], + ['path', { d: 'M4 21a8 8 0 0 1 16 0' }] + ], + users: [ + ['circle', { cx: 9, cy: 8, r: 3 }], + ['circle', { cx: 17, cy: 10, r: 3 }], + ['path', { d: 'M3 21a6 6 0 0 1 12 0M13 21a5 5 0 0 1 8 0' }] + ], + warning: [ + ['path', { d: 'M12 3 22 20H2L12 3Z' }], + ['path', { d: 'M12 9v5M12 17h.01' }] + ] +}; diff --git a/mobile/src/data/mentor.ts b/mobile/src/data/mentor.ts new file mode 100644 index 00000000..8c289565 --- /dev/null +++ b/mobile/src/data/mentor.ts @@ -0,0 +1,18 @@ +import type { MentorMapActionKey } from '../types'; +import { mapIconPath } from '../utils'; + +export const mentorImageSrc = `${import.meta.env.BASE_URL}mentor.png`; + +export const mentorQuickChips = [ + { label: '催费话术', query: '物业费催缴怎么开口' }, + { label: '投诉应对', query: '业主投诉时第一句话怎么说' }, + { label: '收费标准', query: '物业费收费标准怎么向业主解释' }, + { label: '上门带什么', query: '生活顾问上门处理问题需要带什么' } +]; + +export const mentorMapActions: Array<{ key: MentorMapActionKey; label: string; desc: string; tone: 'blue' | 'green' | 'orange' | 'red'; icon: string }> = [ + { key: 'ask', label: '问', desc: '查SOP / 求助话术', tone: 'blue', icon: mapIconPath('ask') }, + { key: 'practice', label: '练', desc: '场景模拟 / 错题重练', tone: 'green', icon: mapIconPath('practice') }, + { key: 'learn', label: '学', desc: '岗前课程 / 每日小训', tone: 'orange', icon: mapIconPath('learn') }, + { key: 'submit', label: '报', desc: '上报案例 / 拍照记录', tone: 'red', icon: mapIconPath('report') } +]; diff --git a/mobile/src/data/navigation.ts b/mobile/src/data/navigation.ts new file mode 100644 index 00000000..0f5ef055 --- /dev/null +++ b/mobile/src/data/navigation.ts @@ -0,0 +1,49 @@ +import type { RoleKey, SupervisorPanelKey, UserPanelKey } from '../types'; + +export const aliases: Record = { + h5: 'user', + user: 'user', + employee: 'user', + candidate: 'candidate', + supervisor: 'supervisor', + admin: 'supervisor', + manager: 'supervisor' +}; + +export const rolePaths: Record = { + user: '/h5/user', + candidate: '/h5/candidate', + supervisor: '/h5/supervisor' +}; + +export const userPanelSegments: Record, string> = { + tasks: 'training', + practice: 'practice', + sop: 'knowledge', + cases: 'cases', + submit: 'submit', + profile: 'profile', + history: 'history', + recommend: 'recommend' +}; + +export const candidatePanelSegments: Record, string> = { + tasks: 'interview', + practice: 'interview', + sop: 'sop', + cases: 'cases', + submit: 'materials', + profile: 'profile', + history: 'history', + recommend: 'recommend' +}; + +export const supervisorPanelSegments: Record, string> = { + team: 'team', + reviews: 'reviews', + assign: 'assign', + weakness: 'weakness', + case: 'cases', + sop: 'sop', + profile: 'profile' +}; diff --git a/mobile/src/data/practice.ts b/mobile/src/data/practice.ts new file mode 100644 index 00000000..8f40ab94 --- /dev/null +++ b/mobile/src/data/practice.ts @@ -0,0 +1,72 @@ +import type { PracticeRecentItem, PracticeScenario, PracticeStyleKey } from '../types'; + +export const practiceScenarios: PracticeScenario[] = [ + { + id: 'complaint-water', + title: '投诉接待', + badge: '高频', + desc: '业主投诉服务或设施问题的接待与处置', + progressText: '2/3', + progress: '66%' + }, + { + id: 'fee-collection', + title: '催费沟通', + badge: '高频', + desc: '逾期费用提醒与关系维护', + progressText: '1/3', + progress: '33%' + }, + { + id: 'repair-elevator-delay', + title: '电梯故障', + badge: '应急', + desc: '电梯故障期间的安抚、解释与反馈', + progressText: '0/3', + progress: '0%' + }, + { + id: 'fee-parking', + title: '停车费催缴', + badge: '高频', + desc: '停车费到期提醒、异议解释与关系维护', + progressText: '1/3', + progress: '33%' + }, + { + id: 'emergency-elder-fall', + title: '突发求助', + badge: '基础', + desc: '老人摔倒等突发情况的响应与协同', + progressText: '0/3', + progress: '0%' + } +]; + +export const practiceRecentFallback: PracticeRecentItem[] = [ + { + scenarioId: 'complaint-water', + title: '投诉接待 · 电梯故障投诉', + time: '今天 09:18', + score: '4.0' + }, + { + scenarioId: 'fee-collection', + title: '催费沟通 · 逾期费用提醒', + time: '昨天 14:32', + score: '3.5' + } +]; + +export const practiceTotalRounds = 3; + +export const waveBars = [12, 20, 28, 16, 34, 24, 18, 32, 22, 30, 14, 26, 18, 35, 20, 12]; + +export const practiceStyleOptions: { key: PracticeStyleKey; label: string }[] = [ + { key: 'serious', label: '再严肃' }, + { key: 'gentle', label: '再温柔' }, + { key: 'detailed', label: '更细致' }, + { key: 'professional', label: '更专业' } +]; + +export const todayPracticeTarget = 1; diff --git a/mobile/src/data/supervisor.ts b/mobile/src/data/supervisor.ts new file mode 100644 index 00000000..777a8dab --- /dev/null +++ b/mobile/src/data/supervisor.ts @@ -0,0 +1,10 @@ +import type { SupervisorPanelKey } from '../types'; + +export const supervisorHeatmapItems: Array<{ title: string; value: string; desc: string; tone: string; target: SupervisorPanelKey }> = [ + { title: '催费开场白', value: '78%', desc: '中', tone: 'heat-low', target: 'assign' }, + { title: '收费异议处理', value: '62%', desc: '低', tone: 'heat-high', target: 'assign' }, + { title: '投诉安抚共情', value: '67%', desc: '低', tone: 'heat-mid', target: 'reviews' }, + { title: '费用减免说明', value: '71%', desc: '中', tone: 'heat-mid', target: 'sop' }, + { title: '法规风险告知', value: '59%', desc: '低', tone: 'heat-high', target: 'sop' }, + { title: '催费跟进话术', value: '81%', desc: '高', tone: 'heat-low', target: 'assign' } +]; diff --git a/mobile/src/styles/app.css b/mobile/src/styles/app.css new file mode 100644 index 00000000..4b4e4c88 --- /dev/null +++ b/mobile/src/styles/app.css @@ -0,0 +1,4690 @@ +:root { + --primary-teal: #0faea6; + --primary-teal-hover: #16c0b7; + --primary-teal-active: #0c948e; + --primary-teal-light: rgba(15, 174, 166, 0.08); + --primary-teal-glow: rgba(15, 174, 166, 0.2); + + --accent-orange: #f07b28; + --accent-orange-light: rgba(244, 164, 80, 0.08); + --accent-orange-glow: rgba(244, 164, 80, 0.15); + + --accent-blue: #2c7ded; + --accent-blue-light: rgba(87, 154, 255, 0.08); + --accent-blue-glow: rgba(87, 154, 255, 0.15); + --mentor-blue: #2e6be6; + --mentor-blue-dark: #1554d1; + --mentor-page-bg: #f3f7ff; + + --accent-purple: #7367df; + --accent-purple-light: rgba(144, 131, 245, 0.08); + + --accent-amber: #edaa14; + --accent-amber-light: rgba(238, 179, 54, 0.08); + + --text-primary: #090f1d; + --text-secondary: #4f5e76; + --text-muted: #8c9ba5; + + --glass-bg: rgba(255, 255, 255, 0.85); + --glass-bg-hover: rgba(255, 255, 255, 0.95); + --glass-border: rgba(220, 228, 235, 0.6); + --glass-border-light: rgba(255, 255, 255, 0.5); + + --shadow-sm: 0 2px 8px rgba(18, 31, 49, 0.03); + --shadow-md: 0 8px 24px rgba(18, 31, 49, 0.06); + --shadow-lg: 0 16px 36px rgba(18, 31, 49, 0.09); + + --transition-ease: all 0.25s ease; + --transition-spring: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); + --transition-spring-fast: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); +} + +:global(html), +:global(body), +:global(#app) { + min-height: 100%; + margin: 0; +} + +:global(body) { + overflow-x: hidden; +} + +* { + box-sizing: border-box; +} + +button { + border: 0; + background: transparent; + color: inherit; + cursor: pointer; + font: inherit; + transition: var(--transition-spring-fast); +} + +button:active { + transform: scale(0.97); +} + +.mobile-aihr { + min-height: 100vh; + background: + radial-gradient(circle at 10% 20%, rgba(15, 174, 166, 0.07) 0%, transparent 40%), + radial-gradient(circle at 90% 10%, rgba(56, 132, 255, 0.07) 0%, transparent 35%), + radial-gradient(circle at 50% 80%, rgba(240, 123, 40, 0.03) 0%, transparent 45%), + linear-gradient(180deg, #f5f8fa 0%, #fcfdfe 100%); + color: var(--text-primary); + display: flex; + justify-content: flex-start; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.page { + width: min(100vw, 426px); + min-height: 100vh; + padding: 12px 14px 110px; + position: relative; +} + +.top { + padding: 0 8px; + margin-bottom: 20px; +} + +.top-row { + display: grid; + grid-template-columns: 1fr auto auto; + gap: 10px; + align-items: center; +} + +.top h1, +.top h2, +.section-title h2, +.task-card h3, +.team-card h3, +p { + margin: 0; +} + +.top h1 { + font-size: 14px; + font-weight: 700; + letter-spacing: 0.05em; + text-transform: uppercase; + color: var(--text-muted); +} + +.role-pill { + height: 30px; + padding: 0 12px; + border: 1px solid var(--glass-border); + border-radius: 99px; + color: var(--primary-teal); + display: inline-flex; + align-items: center; + justify-content: center; + gap: 4px; + font-size: 13px; + font-weight: 700; + background: rgba(255, 255, 255, 0.75); + backdrop-filter: blur(8px); + box-shadow: var(--shadow-sm); +} + +.role-pill:active { + transform: scale(0.95); + background: rgba(255, 255, 255, 0.9); +} + +.avatar { + width: 44px; + height: 44px; + border-radius: 999px; + background: #eef3f7; + overflow: hidden; + position: relative; + box-shadow: 0 4px 12px rgba(18, 32, 50, 0.08); + border: 2px solid #ffffff; +} + +.avatar::before { + content: ''; + position: absolute; + left: 50%; + top: 11px; + width: 17px; + height: 17px; + border-radius: 50%; + transform: translateX(-50%); + background: #f4c7af; + box-shadow: 0 23px 0 8px #d8edf8; +} + +.avatar::after { + content: ''; + position: absolute; + left: 13px; + top: 7px; + width: 20px; + height: 16px; + border-radius: 50% 50% 45% 45%; + background: #1f2731; +} + +.avatar-man::after { + left: 14px; + top: 6px; + width: 19px; + height: 12px; + background: #111821; +} + +.avatar-man::before { + box-shadow: 0 23px 0 8px #dce9f2; +} + +.avatar-candidate::before { + box-shadow: 0 23px 0 8px #d8edf8; +} + +.avatar-img { + object-fit: cover; + display: block; +} + +.avatar-img::before, +.avatar-img::after { + content: none; +} + +.top h2 { + margin-top: 12px; + font-size: 28px; + line-height: 1.2; + font-weight: 800; + letter-spacing: -0.02em; +} + +.top h2 span { + font-size: 24px; +} + +.place { + margin-top: 8px; + color: var(--text-secondary); + display: flex; + align-items: center; + gap: 6px; + font-size: 14px; + font-weight: 600; +} + +.section-card { + margin-top: 16px; + padding: 18px 16px 20px; + border: 1px solid var(--glass-border); + border-top: 1px solid var(--glass-border-light); + border-radius: 20px; + background: var(--glass-bg); + backdrop-filter: blur(16px); + box-shadow: var(--shadow-md); + transition: var(--transition-ease); +} + +.section-card.has-action { + position: relative; +} + +.section-card.has-action > .section-title { + padding-right: 92px; +} + +.section-title { + min-height: 28px; + margin-bottom: 16px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.section-title h2 { + position: relative; + padding-left: 12px; + font-size: 17px; + line-height: 1.2; + font-weight: 800; + letter-spacing: -0.01em; +} + +.section-title h2::before { + content: ''; + position: absolute; + left: 0; + top: 3px; + width: 4px; + height: 16px; + border-radius: 99px; + background: var(--primary-teal); +} + +.section-title button { + position: absolute; + right: 16px; + top: 18px; + color: var(--text-secondary); + display: inline-flex; + align-items: center; + gap: 2px; + white-space: nowrap; + font-size: 13px; + font-weight: 700; + transition: var(--transition-spring-fast); +} + +.section-title button:active { + transform: scale(0.95); +} + +.section-title.compact-action button { + right: 16px; + top: 18px; + height: 28px; + border-radius: 99px; + padding: 0 12px; + color: var(--primary-teal); + background: var(--primary-teal-light); + border: 1px solid rgba(15, 174, 166, 0.12); +} + +.daily-drills { + display: grid; + gap: 10px; + margin-bottom: 14px; +} + +.daily-drills-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; +} + +.daily-drills-head b, +.daily-drills-head small { + display: block; +} + +.daily-drills-head b { + color: var(--text-primary); + font-size: 16px; + line-height: 1.25; + font-weight: 850; +} + +.daily-drills-head small, +.daily-drill-title small, +.daily-drill-actions small { + color: var(--text-secondary); + font-size: 12px; + line-height: 1.3; + font-weight: 700; +} + +.daily-drills-head em { + padding: 5px 8px; + border-radius: 8px; + background: #eef8f1; + color: #2f8f5b; + font-size: 12px; + font-style: normal; + font-weight: 850; +} + +.daily-drill-card { + padding: 12px; + border-radius: 8px; + border: 1px solid rgba(76, 145, 88, 0.14); + background: #ffffff; + display: grid; + gap: 9px; +} + +.daily-drill-card.done { + background: #f8fbf4; +} + +.daily-drill-title b { + display: block; + color: var(--text-primary); + font-size: 14px; + line-height: 1.35; + font-weight: 850; +} + +.daily-drill-title small { + display: block; + margin-top: 3px; +} + +.daily-drill-card textarea { + width: 100%; + min-height: 82px; + resize: vertical; + border-radius: 8px; + border: 1px solid rgba(213, 225, 233, 0.9); + padding: 10px; + color: var(--text-primary); + background: #fbfdff; + font-size: 14px; + line-height: 1.45; + outline: none; +} + +.daily-drill-card textarea:disabled { + color: var(--text-secondary); + background: #f3f6f8; +} + +.daily-drill-actions { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; +} + +.daily-drill-actions button { + min-height: 36px; + border-radius: 8px; + padding: 0 12px; + background: #2f8f5b; + color: #ffffff; + font-size: 13px; + font-weight: 850; +} + +.daily-drill-actions button:disabled { + background: #dce6df; + color: #778879; +} + +.daily-drill-feedback, +.daily-drill-message { + margin: 0; + border-radius: 8px; + padding: 9px 10px; + background: #fff8ed; + color: #6b4a15; + font-size: 12px; + line-height: 1.45; + font-weight: 650; +} + +.scenario-shell { + display: grid; + gap: 12px; +} + +.scenario-shell > p { + margin: -6px 0 2px; + color: var(--text-secondary); + font-size: 14px; + line-height: 1.35; + font-weight: 650; +} + +.scenario-tabs { + margin-right: -16px; + padding: 0 16px 2px 0; + display: flex; + gap: 10px; + overflow-x: auto; + scrollbar-width: none; +} + +.scenario-tabs::-webkit-scrollbar { + display: none; +} + +.scenario-tabs button { + flex: 0 0 auto; + min-height: 38px; + padding: 0 15px; + border: 1px solid rgba(213, 225, 233, 0.78); + border-radius: 14px; + color: var(--text-secondary); + background: rgba(255, 255, 255, 0.9); + box-shadow: 0 4px 12px rgba(18, 31, 49, 0.04); + font-size: 14px; + font-weight: 850; + transition: var(--transition-spring-fast); +} + +.scenario-tabs button.active { + color: #ffffff; + border-color: transparent; + background: linear-gradient(135deg, var(--mentor-blue), #3b7cff); + box-shadow: 0 9px 20px rgba(46, 107, 230, 0.24); +} + +.scenario-tabs button:active { + transform: scale(0.96); +} + +.scenario-card { + position: relative; + min-height: 134px; + padding: 16px 16px 72px; + border: 1px solid rgba(213, 225, 233, 0.76); + border-radius: 18px; + background: rgba(255, 255, 255, 0.96); + box-shadow: 0 12px 28px rgba(18, 31, 49, 0.06); + display: grid; + grid-template-columns: 58px minmax(0, 1fr); + gap: 10px 12px; + overflow: hidden; +} + +.scenario-card::after { + content: ''; + position: absolute; + right: -46px; + bottom: -54px; + width: 150px; + height: 150px; + border-radius: 999px; + background: rgba(46, 107, 230, 0.06); +} + +.scenario-card img { + width: 58px; + height: 58px; + border-radius: 999px; + object-fit: cover; + background: #fde3d9; + box-shadow: 0 8px 18px rgba(18, 31, 49, 0.08); +} + +.scenario-card > span { + min-width: 0; + padding-right: 52px; + display: grid; + align-content: start; + gap: 7px; +} + +.scenario-card > span b { + color: var(--text-primary); + font-size: 21px; + line-height: 1.1; + font-weight: 950; +} + +.scenario-card > span small { + color: var(--text-secondary); + font-size: 13px; + line-height: 1.35; + font-weight: 650; +} + +.scenario-card > em { + position: absolute; + right: 16px; + top: 20px; + z-index: 1; + min-height: 28px; + padding: 5px 10px; + border-radius: 999px; + color: #e5222a; + background: #ffe8ea; + font-size: 13px; + line-height: 1; + font-style: normal; + font-weight: 900; +} + +.scenario-card-progress { + position: absolute; + left: 16px; + right: 148px; + bottom: 24px; + z-index: 1; + display: grid; + grid-template-columns: auto auto minmax(64px, 1fr); + align-items: center; + gap: 9px; +} + +.scenario-card-progress small { + color: var(--text-secondary); + font-size: 13px; + font-weight: 750; +} + +.scenario-card-progress b { + color: var(--mentor-blue); + font-size: 18px; + font-weight: 950; +} + +.scenario-card-progress i { + height: 5px; + border-radius: 999px; + background: #dce6f7; + overflow: hidden; +} + +.scenario-card-progress i span { + display: block; + height: 100%; + border-radius: inherit; + background: var(--mentor-blue); +} + +.scenario-card > button { + position: absolute; + right: 16px; + bottom: 16px; + z-index: 1; + width: 116px; + min-height: 48px; + border-radius: 14px; + color: #ffffff; + background: linear-gradient(135deg, var(--mentor-blue), #3b7cff); + box-shadow: 0 10px 20px rgba(46, 107, 230, 0.24); + font-size: 15px; + font-weight: 900; +} + +.recent-practice { + border: 1px solid rgba(213, 225, 233, 0.76); + border-radius: 18px; + background: rgba(255, 255, 255, 0.96); + box-shadow: 0 10px 24px rgba(18, 31, 49, 0.05); + overflow: hidden; +} + +.recent-practice-head { + min-height: 50px; + padding: 0 14px; + border-bottom: 1px solid rgba(213, 225, 233, 0.58); + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; +} + +.recent-practice-head b { + color: var(--text-primary); + font-size: 16px; + font-weight: 900; +} + +.recent-practice-head button { + color: var(--text-secondary); + white-space: nowrap; + font-size: 13px; + font-weight: 800; +} + +.recent-practice > button { + width: 100%; + min-height: 70px; + padding: 12px 14px; + display: grid; + grid-template-columns: 30px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + text-align: left; +} + +.recent-practice > button + button { + border-top: 1px solid rgba(213, 225, 233, 0.58); +} + +.recent-practice > button > em { + width: 26px; + height: 26px; + border-radius: 999px; + color: #ffffff; + background: linear-gradient(135deg, #35c393, #20ad84); + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 15px; + line-height: 1; + font-style: normal; + font-weight: 950; +} + +.recent-practice > button > span { + min-width: 0; + display: grid; + gap: 5px; +} + +.recent-practice > button > span b { + color: var(--text-primary); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 14px; + line-height: 1.2; + font-weight: 900; +} + +.recent-practice > button > span small { + color: var(--text-secondary); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 12px; + font-weight: 650; +} + +.recent-practice > button > i { + min-width: 96px; + display: grid; + justify-items: start; + gap: 3px; + font-style: normal; +} + +.recent-practice > button > i small { + color: var(--text-secondary); + font-size: 11px; + line-height: 1; + font-weight: 700; +} + +.recent-practice > button > i b { + display: inline; + margin-right: 4px; + color: var(--text-primary); + font-size: 15px; + line-height: 1; + font-weight: 950; +} + +.recent-practice > button > i span { + color: #f6aa1c; + white-space: nowrap; + font-size: 13px; + line-height: 1; + letter-spacing: 0; +} + +.task-card { + min-height: 164px; + padding: 20px 18px; + border: 1px solid rgba(15, 174, 166, 0.15); + border-radius: 16px; + background: linear-gradient(135deg, #10a8a1 0%, #06817b 100%); + display: grid; + grid-template-columns: 1fr 120px; + gap: 6px 10px; + position: relative; + overflow: hidden; + box-shadow: 0 10px 24px rgba(15, 174, 166, 0.15); +} + +.task-copy { + min-width: 0; + position: relative; + z-index: 1; +} + +.task-copy strong { + display: inline-flex; + min-height: 24px; + align-items: center; + border-radius: 6px; + padding: 0 8px; + color: #ffffff; + background: rgba(255, 255, 255, 0.2); + border: 1px solid rgba(255, 255, 255, 0.15); + font-size: 12px; + font-weight: 800; + letter-spacing: 0.02em; +} + +.task-copy h3 { + margin-top: 16px; + font-size: 22px; + line-height: 1.2; + font-weight: 800; + color: #ffffff; + letter-spacing: -0.01em; +} + +.task-copy p { + margin-top: 8px; + color: rgba(255, 255, 255, 0.85); + font-size: 13px; + font-weight: 600; +} + +.task-copy span { + display: block; + margin-top: 20px; + color: rgba(255, 255, 255, 0.9); + font-size: 13px; + font-weight: 700; +} + +.headset-art { + height: 115px; + color: rgba(255, 255, 255, 0.85); + display: grid; + place-items: center; + position: relative; + z-index: 0; +} + +.headset-art::before, +.headset-art::after { + content: ''; + position: absolute; + border-radius: 50%; + background: rgba(255, 255, 255, 0.08); +} + +.headset-art::before { + width: 90px; + height: 90px; + right: 8px; + bottom: 8px; +} + +.headset-art::after { + width: 32px; + height: 32px; + left: 4px; + top: 32px; +} + +.task-card > button { + position: absolute; + right: 18px; + bottom: 18px; + min-width: 116px; + height: 44px; + border-radius: 10px; + color: var(--primary-teal-active); + background: #ffffff; + box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1); + font-size: 15px; + font-weight: 800; + transition: var(--transition-spring); +} + +.task-card > button:active { + transform: scale(0.95); + background: #f4ffff; +} + +.auth-page { + padding-top: 30px; +} + +.auth-top { + margin-bottom: 24px; +} + +.login-panel { + margin: 0 8px; + padding: 24px 20px; + border: 1px solid var(--glass-border); + border-top: 1px solid var(--glass-border-light); + border-radius: 20px; + background: var(--glass-bg); + backdrop-filter: blur(16px); + box-shadow: var(--shadow-lg); + display: grid; + gap: 16px; +} + +.login-panel label { + display: grid; + gap: 6px; + color: var(--text-secondary); + font-size: 13px; + font-weight: 700; +} + +.login-panel input { + width: 100%; + height: 46px; + border: 1px solid rgba(15, 174, 166, 0.2); + border-radius: 11px; + padding: 0 14px; + color: var(--text-primary); + background: #ffffff; + font: inherit; + font-size: 14px; + font-weight: 600; + outline: none; + transition: var(--transition-ease); +} + +.login-panel input:focus { + border-color: var(--primary-teal); + box-shadow: 0 0 0 3px var(--primary-teal-glow); +} + +.code-row { + display: grid; + grid-template-columns: 1fr 112px; + gap: 8px; +} + +.code-row button, +.login-submit { + height: 46px; + border-radius: 11px; + color: #ffffff; + background: linear-gradient(135deg, #1cbdb4, #07948e); + box-shadow: 0 4px 12px rgba(9, 151, 144, 0.18); + font-weight: 800; + transition: var(--transition-spring); +} + +.code-row button:disabled, +.login-submit:disabled { + opacity: 0.55; + transform: none; +} + +.auth-message { + min-height: 18px; + color: #ef6a2e; + font-size: 13px; + font-weight: 700; +} + +.bar { + height: 6px; + margin-top: 8px; + border-radius: 999px; + background: rgba(15, 174, 166, 0.12); + overflow: hidden; +} + +.bar span { + display: block; + height: 100%; + border-radius: inherit; + background: linear-gradient(90deg, #19b8b0, #0a9a94); +} + +.review-card, +.suggestion { + width: 100%; + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + gap: 13px; + text-align: left; +} + +.review-card { + min-height: 76px; + margin-top: 14px; + padding: 14px; + border: 1px solid rgba(238, 179, 54, 0.25); + border-radius: 14px; + background: linear-gradient(135deg, rgba(255, 251, 242, 0.7), rgba(255, 255, 255, 0.95)); + box-shadow: var(--shadow-sm); + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + gap: 12px; + text-align: left; + transition: var(--transition-spring); +} + +.review-card:active { + transform: scale(0.98); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.02); +} + +.review-card b, +.suggestion b, +.todo-list b, +.tool-grid b { + display: block; + color: var(--text-primary); + font-size: 15px; + line-height: 1.2; + font-weight: 750; +} + +.review-card small, +.suggestion small, +.todo-list small, +.tool-grid small { + display: block; + margin-top: 4px; + color: var(--text-secondary); + font-size: 12px; + line-height: 1.35; + white-space: pre-line; + font-weight: 600; +} + +.scenario-section { + margin-top: 18px; + display: grid; + gap: 12px; +} + +.scenario-title { + display: grid; + grid-template-columns: 4px minmax(0, 1fr); + column-gap: 10px; + align-items: center; + padding: 0 4px; +} + +.scenario-title::before { + content: ''; + width: 4px; + height: 34px; + border-radius: 99px; + background: var(--primary-teal); + grid-row: 1 / span 2; +} + +.scenario-title h2 { + margin: 0; + color: var(--text-primary); + font-size: 18px; + line-height: 1.2; + font-weight: 800; +} + +.scenario-title p { + margin-top: 3px; + color: var(--text-secondary); + font-size: 13px; + line-height: 1.35; + font-weight: 650; +} + +.scenario-card-stack { + display: grid; + gap: 12px; +} + +.review-summary-card, +.sop-action-card, +.report-card { + width: 100%; + border: 1px solid var(--glass-border); + border-radius: 18px; + padding: 16px; + background: #ffffff; + box-shadow: var(--shadow-sm); + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto; + align-items: center; + gap: 13px; + text-align: left; + transition: var(--transition-spring); +} + +.review-summary-card:active, +.sop-action-card:active, +.report-card:active { + transform: scale(0.98); +} + +.review-summary-card span, +.sop-action-card span, +.report-card span { + min-width: 0; +} + +.review-summary-card b, +.sop-action-card b, +.report-card b { + display: block; + color: var(--text-primary); + font-size: 16px; + line-height: 1.25; + font-weight: 800; +} + +.review-summary-card small, +.sop-action-card small, +.report-card small { + display: block; + margin-top: 5px; + color: var(--text-secondary); + font-size: 13px; + line-height: 1.4; + font-weight: 600; +} + +.review-summary-card.empty { + grid-template-columns: auto minmax(0, 1fr); +} + +.sop-action-card { + min-height: 112px; + border-color: rgba(15, 174, 166, 0.28); + background: linear-gradient(135deg, #ecfffd 0%, #ffffff 72%); + box-shadow: 0 12px 28px rgba(9, 151, 144, 0.1); +} + +.sop-action-card .icon-bubble { + width: 54px; + height: 54px; +} + +.sop-action-card b { + font-size: 19px; +} + +.report-card { + border-color: rgba(144, 131, 245, 0.18); + background: linear-gradient(135deg, #fbf7ff 0%, #ffffff 76%); +} + +.growth-section .section-card { + margin-top: 0; +} + +.user-redesign { + background: var(--mentor-page-bg); +} + +.user-redesign .tabbar button.active { + color: var(--mentor-blue); + background: rgba(46, 107, 230, 0.1); +} + +.role-redesign { + background: var(--mentor-page-bg); +} + +.candidate-redesign { + padding-bottom: 104px; +} + +.role-redesign .top { + margin-bottom: 12px; +} + +.role-redesign .role-pill { + color: var(--mentor-blue); + border-color: rgba(46, 107, 230, 0.15); + background: rgba(255, 255, 255, 0.86); +} + +.candidate-progress-head { + margin-top: 0; + padding: 14px 12px; + border-radius: 18px; + background: #ffffff; + box-shadow: 0 10px 28px rgba(18, 31, 49, 0.06); +} + +.candidate-progress-head h2 { + margin: 0 0 14px; + text-align: center; + color: var(--text-primary); + font-size: 18px; + line-height: 1.2; + font-weight: 900; +} + +.candidate-step-rail { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 4px; + position: relative; +} + +.candidate-step-rail::before { + content: ''; + position: absolute; + left: 12.5%; + right: 12.5%; + top: 17px; + height: 3px; + border-radius: 999px; + background: #dde6f5; +} + +.candidate-step-rail button { + min-height: 62px; + display: grid; + justify-items: center; + align-content: start; + gap: 7px; + color: var(--text-secondary); + position: relative; + z-index: 1; + font-size: 12px; + font-weight: 800; +} + +.candidate-step-rail em { + width: 34px; + height: 34px; + border-radius: 999px; + border: 3px solid #ffffff; + background: #d8dde8; + color: #ffffff; + display: grid; + place-items: center; + font-size: 14px; + font-style: normal; + font-weight: 900; + box-shadow: 0 4px 12px rgba(18, 31, 49, 0.08); +} + +.candidate-step-rail .done em { + background: #1fbf72; +} + +.candidate-step-rail .active { + color: #2e6be6; +} + +.candidate-step-rail .active em { + background: #2e6be6; +} + +.candidate-material-card, +.candidate-approval-card { + margin-top: 12px; +} + +.candidate-step-note { + margin: -4px 0 12px; + color: var(--text-secondary); + font-size: 13px; + line-height: 1.45; + font-weight: 700; +} + +.candidate-doc-list { + display: grid; + gap: 8px; +} + +.candidate-doc-list button { + min-height: 58px; + padding: 10px 12px; + border-radius: 14px; + background: #ffffff; + display: grid; + grid-template-columns: 30px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + text-align: left; + box-shadow: var(--shadow-sm); + border: 1px solid rgba(213, 225, 233, 0.58); +} + +.candidate-doc-list.compact button { + min-height: 54px; +} + +.candidate-doc-list .icon { + color: #8a96a8; +} + +.candidate-doc-list em { + min-width: 56px; + height: 26px; + padding: 0 8px; + border-radius: 999px; + display: grid; + place-items: center; + font-size: 12px; + font-style: normal; + font-weight: 850; +} + +.candidate-doc-list em.done { + color: #0a8f4f; + background: rgba(32, 191, 114, 0.11); +} + +.candidate-doc-list em.pending { + color: #e2630a; + background: rgba(255, 122, 26, 0.12); +} + +.candidate-submit-button { + width: 100%; + min-height: 54px; + margin-top: 14px; + border-radius: 15px; + color: #ffffff; + background: linear-gradient(135deg, #2e6be6, #0f58d6); + box-shadow: 0 12px 26px rgba(46, 107, 230, 0.28); + font-size: 16px; + font-weight: 900; +} + +.candidate-doc-list b, +.candidate-actions b, +.candidate-material-strip b, +.cockpit-copy b, +.activity-timeline b, +.weakness-grid b { + display: block; + min-width: 0; + color: var(--text-primary); + font-size: 15px; + line-height: 1.25; + font-weight: 900; +} + +.candidate-doc-list small, +.candidate-actions small, +.candidate-material-strip small, +.cockpit-copy span, +.activity-timeline small, +.weakness-grid span { + display: block; + min-width: 0; + margin-top: 4px; + color: var(--text-secondary); + font-size: 12px; + line-height: 1.35; + font-weight: 700; +} + +.candidate-actions { + display: grid; + gap: 10px; +} + +.candidate-primary, +.candidate-secondary, +.candidate-link { + width: 100%; + min-height: 78px; + padding: 13px; + border-radius: 16px; + display: grid; + align-items: center; + text-align: left; + box-shadow: 0 8px 20px rgba(18, 31, 49, 0.07); +} + +.candidate-primary, +.candidate-secondary { + color: #ffffff; +} + +.candidate-primary { + background: linear-gradient(135deg, #2e79ff, #1458dd); +} + +.candidate-secondary { + background: linear-gradient(135deg, #20bf72, #0a9f59); +} + +.candidate-primary span, +.candidate-secondary span { + width: max-content; + max-width: 100%; + min-height: 24px; + padding: 3px 9px; + border-radius: 999px; + background: rgba(255, 255, 255, 0.16); + font-size: 12px; + font-weight: 850; +} + +.candidate-primary b, +.candidate-secondary b, +.candidate-primary small, +.candidate-secondary small { + color: #ffffff; +} + +.candidate-link { + min-height: 66px; + border: 1px solid rgba(213, 225, 233, 0.72); + background: #ffffff; + grid-template-columns: auto minmax(0, 1fr) auto; + gap: 11px; +} + +.candidate-progress-card .progress-grid { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.candidate-material-strip { + margin-top: 10px; + display: grid; + gap: 8px; +} + +.candidate-material-strip button { + min-height: 52px; + padding: 10px 12px; + border-radius: 12px; + background: #f7faff; + display: grid; + text-align: left; +} + +.supervisor-dashboard { + margin-top: 0; + padding: 14px; + border-radius: 18px; + color: #ffffff; + background: linear-gradient(135deg, #0f63d8, #0747b9); + box-shadow: 0 16px 34px rgba(15, 88, 214, 0.22); +} + +.supervisor-dashboard-head { + min-height: 30px; + margin-bottom: 10px; + display: flex; + align-items: center; + justify-content: space-between; +} + +.supervisor-dashboard-head h2 { + margin: 0; + font-size: 18px; + line-height: 1.2; + font-weight: 900; +} + +.supervisor-dashboard-head button { + color: rgba(255, 255, 255, 0.86); + font-size: 13px; + font-weight: 800; +} + +.supervisor-stat-row { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 7px; +} + +.supervisor-stat-row button { + min-height: 102px; + padding: 11px 8px; + border-radius: 11px; + background: #ffffff; + display: grid; + align-content: space-between; + text-align: left; + box-shadow: 0 8px 22px rgba(0, 0, 0, 0.1); +} + +.supervisor-stat-row small, +.weakness-grid small { + color: #d35b00; + font-size: 11px; + line-height: 1.2; + font-weight: 850; +} + +.supervisor-stat-row b { + color: var(--text-primary); + font-size: 27px; + line-height: 1.05; + font-weight: 900; + overflow-wrap: anywhere; +} + +.supervisor-stat-row span { + color: var(--text-secondary); + font-size: 11px; + line-height: 1.25; + font-weight: 750; +} + +.supervisor-stat-row .is-good small, +.supervisor-stat-row .is-good b { + color: #0b9f58; +} + +.supervisor-stat-row .is-risk small, +.supervisor-stat-row .is-risk b { + color: #d7262f; +} + +.activity-timeline { + display: grid; + gap: 9px; +} + +.activity-timeline button { + min-height: 58px; + padding: 9px 10px; + border-radius: 15px; + background: #ffffff; + display: grid; + grid-template-columns: 38px minmax(0, 1fr) auto; + align-items: center; + gap: 9px; + text-align: left; + box-shadow: var(--shadow-sm); +} + +.activity-timeline em { + width: 38px; + height: 38px; + border-radius: 14px; + color: #ffffff; + background: #2e6be6; + display: grid; + place-items: center; + font-size: 16px; + font-style: normal; + font-weight: 900; +} + +.activity-timeline small { + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.activity-timeline i { + min-width: 42px; + height: 24px; + padding: 0 8px; + border-radius: 999px; + color: #0a8f4f; + background: rgba(32, 191, 114, 0.1); + display: grid; + place-items: center; + font-size: 11px; + font-style: normal; + font-weight: 850; +} + +.weakness-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 8px; +} + +.weakness-grid button { + min-height: 96px; + padding: 11px 9px; + border-radius: 15px; + display: grid; + align-content: space-between; + text-align: left; + box-shadow: var(--shadow-sm); +} + +.weakness-grid .heat-high { + background: linear-gradient(135deg, rgba(255, 104, 91, 0.16), #ffffff); + border: 1px solid rgba(255, 104, 91, 0.18); +} + +.weakness-grid .heat-mid { + background: linear-gradient(135deg, rgba(255, 138, 26, 0.16), #ffffff); + border: 1px solid rgba(255, 138, 26, 0.18); +} + +.weakness-grid .heat-low { + background: linear-gradient(135deg, rgba(32, 191, 114, 0.14), #ffffff); + border: 1px solid rgba(32, 191, 114, 0.18); +} + +.supervisor-suggestion { + width: 100%; + margin-top: 12px; + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + text-align: left; +} + +.mentor-hero { + margin-top: 0; + padding: 12px; + border: 1px solid rgba(255, 255, 255, 0.8); + border-radius: 20px; + background: linear-gradient(135deg, #e9f2ff 0%, #ffffff 76%); + box-shadow: 0 12px 30px rgba(46, 107, 230, 0.1); + display: grid; + gap: 10px; +} + +.mentor-topline { + min-height: 30px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + color: #102a5c; + font-size: 14px; + font-weight: 850; +} + +.mentor-role-pill { + color: var(--mentor-blue); + border-color: rgba(46, 107, 230, 0.15); + background: rgba(255, 255, 255, 0.82); +} + +.mentor-main { + display: grid; + grid-template-columns: 72px minmax(0, 1fr); + align-items: center; + gap: 10px; +} + +.mentor-avatar { + width: 64px; + height: 64px; + border-radius: 999px; + position: relative; + border: 3px solid #ffffff; + background: #dfeaff; + box-shadow: 0 8px 22px rgba(46, 107, 230, 0.18); +} + +.mentor-avatar img { + position: relative; + z-index: 1; + width: 100%; + height: 100%; + border-radius: inherit; + object-fit: cover; + display: block; +} + +.mentor-avatar.is-idle img { + animation: mentor-breathe 3s ease-in-out infinite; +} + +.mentor-avatar::before, +.mentor-avatar::after { + content: ''; + position: absolute; + inset: -8px; + border: 2px solid rgba(46, 107, 230, 0.28); + border-radius: inherit; + opacity: 0; + pointer-events: none; +} + +.mentor-avatar.is-listening::before { + animation: mentor-ripple 1.35s ease-out infinite; +} + +.mentor-avatar.is-listening::after { + animation: mentor-ripple 1.35s ease-out 0.45s infinite; +} + +.mentor-eyelid { + position: absolute; + z-index: 2; + top: 27px; + width: 12px; + height: 2px; + border-radius: 999px; + background: rgba(14, 32, 68, 0.42); + transform: scaleY(0); + transform-origin: center; + pointer-events: none; +} + +.mentor-eyelid-left { + left: 21px; +} + +.mentor-eyelid-right { + right: 17px; +} + +.mentor-avatar.is-idle .mentor-eyelid { + animation: mentor-blink 4s ease-in-out infinite; +} + +.mentor-thinking { + position: absolute; + z-index: 3; + left: 50%; + top: -14px; + transform: translateX(-50%); + display: none; + gap: 4px; +} + +.mentor-thinking i { + width: 6px; + height: 6px; + border-radius: 999px; + background: var(--mentor-blue); + animation: mentor-dot 0.9s ease-in-out infinite; +} + +.mentor-thinking i:nth-child(2) { + animation-delay: 0.15s; +} + +.mentor-thinking i:nth-child(3) { + animation-delay: 0.3s; +} + +.mentor-avatar.is-thinking .mentor-thinking { + display: flex; +} + +.mentor-waves { + position: absolute; + z-index: 3; + right: -28px; + top: 18px; + display: none; + align-items: center; + gap: 3px; +} + +.mentor-waves i { + width: 4px; + height: 15px; + border-radius: 999px; + background: var(--mentor-blue); + transform-origin: center; + animation: mentor-wave 0.8s ease-in-out infinite; +} + +.mentor-waves i:nth-child(2) { + height: 24px; + animation-delay: 0.12s; +} + +.mentor-waves i:nth-child(3) { + height: 20px; + animation-delay: 0.24s; +} + +.mentor-waves i:nth-child(4) { + height: 13px; + animation-delay: 0.36s; +} + +.mentor-avatar.is-speaking .mentor-waves { + display: flex; +} + +.mentor-copy { + min-width: 0; + padding: 11px 13px; + border-radius: 16px; + background: #ffffff; + box-shadow: 0 8px 22px rgba(18, 31, 49, 0.07); + position: relative; +} + +.mentor-copy::before { + content: ''; + position: absolute; + left: -8px; + top: 26px; + border: 8px solid transparent; + border-right-color: #ffffff; + border-left: 0; +} + +.mentor-greeting { + display: block; + color: var(--text-secondary); + font-size: 12px; + line-height: 1.2; + font-weight: 750; +} + +.mentor-copy p { + margin-top: 4px; + color: var(--text-primary); + font-size: 18px; + line-height: 1.32; + font-weight: 850; +} + +.mentor-actions { + display: grid; + grid-template-columns: minmax(0, 1fr) 118px; + gap: 10px; +} + +.mentor-actions button { + min-height: 48px; + border-radius: 16px; + font-size: 15px; + font-weight: 850; +} + +.mentor-talk { + color: #ffffff; + background: linear-gradient(135deg, var(--mentor-blue), var(--mentor-blue-dark)); + box-shadow: 0 8px 18px rgba(46, 107, 230, 0.24); + display: inline-flex; + align-items: center; + justify-content: center; + gap: 9px; + touch-action: none; +} + +.mentor-talk span { + width: 34px; + height: 34px; + border-radius: 999px; + display: grid; + place-items: center; + background: rgba(255, 255, 255, 0.18); + font-size: 19px; +} + +.mentor-type { + color: var(--text-primary); + background: #ffffff; + border: 1px solid rgba(46, 107, 230, 0.12); + box-shadow: var(--shadow-sm); +} + +.mentor-chip-row { + margin-top: 12px; + display: flex; + gap: 9px; + overflow-x: auto; + padding: 1px 2px 6px; + scrollbar-width: none; +} + +.mentor-chip-row::-webkit-scrollbar { + display: none; +} + +.mentor-chip-row button { + min-width: max-content; + min-height: 42px; + padding: 0 12px; + border-radius: 999px; + color: var(--text-primary); + background: #ffffff; + box-shadow: 0 7px 18px rgba(18, 31, 49, 0.06); + display: inline-flex; + align-items: center; + gap: 8px; + font-size: 14px; + font-weight: 800; +} + +.mentor-chip-row button span { + width: 18px; + height: 18px; + border-radius: 999px; + background: rgba(46, 107, 230, 0.14); +} + +.mentor-chip-row button b { + color: var(--text-muted); + font-size: 18px; + line-height: 1; +} + +.home-card { + margin-top: 12px; + padding: 16px; + border: 1px solid rgba(220, 228, 235, 0.72); + border-radius: 18px; + background: #ffffff; + box-shadow: 0 10px 28px rgba(18, 31, 49, 0.06); +} + +.home-card-head { + margin-bottom: 12px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; +} + +.home-card-head h2 { + margin: 0; + color: var(--text-primary); + font-size: 20px; + line-height: 1.2; + font-weight: 850; +} + +.home-card-head button { + min-height: 32px; + color: var(--text-secondary); + font-size: 13px; + font-weight: 800; +} + +.agenda-list { + display: grid; + gap: 9px; +} + +.agenda-row { + min-height: 76px; + padding: 12px; + border-radius: 14px; + background: #f7faff; + display: grid; + grid-template-columns: 28px minmax(0, 1fr) 76px; + align-items: center; + gap: 9px; +} + +.agenda-index { + width: 26px; + height: 26px; + border-radius: 999px; + color: #ffffff; + display: grid; + place-items: center; + font-size: 14px; + font-style: normal; + font-weight: 900; +} + +.agenda-index.blue { + background: var(--mentor-blue); +} + +.agenda-index.orange { + background: #ff7a1a; +} + +.agenda-row span { + min-width: 0; +} + +.agenda-row b { + display: block; + color: var(--text-primary); + font-size: 15px; + line-height: 1.25; + font-weight: 850; +} + +.agenda-row small { + display: block; + margin-top: 5px; + color: var(--text-secondary); + font-size: 12px; + line-height: 1.35; + font-weight: 650; +} + +.agenda-action { + min-height: 42px; + border-radius: 12px; + color: #ffffff; + font-size: 14px; + font-weight: 850; +} + +.agenda-action.blue { + background: var(--mentor-blue); + box-shadow: 0 7px 16px rgba(46, 107, 230, 0.2); +} + +.agenda-action.orange { + background: #ff7a1a; + box-shadow: 0 7px 16px rgba(255, 122, 26, 0.18); +} + +.agenda-action:disabled { + color: #97a3b6; + background: #e9eef7; + box-shadow: none; + transform: none; +} + +.agenda-daily { + display: grid; + gap: 7px; +} + +.agenda-daily button { + min-height: 58px; + padding: 10px; + border-radius: 8px; + background: #f8fbf4; + border: 1px solid rgba(76, 145, 88, 0.12); + display: grid; + grid-template-columns: 30px minmax(0, 1fr); + align-items: center; + gap: 8px; + text-align: left; +} + +.agenda-daily em { + width: 26px; + height: 26px; + border-radius: 8px; + background: #2f8f5b; + color: #ffffff; + display: grid; + place-items: center; + font-size: 12px; + font-style: normal; + font-weight: 900; +} + +.agenda-daily b, +.agenda-daily small { + display: block; +} + +.agenda-daily b { + color: var(--text-primary); + font-size: 13px; + line-height: 1.28; + font-weight: 850; +} + +.agenda-daily small { + margin-top: 4px; + color: var(--text-secondary); + font-size: 11px; + line-height: 1.3; + font-weight: 650; +} + +.map-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; +} + +.map-grid button { + min-height: 76px; + border-radius: 16px; + padding: 10px 12px; + color: #ffffff; + text-align: left; + position: relative; + overflow: hidden; + box-shadow: 0 10px 22px rgba(18, 31, 49, 0.12); + display: grid; + grid-template-columns: 40px minmax(0, 1fr) auto; + grid-template-rows: auto auto; + align-items: center; + gap: 4px 9px; +} + +.map-grid img { + position: relative; + z-index: 1; + grid-column: 1; + grid-row: 1; + width: 40px; + height: 40px; + padding: 8px; + border-radius: 999px; + background: rgba(255, 255, 255, 0.22); + object-fit: contain; + mix-blend-mode: screen; + filter: drop-shadow(0 5px 9px rgba(18, 31, 49, 0.12)); +} + +.map-grid span, +.map-grid small, +.map-grid b { + position: relative; + z-index: 1; +} + +.map-grid span { + display: block; + grid-column: 2; + grid-row: 1; + font-size: 28px; + line-height: 1; + font-weight: 900; +} + +.map-grid small { + display: block; + grid-column: 1 / 3; + grid-row: 2; + font-size: 11px; + line-height: 1.2; + font-weight: 750; +} + +.map-grid b { + grid-column: 3; + grid-row: 1 / 3; + justify-self: end; + font-size: 24px; + line-height: 1; +} + +.map-grid .tone-blue { + background: linear-gradient(135deg, #2e79ff, #1458dd); +} + +.map-grid .tone-green { + background: linear-gradient(135deg, #35c76b, #159a49); +} + +.map-grid .tone-orange { + background: linear-gradient(135deg, #ffae2b, #ff7416); +} + +.map-grid .tone-red { + background: linear-gradient(135deg, #ff685b, #f1352c); +} + +.building-page { + min-height: calc(100vh - 190px); + display: grid; + place-items: center; + align-content: center; + gap: 12px; + text-align: center; +} + +.building-icon { + width: 72px; + height: 72px; + border-radius: 24px; + background: #ffffff; + box-shadow: 0 12px 30px rgba(46, 107, 230, 0.12); + display: grid; + place-items: center; + font-size: 34px; +} + +.building-page h2 { + margin: 4px 0 0; + color: var(--text-primary); + font-size: 28px; + line-height: 1.15; + font-weight: 900; +} + +.building-page p { + max-width: 280px; + color: var(--text-secondary); + font-size: 15px; + line-height: 1.45; + font-weight: 650; +} + +.building-page button { + min-width: 144px; + min-height: 46px; + border-radius: 999px; + color: #ffffff; + background: var(--mentor-blue); + box-shadow: 0 8px 18px rgba(46, 107, 230, 0.22); + font-weight: 850; +} + +.mentor-float { + position: fixed; + right: max(18px, calc((100vw - 426px) / 2 + 18px)); + bottom: calc(92px + env(safe-area-inset-bottom)); + z-index: 110; + width: 56px; + height: 56px; + padding: 0; +} + +@keyframes mentor-breathe { + 0%, + 100% { + transform: scale(1); + } + 50% { + transform: scale(1.03); + } +} + +@keyframes mentor-blink { + 0%, + 92%, + 100% { + transform: scaleY(0); + opacity: 0; + } + 94%, + 96% { + transform: scaleY(1); + opacity: 1; + } +} + +@keyframes mentor-ripple { + 0% { + transform: scale(0.85); + opacity: 0.55; + } + 100% { + transform: scale(1.45); + opacity: 0; + } +} + +@keyframes mentor-dot { + 0%, + 100% { + transform: translateY(0); + opacity: 0.45; + } + 50% { + transform: translateY(-5px); + opacity: 1; + } +} + +@keyframes mentor-wave { + 0%, + 100% { + transform: scaleY(0.45); + opacity: 0.55; + } + 50% { + transform: scaleY(1); + opacity: 1; + } +} + +.practice-panel { + margin-top: 14px; + padding: 16px; + border: 1px solid rgba(15, 174, 166, 0.18); + border-radius: 16px; + background: rgba(240, 253, 252, 0.5); + display: grid; + gap: 12px; +} + +.scene-practice { + margin-top: 0; + border-color: rgba(46, 107, 230, 0.16); + background: #ffffff; + box-shadow: 0 10px 28px rgba(18, 31, 49, 0.06); +} + +.practice-panel-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; +} + +.scene-head { + align-items: center; +} + +.scene-head > span { + min-width: 0; + display: grid; + justify-items: center; + gap: 3px; +} + +.scene-head .detail-back, +.scene-head > button { + min-width: 44px; + min-height: 34px; + border-radius: 10px; + color: var(--text-secondary); + font-size: 13px; + font-weight: 850; +} + +.scene-head > button:last-child { + color: var(--mentor-blue); +} + +.scene-progress { + height: 30px; + position: relative; + display: flex; + align-items: center; + justify-content: flex-end; +} + +.scene-progress::before, +.scene-progress span { + content: ''; + position: absolute; + left: 0; + right: 48px; + height: 5px; + border-radius: 999px; +} + +.scene-progress::before { + background: #dbe7fb; +} + +.scene-progress span { + right: auto; + background: var(--mentor-blue); +} + +.scene-progress b { + width: 38px; + color: var(--mentor-blue); + text-align: right; + font-size: 13px; + font-weight: 900; +} + +.emotion-progress::before, +.emotion-progress span { + right: 82px; +} + +.emotion-progress span { + right: auto; + background: linear-gradient(90deg, #25b46f, #ffb020, #f65f61); +} + +.emotion-progress b { + width: 72px; + color: #c96513; +} + +.practice-panel-head span, +.practice-panel-head b { + color: var(--text-primary); + font-size: 15px; + font-weight: 800; +} + +.practice-panel-head small { + color: var(--primary-teal-active); + font-size: 13px; + font-weight: 800; +} + +.scene-brief { + display: grid; + gap: 10px; + padding: 14px; + border: 1px solid rgba(46, 107, 230, 0.14); + border-radius: 14px; + background: #f5f9ff; +} + +.scene-brief b { + color: var(--text-primary); + font-size: 16px; + font-weight: 900; +} + +.scene-brief p { + color: var(--text-secondary); + font-size: 13px; + line-height: 1.45; + font-weight: 650; +} + +.scene-brief button { + min-height: 44px; + border-radius: 12px; + color: #ffffff; + background: var(--mentor-blue); + box-shadow: 0 8px 18px rgba(46, 107, 230, 0.2); + font-size: 15px; + font-weight: 900; +} + +.practice-dialogue { + display: grid; + gap: 10px; +} + +.practice-dialogue p { + padding: 10px 14px; + border-radius: 14px; + color: var(--text-primary); + background: #ffffff; + border: 1px solid rgba(213, 225, 233, 0.5); + font-size: 14px; + line-height: 1.45; + font-weight: 600; + box-shadow: 0 2px 6px rgba(18, 31, 49, 0.02); +} + +.practice-dialogue p.trainee { + border-color: rgba(15, 174, 166, 0.18); + background: #effffd; + border-bottom-right-radius: 4px; +} + +.practice-dialogue p.coach { + border-color: rgba(87, 154, 255, 0.15); + background: #f3f8ff; + border-bottom-left-radius: 4px; +} + +.practice-dialogue span { + display: block; + margin-bottom: 4px; + color: var(--primary-teal); + font-size: 11px; + font-weight: 800; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.practice-message { + display: grid; + grid-template-columns: 42px minmax(0, 1fr); + gap: 10px; + align-items: start; +} + +.practice-message img { + width: 42px; + height: 42px; + border-radius: 999px; + object-fit: cover; + background: #e7f0ff; + box-shadow: 0 6px 14px rgba(18, 31, 49, 0.1); +} + +.practice-message p { + margin: 0; + padding: 11px 13px; + border-radius: 14px; + border-bottom-left-radius: 4px; +} + +.practice-message.customer p { + border-color: rgba(46, 107, 230, 0.18); + background: #f7fbff; +} + +.practice-message.trainee { + grid-template-columns: minmax(0, 1fr) 42px; +} + +.practice-message.trainee img { + grid-column: 2; + background: #dff8f5; +} + +.practice-message.trainee p { + grid-column: 1; + grid-row: 1; + border-color: rgba(15, 174, 166, 0.18); + border-bottom-left-radius: 14px; + border-bottom-right-radius: 4px; + background: #effffd; +} + +.practice-message.coach img { + background: #e8edf5; +} + +.practice-message.coach p { + border-color: rgba(87, 154, 255, 0.15); + background: #f3f8ff; +} + +.coach-style-actions { + grid-column: 2; + display: flex; + flex-wrap: wrap; + gap: 7px; + align-items: center; +} + +.coach-style-actions button { + min-height: 30px; + padding: 0 12px; + border-radius: 999px; + border: 1px solid rgba(87, 154, 255, 0.18); + background: #ffffff; + color: #3769a9; + font-size: 12px; + font-weight: 850; +} + +.coach-style-actions button:disabled { + opacity: 0.55; +} + +.coach-style-note { + width: 100%; + color: #4e77ad; + font-size: 12px; + line-height: 1.25; + font-weight: 750; +} + +.practice-wave { + margin-top: 10px; + min-height: 34px; + padding: 6px 8px; + border-radius: 12px; + background: rgba(255, 255, 255, 0.78); + display: grid; + grid-template-columns: repeat(16, 1fr) auto; + align-items: center; + gap: 3px; +} + +.practice-wave i { + width: 3px; + border-radius: 99px; + background: #5598ef; + opacity: 0.88; +} + +.practice-message.trainee .practice-wave i { + background: #13b686; +} + +.practice-message.coach .practice-wave i { + background: #7ca1d4; +} + +.practice-wave b { + margin-left: 6px; + color: var(--text-secondary); + white-space: nowrap; + font-size: 12px; + line-height: 1; + font-weight: 850; +} + +.round-rating { + position: relative; + padding: 12px 58px 12px 13px; + border: 1px solid rgba(237, 170, 20, 0.22); + border-radius: 14px; + background: #fffaf0; + display: grid; + gap: 5px; +} + +.round-rating b { + color: var(--text-primary); + font-size: 14px; + font-weight: 900; +} + +.round-rating span { + color: #ffb323; + font-size: 22px; + line-height: 1; + letter-spacing: 1px; +} + +.round-rating small { + color: var(--text-secondary); + font-size: 12px; + line-height: 1.4; + font-weight: 650; +} + +.round-rating em { + position: absolute; + right: 14px; + top: 50%; + transform: translateY(-50%); + color: var(--text-primary); + font-size: 20px; + font-style: normal; + font-weight: 900; +} + +.dialogue-memory { + padding: 11px 13px; + border: 1px solid rgba(213, 225, 233, 0.7); + border-radius: 13px; + background: #ffffff; +} + +.dialogue-memory b, +.dialogue-memory small { + display: block; +} + +.dialogue-memory b { + color: var(--text-primary); + font-size: 14px; + font-weight: 900; +} + +.dialogue-memory small { + margin-top: 4px; + color: var(--text-secondary); + font-size: 12px; + line-height: 1.35; + font-weight: 650; +} + +.practice-live { + display: grid; + gap: 12px; +} + +.practice-live textarea { + width: 100%; + resize: vertical; + min-height: 76px; + border: 1px solid rgba(15, 174, 166, 0.22); + border-radius: 12px; + padding: 12px; + color: var(--text-primary); + background: #ffffff; + font: inherit; + font-size: 14px; + font-weight: 600; + outline: none; + transition: var(--transition-ease); +} + +.practice-live textarea:focus { + border-color: var(--primary-teal); + box-shadow: 0 0 0 3px var(--primary-teal-glow); +} + +.interview-questions { + display: grid; + gap: 12px; +} + +.interview-question { + display: grid; + gap: 6px; +} + +.interview-question span { + color: var(--text-primary); + font-size: 14px; + line-height: 1.4; + font-weight: 800; +} + +.interview-question small { + color: var(--text-secondary); + font-size: 12px; + line-height: 1.35; + font-weight: 650; +} + +.interview-question textarea { + width: 100%; + min-height: 76px; + resize: vertical; + border: 1px solid rgba(15, 174, 166, 0.22); + border-radius: 12px; + padding: 12px; + color: var(--text-primary); + background: #ffffff; + font: inherit; + font-size: 14px; + font-weight: 600; + outline: none; +} + +.interview-question textarea:focus { + border-color: var(--primary-teal); + box-shadow: 0 0 0 3px var(--primary-teal-glow); +} + +.practice-result-actions { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 9px; +} + +.practice-actions { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 9px; +} + +.practice-actions button, +.practice-result-actions button { + min-height: 42px; + border-radius: 10px; + color: var(--primary-teal-active); + background: var(--primary-teal-light); + font-size: 13px; + font-weight: 800; + transition: var(--transition-spring); + border: 1px solid rgba(15, 174, 166, 0.1); +} + +.practice-actions button:last-child, +.practice-result-actions button:first-child { + color: #ffffff; + background: linear-gradient(135deg, #1cbdb4, #07948e); + box-shadow: 0 4px 12px rgba(9, 151, 144, 0.2); + border: none; +} + +.practice-actions button:disabled { + opacity: 0.55; + transform: none; +} + +.practice-audio-input { + display: none; +} + +.practice-result { + display: grid; + gap: 9px; +} + +.practice-prep-card, +.practice-help-card { + display: grid; + gap: 6px; + padding: 10px; + border: 1px solid rgba(15, 174, 166, 0.14); + border-radius: 12px; + background: var(--primary-teal-light); +} + +.practice-prep-card b, +.practice-help-card b { + color: var(--text-primary); + font-size: 13px; + font-weight: 900; +} + +.practice-prep-card small, +.practice-help-card small, +.practice-prep-card em, +.practice-help-card em { + color: var(--text-secondary); + font-size: 12px; + font-style: normal; + line-height: 1.45; +} + +.practice-result strong { + color: var(--text-primary); + font-size: 15px; + line-height: 1.35; + font-weight: 800; +} + +.practice-result p { + color: var(--text-secondary); + font-size: 13px; + line-height: 1.45; + font-weight: 600; +} + +.scene-rating { + min-height: 42px; + padding: 8px 10px; + border: 1px solid rgba(237, 170, 20, 0.22); + border-radius: 12px; + background: #fffaf0; + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; +} + +.scene-rating span { + color: #ffb323; + font-size: 20px; + letter-spacing: 1px; +} + +.scene-rating b { + color: var(--text-primary); + font-size: 15px; + font-weight: 900; +} + +.practice-panel > em { + color: var(--primary-teal-active); + font-size: 13px; + font-style: normal; + font-weight: 800; +} + +.user-panel { + display: grid; + gap: 12px; +} + +.flow-steps { + display: grid; + gap: 9px; +} + +.flow-steps button { + width: 100%; + min-height: 64px; + padding: 10px 12px; + border: 1px solid rgba(213, 225, 233, 0.62); + border-radius: 13px; + background: #ffffff; + box-shadow: var(--shadow-sm); + display: grid; + grid-template-columns: 34px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + text-align: left; + transition: var(--transition-spring); +} + +.flow-steps button:active { + transform: scale(0.985); +} + +.flow-steps button.active { + border-color: rgba(15, 174, 166, 0.48); + background: linear-gradient(135deg, rgba(240, 253, 252, 0.98), #ffffff); +} + +.flow-steps em { + width: 34px; + height: 34px; + border-radius: 10px; + background: var(--primary-teal-light); + color: var(--primary-teal-active); + display: grid; + place-items: center; + font-style: normal; + font-size: 15px; + font-weight: 900; +} + +.flow-steps b { + display: block; + color: var(--text-primary); + font-size: 14px; + line-height: 1.25; + font-weight: 850; +} + +.flow-steps small { + display: block; + margin-top: 3px; + color: var(--text-secondary); + font-size: 12px; + line-height: 1.35; + font-weight: 650; +} + +.panel-row { + width: 100%; + min-height: 66px; + padding: 12px; + border: 1px solid rgba(213, 225, 233, 0.6); + border-radius: 14px; + background: #ffffff; + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto; + align-items: center; + gap: 12px; + text-align: left; + transition: var(--transition-spring); + box-shadow: var(--shadow-sm); +} + +.panel-row:active { + transform: scale(0.98); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.02); +} + +.panel-row b, +.knowledge-result strong, +.case-result h3, +.result-list h3, +.snippet-list h3 { + color: var(--text-primary); + font-weight: 800; +} + +.panel-row b { + display: block; + font-size: 15px; + line-height: 1.25; +} + +.panel-row small { + display: block; + margin-top: 4px; + color: var(--text-secondary); + font-size: 12px; + line-height: 1.35; + font-weight: 650; +} + +.knowledge-search { + display: grid; + grid-template-columns: minmax(0, 1fr) 78px; + gap: 8px; +} + +.digest-card { + padding: 14px; + border-radius: 12px; + background: linear-gradient(160deg, rgba(35, 150, 133, 0.08), rgba(35, 150, 133, 0.02)); + border: 1px solid rgba(35, 150, 133, 0.22); +} + +.digest-head { + display: flex; + align-items: flex-start; + gap: 10px; +} + +.digest-head strong, +.digest-card > strong { + flex: 1; + display: block; + font-size: 16px; + line-height: 1.45; + color: var(--text-primary, #16323f); +} + +.digest-speak { + flex-shrink: 0; + min-height: 32px; + padding: 0 12px; + border-radius: 16px; + border: 1px solid rgba(35, 150, 133, 0.45); + background: #ffffff; + color: #1f8a76; + font-size: 13px; + font-weight: 650; +} + +.digest-points { + margin: 10px 0 0; + padding-left: 20px; + display: grid; + gap: 6px; + font-size: 14px; + line-height: 1.5; +} + +.answer-feedback-actions { + margin-top: 10px; + display: flex; + gap: 8px; +} + +.answer-feedback-actions button { + width: 40px; + height: 40px; + border: 1px solid rgba(46, 107, 230, 0.18); + border-radius: 12px; + background: #ffffff; + font-size: 18px; + line-height: 1; + transition: var(--transition-spring-fast); +} + +.answer-feedback-actions button.active { + border-color: rgba(46, 107, 230, 0.55); + background: rgba(46, 107, 230, 0.12); +} + +.answer-feedback-actions button:disabled { + opacity: 0.68; + transform: none; +} + +.digest-cautions { + margin-top: 10px; + padding: 8px 10px; + border-radius: 8px; + background: rgba(240, 160, 32, 0.12); + border: 1px solid rgba(240, 160, 32, 0.35); +} + +.digest-cautions p { + margin: 0; + font-size: 13px; + line-height: 1.5; + color: #9a6206; +} + +.digest-cautions p + p { + margin-top: 4px; +} + +.digest-reference { + margin: 10px 0 0; + font-size: 12px; + color: var(--text-secondary); +} + +.snippet-toggle { + width: 100%; + min-height: 38px; + margin-top: 10px; + border-radius: 10px; + border: 1px dashed rgba(35, 150, 133, 0.4); + background: transparent; + color: #1f8a76; + font-size: 13px; + font-weight: 650; +} + +.sop-result .snippet-list blockquote:not(.expanded) span { + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.sop-result .snippet-list blockquote em { + display: block; + margin-top: 6px; + font-size: 12px; + font-style: normal; + color: #1f8a76; +} + +.knowledge-tabs { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px; +} + +.knowledge-tabs button { + min-height: 38px; + border-radius: 10px; + color: var(--text-secondary); + background: #ffffff; + border: 1px solid rgba(213, 225, 233, 0.7); + font-size: 14px; + font-weight: 800; +} + +.knowledge-tabs button.active { + color: var(--primary-teal-active); + background: var(--primary-teal-light); + border-color: rgba(15, 174, 166, 0.22); +} + +.knowledge-search input { + min-width: 0; + height: 42px; + border: 1px solid rgba(15, 174, 166, 0.2); + border-radius: 10px; + padding: 0 12px; + color: var(--text-primary); + background: #ffffff; + font: inherit; + font-size: 14px; + font-weight: 700; + outline: none; + transition: var(--transition-ease); +} + +.knowledge-search input:focus { + border-color: var(--primary-teal); + box-shadow: 0 0 0 3px var(--primary-teal-glow); +} + +.knowledge-search button, +.panel-primary { + min-height: 42px; + border-radius: 10px; + color: #ffffff; + background: linear-gradient(135deg, #1cbdb4, #07948e); + box-shadow: 0 4px 12px rgba(9, 151, 144, 0.15); + font-size: 14px; + font-weight: 800; + transition: var(--transition-spring); +} + +.knowledge-search button:disabled, +.panel-primary:disabled { + opacity: 0.55; + transform: none; +} + +.panel-message { + color: var(--primary-teal-active); + font-size: 13px; + font-style: normal; + font-weight: 800; +} + +.knowledge-result, +.case-result { + display: grid; + gap: 10px; +} + +.knowledge-result strong { + font-size: 16px; + line-height: 1.35; +} + +.knowledge-result > p, +.case-result p, +.case-result dd { + margin: 0; + color: var(--text-secondary); + font-size: 13px; + line-height: 1.45; + font-weight: 650; +} + +.panel-tags { + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.panel-tags span { + max-width: 100%; + padding: 4px 10px; + border-radius: 99px; + color: var(--primary-teal-active); + background: var(--primary-teal-light); + border: 1px solid rgba(15, 174, 166, 0.1); + font-size: 11px; + line-height: 1.2; + font-weight: 750; +} + +.result-list, +.snippet-list { + display: grid; + gap: 8px; +} + +.result-list h3, +.snippet-list h3, +.case-result h3 { + margin: 0; + font-size: 14px; +} + +.result-list p, +.snippet-list blockquote, +.case-result > div { + margin: 0; + padding: 12px; + border: 1px solid rgba(213, 225, 233, 0.5); + border-radius: 12px; + background: #ffffff; + box-shadow: var(--shadow-sm); +} + +.result-list b, +.snippet-list b, +.case-result b { + display: block; + color: var(--text-primary); + font-size: 14px; + line-height: 1.25; + font-weight: 800; +} + +.result-list small, +.snippet-list span { + display: block; + margin-top: 4px; + color: var(--text-secondary); + font-size: 12px; + line-height: 1.4; + font-weight: 650; +} + +.assign-button { + width: 100%; +} + +.file-picker { + min-height: 90px; + padding: 16px; + border: 2px dashed rgba(15, 174, 166, 0.25); + border-radius: 14px; + background: rgba(240, 253, 252, 0.2); + display: grid; + align-content: center; + gap: 6px; + position: relative; + overflow: hidden; + transition: var(--transition-ease); +} + +.file-picker:active { + background: rgba(240, 253, 252, 0.4); +} + +.file-picker span { + color: var(--text-primary); + font-size: 14px; + font-weight: 800; +} + +.file-picker small { + color: var(--text-secondary); + font-size: 11px; + line-height: 1.35; + font-weight: 600; +} + +.file-picker input { + position: absolute; + inset: 0; + opacity: 0; + cursor: pointer; +} + +.case-result dl { + margin: 0; + display: grid; + gap: 6px; +} + +.case-result dt { + color: var(--primary-teal-active); + font-size: 13px; + font-weight: 900; +} + +.panel-profile { + margin-top: 0; +} + +.growth-summary { + margin-top: 0; +} + +.sop-overlay { + position: fixed; + inset: 0; + z-index: 120; + display: flex; + justify-content: center; + overflow-y: auto; + background: + radial-gradient(circle at 10% 20%, rgba(46, 107, 230, 0.08) 0%, transparent 40%), + radial-gradient(circle at 90% 10%, rgba(56, 132, 255, 0.07) 0%, transparent 35%), + linear-gradient(180deg, #f5f8fa 0%, #fcfdfe 100%); +} + +.sop-panel { + width: min(100vw, 426px); + min-height: 100vh; + padding: 14px 14px 110px; + display: grid; + align-content: start; + gap: 14px; +} + +.sop-head { + display: grid; + grid-template-columns: 72px 1fr 72px; + align-items: center; + padding: 2px 0 4px; +} + +.sop-head h2 { + margin: 0; + text-align: center; + color: var(--text-primary); + font-size: 18px; + font-weight: 850; +} + +.sop-back { + width: 64px; + height: 36px; + border-radius: 11px; + color: var(--primary-teal-active); + background: var(--primary-teal-light); + font-size: 14px; + font-weight: 800; +} + +.sop-form { + padding: 16px; + border: 1px solid var(--glass-border); + border-top: 1px solid var(--glass-border-light); + border-radius: 18px; + background: var(--glass-bg); + box-shadow: var(--shadow-md); + display: grid; + gap: 10px; +} + +.sop-form input { + width: 100%; + min-width: 0; + height: 46px; + border: 1px solid rgba(15, 174, 166, 0.2); + border-radius: 11px; + padding: 0 13px; + color: var(--text-primary); + background: #ffffff; + font: inherit; + font-size: 14px; + font-weight: 700; + outline: none; +} + +.sop-form input:focus { + border-color: var(--primary-teal); + box-shadow: 0 0 0 3px var(--primary-teal-glow); +} + +.sop-actions { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 9px; +} + +.sop-actions button { + min-height: 42px; + border-radius: 10px; + font-size: 14px; + font-weight: 800; +} + +.sop-voice { + color: var(--primary-teal-active); + background: var(--primary-teal-light); + border: 1px solid rgba(15, 174, 166, 0.1); +} + +.sop-submit { + color: #ffffff; + background: linear-gradient(135deg, #1cbdb4, #07948e); + box-shadow: 0 4px 12px rgba(9, 151, 144, 0.15); +} + +.sop-actions button:disabled { + opacity: 0.55; + transform: none; +} + +.sop-result { + padding: 16px; + border: 1px solid var(--glass-border); + border-radius: 18px; + background: #ffffff; + box-shadow: var(--shadow-md); +} + +.sop-panel .sop-back { + color: #1c56c6; + background: rgba(46, 107, 230, 0.1); +} + +.sop-panel .sop-form input { + border-color: rgba(46, 107, 230, 0.2); +} + +.sop-panel .sop-form input:focus { + border-color: #2e6be6; + box-shadow: 0 0 0 3px rgba(46, 107, 230, 0.14); +} + +.sop-panel .sop-voice, +.sop-panel .digest-speak, +.sop-panel .snippet-toggle, +.sop-panel .snippet-list blockquote em, +.sop-panel .panel-message { + color: #1c56c6; +} + +.sop-panel .sop-voice { + background: rgba(46, 107, 230, 0.1); + border-color: rgba(46, 107, 230, 0.16); +} + +.sop-panel .sop-submit { + background: linear-gradient(135deg, #2e6be6, #0f58d6); + box-shadow: 0 4px 12px rgba(46, 107, 230, 0.18); +} + +.sop-panel .digest-card { + border-color: rgba(46, 107, 230, 0.24); + background: linear-gradient(160deg, rgba(46, 107, 230, 0.09), rgba(46, 107, 230, 0.02)); +} + +.sop-panel .digest-speak { + border-color: rgba(46, 107, 230, 0.36); +} + +.sop-panel .snippet-toggle { + border-color: rgba(46, 107, 230, 0.35); +} + +.summary-card-entry { + margin-top: 12px; + display: grid; + gap: 7px; +} + +.summary-card-trigger { + width: 100%; + min-height: 58px; + border-radius: 22px; + color: #ffffff; + background: linear-gradient(135deg, #2e6be6, #0b55d8); + box-shadow: 0 10px 24px rgba(46, 107, 230, 0.26); + display: grid; + place-items: center; + gap: 2px; + font-weight: 900; +} + +.summary-card-trigger span { + font-size: 16px; + line-height: 1.1; +} + +.summary-card-trigger small { + font-size: 12px; + line-height: 1; + opacity: 0.82; +} + +.summary-card-trigger:disabled { + opacity: 0.62; + box-shadow: none; +} + +.summary-card-entry em { + color: #c25712; + font-size: 12px; + font-style: normal; + font-weight: 750; +} + +.summary-card-mask { + position: fixed; + inset: 0; + z-index: 180; + display: flex; + align-items: flex-end; + justify-content: center; + background: rgba(0, 0, 0, 0.45); +} + +.summary-card-sheet { + position: relative; + width: min(100vw, 860px); + height: 88vh; + max-height: 88vh; + padding: 22px 16px 0; + border-radius: 24px 24px 0 0; + background: #f8fbff; + box-shadow: 0 -18px 44px rgba(13, 31, 68, 0.24); + overflow-y: auto; + animation: summary-sheet-in 220ms ease-out; +} + +@keyframes summary-sheet-in { + from { + transform: translateY(100%); + } + to { + transform: translateY(0); + } +} + +.summary-card-handle { + position: absolute; + top: 9px; + left: 50%; + width: 66px; + height: 6px; + border-radius: 999px; + background: rgba(25, 42, 70, 0.18); + transform: translateX(-50%); +} + +.summary-card-close { + position: absolute; + top: 18px; + right: 16px; + width: 38px; + height: 38px; + border-radius: 50%; + border: 1px solid rgba(21, 39, 70, 0.16); + color: #182842; + background: #ffffff; + font-size: 30px; + line-height: 1; + box-shadow: var(--shadow-sm); +} + +.summary-card-head { + min-height: 46px; + padding: 12px 48px 12px; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +.summary-card-head h2 { + min-width: 0; + margin: 0; + color: #101828; + font-size: 22px; + line-height: 1.2; + font-weight: 900; + overflow-wrap: anywhere; +} + +.summary-card-head span { + flex-shrink: 0; + padding: 2px 7px; + border: 1px solid rgba(46, 107, 230, 0.35); + border-radius: 999px; + color: #1f62dc; + background: #ffffff; + font-size: 12px; + font-weight: 800; +} + +.summary-card-grid { + display: grid; + gap: 8px; +} + +@media (min-width: 400px) { + .summary-card-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +.summary-card-block { + min-width: 0; + padding: 12px; + border: 1px solid rgba(213, 225, 233, 0.8); + border-radius: 10px; + background: #ffffff; + box-shadow: 0 6px 18px rgba(17, 33, 63, 0.06); +} + +.summary-card-block h3 { + margin: 0 0 10px; + display: flex; + align-items: center; + gap: 7px; + color: #101828; + font-size: 15px; + line-height: 1.2; + font-weight: 900; +} + +.summary-card-block h3::before { + content: ""; + width: 5px; + height: 22px; + border-radius: 999px; + background: var(--card-accent); +} + +.summary-card-block.is-steps { + --card-accent: #2e6be6; +} + +.summary-card-block.is-objections { + --card-accent: #ff7a1a; +} + +.summary-card-block.is-scripts { + --card-accent: #18b66a; +} + +.summary-card-block.is-reminders { + --card-accent: #f6b91a; +} + +.summary-card-block ol, +.summary-card-block ul { + margin: 0; + padding: 0; + list-style: none; +} + +.summary-card-block.is-steps ol { + display: grid; + gap: 7px; +} + +.summary-card-block.is-steps li { + min-height: 54px; + padding: 8px; + border-radius: 10px; + background: linear-gradient(135deg, rgba(46, 107, 230, 0.11), rgba(46, 107, 230, 0.04)); + display: grid; + grid-template-columns: 34px minmax(0, 1fr); + align-items: center; + gap: 9px; +} + +.summary-card-block.is-steps em { + width: 30px; + height: 30px; + border-radius: 50%; + color: #ffffff; + background: #2e6be6; + display: grid; + place-items: center; + font-size: 16px; + font-style: normal; + font-weight: 900; +} + +.summary-card-block b { + display: block; + min-width: 0; + color: #101828; + font-size: 14px; + line-height: 1.25; + font-weight: 900; +} + +.summary-card-block small, +.summary-card-block span { + min-width: 0; + color: #475467; + font-size: 12px; + line-height: 1.35; + font-weight: 700; +} + +.objection-list { + display: grid; + gap: 8px; +} + +.objection-list p { + margin: 0; + min-height: 42px; + padding: 8px 10px; + border-radius: 10px; + background: linear-gradient(90deg, rgba(255, 122, 26, 0.14), rgba(255, 122, 26, 0.05)); + display: grid; + grid-template-columns: minmax(72px, 0.55fr) minmax(0, 1fr); + align-items: center; + gap: 8px; +} + +.summary-card-block.is-scripts blockquote { + position: relative; + margin: 0; + padding: 11px 14px; + border: 1px solid rgba(24, 182, 106, 0.18); + border-radius: 10px; + color: #183b2b; + background: rgba(24, 182, 106, 0.08); + font-size: 13px; + line-height: 1.55; + font-weight: 750; +} + +.summary-card-block.is-scripts blockquote + blockquote { + margin-top: 8px; +} + +.summary-card-block.is-scripts blockquote::before, +.summary-card-block.is-scripts blockquote::after { + position: absolute; + color: rgba(24, 182, 106, 0.32); + font-size: 28px; + line-height: 1; + font-weight: 900; +} + +.summary-card-block.is-scripts blockquote::before { + content: "“"; + left: 5px; + top: 2px; +} + +.summary-card-block.is-scripts blockquote::after { + content: "”"; + right: 8px; + bottom: 0; +} + +.summary-card-block.is-reminders ul { + display: grid; + gap: 9px; +} + +.summary-card-block.is-reminders li { + display: grid; + grid-template-columns: 20px minmax(0, 1fr); + gap: 8px; + color: #182842; + font-size: 13px; + line-height: 1.35; + font-weight: 780; +} + +.summary-card-block.is-reminders li::before { + content: "✓"; + width: 18px; + height: 18px; + border-radius: 50%; + color: #ffffff; + background: #f6b91a; + display: grid; + place-items: center; + font-size: 12px; + font-weight: 900; +} + +.summary-card-inline-message { + margin: 10px 0 0; + color: #c25712; + text-align: center; + font-size: 12px; + line-height: 1.35; + font-weight: 750; +} + +.summary-card-footer { + position: sticky; + bottom: 0; + margin: 14px -16px 0; + padding: 10px 16px calc(10px + env(safe-area-inset-bottom)); + border-top: 1px solid rgba(213, 225, 233, 0.72); + background: rgba(248, 251, 255, 0.96); +} + +.summary-card-footer-actions { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; +} + +.summary-card-footer button { + min-height: 52px; + border-radius: 12px; + color: #ffffff; + font-size: 16px; + font-weight: 900; +} + +.summary-card-footer button.listen { + background: linear-gradient(135deg, #2e6be6, #0f58d6); + box-shadow: 0 8px 18px rgba(46, 107, 230, 0.2); +} + +.summary-card-footer button.practice { + background: linear-gradient(135deg, #20bf72, #0a9f59); + box-shadow: 0 8px 18px rgba(32, 191, 114, 0.2); +} + +.summary-card-footer button:disabled { + opacity: 0.62; +} + +.summary-card-footer p { + margin: 8px 0 0; + color: #667085; + text-align: center; + font-size: 12px; + line-height: 1.35; + font-weight: 650; +} + +.tool-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 12px; +} + +.tool-grid button { + min-height: 88px; + border: 1px solid var(--glass-border); + border-radius: 14px; + padding: 14px 12px; + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + background: #ffffff; + box-shadow: var(--shadow-sm); + transition: var(--transition-spring); + position: relative; + text-align: left; +} + +.tool-grid button.tone-teal, +.tool-grid button.tone-blue, +.tool-grid button.tone-orange, +.tool-grid button.tone-purple, +.tool-grid button.tone-amber { + background: #ffffff; + border: 1px solid var(--glass-border); + color: var(--text-primary); +} + +.tool-grid button:active { + transform: scale(0.96); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.02); +} + +.tool-grid button.tone-teal:active { border-color: var(--primary-teal-active); } +.tool-grid button.tone-blue:active { border-color: var(--accent-blue); } +.tool-grid button.tone-orange:active { border-color: var(--accent-orange); } +.tool-grid button.tone-purple:active { border-color: var(--accent-purple); } +.tool-grid button.tone-amber:active { border-color: var(--accent-amber); } + +.tool-grid button > .icon { + width: 16px; + height: 16px; + color: var(--text-muted); +} + +.icon-bubble { + width: 48px; + height: 48px; + border-radius: 999px; + display: grid; + place-items: center; + flex: none; +} + +.tone-teal { + color: var(--primary-teal-active); + border: 1px solid rgba(15, 174, 166, 0.2); + background: linear-gradient(135deg, #f0fdfa, #ffffff); +} + +.tone-blue { + color: var(--accent-blue); + border: 1px solid rgba(87, 154, 255, 0.2); + background: linear-gradient(135deg, #eff6ff, #ffffff); +} + +.tone-orange { + color: var(--accent-orange); + border: 1px solid rgba(244, 164, 80, 0.2); + background: linear-gradient(135deg, #fff7ed, #ffffff); +} + +.tone-purple { + color: var(--accent-purple); + border: 1px solid rgba(144, 131, 245, 0.2); + background: linear-gradient(135deg, #faf5ff, #ffffff); +} + +.tone-amber { + color: var(--accent-amber); + border: 1px solid rgba(238, 179, 54, 0.2); + background: linear-gradient(135deg, #fefce8, #ffffff); +} + +.progress-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 10px; +} + +.progress-tile { + min-height: 110px; + border: 1px solid var(--glass-border); + border-radius: 14px; + padding: 14px 10px 12px; + background: #ffffff; + box-shadow: var(--shadow-sm); + display: grid; + align-content: space-between; +} + +.progress-tile small, +.progress-tile em { + display: block; + color: var(--text-secondary); + font-style: normal; + font-weight: 600; +} + +.progress-tile small { + margin-top: 2px; + font-size: 13px; +} + +.progress-tile b { + display: block; + color: var(--text-primary); + font-size: 26px; + line-height: 1; + font-weight: 800; + letter-spacing: -0.01em; +} + +.progress-tile em { + margin-top: 4px; + font-size: 11px; + line-height: 1.2; +} + +.progress-tile.tone-blue .bar span { + background: linear-gradient(90deg, #2f85ff, #1670f8); +} + +.progress-tile.tone-orange .bar span { + background: linear-gradient(90deg, #ff8a36, #f27a24); +} + +.profile-card { + margin-top: 14px; + padding: 14px; + border: 1px solid rgba(15, 174, 166, 0.18); + border-radius: 16px; + background: rgba(240, 253, 252, 0.4); + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 9px; +} + +.profile-card > span { + min-height: 58px; + border-radius: 10px; + background: #ffffff; + display: grid; + place-items: center; + box-shadow: var(--shadow-sm); +} + +.profile-card small { + color: var(--text-secondary); + font-size: 11px; + font-weight: 700; +} + +.profile-card b { + color: var(--text-primary); + font-size: 22px; + line-height: 1; + font-weight: 800; +} + +.profile-dims { + grid-column: 1 / -1; + display: grid; + gap: 8px; +} + +.profile-dims p { + min-height: 38px; + padding: 8px 12px; + border-radius: 10px; + background: #ffffff; + display: grid; + grid-template-columns: 50px 36px 1fr; + align-items: center; + gap: 8px; + box-shadow: var(--shadow-sm); +} + +.profile-dims span { + color: var(--primary-teal-active); + font-size: 13px; + font-weight: 800; +} + +.profile-dims b { + font-size: 17px; + font-weight: 800; +} + +.profile-dims small { + color: var(--text-secondary); + font-size: 12px; + font-weight: 600; +} + +.growth-path-list { + grid-column: 1 / -1; + display: grid; + gap: 8px; +} + +.growth-path-list p { + margin: 0; + padding: 10px 12px; + border-radius: 10px; + background: #ffffff; + display: grid; + grid-template-columns: 1fr auto; + gap: 5px 10px; + box-shadow: var(--shadow-sm); +} + +.growth-path-list span { + color: var(--primary-teal-active); + font-size: 13px; + font-weight: 900; +} + +.growth-path-list b { + color: var(--text-primary); + font-size: 15px; + font-weight: 900; +} + +.growth-path-list small { + grid-column: 1 / -1; + color: var(--text-secondary); + font-size: 12px; + line-height: 1.45; +} + +.record-list { + margin-top: 14px; + display: grid; + gap: 8px; +} + +.record-list h3 { + margin: 0; + color: var(--text-primary); + font-size: 16px; + font-weight: 800; +} + +.record-list button { + min-height: 58px; + padding: 12px; + border: 1px solid rgba(213, 225, 233, 0.5); + border-radius: 12px; + background: #ffffff; + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 9px; + align-items: center; + text-align: left; + box-shadow: var(--shadow-sm); + transition: var(--transition-spring); +} + +.record-list button:active { + transform: scale(0.98); +} + +.record-list b { + color: var(--text-primary); + font-size: 14px; + line-height: 1.25; + font-weight: 800; +} + +.record-list small { + margin-top: 4px; + color: var(--text-secondary); + font-size: 12px; + line-height: 1.35; + font-weight: 600; +} + +.record-list em { + min-width: 48px; + height: 24px; + padding: 0 8px; + border-radius: 99px; + color: var(--primary-teal-active); + background: var(--primary-teal-light); + display: grid; + place-items: center; + font-size: 11px; + font-style: normal; + font-weight: 800; +} + +.review-message, +.review-detail > em { + color: var(--primary-teal-active); + font-size: 13px; + font-style: normal; + font-weight: 800; +} + +.review-detail { + margin-top: 14px; + padding: 16px; + border: 1px solid rgba(15, 174, 166, 0.18); + border-radius: 8px; + background: rgba(240, 253, 252, 0.4); + display: grid; + gap: 12px; +} + +.detail-back { + width: max-content; + min-height: 32px; + padding: 0 12px; + border-radius: 9px; + color: var(--primary-teal-active); + background: var(--primary-teal-light); + font-size: 12px; + font-weight: 800; +} + +.review-detail-head { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + align-items: center; + gap: 10px; +} + +.review-detail-head b, +.review-summary b { + display: block; + color: var(--text-primary); + font-size: 15px; + font-weight: 800; +} + +.review-detail-head small, +.review-summary p { + margin-top: 4px; + color: var(--text-secondary); + font-size: 13px; + line-height: 1.45; + font-weight: 600; +} + +.review-detail-head em { + min-width: 52px; + height: 24px; + padding: 0 8px; + border-radius: 99px; + color: var(--primary-teal-active); + background: var(--primary-teal-light); + display: grid; + place-items: center; + font-size: 11px; + font-style: normal; + font-weight: 800; +} + +.review-score-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 8px; +} + +.review-score-grid p { + min-height: 58px; + border-radius: 10px; + background: #ffffff; + display: grid; + place-items: center; + box-shadow: var(--shadow-sm); +} + +.review-score-grid span, +.review-score-grid small { + color: var(--text-secondary); + font-size: 11px; + font-weight: 700; +} + +.review-score-grid b { + color: var(--text-primary); + font-size: 20px; + line-height: 1; + font-weight: 800; +} + +.review-dialogue { + max-height: 250px; + overflow: auto; +} + +.review-dialogue audio { + width: 100%; + margin-top: 6px; +} + +.review-annotations { + display: grid; + gap: 8px; +} + +.review-annotations > b { + color: var(--text-primary); + font-size: 14px; + font-weight: 900; +} + +.review-annotations p { + display: grid; + gap: 5px; + margin: 0; + padding: 10px; + border-radius: 12px; + background: var(--primary-teal-light); +} + +.review-annotations span, +.review-annotations em, +.review-annotations i { + color: var(--text-secondary); + font-size: 12px; + font-style: normal; +} + +.review-annotations small { + color: var(--text-primary); + font-size: 13px; + line-height: 1.45; +} + +.review-annotations strong { + color: var(--primary-teal-active); + font-size: 12px; + line-height: 1.45; +} + +.review-advice-box { + display: grid; + gap: 8px; +} + +.review-advice-box > b { + color: var(--text-primary); + font-size: 14px; + font-weight: 900; +} + +.review-advice-box p { + margin: 0; + padding: 10px; + border-radius: 10px; + color: var(--text-primary); + background: #ffffff; + box-shadow: var(--shadow-sm); + font-size: 13px; + line-height: 1.45; +} + +.review-advice-box textarea { + min-height: 74px; + resize: vertical; + border: 1px solid var(--line-soft); + border-radius: 10px; + padding: 10px; + color: var(--text-primary); + background: #ffffff; + font-size: 13px; + line-height: 1.45; + outline: none; +} + +.review-advice-box label { + display: inline-flex; + align-items: center; + gap: 8px; + color: var(--text-secondary); + font-size: 12px; + font-weight: 800; +} + +.review-advice-box .review-score-field { + justify-content: space-between; +} + +.review-advice-box input[type='number'] { + width: 96px; + min-height: 36px; + border: 1px solid var(--line-soft); + border-radius: 10px; + padding: 0 10px; + color: var(--text-primary); + background: #ffffff; + font-size: 13px; + font-weight: 800; + outline: none; +} + +.review-detail > button:not(.detail-back) { + min-height: 42px; + border-radius: 10px; + color: #ffffff; + background: linear-gradient(135deg, #1cbdb4, #07948e); + box-shadow: 0 4px 12px rgba(9, 151, 144, 0.15); + font-size: 14px; + font-weight: 800; + transition: var(--transition-spring); +} + +.review-detail > button:not(.detail-back):disabled { + color: var(--primary-teal-active); + background: var(--primary-teal-light); + box-shadow: none; + opacity: 0.55; + transform: none; +} + +.team-card { + border: 1px solid rgba(15, 174, 166, 0.15); + border-radius: 16px; + padding: 20px 16px; + background: linear-gradient(135deg, #f0fdfa 0%, #ffffff 100%); + display: grid; + grid-template-columns: 1fr 154px; + gap: 12px; + box-shadow: var(--shadow-sm); +} + +.team-copy h3 { + font-size: 20px; + line-height: 1.2; + font-weight: 800; + color: var(--text-primary); +} + +.team-copy p { + margin-top: 10px; + color: var(--text-secondary); + font-size: 14px; + font-weight: 600; +} + +.team-copy .bar { + margin-top: 24px; +} + +.team-copy > span { + display: block; + margin-top: 12px; + color: var(--text-secondary); + font-size: 14px; + font-weight: 600; +} + +.team-copy > span b { + color: var(--text-primary); + font-size: 16px; + font-weight: 800; +} + +.ring-box { + display: grid; + justify-items: center; + align-content: start; + gap: 13px; +} + +.ring { + width: 106px; + height: 106px; + border-radius: 50%; + background: conic-gradient(var(--primary-teal-active) calc(var(--value) * 1%), #e2e8f0 0); + display: grid; + place-items: center; + position: relative; + box-shadow: var(--shadow-sm); +} + +.ring::before { + content: ''; + position: absolute; + inset: 14px; + border-radius: inherit; + background: #ffffff; +} + +.ring b, +.ring small { + position: relative; + z-index: 1; +} + +.ring b { + margin-top: 8px; + color: var(--text-primary); + font-size: 24px; + line-height: 1; + font-weight: 800; +} + +.ring small { + margin-top: -30px; + color: var(--text-secondary); + font-size: 12px; + font-weight: 600; +} + +.ring-box button { + min-width: 105px; + height: 38px; + border-radius: 9px; + color: #ffffff; + background: linear-gradient(135deg, #1bbab1, #078f89); + box-shadow: 0 4px 12px rgba(10, 151, 144, 0.15); + font-size: 14px; + font-weight: 800; + transition: var(--transition-spring); +} + +.ring-box button:active { + transform: scale(0.95); +} + +.mini-stats { + grid-column: 1 / -1; + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 6px; +} + +.mini-stat { + min-height: 54px; + border: 1px solid rgba(213, 225, 233, 0.5); + border-radius: 12px; + background: rgba(255, 255, 255, 0.9); + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 8px 4px; + box-shadow: var(--shadow-sm); + overflow: hidden; +} + +.mini-stat .icon-bubble { + width: 28px; + height: 28px; + flex-shrink: 0; +} + +.mini-stat span { + display: flex; + flex-direction: column; + justify-content: center; + min-width: 0; +} + +.mini-stat small { + display: block; + color: var(--text-secondary); + font-size: 11px; + line-height: 1.1; + font-weight: 600; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + +.mini-stat b { + display: block; + color: var(--text-primary); + font-size: 17px; + line-height: 1.1; + font-weight: 800; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + +.todo-list { + border: 1px solid rgba(213, 225, 233, 0.5); + border-radius: 14px; + overflow: hidden; + box-shadow: var(--shadow-sm); +} + +.todo-list button { + width: 100%; + min-height: 70px; + padding: 11px 14px; + display: grid; + grid-template-columns: auto 1fr auto auto; + align-items: center; + gap: 12px; + background: #ffffff; + text-align: left; +} + +.todo-list button + button { + border-top: 1px solid rgba(213, 225, 233, 0.4); +} + +.todo-list .icon-bubble { + width: 44px; + height: 44px; +} + +.todo-list em { + width: 26px; + height: 26px; + border-radius: 999px; + color: #ffffff; + background: linear-gradient(135deg, #ff6363, #ef3535); + display: grid; + place-items: center; + font-size: 14px; + font-style: normal; + font-weight: 800; +} + +.suggestion { + margin-top: 14px; + min-height: 62px; + padding: 12px 14px; + border: 1px solid rgba(239, 181, 54, 0.25); + border-radius: 14px; + background: linear-gradient(135deg, rgba(255, 250, 240, 0.7), rgba(255, 255, 255, 0.95)); + box-shadow: var(--shadow-sm); + transition: var(--transition-spring); +} + +.suggestion:active { + transform: scale(0.98); +} + +.suggestion .icon-bubble { + width: 44px; + height: 44px; +} + +.build-toast { + position: fixed; + left: 50%; + bottom: calc(88px + env(safe-area-inset-bottom)); + z-index: 160; + width: min(360px, calc(100vw - 32px)); + transform: translateX(-50%); + padding: 12px 14px; + border: 1px solid var(--glass-border); + border-radius: 14px; + color: var(--text-primary); + background: #ffffff; + box-shadow: var(--shadow-lg); + font-size: 13px; + line-height: 1.4; + font-weight: 800; + text-align: center; +} + +.tabbar { + position: fixed; + left: 50%; + bottom: 8px; + z-index: 99; + width: calc(min(100vw, 426px) - 24px); + transform: translateX(-50%); + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 4px; + padding: 5px; + border: 1px solid var(--glass-border); + border-radius: 20px; + background: rgba(255, 255, 255, 0.88); + backdrop-filter: blur(20px); + box-shadow: 0 8px 32px rgba(18, 31, 49, 0.08); +} + +.tabbar button { + min-height: 40px; + color: var(--text-secondary); + display: grid; + justify-items: center; + align-content: center; + gap: 2px; + border-radius: 12px; + transition: var(--transition-spring-fast); +} + +.tabbar button:active { + transform: scale(0.92); +} + +.tabbar button.active { + color: var(--primary-teal-active); + background: var(--primary-teal-light); +} + +.tabbar span { + font-size: 11px; + line-height: 1; + font-weight: 700; +} + +.icon { + display: block; +} + +@media (prefers-reduced-motion: reduce) { + .mentor-avatar, + .mentor-avatar::before, + .mentor-avatar::after, + .mentor-avatar img, + .mentor-eyelid, + .mentor-thinking i, + .mentor-waves i, + .summary-card-sheet { + animation: none !important; + transition: none !important; + } + + .mentor-avatar img { + transform: none !important; + } +} + +@media (max-width: 380px) { + .page { + padding-inline: 10px; + padding-bottom: 96px; + } + + .tabbar { + width: calc(100vw - 16px); + bottom: 8px; + border-radius: 16px; + } + + .top h2 { + font-size: 26px; + } + + .task-card, + .team-card { + grid-template-columns: 1fr; + } + + .headset-art { + display: none; + } + + .mentor-hero { + padding: 11px; + border-radius: 18px; + } + + .mentor-main { + grid-template-columns: 64px minmax(0, 1fr); + } + + .mentor-avatar { + width: 58px; + height: 58px; + } + + .mentor-copy p { + font-size: 16px; + } + + .mentor-actions { + grid-template-columns: minmax(0, 1fr) 108px; + } + + .mentor-actions button { + min-height: 46px; + } + + .agenda-row { + grid-template-columns: 26px minmax(0, 1fr); + } + + .agenda-action { + grid-column: 2; + width: 84px; + } + + .map-grid { + gap: 8px; + } + + .map-grid button { + min-height: 74px; + padding: 10px 11px; + } + + .map-grid small { + font-size: 12px; + } + + .task-card > button { + position: static; + margin-top: 8px; + width: 100%; + } + + .mini-stats, + .progress-grid, + .tool-grid { + grid-template-columns: 1fr; + } +} + +@media (min-width: 640px) { + .mobile-aihr { + justify-content: center; + } +} diff --git a/mobile/src/types.ts b/mobile/src/types.ts new file mode 100644 index 00000000..be8afdc2 --- /dev/null +++ b/mobile/src/types.ts @@ -0,0 +1,447 @@ +export type RoleKey = 'user' | 'candidate' | 'supervisor'; + +export type Tone = 'teal' | 'blue' | 'orange' | 'purple' | 'amber'; + +export type UserPanelKey = '' | 'tasks' | 'practice' | 'sop' | 'cases' | 'submit' | 'profile' | 'history' | 'recommend'; + +export type SupervisorPanelKey = '' | 'team' | 'reviews' | 'assign' | 'weakness' | 'case' | 'sop' | 'profile'; + +export type FlowTarget = UserPanelKey | SupervisorPanelKey; + +export type MentorState = 'idle' | 'listening' | 'thinking' | 'speaking'; + +export type MentorMapActionKey = 'ask' | 'practice' | 'learn' | 'submit'; + +export type IconName = + | 'bars' + | 'book' + | 'book-search' + | 'briefcase' + | 'bulb' + | 'chevron-down' + | 'chevron-right' + | 'clipboard' + | 'document' + | 'folder' + | 'graduation' + | 'headset' + | 'home' + | 'map-pin' + | 'megaphone' + | 'mic' + | 'pen' + | 'presentation' + | 'target' + | 'upload' + | 'user' + | 'users' + | 'warning'; + +export interface ToolItem { + icon: IconName; + title: string; + desc: string; + tone: Tone; +} + +export interface MetricItem { + icon: IconName; + title: string; + value: string; + desc: string; + tone: Tone; + progress: number; +} + +export interface PrimaryTask { + badge: string; + title: string; + desc: string; + progressText: string; + progress: number; + cta: string; + icon: IconName; +} + +export interface ReviewTask { + title: string; + desc: string; +} + +export interface TabItem { + label: string; + icon: IconName; + active: boolean; +} + +export interface FlowStep { + phase: string; + title: string; + desc: string; + target: FlowTarget; +} + +export interface TeamStat { + icon: IconName; + title: string; + value: string; + tone: Tone; +} + +export interface TeamOverview { + title: string; + progressText: string; + progress: number; + completionLabel: string; + detailCta: string; + stats: TeamStat[]; +} + +export interface TodoItem extends ToolItem { + count: number; +} + +export interface SuggestionItem { + icon: IconName; + title: string; + desc: string; + tone: Tone; +} + +export interface RoleHome { + role: RoleKey; + roleLabel: string; + avatarTone: string; + greeting: string; + location: string; + toolTitle?: string; + recommend?: string; + primary?: PrimaryTask; + review?: ReviewTask; + tools: ToolItem[]; + metrics?: MetricItem[]; + tabs: TabItem[]; + team?: TeamOverview; + todos?: TodoItem[]; + suggestion?: SuggestionItem; +} + +export type PracticeStatus = 'idle' | 'starting' | 'active' | 'submitting' | 'finished'; + +export type InterviewStatus = PracticeStatus; + +export type PracticeRole = 'customer' | 'trainee' | 'coach'; + +export type PracticeStyleKey = 'serious' | 'gentle' | 'detailed' | 'professional'; + +export interface PracticeTurn { + role: PracticeRole; + label: string; + text: string; + roundIndex?: number; + styleNote?: string; +} + +export interface PracticeStartResponse { + sessionId: string; + customerText: string; + emotion?: number; + trust?: number; +} + +export interface PracticePrepCardResponse { + keyPoints: string[]; + redLines: string[]; + scripts: string[]; + promptVersion: string; +} + +export interface PracticeTurnResponse { + customerText: string; + coachHint: string; + message?: string; + emotion?: number; + trust?: number; + redFlag?: boolean; + roundIndex: number; + finished: boolean; +} + +export interface PracticeFinishResponse { + totalScore: number; + mentorRewrite: string; + aiComment: string; +} + +export interface PracticeRecord { + id?: number; + sessionId?: string; + time: string; + trainee: string; + scene: string; + score: number; + status: string; + summary: string; +} + +export interface PracticeScenario { + id: string; + title: string; + badge: string; + desc: string; + progressText: string; + progress: string; +} + +export interface PracticeRecentItem { + scenarioId: string; + title: string; + time: string; + score: string; + record?: PracticeRecord; +} + +export interface PracticeDialogue { + role: PracticeRole; + label: string; + text: string; + audioUrl?: string; +} + +export interface PracticeAnnotation { + turnIndex: number; + sourceText: string; + issue: string; + rewrite: string; + sopPoint: string; +} + +export interface PracticeReviewDetail extends PracticeRecord { + mentorRewrite: string; + aiComment: string; + reviewAdvice?: string; + incentivePoint?: number; + scoreItems: CompetencyDimension[]; + dialogue: PracticeDialogue[]; + annotations: PracticeAnnotation[]; +} + +export interface InterviewQuestion { + questionId: string; + seq: number; + questionText: string; + point: string; + scenario: string; + sampleAnswer: string; +} + +export interface InterviewStartResponse { + sessionId: string; + candidateId: string; + candidateName: string; + positionCode: string; + questions: InterviewQuestion[]; + source: string; +} + +export interface InterviewRecord { + time: string; + candidate: string; + position: string; + score: number; + result: string; + summary: string; +} + +export interface InterviewFinishResponse { + totalScore: number; + suggestion: string; + result: string; + aiSummary: string; + evidence: string; + dimensions: CompetencyDimension[]; + records: InterviewRecord[]; + source: string; +} + +export interface CompetencyDimension { + label: string; + value: number | string; + note: string; +} + +export interface CompetencyProfile { + score: number; + completed: number; + pendingReview: number; + trainingMinutes?: number; + contribution?: number; + assessmentScore?: number; + aiLevel?: string; + dimensions: CompetencyDimension[]; + growthPath?: Array<{ level: string; progress: number; status: string; evidence: string }>; +} + +export interface PracticeAlert { + type: string; + title: string; + desc: string; + severity: string; + extPartyId: string; +} + +export interface PracticeAssignment { + id?: number; + extPartyId: string; + traineeName: string; + scenarioId: string; + scenarioName: string; + source: string; + reason: string; + status: string; + createTime: string; + question?: string; + referenceAnswer?: string; + userAnswer?: string; + feedback?: string; + correct?: boolean; +} + +export interface DailyDrillAnswerResponse { + id: number; + status: string; + correct: boolean; + score: number; + feedback: string; + referenceAnswer: string; +} + +export interface KnowledgeDoc { + title: string; + desc: string; + hit: string; + type: string; +} + +export interface KnowledgeSnippet { + title: string; + text: string; + fragmentId?: number; +} + +export interface KnowledgeRecord { + title: string; + category: string; + version: string; + status: string; + owner: string; + summary: string; +} + +export interface KnowledgeSearchResponse { + queryText: string; + category: string; + answer: string; + reference: string; + docs: KnowledgeDoc[]; + snippets: KnowledgeSnippet[]; + training: string[]; + records: KnowledgeRecord[]; + keyPoints?: string[]; + cautions?: string[]; +} + +export type AnswerFeedbackVerdict = 'up' | 'down'; + +export interface SummaryCardStep { + label: string; + desc: string; +} + +export interface SummaryCardObjection { + concern: string; + response: string; +} + +export interface SummaryCardResponse { + title: string; + steps: SummaryCardStep[]; + objections: SummaryCardObjection[]; + scripts: string[]; + reminders: string[]; +} + +export interface CaseTag { + text: string; + type: string; +} + +export interface CaseSummaryItem { + label: string; + text: string; +} + +export interface CaseUploadResponse { + caseId: string; + fileName: string; + transcript: string; + tags: CaseTag[]; + source: string; +} + +export interface CaseOrganizeResponse { + caseId: string; + summary: CaseSummaryItem[]; + tags: CaseTag[]; + aiSummary: string; + source: string; +} + +export interface CaseRecord { + title: string; + type: string; + status: string; + time: string; + owner: string; + summary: string; +} + +export interface CaseCurateResponse { + selectedCaseIds: string[]; + records: CaseRecord[]; + sampleHint: string; +} + +export interface MaterialResult { + upload: CaseUploadResponse; + organize: CaseOrganizeResponse; + curate: CaseCurateResponse; +} + +export interface CandidateMaterialResponse { + id: number | string; + ossId: number | string; + fileName: string; + materialType: string; + fileSize: number; + status: string; + time: string; +} + +export interface MobileRoute { + role: RoleKey; + page: string; + detail: string; +} + +export interface ApiPayload { + code?: number; + msg?: string; + data?: T; +} + +export interface LoginResult { + access_token: string; + expire_in: number; + client_id: string; +} diff --git a/mobile/src/utils.ts b/mobile/src/utils.ts new file mode 100644 index 00000000..f79e75fa --- /dev/null +++ b/mobile/src/utils.ts @@ -0,0 +1,51 @@ +import type { MobileRoute, PracticeRole, RoleKey, SupervisorPanelKey, UserPanelKey } from './types'; +import { aliases, candidatePanelSegments, rolePaths, supervisorPanelSegments, userPanelSegments } from './data/navigation'; + +export const pathParts = () => window.location.pathname.split('/').filter(Boolean); + +export const readRole = (): RoleKey => { + const parts = pathParts(); + const part = parts[0] === 'h5' ? parts[1] : parts.find((item) => aliases[item]); + return aliases[part || 'user'] || 'user'; +}; + +export const readRoute = (): MobileRoute => { + const parts = pathParts(); + const offset = parts[0] === 'h5' ? 2 : 1; + return { role: readRole(), page: parts[offset] || '', detail: parts[offset + 1] || '' }; +}; + +export const clampPercent = (value: number) => `${Math.max(0, Math.min(value, 100))}%`; + +export const readStoredCredential = (key: string) => { + const value = localStorage.getItem(key)?.trim() || ''; + return value === 'undefined' || value === 'null' ? '' : value; +}; + +export const practiceAvatarSrc = (role: PracticeRole) => `${import.meta.env.BASE_URL}practice/${role === 'customer' ? 'customer' : role === 'trainee' ? 'trainee' : 'coach'}-avatar.svg`; + +export const practiceTurnDuration = (role: PracticeRole, index: number) => (role === 'coach' ? '00:15' : role === 'trainee' ? '已发送' : index > 0 ? '00:12' : '00:18'); + +export const formatPracticeScore = (score: number | string) => { + const value = Number(score); + return Number.isFinite(value) ? value.toFixed(1) : String(score || '4.0'); +}; + +export const scoreStars = (score: number | string) => { + const value = Number(score); + const filled = Number.isFinite(value) ? Math.max(0, Math.min(5, Math.round(value))) : 4; + return `${'★ '.repeat(filled)}${'☆ '.repeat(5 - filled)}`.trim(); +}; + +export const mapIconPath = (name: string) => `${import.meta.env.BASE_URL}map-icons/${name}.png`; + +export const userPanelPath = (panel: UserPanelKey) => + panel ? `${rolePaths.user}/${userPanelSegments[panel]}` : rolePaths.user; + +export const candidatePanelPath = (panel: UserPanelKey) => + panel ? `${rolePaths.candidate}/${candidatePanelSegments[panel]}` : rolePaths.candidate; + +export const supervisorPanelPath = (panel: SupervisorPanelKey) => + panel ? `${rolePaths.supervisor}/${supervisorPanelSegments[panel]}` : rolePaths.supervisor; + +export const ringStyle = (value: number) => ({ '--value': value } as Record);