- 세트 엔진(수축→이완×횟수, 중단=미기록) iOS·워치 공용, 완주만 records.json 저장 - 첫 화면 시작 버튼 + 세팅(시간·횟수·진동 패턴)/설정(테마) 시트, 아래 스와이프 통계 - 통계: 하루(시간대별)/주간/월간 꺾은선, 달력 기준↔롤링(지난 7일·30일) 전환 - Live Activity(수축/이완·n/총·카운트다운), 백그라운드 무음 오디오로 타이머·진동 유지 - 단축어 '케겔 운동 시작', 워치 앱(즉시 시작·워치 전용 진동·physical-therapy 세션·기록 폰 병합) - 하루 다님 팔레트 계승(라이트/다크/시스템), 앱 아이콘 SVG→PNG 등록 - 검증: Debug·Release·워치 빌드 그린, 시뮬 QA 10장(26·18.5·워치 46/40mm), 완주·기록 경로 확인 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UPmp29DQHY6Ahfss5SRopT
58 lines
1.9 KiB
Swift
58 lines
1.9 KiB
Swift
//
|
|
// Theme.swift
|
|
// Keging
|
|
//
|
|
// 컬러 팔레트 — 하루 다님 팔레트 계승 (CLAUDE.md §4)
|
|
//
|
|
|
|
import SwiftUI
|
|
#if canImport(UIKit)
|
|
import UIKit
|
|
#endif
|
|
|
|
extension Color {
|
|
/// "#RRGGBB" 형식의 hex 문자열로 생성
|
|
init(hex: String) {
|
|
let cleaned = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
|
|
var value: UInt64 = 0
|
|
Scanner(string: cleaned).scanHexInt64(&value)
|
|
let r = Double((value >> 16) & 0xFF) / 255
|
|
let g = Double((value >> 8) & 0xFF) / 255
|
|
let b = Double(value & 0xFF) / 255
|
|
self.init(red: r, green: g, blue: b)
|
|
}
|
|
|
|
#if os(iOS)
|
|
/// 라이트/다크 모드에 따라 달라지는 동적 색
|
|
init(light: Color, dark: Color) {
|
|
self.init(uiColor: UIColor { traits in
|
|
traits.userInterfaceStyle == .dark ? UIColor(dark) : UIColor(light)
|
|
})
|
|
}
|
|
#endif
|
|
}
|
|
|
|
enum AppTheme {
|
|
#if os(iOS)
|
|
/// Primary Green: 라이트 딥 모스 그린 / 다크 세이지 민트
|
|
static let green = Color(light: Color(hex: "#2F6B4F"), dark: Color(hex: "#7FBF9E"))
|
|
/// Accent Yellow: 라이트 머스터드 골드 / 다크 소프트 앰버
|
|
static let yellow = Color(light: Color(hex: "#D9A621"), dark: Color(hex: "#E8C558"))
|
|
/// Background: 라이트 웜 화이트 / 다크 그린 틴트 블랙
|
|
static let background = Color(light: Color(hex: "#FAFAF6"), dark: Color(hex: "#111512"))
|
|
/// 카드 등 한 단계 떠 있는 표면
|
|
static let surface = Color(light: .white, dark: Color(hex: "#1B211D"))
|
|
#else
|
|
// 워치는 상시 다크 — 다크 팔레트 고정
|
|
static let green = Color(hex: "#7FBF9E")
|
|
static let yellow = Color(hex: "#E8C558")
|
|
static let background = Color.black
|
|
static let surface = Color(hex: "#1B211D")
|
|
#endif
|
|
|
|
/// 수축 국면 표시 색 (라이트/다크 공통 톤)
|
|
static let contract = green
|
|
/// 이완 국면 표시 색
|
|
static let relax = yellow
|
|
}
|