diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 9bf21f7..c980f76 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -10,6 +10,7 @@ import { } from 'vue' import { useRoute, useRouter } from 'vue-router' +import { SkyProvider } from '@/ui' import PhoneHomeIndicator from '@/components/PhoneHomeIndicator.vue' import PhoneControlCenter from '@/components/PhoneControlCenter.vue' import PhoneMediaCapture from '@/components/PhoneMediaCapture.vue' @@ -293,7 +294,6 @@ const activeAppId = computed(() => const WHITE_STATUS_BAR_APP_IDS = new Set([ 'calculator', 'camera', - 'darkchat', 'fliptok', 'neon-drop', 'sky-flappy', @@ -331,9 +331,7 @@ const activitySuspended = ref(false) const simPicker = ref(null) const setupRequired = computed( () => - !( - isDevelopment && setupDevelopmentSkipped.value - ) && + !(isDevelopment && setupDevelopmentSkipped.value) && (!phone.preferences.settings.setupCompleted || (isDevelopment && developmentParameters.has('setupPreview') && @@ -494,7 +492,10 @@ async function bootstrapUnlockedPhoneData(): Promise { try { await task() } catch (error) { - console.error('[sky_phone] Failed to bootstrap unlocked phone data.', error) + console.error( + '[sky_phone] Failed to bootstrap unlocked phone data.', + error, + ) } } } @@ -1476,7 +1477,6 @@ onBeforeUnmount(() => { :style="phoneDisplayStyle" :class="{ dark: phone.isDarkMode, - 'phone-app--darkchat': route.params.appId === 'darkchat', 'phone-app--light': !phone.isDarkMode, 'phone-app--messages': route.params.appId === 'messages', 'phone-app--status-light': @@ -1498,19 +1498,25 @@ onBeforeUnmount(() => { @lock="lockPhone" /> - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/assets/img/app-icons/local-pages.webp b/frontend/src/assets/img/app-icons/local-pages.webp index e69de29..91bd3b1 100644 Binary files a/frontend/src/assets/img/app-icons/local-pages.webp and b/frontend/src/assets/img/app-icons/local-pages.webp differ diff --git a/frontend/src/assets/img/weather-icons/clear.webp b/frontend/src/assets/img/weather-icons/clear.webp index e69de29..ea4240c 100644 Binary files a/frontend/src/assets/img/weather-icons/clear.webp and b/frontend/src/assets/img/weather-icons/clear.webp differ diff --git a/frontend/src/assets/main.css b/frontend/src/assets/main.css index 84d8af8..4e2c2cf 100644 --- a/frontend/src/assets/main.css +++ b/frontend/src/assets/main.css @@ -347,6 +347,10 @@ button { color-scheme: light; } +.phone-app-theme { + display: contents; +} + /* FiveM CEF blur-free glass fallback. Ultimate keeps the native effects. */ .phone-app--performance { --phone-performance-glass: rgb(28 28 31 / 96%); @@ -390,12 +394,7 @@ button { --tw-scale-x: 1 !important; --tw-scale-y: 1 !important; --tw-scale-z: 1 !important; - transform: - translate3d( - var(--tw-translate-x, 0), - var(--tw-translate-y, 0), - 0 - ) + transform: translate3d(var(--tw-translate-x, 0), var(--tw-translate-y, 0), 0) scale(1) !important; } .phone-app--performance .k-glass { @@ -403,8 +402,7 @@ button { } /* Konsta's default background utility is the solid-surface opt-in marker. Custom color utilities replace it, so semantic Glass colors stay intact. */ -.phone-app--performance - .k-glass:where([class~='bg-ios-light-glass']) { +.phone-app--performance .k-glass:where([class~='bg-ios-light-glass']) { background: var(--phone-performance-glass) !important; } .phone-app--performance @@ -1402,17 +1400,6 @@ button { } } -/* DarkChat is intentionally independent from the phone appearance setting. */ -.phone-app--darkchat, -.phone-app--darkchat .phone-app-window, -.phone-app--darkchat .phone-app-window__content { - background: #000 !important; - color-scheme: dark; -} -.phone-app--darkchat .phone-status-bar { - color: #fff !important; - --status-bar-color: #fff; -} .app-icon--darkchat { background: #050507; } @@ -2847,6 +2834,8 @@ button { padding: 0; border: 1px solid #ffffff73; box-shadow: 0 1px 4px #0009; + background: #8e8e93; + color: #000; } .app-icon-item--editing:not(.app-icon-item--dragging) .app-icon-button { animation: app-icon-wobble 0.15s ease-in-out infinite alternate; @@ -3412,8 +3401,8 @@ button { padding-top: 46px; padding-bottom: 25px; overflow: hidden; - background: #000; - color: #fff; + background: var(--sky-bg); + color: var(--sky-text); } .weather-app { @@ -3564,7 +3553,12 @@ button { infinite; } .weather-app__sun-glow { - background: radial-gradient(circle at 74% 18%, #ffe6a766 0 5%, #ffcb6c28 14%, transparent 31%); + background: radial-gradient( + circle at 74% 18%, + #ffe6a766 0 5%, + #ffcb6c28 14%, + transparent 31% + ); } .weather-app__stars { background: @@ -3721,7 +3715,7 @@ button { } .banking-navbar { - --k-safe-area-top: 46px; + --sky-navbar-safe-area-top: 46px; position: absolute; z-index: 5; top: 0; @@ -3774,6 +3768,14 @@ button { text-align: center; } +.banking-empty { + min-height: 0; + margin: 0; + padding: 24px; + border: 0; + background: transparent; +} + .banking-empty p { margin: 0 0 8px; color: rgb(208 220 248 / 58%); @@ -4124,15 +4126,63 @@ button { line-height: 1.4; } -.banking-sheet__content > button:last-child { - margin-top: 15px; -} - -.banking-sheet__content > button:last-child > span { +.banking-sheet__content > .sky-button:last-child { display: flex; align-items: center; justify-content: center; gap: 8px; + margin-top: 15px; +} + +.phone-app--light .banking-app { + --bank-green: #168b5b; + background: + radial-gradient(ellipse at 50% -8%, rgb(65 203 205 / 24%), transparent 42%), + radial-gradient(circle at 92% 18%, rgb(45 118 255 / 16%), transparent 34%), + linear-gradient(180deg, #edf9fb 0%, #f4f7fc 42%, #eef1f7 100%) !important; + color: var(--sky-text); +} + +.phone-app--light .banking-app::before { + background: + radial-gradient(circle at 8% 54%, rgb(28 170 153 / 8%), transparent 31%), + radial-gradient(circle at 78% 72%, rgb(77 75 255 / 6%), transparent 30%), + linear-gradient(180deg, rgb(255 255 255 / 38%), transparent 32%); +} + +.phone-app--light .banking-navbar { + color: var(--sky-text); +} + +.phone-app--light .banking-loading, +.phone-app--light .banking-empty, +.phone-app--light .banking-empty p, +.phone-app--light .banking-balance__label, +.phone-app--light .banking-balance__trend, +.phone-app--light .banking-action, +.phone-app--light .banking-section-title > svg, +.phone-app--light .banking-no-transactions, +.phone-app--light .banking-activity-hero span, +.phone-app--light .banking-activity-hero small, +.phone-app--light .banking-chart-legend, +.phone-app--light .banking-chart__day span, +.phone-app--light .banking-modal__close, +.phone-app--light .banking-sheet__content > p, +.phone-app--light .banking-contact-picker > span, +.phone-app--light .banking-contact-picker > p { + color: var(--sky-muted); +} + +.phone-app--light .banking-balance__label small, +.phone-app--light .banking-no-transactions, +.phone-app--light .banking-modal__close { + border-color: var(--sky-hairline); + background: rgb(255 255 255 / 52%); +} + +.phone-app--light .banking-action--primary, +.phone-app--light .banking-action--primary .banking-action__icon { + color: #ffffff; } .weather-scroll { z-index: 1; @@ -4146,7 +4196,9 @@ button { justify-content: center; margin-top: -56px; opacity: 0; - transition: opacity 160ms ease, transform 160ms ease; + transition: + opacity 160ms ease, + transform 160ms ease; pointer-events: none; } .weather-pull-refresh.is-visible { @@ -4237,9 +4289,15 @@ button { margin-top: 2px; color: #b7d9ec; } -.weather-detail-card:nth-child(1) svg { color: var(--weather-accent-gold); } -.weather-detail-card:nth-child(3) svg { color: #79d8d0; } -.weather-detail-card:nth-child(4) svg { color: var(--weather-accent-cyan); } +.weather-detail-card:nth-child(1) svg { + color: var(--weather-accent-gold); +} +.weather-detail-card:nth-child(3) svg { + color: #79d8d0; +} +.weather-detail-card:nth-child(4) svg { + color: var(--weather-accent-cyan); +} .weather-detail-card span { color: var(--weather-muted); font-size: 9px; @@ -4253,7 +4311,9 @@ button { font-weight: 680; line-height: 1.1; } -.weather-detail-card:nth-child(4) strong { color: var(--weather-accent-cyan); } +.weather-detail-card:nth-child(4) strong { + color: var(--weather-accent-cyan); +} .weather-panel { margin: 0; overflow: hidden; @@ -4270,7 +4330,10 @@ button { font-weight: 650; letter-spacing: -0.01em; } -.weather-panel h2 svg { color: var(--weather-accent-cyan); opacity: 0.8; } +.weather-panel h2 svg { + color: var(--weather-accent-cyan); + opacity: 0.8; +} .weather-hourly { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); @@ -4387,10 +4450,14 @@ button { min-height: 0; flex: 1; overflow-y: auto; - padding: 0; + padding: 0 0 + calc(var(--sky-tabbar-height) + var(--sky-safe-area-bottom) + 16px); } -.clock-navbar__empty-inner { - height: 0; +.clock-navbar.sky-navbar--no-navigation { + min-height: calc( + var(--sky-navbar-safe-area-top) + var(--sky-navbar-large-title-height) + ); + padding-top: var(--sky-navbar-safe-area-top); } .phone-call-content { min-height: 0; @@ -4564,6 +4631,9 @@ button { width: calc(100% - 32px); margin: 18px 16px 0; } +.clock-alarm-save.sky-link { + color: #ff9f0a; +} .clock-tool { margin: 0; padding: 0 16px; diff --git a/frontend/src/components/AlarmEditor.vue b/frontend/src/components/AlarmEditor.vue index 3c95e3a..0e63097 100644 --- a/frontend/src/components/AlarmEditor.vue +++ b/frontend/src/components/AlarmEditor.vue @@ -1,25 +1,21 @@ diff --git a/frontend/src/ui/SkyTabBar.test.ts b/frontend/src/ui/SkyTabBar.test.ts index 280ccee..ca12d1b 100644 --- a/frontend/src/ui/SkyTabBar.test.ts +++ b/frontend/src/ui/SkyTabBar.test.ts @@ -51,6 +51,21 @@ describe('SkyTabBar', () => { expect(html).toContain('sky-tabbar--labels') }) + it('keeps migrated component and styling hooks on their intended layers', async () => { + const html = await renderToString( + createSSRApp(SkyTabBar, { + bgClass: 'custom-background', + component: 'footer', + innerClass: 'custom-inner', + label: 'Navigation', + }), + ) + + expect(html).toMatch(/^