Files
AvianVisitors/avian/frontend/index.html
T
Twarner491 0105fb54f0 Menu: rename 'avianvisitors' link to 'github' + add built-by attribution
avian/api/menu.php: 4th drawer link label is now 'github' (shorter,
matches what the link actually points to).

avian/frontend/index.html: 'built by teddy' attribution sits below
the menu items (sibling of #dd-items inside #menu-dd) so it shows in
both local and forwarded modes. Drops the redundant 'built with
AvianVisitors' line that lived inside the lock screen - the github
menu item covers source-of-truth attribution.
2026-05-28 12:10:09 -07:00

204 lines
9.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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 class="av-local">
<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>
<button class="menu-btn" id="menuBtn">menu</button>
</header>
<aside id="menu-dd" aria-hidden="true">
<div id="dd-locked">
<form class="lock-row" id="unlockForm">
<input id="lockPass" type="password" placeholder="password" autocomplete="current-password">
<button type="submit" aria-label="unlock"></button>
</form>
<p class="lock-hint" id="lockHint">enter password to unlock tools.</p>
</div>
<nav class="menu-items" id="dd-items"></nav>
<p class="built-by">built by <a href="https://theodore.net" target="_blank" rel="noopener">teddy</a></p>
</aside>
<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">
<!-- ========== View 1 — Collage ========== -->
<section class="view" id="v0" aria-label="Bird collage">
<div class="gcollage" id="collage"></div>
</section>
<!-- ========== View 2 — Stats ========== -->
<section class="view" id="v1" aria-label="Stats">
<div class="stats-grid">
<div class="stats-timeline" id="statsTimeline">
<!-- Editorial detection timeline. Each column = one species
from the current time window. The black square's vertical
position encodes detection count; the species name + sci
name sit rotated below. Vertical hairlines separate
columns. Hard-rendered by renderStatsTimeline(). -->
</div>
<aside class="stats-side">
<div class="grp">
<h3>By Period</h3>
<small>detections, grouped by recency</small>
<ol id="statsByPeriod"></ol>
</div>
<div class="grp">
<h3>Top Species</h3>
<small id="statsTopSpecCap">most-heard, current window</small>
<ol id="statsTopSpec"></ol>
</div>
<div class="grp">
<h3>First Detections</h3>
<small>newest additions to the life list</small>
<ol id="statsFirstSeen"></ol>
</div>
</aside>
</div>
</section>
<!-- ========== View 3 — Atlas ========== -->
<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>
<div id="detail-modal" aria-hidden="true" role="dialog" aria-labelledby="modalCommon">
<div class="modal-backdrop" data-close="1"></div>
<article class="modal-card">
<button class="modal-close" type="button" aria-label="Close" data-close="1">×</button>
<div class="modal-grid">
<div class="modal-img">
<img id="modalImg" src="" alt="" loading="eager">
<div class="pose-toggle" id="modalPoseToggle" role="tablist" aria-label="Pose">
<i class="seg-pill" aria-hidden="true"></i>
<button type="button" data-pose="1" aria-label="perched">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round">
<path d="M3.5 6.5 C 4 4, 6 3, 8 4 C 10 3.6, 11.6 4.6, 12 6.5 L 11.5 8 C 11 9.6, 9.4 10.4, 8 10.4 C 6.4 10.4, 4.8 9.6, 4.2 8 Z"/>
<circle cx="10.6" cy="5.7" r=".4" fill="currentColor"/>
<path d="M12 6.2 L 13.6 5.8"/>
<path d="M7.5 10.4 L 7.2 12.2"/>
<path d="M8.6 10.4 L 8.9 12.2"/>
<path d="M2 12.6 H 13"/>
</svg>
<span class="tip">perched</span>
</button>
<button type="button" data-pose="2" aria-label="in flight">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round">
<path d="M1.5 8 Q 4.5 4, 7.5 7.5 Q 11 4, 14.5 8"/>
<path d="M7.5 7.5 L 8 9.5"/>
<circle cx="8.5" cy="7.2" r=".4" fill="currentColor"/>
<path d="M8.6 7 L 10 6.6"/>
</svg>
<span class="tip">in flight</span>
</button>
</div>
</div>
<div class="modal-info">
<h2 id="modalCommon"></h2>
<p class="sci" id="modalSci"></p>
<div class="modal-stats">
<div><span class="n" id="modalAllTime"></span><span class="lbl">all time</span></div>
<div id="modalWindowStat"><span class="n" id="modalWindow"></span><span class="lbl" id="modalWindowLbl">window</span></div>
<div><span class="n" id="modalFirstSeen"></span><span class="lbl">first heard</span></div>
</div>
<p class="desc placeholder" id="modalDesc">Loading description…</p>
<div class="modal-meta">
<span class="meta-item"><span class="k">genus</span><span class="v" id="modalGenus"></span></span>
<span class="meta-item"><span class="k">rarity</span><span class="v" id="modalRarity"></span></span>
</div>
</div>
</div>
<div class="modal-recordings">
<div class="rec-head">
<h3>Recordings</h3>
<span class="rec-count" id="modalRecCount"></span>
</div>
<ol id="modalRecordings">
<li class="rec-empty">Loading recordings…</li>
</ol>
</div>
<div class="modal-actions">
<a id="modalWiki" class="chip ext" target="_blank" rel="noopener">wiki</a>
<a id="modalEbird" class="chip ext" target="_blank" rel="noopener">ebird</a>
</div>
</article>
</div>
<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>
</div>
</div>
<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>
<!-- AvianVisitors: empty admin-screen stub. The live JS expects this
element to exist (openAdmin/closeAdmin call setAttribute on it).
Menu items navigate to BirdNET-Pi's stock pages instead of opening
in-app admin views, so this stays empty. -->
<section class="admin-screen" id="adminScreen" aria-hidden="true">
<div class="admin-frame">
<header class="admin-title"><h1 id="adminTitle"></h1></header>
<div class="admin-body" id="adminBody"></div>
</div>
</section>
<script src="./apt.js"></script>
</body>
</html>