feat: init birds page f60bc492
Steve · 2026-04-25 07:36 6 file(s) · +462 −1
packages/client/MyEBirdData.csv (added) +51 −0
1 +
Submission ID,Common Name,Scientific Name,Taxonomic Order,Count,State/Province,County,Location ID,Location,Latitude,Longitude,Date,Time,Protocol,Duration (Min),All Obs Reported,Distance Traveled (km),Area Covered (ha),Number of Observers,Breeding Code,Observation Details,Checklist Comments,ML Catalog Numbers
2 +
S52901738,Mourning Dove,Zenaida macroura,2412,1,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
3 +
S274971512,Chimney Swift,Chaetura pelagica,3896,X,US-TN,Hamilton,L53163921,Yellow house,35.004486,-85.328152,2025-09-22,07:22 PM,eBird - Casual Observation,,0,,,1
4 +
S285949309,Common Loon,Gavia immer,6933,X,US-VA,Hampton,L55417840,Grandview,37.082234,-76.274658,2025-11-24,10:36 AM,eBird - Casual Observation,,0,,,1
5 +
S285949853,Double-crested Cormorant,Nannopterum auritum,7424,X,US-VA,Hampton,L55417840,Grandview,37.082234,-76.274658,2025-11-24,,eBird - Casual Observation,,0,,,1
6 +
S285949916,Black Vulture,Coragyps atratus,7811,X,US-VA,Hampton,L55417840,Grandview,37.082234,-76.274658,2025-11-24,,eBird - Casual Observation,,0,,,1
7 +
S269906110,Cooper's Hawk,Astur cooperii,8278,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-08-27,06:37 PM,eBird - Casual Observation,,0,,,1
8 +
S288732135,Cooper's Hawk,Astur cooperii,8278,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-12-15,,eBird - Casual Observation,,0,,,1
9 +
S307412404,Bald Eagle,Haliaeetus leucocephalus,8367,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2026-03-08,05:57 PM,eBird - Casual Observation,,0,,,1
10 +
S283025851,Barred Owl,Strix varia,9219,X,US-TN,Sevier,L54820414,302,35.724099,-83.488389,2025-11-05,01:24 PM,eBird - Casual Observation,,0,,,1
11 +
S281776897,Belted Kingfisher,Megaceryle alcyon,10306,X,US-TN,Hamilton,L54549354,Reflection,35.008206,-85.367618,2025-10-28,10:12 AM,eBird - Casual Observation,,0,,,1
12 +
S280997034,Yellow-bellied Sapsucker,Sphyrapicus varius,11126,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-10-23,06:13 PM,eBird - Casual Observation,,0,,,1
13 +
S293484611,Yellow-bellied Sapsucker,Sphyrapicus varius,11126,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2026-01-10,11:24 AM,eBird - Casual Observation,,0,,,1
14 +
S52901738,Red-headed Woodpecker,Melanerpes erythrocephalus,11145,1,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
15 +
S245506705,Red-bellied Woodpecker,Melanerpes carolinus,11199,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-06-01,11:28 AM,eBird - Casual Observation,,0,,,1
16 +
S52901738,Downy Woodpecker,Dryobates pubescens,11400,4,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
17 +
S291928629,Hairy Woodpecker,Leuconotopicus villosus,11427,X,US-TN,Hamilton,L56728377,Reflection,35.012076,-85.365562,2026-01-02,02:04 PM,eBird - Casual Observation,,0,,,1
18 +
S326724606,Pileated Woodpecker,Dryocopus pileatus,11762,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2026-04-24,06:35 PM,eBird - Casual Observation,,0,,,1
19 +
S52901738,Blue Jay,Cyanocitta cristata,21294,6,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
20 +
S245511194,American Crow,Corvus brachyrhynchos,21557,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-06-01,11:36 AM,eBird - Casual Observation,,0,,,1
21 +
S52901738,Carolina Chickadee,Poecile carolinensis,22060,8,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
22 +
S229033893,Tufted Titmouse,Baeolophus bicolor,22160,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-04-24,07:50 PM,eBird - Casual Observation,,0,,,1
23 +
S52901738,Tufted Titmouse,Baeolophus bicolor,22160,5,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
24 +
S52901738,White-breasted Nuthatch,Sitta carolinensis,26889,4,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
25 +
S286968969,Brown-headed Nuthatch,Sitta pusilla,26932,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-12-01,02:50 PM,eBird - Casual Observation,,0,,,1
26 +
S316759515,Blue-gray Gnatcatcher,Polioptila caerulea,27123,X,US-TN,Hamilton,L56726540,Reflection,35.008516,-85.365789,2026-04-04,09:35 AM,eBird - Casual Observation,,0,,,1
27 +
S274271892,Carolina Wren,Thryothorus ludovicianus,27348,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-09-19,01:48 PM,eBird - Casual Observation,,0,,,1
28 +
S52901738,Carolina Wren,Thryothorus ludovicianus,27348,2,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
29 +
S280948076,Gray Catbird,Dumetella carolinensis,28000,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-10-23,11:48 AM,eBird - Casual Observation,,0,,,1
30 +
S245511364,Brown Thrasher,Toxostoma rufum,28037,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-06-01,11:36 AM,eBird - Casual Observation,,0,,,1
31 +
S245511086,Northern Mockingbird,Mimus polyglottos,28114,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-06-01,11:36 AM,eBird - Casual Observation,,0,,,1
32 +
S245510383,Eastern Bluebird,Sialia sialis,28126,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-04-14,,eBird - Casual Observation,,0,,,1
33 +
S245510815,American Robin,Turdus migratorius,28633,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-06-01,11:35 AM,eBird - Casual Observation,,0,,,1
34 +
S291928581,Cedar Waxwing,Bombycilla cedrorum,29888,X,US-TN,Hamilton,L56728377,Reflection,35.012076,-85.365562,2026-01-02,02:04 PM,eBird - Casual Observation,,0,,,1
35 +
S52901738,House Sparrow,Passer domesticus,31534,7,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
36 +
S52901738,House Finch,Haemorhous mexicanus,32310,7,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
37 +
S277843076,American Goldfinch,Spinus tristis,32617,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-10-07,12:51 PM,eBird - Casual Observation,,0,,,1
38 +
S52901738,American Goldfinch,Spinus tristis,32617,3,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
39 +
S309087566,Chipping Sparrow,Spizella passerina,32990,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2026-03-14,11:36 AM,eBird - Casual Observation,,0,,,1
40 +
S52901738,Dark-eyed Junco,Junco hyemalis,33124,2,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
41 +
S285232936,White-throated Sparrow,Zonotrichia albicollis,33201,X,US-TN,Hamilton,L55269775,Coolidge Park,35.059942,-85.307549,2025-11-19,05:42 PM,eBird - Casual Observation,,0,,,1
42 +
S285323117,White-throated Sparrow,Zonotrichia albicollis,33201,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-11-20,11:53 AM,eBird - Casual Observation,,0,,,1
43 +
S245510630,Song Sparrow,Melospiza melodia,33277,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-06-01,11:35 AM,eBird - Casual Observation,,0,,,1
44 +
S245510210,Eastern Towhee,Pipilo erythrophthalmus,33415,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-06-01,11:34 AM,eBird - Casual Observation,,0,,,1
45 +
S250718329,Brown-headed Cowbird,Molothrus ater,33833,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-06-15,01:21 PM,eBird - Casual Observation,,0,,,1
46 +
S316736239,Palm Warbler,Setophaga palmarum,34148,X,US-TN,Hamilton,L61794176,Reflection,35.009712,-85.364895,2026-04-04,,eBird - Casual Observation,,0,,,1
47 +
S291920127,Yellow-rumped Warbler,Setophaga coronata,34159,X,US-TN,Hamilton,L56726540,Reflection,35.008516,-85.365789,2026-01-02,01:38 PM,eBird - Casual Observation,,0,,,1
48 +
S245701356,Summer Tanager,Piranga rubra,34432,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-06-01,,eBird - Casual Observation,,0,,,1
49 +
S324815983,Summer Tanager,Piranga rubra,34432,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2026-04-20,05:41 PM,eBird - Casual Observation,,0,,,1
50 +
S52901738,Northern Cardinal,Cardinalis cardinalis,34515,6,US-OH,Wayne,L633955,Rittman,40.97815,-81.78206,2019-02-17,08:00 AM,eBird - Stationary Count,240,1,,,1
51 +
S243855815,Indigo Bunting,Passerina cyanea,34607,X,US-TN,Hamilton,L43356473,Home,35.007848,-85.331243,2025-05-28,12:26 PM,eBird - Casual Observation,,0,,,1
packages/client/package.json +2 −1
11 11
		"format": "biome format --write src package.json",
12 12
		"deploy:orbiter": "orbiter deploy",
13 13
		"deploy": "bun run build && wrangler pages deploy dist",
14 -
		"publish:atproto": "bun run scripts/publish-to-atproto.ts"
14 +
		"publish:atproto": "bun run scripts/publish-to-atproto.ts",
15 +
		"parse:birds": "bun run scripts/parse-birds.ts"
15 16
	},
16 17
	"devDependencies": {
17 18
		"@astrojs/mdx": "4.3.13",
packages/client/scripts/parse-birds.ts (added) +53 −0
1 +
import { readFileSync, writeFileSync } from "fs";
2 +
import { join } from "path";
3 +
4 +
const csvPath = join(import.meta.dir, "../MyEBirdData.csv");
5 +
const outPath = join(import.meta.dir, "../src/data/birds.ts");
6 +
7 +
const csv = readFileSync(csvPath, "utf-8");
8 +
const lines = csv.trim().split("\n");
9 +
const headers = lines[0].split(",");
10 +
11 +
const idx = (name: string) => headers.indexOf(name);
12 +
13 +
const seen = new Set<string>();
14 +
const birds: { commonName: string; scientificName: string; date: string; location: string; state: string }[] = [];
15 +
16 +
for (const line of lines.slice(1)) {
17 +
	// Handle potential commas in quoted fields
18 +
	const cols: string[] = [];
19 +
	let inQuote = false;
20 +
	let cur = "";
21 +
	for (const ch of line) {
22 +
		if (ch === '"') { inQuote = !inQuote; }
23 +
		else if (ch === "," && !inQuote) { cols.push(cur); cur = ""; }
24 +
		else { cur += ch; }
25 +
	}
26 +
	cols.push(cur);
27 +
28 +
	const commonName = cols[idx("Common Name")]?.trim();
29 +
	const scientificName = cols[idx("Scientific Name")]?.trim();
30 +
	const date = cols[idx("Date")]?.trim();
31 +
	const location = cols[idx("Location")]?.trim();
32 +
	const state = cols[idx("State/Province")]?.trim();
33 +
34 +
	if (!commonName || seen.has(commonName)) continue;
35 +
	seen.add(commonName);
36 +
	birds.push({ commonName, scientificName, date, location, state });
37 +
}
38 +
39 +
birds.sort((a, b) => a.commonName.localeCompare(b.commonName));
40 +
41 +
const ts = `export type BirdEntry = {
42 +
	commonName: string;
43 +
	scientificName: string;
44 +
	date: string;
45 +
	location: string;
46 +
	state: string;
47 +
};
48 +
49 +
export const birds: BirdEntry[] = ${JSON.stringify(birds, null, "\t")};
50 +
`;
51 +
52 +
writeFileSync(outPath, ts);
53 +
console.log(`Wrote ${birds.length} species to ${outPath}`);
packages/client/src/data/birds.ts (added) +311 −0
1 +
export type BirdEntry = {
2 +
	commonName: string;
3 +
	scientificName: string;
4 +
	date: string;
5 +
	location: string;
6 +
	state: string;
7 +
};
8 +
9 +
export const birds: BirdEntry[] = [
10 +
	{
11 +
		"commonName": "American Crow",
12 +
		"scientificName": "Corvus brachyrhynchos",
13 +
		"date": "2025-06-01",
14 +
		"location": "Home",
15 +
		"state": "US-TN"
16 +
	},
17 +
	{
18 +
		"commonName": "American Goldfinch",
19 +
		"scientificName": "Spinus tristis",
20 +
		"date": "2025-10-07",
21 +
		"location": "Home",
22 +
		"state": "US-TN"
23 +
	},
24 +
	{
25 +
		"commonName": "American Robin",
26 +
		"scientificName": "Turdus migratorius",
27 +
		"date": "2025-06-01",
28 +
		"location": "Home",
29 +
		"state": "US-TN"
30 +
	},
31 +
	{
32 +
		"commonName": "Bald Eagle",
33 +
		"scientificName": "Haliaeetus leucocephalus",
34 +
		"date": "2026-03-08",
35 +
		"location": "Home",
36 +
		"state": "US-TN"
37 +
	},
38 +
	{
39 +
		"commonName": "Barred Owl",
40 +
		"scientificName": "Strix varia",
41 +
		"date": "2025-11-05",
42 +
		"location": "302",
43 +
		"state": "US-TN"
44 +
	},
45 +
	{
46 +
		"commonName": "Belted Kingfisher",
47 +
		"scientificName": "Megaceryle alcyon",
48 +
		"date": "2025-10-28",
49 +
		"location": "Reflection",
50 +
		"state": "US-TN"
51 +
	},
52 +
	{
53 +
		"commonName": "Black Vulture",
54 +
		"scientificName": "Coragyps atratus",
55 +
		"date": "2025-11-24",
56 +
		"location": "Grandview",
57 +
		"state": "US-VA"
58 +
	},
59 +
	{
60 +
		"commonName": "Blue Jay",
61 +
		"scientificName": "Cyanocitta cristata",
62 +
		"date": "2019-02-17",
63 +
		"location": "Rittman",
64 +
		"state": "US-OH"
65 +
	},
66 +
	{
67 +
		"commonName": "Blue-gray Gnatcatcher",
68 +
		"scientificName": "Polioptila caerulea",
69 +
		"date": "2026-04-04",
70 +
		"location": "Reflection",
71 +
		"state": "US-TN"
72 +
	},
73 +
	{
74 +
		"commonName": "Brown Thrasher",
75 +
		"scientificName": "Toxostoma rufum",
76 +
		"date": "2025-06-01",
77 +
		"location": "Home",
78 +
		"state": "US-TN"
79 +
	},
80 +
	{
81 +
		"commonName": "Brown-headed Cowbird",
82 +
		"scientificName": "Molothrus ater",
83 +
		"date": "2025-06-15",
84 +
		"location": "Home",
85 +
		"state": "US-TN"
86 +
	},
87 +
	{
88 +
		"commonName": "Brown-headed Nuthatch",
89 +
		"scientificName": "Sitta pusilla",
90 +
		"date": "2025-12-01",
91 +
		"location": "Home",
92 +
		"state": "US-TN"
93 +
	},
94 +
	{
95 +
		"commonName": "Carolina Chickadee",
96 +
		"scientificName": "Poecile carolinensis",
97 +
		"date": "2019-02-17",
98 +
		"location": "Rittman",
99 +
		"state": "US-OH"
100 +
	},
101 +
	{
102 +
		"commonName": "Carolina Wren",
103 +
		"scientificName": "Thryothorus ludovicianus",
104 +
		"date": "2025-09-19",
105 +
		"location": "Home",
106 +
		"state": "US-TN"
107 +
	},
108 +
	{
109 +
		"commonName": "Cedar Waxwing",
110 +
		"scientificName": "Bombycilla cedrorum",
111 +
		"date": "2026-01-02",
112 +
		"location": "Reflection",
113 +
		"state": "US-TN"
114 +
	},
115 +
	{
116 +
		"commonName": "Chimney Swift",
117 +
		"scientificName": "Chaetura pelagica",
118 +
		"date": "2025-09-22",
119 +
		"location": "Yellow house",
120 +
		"state": "US-TN"
121 +
	},
122 +
	{
123 +
		"commonName": "Chipping Sparrow",
124 +
		"scientificName": "Spizella passerina",
125 +
		"date": "2026-03-14",
126 +
		"location": "Home",
127 +
		"state": "US-TN"
128 +
	},
129 +
	{
130 +
		"commonName": "Common Loon",
131 +
		"scientificName": "Gavia immer",
132 +
		"date": "2025-11-24",
133 +
		"location": "Grandview",
134 +
		"state": "US-VA"
135 +
	},
136 +
	{
137 +
		"commonName": "Cooper's Hawk",
138 +
		"scientificName": "Astur cooperii",
139 +
		"date": "2025-08-27",
140 +
		"location": "Home",
141 +
		"state": "US-TN"
142 +
	},
143 +
	{
144 +
		"commonName": "Dark-eyed Junco",
145 +
		"scientificName": "Junco hyemalis",
146 +
		"date": "2019-02-17",
147 +
		"location": "Rittman",
148 +
		"state": "US-OH"
149 +
	},
150 +
	{
151 +
		"commonName": "Double-crested Cormorant",
152 +
		"scientificName": "Nannopterum auritum",
153 +
		"date": "2025-11-24",
154 +
		"location": "Grandview",
155 +
		"state": "US-VA"
156 +
	},
157 +
	{
158 +
		"commonName": "Downy Woodpecker",
159 +
		"scientificName": "Dryobates pubescens",
160 +
		"date": "2019-02-17",
161 +
		"location": "Rittman",
162 +
		"state": "US-OH"
163 +
	},
164 +
	{
165 +
		"commonName": "Eastern Bluebird",
166 +
		"scientificName": "Sialia sialis",
167 +
		"date": "2025-04-14",
168 +
		"location": "Home",
169 +
		"state": "US-TN"
170 +
	},
171 +
	{
172 +
		"commonName": "Eastern Towhee",
173 +
		"scientificName": "Pipilo erythrophthalmus",
174 +
		"date": "2025-06-01",
175 +
		"location": "Home",
176 +
		"state": "US-TN"
177 +
	},
178 +
	{
179 +
		"commonName": "Gray Catbird",
180 +
		"scientificName": "Dumetella carolinensis",
181 +
		"date": "2025-10-23",
182 +
		"location": "Home",
183 +
		"state": "US-TN"
184 +
	},
185 +
	{
186 +
		"commonName": "Hairy Woodpecker",
187 +
		"scientificName": "Leuconotopicus villosus",
188 +
		"date": "2026-01-02",
189 +
		"location": "Reflection",
190 +
		"state": "US-TN"
191 +
	},
192 +
	{
193 +
		"commonName": "House Finch",
194 +
		"scientificName": "Haemorhous mexicanus",
195 +
		"date": "2019-02-17",
196 +
		"location": "Rittman",
197 +
		"state": "US-OH"
198 +
	},
199 +
	{
200 +
		"commonName": "House Sparrow",
201 +
		"scientificName": "Passer domesticus",
202 +
		"date": "2019-02-17",
203 +
		"location": "Rittman",
204 +
		"state": "US-OH"
205 +
	},
206 +
	{
207 +
		"commonName": "Indigo Bunting",
208 +
		"scientificName": "Passerina cyanea",
209 +
		"date": "2025-05-28",
210 +
		"location": "Home",
211 +
		"state": "US-TN"
212 +
	},
213 +
	{
214 +
		"commonName": "Mourning Dove",
215 +
		"scientificName": "Zenaida macroura",
216 +
		"date": "2019-02-17",
217 +
		"location": "Rittman",
218 +
		"state": "US-OH"
219 +
	},
220 +
	{
221 +
		"commonName": "Northern Cardinal",
222 +
		"scientificName": "Cardinalis cardinalis",
223 +
		"date": "2019-02-17",
224 +
		"location": "Rittman",
225 +
		"state": "US-OH"
226 +
	},
227 +
	{
228 +
		"commonName": "Northern Mockingbird",
229 +
		"scientificName": "Mimus polyglottos",
230 +
		"date": "2025-06-01",
231 +
		"location": "Home",
232 +
		"state": "US-TN"
233 +
	},
234 +
	{
235 +
		"commonName": "Palm Warbler",
236 +
		"scientificName": "Setophaga palmarum",
237 +
		"date": "2026-04-04",
238 +
		"location": "Reflection",
239 +
		"state": "US-TN"
240 +
	},
241 +
	{
242 +
		"commonName": "Pileated Woodpecker",
243 +
		"scientificName": "Dryocopus pileatus",
244 +
		"date": "2026-04-24",
245 +
		"location": "Home",
246 +
		"state": "US-TN"
247 +
	},
248 +
	{
249 +
		"commonName": "Red-bellied Woodpecker",
250 +
		"scientificName": "Melanerpes carolinus",
251 +
		"date": "2025-06-01",
252 +
		"location": "Home",
253 +
		"state": "US-TN"
254 +
	},
255 +
	{
256 +
		"commonName": "Red-headed Woodpecker",
257 +
		"scientificName": "Melanerpes erythrocephalus",
258 +
		"date": "2019-02-17",
259 +
		"location": "Rittman",
260 +
		"state": "US-OH"
261 +
	},
262 +
	{
263 +
		"commonName": "Song Sparrow",
264 +
		"scientificName": "Melospiza melodia",
265 +
		"date": "2025-06-01",
266 +
		"location": "Home",
267 +
		"state": "US-TN"
268 +
	},
269 +
	{
270 +
		"commonName": "Summer Tanager",
271 +
		"scientificName": "Piranga rubra",
272 +
		"date": "2025-06-01",
273 +
		"location": "Home",
274 +
		"state": "US-TN"
275 +
	},
276 +
	{
277 +
		"commonName": "Tufted Titmouse",
278 +
		"scientificName": "Baeolophus bicolor",
279 +
		"date": "2025-04-24",
280 +
		"location": "Home",
281 +
		"state": "US-TN"
282 +
	},
283 +
	{
284 +
		"commonName": "White-breasted Nuthatch",
285 +
		"scientificName": "Sitta carolinensis",
286 +
		"date": "2019-02-17",
287 +
		"location": "Rittman",
288 +
		"state": "US-OH"
289 +
	},
290 +
	{
291 +
		"commonName": "White-throated Sparrow",
292 +
		"scientificName": "Zonotrichia albicollis",
293 +
		"date": "2025-11-19",
294 +
		"location": "Coolidge Park",
295 +
		"state": "US-TN"
296 +
	},
297 +
	{
298 +
		"commonName": "Yellow-bellied Sapsucker",
299 +
		"scientificName": "Sphyrapicus varius",
300 +
		"date": "2025-10-23",
301 +
		"location": "Home",
302 +
		"state": "US-TN"
303 +
	},
304 +
	{
305 +
		"commonName": "Yellow-rumped Warbler",
306 +
		"scientificName": "Setophaga coronata",
307 +
		"date": "2026-01-02",
308 +
		"location": "Reflection",
309 +
		"state": "US-TN"
310 +
	}
311 +
];
packages/client/src/data/constants.ts +4 −0
32 32
    path: "/cellar",
33 33
  },
34 34
  {
35 +
    title: "Birds",
36 +
    path: "/birds",
37 +
  },
38 +
  {
35 39
    title: "Feeds",
36 40
    path: "/feeds",
37 41
  },
packages/client/src/pages/birds.astro (added) +41 −0
1 +
---
2 +
import PageLayout from "@/layouts/Base.astro";
3 +
import { birds } from "@/data/birds";
4 +
5 +
const meta = {
6 +
	title: "Birds",
7 +
	description: "My life list — every species I've logged on eBird",
8 +
};
9 +
---
10 +
11 +
<PageLayout meta={meta}>
12 +
	<div class="flex min-h-screen flex-col items-start justify-start gap-6">
13 +
		<div>
14 +
			<h1 class="title">Birds</h1>
15 +
			<p class="mt-2 text-sm text-gray-400">{birds.length} species observed</p>
16 +
		</div>
17 +
		<div class="w-full">
18 +
			<table class="w-full text-sm border-collapse">
19 +
				<thead>
20 +
					<tr class="border-b border-gray-700 text-left text-gray-400">
21 +
						<th class="pb-2 pr-6 font-normal">#</th>
22 +
						<th class="pb-2 pr-6 font-normal">Common Name</th>
23 +
						<th class="pb-2 pr-6 font-normal italic">Scientific Name</th>
24 +
25 +
					</tr>
26 +
				</thead>
27 +
				<tbody>
28 +
					{birds.map((bird, i) => (
29 +
						<tr class="border-b border-gray-800 hover:bg-gray-900/40 transition-colors">
30 +
							<td class="py-2 pr-6 text-gray-500 tabular-nums">{i + 1}</td>
31 +
							<td class="py-2 pr-6 font-medium">
32 +
								<a href={`https://www.allaboutbirds.org/guide/${bird.commonName.replace(/ /g, "_")}`} target="_blank" rel="noopener noreferrer" class="hover:underline">{bird.commonName}</a>
33 +
							</td>
34 +
							<td class="py-2 pr-6 text-gray-400 italic">{bird.scientificName}</td>
35 +
						</tr>
36 +
					))}
37 +
				</tbody>
38 +
			</table>
39 +
		</div>
40 +
	</div>
41 +
</PageLayout>