f8e599ccdc
The previous styles.css was a from-memory reconstruction with wrong
palette (tan paper #f4ede0 vs the live near-white #fcfcfb, red accent
vs warm-grey). HTML class names also diverged (.collage vs .gcollage,
#atlasList vs #atlasGrid, .stats-tl vs .stats-timeline). Result: the
overlay looked nothing like the live site.
Now:
- styles.css copied verbatim from the apt.ts <style> block (1449 lines)
- index.html mirrors the live body structure: header.top + main.stage
with view sections id=v0/v1/v2, nav.slider, about-modal
- apt.js updated for matching IDs/classes:
- View switching via translateX on .views container (live uses
flex: 0 0 100% per view, slides between them)
- Hover state via alpha-mask hit-testing in mousemove (.gtile is
pointer-events:none, bounding rects overlap)
- Atlas builds .bird-card elements (the live CSS class)
- atlasSort data-sort='alpha' (was 'first')
- #atlasGrid (was #atlasList)
Verified against Docker container faithfully replicating BirdNET-Pi's
runtime (Caddy + PHP-FPM as caddy user + php-fpm-socket-helper):
side-by-side screenshots with bird.onethreenine.net show identical
palette, typography, pill chrome, tile rendering. Differences are
content-only (different seeded species).
92 lines
4.0 KiB
HTML
92 lines
4.0 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
|
||
<title>your birds</title>
|
||
<meta name="description" content="A live bird collage from your window.">
|
||
<link rel="stylesheet" href="./styles.css">
|
||
</head>
|
||
<body>
|
||
|
||
<header class="top">
|
||
<div class="window-pick" id="winPick" role="tablist">
|
||
<i class="seg-pill" aria-hidden="true"></i>
|
||
<button data-h="1" type="button">1H</button>
|
||
<button data-h="12" type="button">12H</button>
|
||
<button data-h="24" type="button" aria-current="true">24H</button>
|
||
<button data-h="168" type="button">7D</button>
|
||
<button data-h="1000000" type="button">ALL</button>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="stage">
|
||
<header class="static-head">
|
||
<button type="button" class="pre" id="aboutLink">your birds</button>
|
||
<h1 id="staticTitle">Heard Recently</h1>
|
||
</header>
|
||
|
||
<div class="views" id="views">
|
||
<section class="view" id="v0" aria-label="Bird collage">
|
||
<div class="gcollage" id="collage"></div>
|
||
</section>
|
||
|
||
<section class="view" id="v1" aria-label="Stats">
|
||
<div class="stats-grid">
|
||
<div class="stats-timeline" id="statsTimeline"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="view" id="v2" aria-label="Atlas">
|
||
<div class="atlas-controls">
|
||
<div class="atlas-sort" id="atlasSort" role="tablist" aria-label="sort atlas">
|
||
<i class="seg-pill" aria-hidden="true"></i>
|
||
<button data-sort="count" type="button" aria-current="true" aria-label="most heard">
|
||
<svg viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
|
||
<path d="M2 12 V8"/><path d="M6 12 V5"/><path d="M10 12 V3"/>
|
||
</svg>
|
||
<span class="tip">most heard</span>
|
||
</button>
|
||
<button data-sort="recent" type="button" aria-label="most recent">
|
||
<svg viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="7" cy="7" r="5.2"/><path d="M7 4 V7 L9.2 8.3"/>
|
||
</svg>
|
||
<span class="tip">most recent</span>
|
||
</button>
|
||
<button data-sort="alpha" type="button" aria-label="alphabetical">
|
||
<svg viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round">
|
||
<path d="M2.4 11.5 L4 4.5 L5.6 11.5"/><path d="M2.9 9.2 H5.1"/>
|
||
<path d="M8.2 11.5 V4.5 H10.4 a1.3 1.3 0 0 1 0 2.6 H8.2"/><path d="M8.2 7.1 H10.6 a1.5 1.5 0 0 1 0 3 H8.2"/>
|
||
</svg>
|
||
<span class="tip">a → z</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="atlas-grid" id="atlasGrid"></div>
|
||
</section>
|
||
</div>
|
||
</main>
|
||
|
||
<nav class="slider" id="slider" aria-label="View">
|
||
<i class="seg-pill" aria-hidden="true"></i>
|
||
<button type="button" data-i="0" aria-current="true">collage</button>
|
||
<button type="button" data-i="1">stats</button>
|
||
<button type="button" data-i="2">atlas</button>
|
||
</nav>
|
||
|
||
<div id="about-modal" aria-hidden="true" role="dialog" aria-labelledby="aboutTitle">
|
||
<div class="modal-backdrop" data-close="1"></div>
|
||
<div class="about-card" role="document">
|
||
<button type="button" class="modal-close" data-close="1" aria-label="close">×</button>
|
||
<p class="about-eyebrow">your birds</p>
|
||
<h2 id="aboutTitle">The birds outside your window</h2>
|
||
<p class="about-body">A tiny microphone identifies every passing bird with Cornell's <a href="https://birdnet.cornell.edu/" target="_blank" rel="noopener">BirdNET</a>. Each species shows up as an illustration in the collage, sized by how often it's been heard.</p>
|
||
<button type="button" class="about-explore" data-close="1">explore the birds →</button>
|
||
<p class="built-by">built with <a href="https://github.com/Twarner491/AvianVisitors" target="_blank" rel="noopener">AvianVisitors</a></p>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="./apt.js"></script>
|
||
</body>
|
||
</html>
|