image cache on cloudflare r2
1:root {
2 --tropical-teal: #05a8aa;
3 --celadon: #b8d5b8;
4 --desert-sand: #d7b49e;
5 --spicy-paprika: #dc602e;
6 --tomato-jam: #bc412b;
7
8 --bg-primary: #faf6f3;
9 --bg-secondary: #fff;
10 --text-primary: #2d2a26;
11 --text-secondary: #6b635a;
12 --border: #e8e0d8;
13}
14
15* {
16 box-sizing: border-box;
17 margin: 0;
18 padding: 0;
19}
20
21body {
22 font-family:
23 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
24 background: var(--bg-primary);
25 color: var(--text-primary);
26 line-height: 1.5;
27}
28
29.dashboard {
30 max-width: 1200px;
31 margin: 0 auto;
32 padding: 24px;
33}
34
35header {
36 display: flex;
37 justify-content: space-between;
38 align-items: center;
39 margin-bottom: 32px;
40 padding-bottom: 16px;
41 border-bottom: 2px solid var(--desert-sand);
42}
43
44header h1 {
45 font-size: 1.75rem;
46 font-weight: 600;
47 color: var(--tomato-jam);
48}
49
50.time-selector {
51 display: flex;
52 gap: 8px;
53}
54
55.time-selector button {
56 padding: 8px 16px;
57 border: 1px solid var(--border);
58 background: var(--bg-secondary);
59 border-radius: 6px;
60 cursor: pointer;
61 font-size: 0.875rem;
62 color: var(--text-secondary);
63 transition: all 0.15s ease;
64}
65
66.time-selector button:hover {
67 border-color: var(--spicy-paprika);
68 color: var(--spicy-paprika);
69}
70
71.time-selector button.active {
72 background: var(--spicy-paprika);
73 border-color: var(--spicy-paprika);
74 color: white;
75}
76
77.stats-grid {
78 display: grid;
79 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
80 gap: 16px;
81 margin-bottom: 32px;
82}
83
84.stat-card {
85 background: var(--bg-secondary);
86 border-radius: 12px;
87 padding: 20px;
88 border: 1px solid var(--border);
89}
90
91.stat-card .label {
92 font-size: 0.875rem;
93 color: var(--text-secondary);
94 margin-bottom: 4px;
95}
96
97.stat-card .value {
98 font-size: 2rem;
99 font-weight: 600;
100 color: var(--spicy-paprika);
101}
102
103.chart-container {
104 background: var(--bg-secondary);
105 border-radius: 12px;
106 padding: 24px;
107 margin-bottom: 24px;
108 border: 1px solid var(--border);
109}
110
111.chart-container h2 {
112 font-size: 1rem;
113 font-weight: 600;
114 margin-bottom: 16px;
115 color: var(--text-primary);
116}
117
118.chart-outer {
119 position: relative;
120 height: 300px;
121}
122
123.chart-wrapper {
124 height: 100%;
125}
126
127.chart-loading {
128 position: absolute;
129 inset: 0;
130 display: flex;
131 align-items: center;
132 justify-content: center;
133 background: rgba(250, 246, 243, 0.5);
134 backdrop-filter: blur(1px);
135 font-size: 0.75rem;
136 color: var(--text-secondary);
137 opacity: 0;
138 pointer-events: none;
139 transition: opacity 0.15s ease-out;
140 z-index: 10;
141}
142
143.chart-loading.visible {
144 opacity: 1;
145}
146
147.chart-hint {
148 font-size: 0.75rem;
149 color: var(--text-secondary);
150 margin-top: 8px;
151}
152
153.top-images {
154 background: var(--bg-secondary);
155 border-radius: 12px;
156 padding: 24px;
157 border: 1px solid var(--border);
158}
159
160.top-images h2 {
161 font-size: 1rem;
162 font-weight: 600;
163 margin-bottom: 16px;
164 color: var(--text-primary);
165}
166
167.image-list {
168 display: flex;
169 flex-direction: column;
170 gap: 8px;
171}
172
173.image-row {
174 display: flex;
175 align-items: center;
176 gap: 12px;
177 padding: 12px;
178 border-radius: 8px;
179 background: var(--bg-primary);
180 cursor: pointer;
181 transition: background 0.15s ease;
182}
183
184.image-row:hover {
185 background: var(--desert-sand);
186}
187
188.image-rank {
189 width: 28px;
190 height: 28px;
191 border-radius: 50%;
192 background: var(--celadon);
193 display: flex;
194 align-items: center;
195 justify-content: center;
196 font-size: 0.75rem;
197 font-weight: 600;
198 color: var(--text-primary);
199 flex-shrink: 0;
200}
201
202.image-row:nth-child(1) .image-rank {
203 background: var(--spicy-paprika);
204 color: white;
205}
206
207.image-row:nth-child(2) .image-rank {
208 background: var(--tomato-jam);
209 color: white;
210}
211
212.image-row:nth-child(3) .image-rank {
213 background: var(--tropical-teal);
214 color: white;
215}
216
217.image-key {
218 flex: 1;
219 font-family: ui-monospace, monospace;
220 font-size: 0.875rem;
221 color: var(--text-primary);
222 overflow: hidden;
223 text-overflow: ellipsis;
224}
225
226.image-hits {
227 font-weight: 600;
228 color: var(--spicy-paprika);
229 font-size: 0.875rem;
230}
231
232.loading {
233 display: flex;
234 align-items: center;
235 justify-content: center;
236 height: 200px;
237 color: var(--text-secondary);
238}
239
240.u-over {
241 cursor: crosshair;
242}
243
244footer {
245 margin-top: 48px;
246 padding-top: 24px;
247 border-top: 1px solid var(--border);
248 text-align: center;
249 font-size: 0.875rem;
250 color: var(--text-secondary);
251}
252
253footer a {
254 color: var(--text-secondary);
255 text-decoration: none;
256 transition: color 0.15s ease;
257}
258
259footer a:hover {
260 color: var(--spicy-paprika);
261}
262
263footer .heart {
264 color: var(--spicy-paprika);
265}
266
267footer .repo-link {
268 display: block;
269 margin-top: 8px;
270 font-size: 0.75rem;
271}