|
3 | 3 | <meta charset="utf-8"/> |
4 | 4 | <link rel="icon" type="image/x-icon" href="/static/favicon.ico"/> |
5 | 5 | <style> |
| 6 | +@font-face { |
| 7 | + font-family: 'Libre Caslon Text'; |
| 8 | + src: local('Libre Caslon Text Regular'), url(/static/LibreCaslonText-Regular.ttf) format('truetype'); |
| 9 | +} |
| 10 | + |
6 | 11 | :root { |
7 | 12 | color-scheme: light dark; |
8 | | - --bg-light: #f9f9f9; |
9 | | - --bg-dark: #121212; |
10 | | - --fg-light: #111; |
11 | | - --fg-dark: #f5f5f5; |
12 | | - --accent: #4e9af1; |
13 | 13 | --btn-bg: light-dark(#e0e0e0, #2a2a2a); |
14 | 14 | --btn-hover: light-dark(#cfcfcf, #3a3a3a); |
15 | | - --font-stack: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; |
16 | 15 | --radius: 0.5rem; |
17 | 16 | --gap: 1rem; |
18 | | - --mono-font: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; |
19 | | - |
20 | | - background-color: light-dark(var(--bg-light), var(--bg-dark)); |
21 | | - color: light-dark(var(--fg-light), var(--fg-dark)); |
| 17 | + --background-color: light-dark(#f9f9f9, #121212); |
| 18 | + --font-color: light-dark(#111111, #f5f5f5); |
| 19 | + --tile-background-color: light-dark(rgba(0, 0, 0, 0.02), rgba(255, 255, 255, 0.02)); |
22 | 20 | } |
23 | 21 |
|
24 | 22 | html, body { |
|
27 | 25 | height: 100vh; |
28 | 26 | background: var(--background-color); |
29 | 27 | color: var(--font-color); |
30 | | - font-family: var(--font-stack); |
| 28 | + font-family: "Libre Caslon Text"; |
31 | 29 | } |
32 | 30 |
|
33 | | -.page-content.hourglass { |
| 31 | +.flex-col { |
34 | 32 | display: flex; |
35 | 33 | flex-direction: column; |
36 | | - align-items: center; |
37 | | - gap: var(--gap); |
38 | | - max-width: 600px; |
39 | | - width: 100%; |
40 | | - padding: 1rem; |
41 | | - box-sizing: border-box; |
42 | | - margin: auto; |
43 | 34 | } |
44 | 35 |
|
45 | | -#hourglass-header { |
46 | | - width: 100%; |
| 36 | +.flex-row { |
47 | 37 | display: flex; |
48 | | - justify-content: flex-end; |
| 38 | + flex-direction: row; |
49 | 39 | } |
50 | 40 |
|
51 | | -#fullscreen-btn { |
52 | | - cursor: pointer; |
53 | | - font-size: 1.25rem; |
54 | | - padding: 0.25rem 0.5rem; |
55 | | - border-radius: var(--radius); |
56 | | - transition: background 0.2s; |
| 41 | +.gappy { |
| 42 | + gap: var(--gap); |
57 | 43 | } |
58 | 44 |
|
59 | | -#fullscreen-btn:hover { |
60 | | - background: rgba(128, 128, 128, 0.2); |
| 45 | +.hourglass { |
| 46 | + align-items: center; |
| 47 | + width: fit-content; |
| 48 | + padding: 1rem; |
| 49 | + box-sizing: border-box; |
| 50 | + margin: auto; |
| 51 | + height: 100vh; |
| 52 | + justify-content: center; |
61 | 53 | } |
62 | 54 |
|
63 | 55 | #hourglass-display { |
64 | 56 | width: 100%; |
65 | 57 | display: flex; |
66 | 58 | flex-direction: column; |
67 | 59 | align-items: center; |
68 | | - gap: 0.25rem; |
69 | | - background: light-dark(#ffffff, #1b1b1b); |
| 60 | + background: var(--tile-background-color); |
70 | 61 | border-radius: var(--radius); |
71 | 62 | padding: 1rem; |
72 | | - box-shadow: 0 2px 5px rgba(0,0,0,0.05); |
| 63 | + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); |
73 | 64 | box-sizing: border-box; |
74 | 65 | } |
75 | 66 |
|
76 | | -.table-row { |
77 | | - display: flex; |
78 | | - justify-content: center; |
79 | | - width: 100%; |
80 | | -} |
81 | | - |
82 | | -.table-column { |
83 | | - text-align: center; |
84 | | -} |
85 | | - |
86 | 67 | .timedisplay { |
87 | | - font-family: var(--mono-font); |
88 | | - font-size: clamp(3rem, 10vw, 6rem); |
| 68 | + font-size: 10rem; |
89 | 69 | font-weight: bold; |
90 | 70 | line-height: 1.1; |
91 | | - width: 8ch; /* Enough for 9999 */ |
| 71 | + width: 5ch; /* Enough for 9999 */ |
92 | 72 | text-align: center; |
93 | 73 | } |
94 | 74 |
|
95 | 75 | .label { |
96 | | - font-size: 1rem; |
| 76 | + font-size: 2rem; |
97 | 77 | opacity: 0.7; |
98 | 78 | margin-bottom: 0.5rem; |
99 | 79 | } |
|
107 | 87 | font-weight: 500; |
108 | 88 | transition: background 0.2s; |
109 | 89 | user-select: none; |
| 90 | + font-size: 3rem; |
110 | 91 | } |
111 | 92 |
|
112 | 93 | .btn:hover { |
|
117 | 98 | margin-top: 0.5rem; |
118 | 99 | display: flex; |
119 | 100 | align-items: center; |
120 | | - gap: 0.5rem; |
| 101 | + font-size: 2rem; |
121 | 102 | } |
122 | 103 |
|
123 | 104 | #hourglass-timerequested { |
|
130 | 111 | color: inherit; |
131 | 112 | } |
132 | 113 |
|
133 | | -/* 📱 Fullscreen stacked layout for mobile */ |
134 | | -@media (max-width: 600px) { |
135 | | - body, html { |
136 | | - overflow: hidden; |
137 | | - } |
138 | | - |
139 | | - .page-content.hourglass { |
140 | | - padding: 0; |
141 | | - height: 100vh; |
142 | | - max-width: none; |
143 | | - width: 100%; |
144 | | - justify-content: space-between; |
145 | | - } |
146 | | - |
147 | | - #hourglass-display { |
148 | | - flex-grow: 1; |
149 | | - width: 100%; |
150 | | - border-radius: 0; |
151 | | - padding: 0; |
152 | | - gap: 0; |
153 | | - } |
154 | | - |
155 | | - .table-row { |
156 | | - flex-direction: column; |
157 | | - flex: 1 1 50%; |
158 | | - justify-content: center; |
159 | | - } |
160 | | - |
161 | | - .table-row:nth-of-type(1), |
162 | | - .table-row:nth-of-type(3) { |
163 | | - height: 50vh; |
164 | | - display: flex; |
165 | | - align-items: center; |
166 | | - justify-content: center; |
167 | | - } |
168 | | - |
169 | | - .timedisplay { |
170 | | - font-size: 20vw; |
171 | | - width: 100%; |
172 | | - } |
173 | | - |
174 | | - .label { |
175 | | - font-size: 1rem; |
176 | | - text-align: center; |
177 | | - } |
178 | | - |
179 | | - .table-row:nth-of-type(5) { |
180 | | - flex-direction: row; |
181 | | - justify-content: center; |
182 | | - padding: 1rem; |
183 | | - } |
184 | | - |
185 | | - #hourglass-form { |
186 | | - flex-direction: row; |
187 | | - justify-content: center; |
188 | | - padding: 1rem; |
189 | | - } |
190 | | -} |
191 | | - |
192 | 114 | </style> |
193 | 115 | </head> |
194 | 116 | <body> |
195 | 117 | <div id="main"> |
196 | 118 | <div id="contents"> |
197 | 119 | <audio id="hourglass-beep" src="{{ static_url }}/sounds/timer-beep.mp3" preload="auto"></audio> |
198 | 120 | <audio id="hourglass-end" src="{{ static_url }}/sounds/timer-end.mp3" preload="auto"></audio> |
199 | | - <div class="page-content hourglass"> |
200 | | - <div id="hourglass-header"><div id="fullscreen-btn" title="fullscreen">⛶</div></div> |
201 | | - <div id="hourglass-display" class="table no-borders"> |
202 | | - <div class="table-row non-alternating"> |
203 | | - <div class="table-column timedisplay" id="hourglass-timeleft"></div> |
| 121 | + <div class="hourglass flex-col gappy"> |
| 122 | + <div id="hourglass-display" class="flex-col gappy"> |
| 123 | + <div class="flex-row"> |
| 124 | + <div class="timedisplay" id="hourglass-timeleft"></div> |
204 | 125 | </div> |
205 | | - <div class="table-row non-alternating label"> |
206 | | - <div class="table-column">seconds left</div> |
| 126 | + <div class="flex-row label"> |
| 127 | + <div class="flex-col">seconds left</div> |
207 | 128 | </div> |
208 | | - <div class="table-row non-alternating"> |
209 | | - <div class="table-column timedisplay" id="hourglass-timeelapsed"></div> |
| 129 | + <div class="flex-row"> |
| 130 | + <div class="timedisplay" id="hourglass-timeelapsed"></div> |
210 | 131 | </div> |
211 | | - <div class="table-row non-alternating label"> |
212 | | - <div class="table-column">seconds elapsed</div> |
| 132 | + <div class="flex-row label"> |
| 133 | + <div class="flex-col">seconds elapsed</div> |
213 | 134 | </div> |
214 | | - <div class="table-row non-alternating"> |
215 | | - <div class="table-column btn hourglass-btn" id="hg-control">Start</div> |
216 | | - <div class="table-column btn hourglass-btn" id="hg-flip">Flip</div> |
| 135 | + <div class="flex-row gappy"> |
| 136 | + <div class="btn" id="hg-control">Start</div> |
| 137 | + <div class="btn" id="hg-flip">Flip</div> |
217 | 138 | </div> |
218 | 139 | </div> |
219 | | - <form id="hourglass-form"> |
| 140 | + <form id="hourglass-form" class="gappy"> |
220 | 141 | <input inputmode="numeric" id="hourglass-timerequested">seconds |
221 | 142 | </form> |
222 | 143 | </div> |
|
269 | 190 | document.getElementById("hg-control").textContent = "Reset"; |
270 | 191 | } |
271 | 192 |
|
272 | | - function enterAppMode() { |
273 | | - if (document.fullscreenElement) { |
274 | | - document.exitFullscreen(); |
275 | | - } else { |
276 | | - const div = document.getElementsByClassName("page-content")[0]; |
277 | | - div.requestFullscreen(); |
278 | | - } |
279 | | - }; |
280 | | - |
281 | 193 | // primary action taken on click/hitting space |
282 | 194 | function primaryAction() { |
283 | 195 | if (timeLeft <= 0 || !currentTimer) { |
|
300 | 212 | document.getElementById("hourglass-timeleft").textContent = 180; |
301 | 213 | document.getElementById("hourglass-timeelapsed").textContent = 0; |
302 | 214 |
|
303 | | - document.getElementById("fullscreen-btn").onclick = function(e) { |
304 | | - e.preventDefault(); |
305 | | - enterAppMode(); |
306 | | - } |
307 | 215 | document.getElementById("hourglass-display").onclick = function(e) { |
308 | 216 | e.preventDefault(); |
309 | 217 | primaryAction(); |
|
0 commit comments