-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.html
More file actions
128 lines (124 loc) · 4.56 KB
/
Copy pathindex.html
File metadata and controls
128 lines (124 loc) · 4.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<meta name="description" content="Smart finance tracker for everyday budgeting. Track income, expenses, and categories with Budget Buddy." />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="Budget Buddy" />
<meta name="theme-color" content="#2563eb" />
<!-- manifest.webmanifest is injected by vite-plugin-pwa -->
<title>Budget Buddy</title>
<script>
(function () {
var root = document.documentElement;
function applyHue(s, isDark) {
if (s.primaryHue === undefined) return;
root.style.setProperty('--primary-hue', s.primaryHue);
// Keep the live <meta name="theme-color"> in sync at first paint so the
// Android Chrome address bar doesn't flash the manifest-static blue.
var meta = document.querySelector('meta[name="theme-color"]');
if (meta) meta.setAttribute('content', 'hsl(' + s.primaryHue + ' 70% ' + (isDark ? 70 : 45) + '%)');
}
function applyTheme(s) {
var theme = s.theme || 'system';
var prefersDark = globalThis.matchMedia('(prefers-color-scheme: dark)').matches;
var isDark = theme === 'dark' || (theme === 'system' && prefersDark);
if (isDark) root.classList.add('dark');
root.style.colorScheme = isDark ? 'dark' : 'light';
applyHue(s, isDark);
if (s.fontSize !== undefined)
root.style.setProperty('--font-size-base', s.fontSize + 'px');
}
try {
var stored = localStorage.getItem('budget-buddy-theme');
if (stored) applyTheme(JSON.parse(stored).state);
} catch (e) {
// Pre-hydration theming is best-effort; the React app re-applies the
// stored theme on mount, so a parse/storage failure here is non-fatal.
console.warn('Theme bootstrap failed:', e);
}
})();
</script>
<style>
:root {
--primary-hue: 240;
color-scheme: light dark;
--background: light-dark(#ffffff, #09090b);
--foreground: light-dark(#09090b, #fafafa);
--primary: light-dark(hsl(var(--primary-hue) 70% 45%), hsl(var(--primary-hue) 70% 70%));
}
body {
background-color: var(--background);
margin: 0;
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.loader-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
height: 100dvh;
gap: 1.5rem;
animation: fade-in 0.6s ease-out;
}
.spinner {
position: relative;
width: 48px;
height: 48px;
}
.spinner:before,
.spinner:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
border: 4.5px solid transparent;
}
.spinner:before {
border-top-color: var(--primary);
animation: rotate 0.8s cubic-bezier(0.55, 0.1, 0.15, 0.9) infinite;
z-index: 10;
}
.spinner:after {
border: 4.5px solid var(--primary);
opacity: 0.15;
}
.brand-name {
font-size: 1.25rem;
font-weight: 600;
color: var(--foreground);
letter-spacing: -0.025em;
opacity: 0.9;
}
@keyframes rotate {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@keyframes fade-in {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body>
<div id="root">
<div class="loader-container">
<div class="spinner"></div>
<div class="brand-name">Budget Buddy</div>
</div>
</div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>