Skip to content

Commit 6ef85da

Browse files
authored
Improve lighthouse scores (#100)
* Tweak colors for a11y * Fix summary a11y
1 parent f1caf05 commit 6ef85da

File tree

7 files changed

+211
-200
lines changed

7 files changed

+211
-200
lines changed

static/index.html

Lines changed: 160 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>Hacker Digest - Daily Hacker News email digest</title>
7+
<meta
8+
name="description"
9+
content="The top posts on Hacker News, delivered to your email inbox every day."
10+
/>
11+
<link rel="icon" href="data:," />
712
<link rel="preconnect" href="https://fonts.googleapis.com" />
813
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
914
<link
10-
href="https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,opsz,wght@0,8..60,200..900;1,8..60,200..900&display=swap"
15+
href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap"
1116
rel="stylesheet"
1217
/>
1318
<link href="/style.css" rel="stylesheet" />
@@ -30,7 +35,7 @@
3035
.form-group label {
3136
display: block;
3237
margin-bottom: 8px;
33-
font-weight: 600;
38+
font-weight: 700;
3439
}
3540

3641
.form-group input[type="email"],
@@ -39,14 +44,16 @@
3944
padding: 12px;
4045
font-size: 16px;
4146
font-family: inherit;
42-
border: 2px solid #ccc;
47+
border: 2px solid var(--dim);
4348
border-radius: 4px;
4449
box-sizing: border-box;
50+
background-color: var(--bg-alt);
51+
color: var(--fg);
4552
}
4653

4754
.form-group input[type="email"]:focus,
4855
.form-group select:focus {
49-
border-color: #ff6600;
56+
border-color: var(--primary);
5057
outline: none;
5158
}
5259

@@ -57,15 +64,20 @@
5764
}
5865

5966
.message.success {
60-
background-color: #d4edda;
61-
color: #155724;
62-
border: 1px solid #c3e6cb;
67+
background-color: color-mix(
68+
in srgb,
69+
var(--green) 15%,
70+
var(--bg)
71+
);
72+
color: var(--fg);
73+
border: 1px solid
74+
color-mix(in srgb, var(--green) 30%, var(--bg));
6375
}
6476

6577
.message.error {
66-
background-color: #f8d7da;
67-
color: #721c24;
68-
border: 1px solid #f5c6cb;
78+
background-color: color-mix(in srgb, var(--red) 15%, var(--bg));
79+
color: var(--fg);
80+
border: 1px solid color-mix(in srgb, var(--red) 30%, var(--bg));
6981
}
7082

7183
.website-field {
@@ -76,161 +88,151 @@
7688
.cf-turnstile {
7789
margin-top: 20px;
7890
}
79-
80-
@media (prefers-color-scheme: dark) {
81-
.form-group input[type="email"],
82-
.form-group select {
83-
background-color: #333;
84-
color: #fff;
85-
border-color: #555;
86-
}
87-
88-
.message.success {
89-
background-color: #1a3d1a;
90-
color: #9fdf9f;
91-
border-color: #2a5a2a;
92-
}
93-
94-
.message.error {
95-
background-color: #3d1a1a;
96-
color: #df9f9f;
97-
border-color: #5a2a2a;
98-
}
99-
}
10091
</style>
10192
</head>
10293

10394
<body>
104-
<div class="hero">
105-
<h1>Hacker Digest</h1>
106-
<p>
107-
The top posts on
108-
<a href="https://news.ycombinator.com">Hacker News</a>,
109-
delivered to your inbox every day. Fully open-source
110-
<a href="https://github.com/samshadwell/HNDigest">on GitHub</a>.
111-
No ads, no sponsors, just links.
112-
</p>
113-
</div>
114-
115-
<form class="subscribe-form" id="subscribe-form">
116-
<div class="form-group">
117-
<label for="email">Email address</label>
118-
<input
119-
type="email"
120-
id="email"
121-
name="email"
122-
required
123-
placeholder="you@example.com"
124-
/>
125-
</div>
126-
127-
<div class="form-group">
128-
<label for="strategy">Digest type</label>
129-
<select id="strategy" name="strategy" required>
130-
<option value="TOP_N#10">Top 10 stories by points</option>
131-
<option value="TOP_N#20">Top 20 stories by points</option>
132-
<option value="TOP_N#50">Top 50 stories by points</option>
133-
<option value="POINT_THRESHOLD#500">
134-
All stories with 500+ points
135-
</option>
136-
<option selected value="POINT_THRESHOLD#250">
137-
All stories with 250+ points
138-
</option>
139-
<option value="POINT_THRESHOLD#100">
140-
All stories with 100+ points
141-
</option>
142-
</select>
143-
</div>
144-
145-
<div class="website-field" aria-hidden="true">
146-
<label for="website">Website</label>
147-
<input
148-
type="text"
149-
id="website"
150-
name="website"
151-
tabindex="-1"
152-
autocomplete="off"
153-
/>
154-
</div>
155-
156-
<button type="submit" id="submit-btn">Subscribe</button>
157-
158-
<div id="message" class="message" style="display: none"></div>
159-
160-
<div
161-
class="cf-turnstile"
162-
data-sitekey="${turnstile_site_key}"
163-
data-appearance="interaction-only"
164-
id="turnstile-widget"
165-
></div>
166-
</form>
167-
168-
<details>
169-
<summary>FAQ</summary>
170-
<h3>What do these newsletters look like?</h3>
171-
<p>
172-
<a href="/example.html">Here’s an example</a> of the 250+ points
173-
newsletter for February 19, 2026.
174-
</p>
175-
176-
<h3>Which digest type should I choose?</h3>
177-
<p>
178-
The one I personally use is <q>All stories with 250+ points</q>,
179-
which is why it’s the default! If you don’t like it, you can
180-
sign up again with a different option and it will override your
181-
existing subscription.
182-
</p>
183-
184-
<h3>Why this digest instead of {some other option}?</h3>
185-
<p>
186-
No strong reason! I built this as a personal project for myself
187-
initially, mostly as a learning experience. Now that
188-
<q>learning experience</q> has been expanded to include opening
189-
it up for everyone to use. I don’t have any personal experience
190-
with other options, but some things I like about this one:
191-
</p>
192-
<ul>
193-
<li>
194-
All of the code, including deployment configuration, is
195-
open-source and available
95+
<main>
96+
<div class="hero">
97+
<h1>Hacker Digest</h1>
98+
<p>
99+
The top posts on
100+
<a href="https://news.ycombinator.com">Hacker News</a>,
101+
delivered to your email inbox every day. Fully open-source
196102
<a href="https://github.com/samshadwell/HNDigest"
197103
>on GitHub</a
198-
>
199-
so I understand exactly how the digest is generated
200-
</li>
201-
<li>No ads, no sponsors, no tracking links</li>
202-
<li>I get to control how many/few posts I get per day</li>
203-
<li>I built it myself!</li>
204-
</ul>
205-
206-
<h3>Why does this end up in my spam folder?</h3>
207-
<p>
208-
Spam filters can be varied and mysterious. One reason I’ve seen:
209-
because these emails serve links to other websites, if a linked
210-
website has a poor reputation then this email might inherit that
211-
reputation. The best way to prevent these emails from being
212-
routed to spam is to add the sender
213-
<span class="monospace">mail@hndigest.samshadwell.com</span> to
214-
your contacts list.
215-
</p>
216-
217-
<h3>How is this monetized?</h3>
218-
<p>
219-
It is not! I’m not seeking to monetize this service. So far I
220-
have covered all the costs, a grand total of $0.
221-
</p>
222-
223-
<h3>How can I provide feedback?</h3>
224-
<p>
225-
The best place is on the
226-
<a href="https://github.com/samshadwell/HNDigest/issues"
227-
>issues page</a
228-
>
229-
for the project's GitHub repository. Otherwise, you can email me
230-
at <a href="mailto:hi@samshadwell.com">hi@samshadwell.com</a>.
231-
</p>
232-
</details>
104+
>. No ads, no sponsors, just links.
105+
</p>
106+
</div>
233107

108+
<form class="subscribe-form" id="subscribe-form">
109+
<div class="form-group">
110+
<label for="email">Email address</label>
111+
<input
112+
type="email"
113+
id="email"
114+
name="email"
115+
required
116+
placeholder="you@example.com"
117+
/>
118+
</div>
119+
120+
<div class="form-group">
121+
<label for="strategy">Digest type</label>
122+
<select id="strategy" name="strategy" required>
123+
<option value="TOP_N#10">
124+
Top 10 stories by points
125+
</option>
126+
<option value="TOP_N#20">
127+
Top 20 stories by points
128+
</option>
129+
<option value="TOP_N#50">
130+
Top 50 stories by points
131+
</option>
132+
<option value="POINT_THRESHOLD#500">
133+
All stories with 500+ points
134+
</option>
135+
<option selected value="POINT_THRESHOLD#250">
136+
All stories with 250+ points
137+
</option>
138+
<option value="POINT_THRESHOLD#100">
139+
All stories with 100+ points
140+
</option>
141+
</select>
142+
</div>
143+
144+
<div class="website-field" aria-hidden="true">
145+
<label for="website">Website</label>
146+
<input
147+
type="text"
148+
id="website"
149+
name="website"
150+
tabindex="-1"
151+
autocomplete="off"
152+
/>
153+
</div>
154+
155+
<button type="submit" id="submit-btn">Subscribe</button>
156+
157+
<div id="message" class="message" style="display: none"></div>
158+
159+
<div
160+
class="cf-turnstile"
161+
data-sitekey="${turnstile_site_key}"
162+
data-appearance="interaction-only"
163+
id="turnstile-widget"
164+
></div>
165+
</form>
166+
167+
<details>
168+
<summary><h2>FAQ</h2></summary>
169+
<h3>What do these newsletters look like?</h3>
170+
<p>
171+
<a href="/example.html">Here’s an example</a> of the 250+
172+
points newsletter for February 19, 2026.
173+
</p>
174+
175+
<h3>Which digest type should I choose?</h3>
176+
<p>
177+
The one I personally use is
178+
<q>All stories with 250+ points</q>, which is why it’s the
179+
default! If you don’t like it, you can sign up again with a
180+
different option and it will override your existing
181+
subscription.
182+
</p>
183+
184+
<h3>Why this digest instead of {some other option}?</h3>
185+
<p>
186+
No strong reason! I built this as a personal project for
187+
myself initially, mostly as a learning experience. Now that
188+
<q>learning experience</q> has been expanded to include
189+
opening it up for everyone to use. I don’t have any personal
190+
experience with other options, but some things I like about
191+
this one:
192+
</p>
193+
<ul>
194+
<li>
195+
All of the code, including deployment configuration, is
196+
open-source and available
197+
<a href="https://github.com/samshadwell/HNDigest"
198+
>on GitHub</a
199+
>
200+
so I understand exactly how the digest is generated
201+
</li>
202+
<li>No ads, no sponsors, no tracking links</li>
203+
<li>I get to control how many/few posts I get per day</li>
204+
<li>I built it myself!</li>
205+
</ul>
206+
207+
<h3>Why does this end up in my spam folder?</h3>
208+
<p>
209+
Spam filters can be varied and mysterious. One reason I’ve
210+
seen: because these emails serve links to other websites, if
211+
a linked website has a poor reputation then this email might
212+
inherit that reputation. The best way to prevent these
213+
emails from being routed to spam is to add the sender
214+
<span class="monospace">mail@hndigest.samshadwell.com</span>
215+
to your contacts list.
216+
</p>
217+
218+
<h3>How is this monetized?</h3>
219+
<p>
220+
It is not! I’m not seeking to monetize this service. So far
221+
I have covered all the costs, a grand total of $0.
222+
</p>
223+
224+
<h3>How can I provide feedback?</h3>
225+
<p>
226+
The best place is on the
227+
<a href="https://github.com/samshadwell/HNDigest/issues"
228+
>issues page</a
229+
>
230+
for the project's GitHub repository. Otherwise, you can
231+
email me at
232+
<a href="mailto:hi@samshadwell.com">hi@samshadwell.com</a>.
233+
</p>
234+
</details>
235+
</main>
234236
<p class="footer">
235237
© 2025-2026, Samuel Shadwell. All rights reserved. Not affiliated
236238
with Hacker News or Y Combinator.

0 commit comments

Comments
 (0)