aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Hoang <tyler@tylerhoang.xyz>2026-06-03 15:51:36 -0700
committerTyler Hoang <tyler@tylerhoang.xyz>2026-06-03 15:51:36 -0700
commitd70ce65502caf70daaa9eb6b85c698554786734e (patch)
tree7ff9c0241fcae575faae11a14c339f308e80d054
parent3a40505f01a1281ca5a86408f0dc4e2a3ef2cf20 (diff)
add Keep Android Open system notice + tray countdownHEADmaster
Auto-opens on first visit (dismissable via localStorage); pulsing taskbar badge with live days-remaining stays as the persistent re-entry point. Counts down to Sept 1 2026 UTC. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
-rw-r--r--index.css108
-rwxr-xr-xindex.html31
-rw-r--r--index.js46
3 files changed, 185 insertions, 0 deletions
diff --git a/index.css b/index.css
index a38a327..ab5ea4b 100644
--- a/index.css
+++ b/index.css
@@ -99,6 +99,114 @@
.tray { display: inline-flex; align-items: center; gap: 8px; padding: 0 12px; font-size: 12px; color: oklch(25% 0.05 240); }
.clock { font-family: "Segoe UI", Tahoma; font-weight: 600; }
+ /* SYSTEM-TRAY ALERT (keep android open) */
+ .tray-alert {
+ display: inline-flex; align-items: center; gap: 6px;
+ padding: 4px 10px; border-radius: 12px; cursor: pointer;
+ background: linear-gradient(to bottom, rgba(255,255,255,0.55), rgba(255,220,180,0.35));
+ border: 1px solid rgba(220,140,60,0.45);
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.85), 0 1px 3px rgba(180,90,30,0.18);
+ transition: transform 160ms, box-shadow 160ms;
+ }
+ .tray-alert:hover { transform: translateY(-1px); box-shadow: inset 0 1px 0 rgba(255,255,255,0.85), 0 3px 8px rgba(180,90,30,0.3); }
+ .tra-led {
+ width: 8px; height: 8px; border-radius: 50%;
+ background: radial-gradient(circle at 30% 30%, oklch(96% 0.16 60), oklch(62% 0.20 45));
+ box-shadow: 0 0 6px oklch(70% 0.20 50 / 0.9);
+ animation: tra-pulse 1.8s ease-in-out infinite;
+ }
+ @keyframes tra-pulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.55; transform: scale(0.78); } }
+ .tra-label { font-size: 11px; font-weight: 600; letter-spacing: 0.4px; color: oklch(38% 0.12 50); text-transform: uppercase; }
+ .tra-count { font-family: 'IBM Plex Mono', monospace; font-size: 11px; font-weight: 600; color: oklch(30% 0.10 45); }
+
+ body[data-theme="chrome"] .tray-alert {
+ background: linear-gradient(to bottom, oklch(30% 0.04 280), oklch(20% 0.05 290)) !important;
+ border-color: oklch(60% 0.20 50) !important;
+ box-shadow: inset 0 1px 0 oklch(50% 0.10 280), 0 0 12px oklch(60% 0.20 45 / 0.4) !important;
+ }
+ body[data-theme="chrome"] .tra-label { color: oklch(85% 0.14 60) !important; }
+ body[data-theme="chrome"] .tra-count { color: oklch(92% 0.06 60) !important; }
+
+ /* SYSTEM ALERT WINDOW */
+ .win.koa-alert { z-index: 300; }
+ .koa-title {
+ background: linear-gradient(to bottom, oklch(72% 0.14 35), oklch(55% 0.18 30) 50%, oklch(42% 0.16 28)) !important;
+ color: oklch(99% 0 0) !important;
+ text-shadow: 0 1px 2px oklch(20% 0.10 30 / 0.7) !important;
+ }
+ .koa-body { padding: 14px 16px 16px !important; }
+ .koa-hero { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
+ .koa-bot {
+ width: 48px; height: 48px; flex-shrink: 0; border-radius: 14px;
+ display: flex; align-items: center; justify-content: center;
+ font-size: 28px;
+ background: linear-gradient(135deg, oklch(90% 0.14 145), oklch(65% 0.20 145));
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.8), 0 3px 10px oklch(55% 0.18 145 / 0.4);
+ animation: koa-bot-bob 3.4s ease-in-out infinite;
+ }
+ @keyframes koa-bot-bob { 50% { transform: translateY(-3px) rotate(-4deg); } }
+ .koa-eyebrow {
+ font-size: 10px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase;
+ color: oklch(48% 0.18 35); margin-bottom: 3px;
+ }
+ .koa-headline {
+ font-size: 17px; font-weight: 700; line-height: 1.2;
+ color: oklch(22% 0.06 240);
+ letter-spacing: -0.2px;
+ }
+ .koa-copy { margin: 0 0 12px; font-size: 12.5px; line-height: 1.55; color: oklch(25% 0.04 240); }
+ .koa-countdown {
+ display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px;
+ margin-bottom: 14px;
+ }
+ .koa-cd-cell {
+ display: flex; flex-direction: column; align-items: center; gap: 3px;
+ padding: 9px 4px 7px; border-radius: 10px;
+ background: linear-gradient(to bottom, rgba(255,255,255,0.6), rgba(220,232,245,0.4));
+ border: 1px solid rgba(120,160,200,0.5);
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.85), 0 1px 2px rgba(40,80,140,0.08);
+ }
+ .koa-cd-n {
+ font-family: 'IBM Plex Mono', monospace; font-size: 19px; font-weight: 600;
+ color: oklch(35% 0.14 35);
+ line-height: 1;
+ }
+ .koa-cd-l {
+ font-size: 9px; letter-spacing: 1.2px; text-transform: uppercase;
+ color: oklch(40% 0.04 240); font-weight: 600;
+ }
+ .koa-actions { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
+ .koa-dismiss {
+ background: transparent; border: 0; cursor: pointer;
+ font-size: 11px; color: oklch(40% 0.03 240); text-decoration: underline;
+ font-family: inherit;
+ }
+ .koa-dismiss:hover { color: oklch(22% 0.06 240); }
+
+ body[data-theme="chrome"] .koa-title {
+ background: linear-gradient(180deg,
+ oklch(58% 0.20 30) 0%,
+ oklch(42% 0.20 28) 45%,
+ oklch(28% 0.16 25) 52%,
+ oklch(40% 0.20 28) 60%,
+ oklch(52% 0.20 30) 100%) !important;
+ color: oklch(99% 0.02 60) !important;
+ text-shadow: 0 1px 0 oklch(18% 0.10 25 / 0.85), 0 0 6px oklch(80% 0.18 50 / 0.4) !important;
+ border-bottom: 1px solid oklch(20% 0.10 25) !important;
+ }
+ body[data-theme="chrome"] .koa-headline { color: oklch(18% 0.06 240) !important; text-shadow: 0 1px 0 rgba(255,255,255,0.5); }
+ body[data-theme="chrome"] .koa-copy { color: oklch(22% 0.03 240) !important; }
+ body[data-theme="chrome"] .koa-eyebrow { color: oklch(48% 0.20 35) !important; }
+ body[data-theme="chrome"] .koa-cd-cell {
+ background: linear-gradient(to bottom, oklch(18% 0.03 250), oklch(10% 0.03 250)) !important;
+ border: 1px solid oklch(35% 0.06 250) !important;
+ box-shadow: inset 0 1px 0 oklch(40% 0.06 250 / 0.5), 0 1px 3px rgba(0,0,0,0.4) !important;
+ }
+ body[data-theme="chrome"] .koa-cd-n { color: oklch(92% 0.16 60) !important; text-shadow: 0 0 8px oklch(70% 0.20 50 / 0.7); }
+ body[data-theme="chrome"] .koa-cd-l { color: oklch(70% 0.04 240) !important; }
+ body[data-theme="chrome"] .koa-dismiss { color: oklch(35% 0.04 240) !important; }
+ body[data-theme="chrome"] .koa-dismiss:hover { color: oklch(18% 0.06 240) !important; }
+
/* SERVER ROW */
.srv-row {
display: flex; align-items: center; gap: 10px; padding: 7px 0;
diff --git a/index.html b/index.html
index 7f90e92..59faa39 100755
--- a/index.html
+++ b/index.html
@@ -330,12 +330,43 @@
<div id="cc"></div>
<div class="sep"></div>
<div class="tray">
+ <span class="tray-alert" id="koa-tray" title="System notice โ€” keep android open" data-open="koa">
+ <span class="tra-led"></span>
+ <span class="tra-label">android</span>
+ <span class="tra-count" id="koa-tray-count">โ€”</span>
+ </span>
+ <span style="opacity:0.6">|</span>
<span class="clock" id="clock"></span>
<span style="opacity:0.6">|</span>
<span>๐Ÿ“ถ โ˜ 73ยฐF</span>
</div>
</div>
+ <!-- SYSTEM ALERT โ€” Keep Android Open -->
+ <div class="win glass koa-alert" id="w-koa" style="left: 520px; top: 180px; width: 380px; display: none;">
+ <div class="titlebar koa-title"><div class="dots"><div class="dot r no-drag" onclick="this.closest('.win').style.display='none'"></div><div class="dot y"></div><div class="dot g"></div></div>System Notice โ€” keepandroidopen.org</div>
+ <div class="body koa-body">
+ <div class="koa-hero">
+ <div class="koa-bot">๐Ÿค–</div>
+ <div>
+ <div class="koa-eyebrow">scheduled event ยท sep 2026</div>
+ <div class="koa-headline">Android sideloading goes away.</div>
+ </div>
+ </div>
+ <p class="koa-copy">Starting September 2026, Google will require every Android app to be registered with a verified developer identity โ€” including apps installed outside the Play Store. F-Droid, sideloaded APKs, custom ROMs that aren't signed through Google: all affected.</p>
+ <div class="koa-countdown" id="koa-countdown">
+ <div class="koa-cd-cell"><span class="koa-cd-n" id="koa-cd-d">โ€”</span><span class="koa-cd-l">days</span></div>
+ <div class="koa-cd-cell"><span class="koa-cd-n" id="koa-cd-h">โ€”</span><span class="koa-cd-l">hrs</span></div>
+ <div class="koa-cd-cell"><span class="koa-cd-n" id="koa-cd-m">โ€”</span><span class="koa-cd-l">min</span></div>
+ <div class="koa-cd-cell"><span class="koa-cd-n" id="koa-cd-s">โ€”</span><span class="koa-cd-l">sec</span></div>
+ </div>
+ <div class="koa-actions">
+ <a class="aqua sm" href="https://keepandroidopen.org" target="_blank" rel="noopener" style="text-decoration:none;">learn more โ†’</a>
+ <button class="koa-dismiss no-drag" id="koa-dismiss">don't show again</button>
+ </div>
+ </div>
+ </div>
+
<audio id="bgm" loop preload="none"></audio>
</div>
diff --git a/index.js b/index.js
index 06d1f61..bec056d 100644
--- a/index.js
+++ b/index.js
@@ -61,6 +61,52 @@
ic.addEventListener('click', () => openWindow(ic.dataset.open));
});
+ // Keep Android Open โ€” system notice. Sept 1, 2026 UTC is the target.
+ const KOA_TARGET = Date.UTC(2026, 8, 1, 0, 0, 0);
+ const KOA_KEY = 'tyler.koa.dismissed';
+ function koaTick() {
+ const ms = KOA_TARGET - Date.now();
+ const tray = document.getElementById('koa-tray-count');
+ if (ms <= 0) {
+ if (tray) tray.textContent = 'now';
+ ['d','h','m','s'].forEach(k => {
+ const el = document.getElementById('koa-cd-' + k);
+ if (el) el.textContent = '0';
+ });
+ return;
+ }
+ const d = Math.floor(ms / 86400000);
+ const h = Math.floor((ms % 86400000) / 3600000);
+ const m = Math.floor((ms % 3600000) / 60000);
+ const s = Math.floor((ms % 60000) / 1000);
+ if (tray) tray.textContent = d + 'd';
+ const dEl = document.getElementById('koa-cd-d'); if (dEl) dEl.textContent = d;
+ const hEl = document.getElementById('koa-cd-h'); if (hEl) hEl.textContent = String(h).padStart(2,'0');
+ const mEl = document.getElementById('koa-cd-m'); if (mEl) mEl.textContent = String(m).padStart(2,'0');
+ const sEl = document.getElementById('koa-cd-s'); if (sEl) sEl.textContent = String(s).padStart(2,'0');
+ }
+ koaTick(); setInterval(koaTick, 1000);
+
+ const koaTray = document.getElementById('koa-tray');
+ if (koaTray) koaTray.addEventListener('click', () => openWindow('koa'));
+
+ const koaDismiss = document.getElementById('koa-dismiss');
+ if (koaDismiss) koaDismiss.addEventListener('click', () => {
+ localStorage.setItem(KOA_KEY, '1');
+ document.getElementById('w-koa').style.display = 'none';
+ });
+
+ const koaWin = document.getElementById('w-koa');
+ if (koaWin) {
+ const z = window.__uiScale || 1;
+ const vw = window.innerWidth / z;
+ koaWin.style.left = Math.max(20, (vw - 380) / 2) + 'px';
+ }
+
+ if (!localStorage.getItem(KOA_KEY)) {
+ setTimeout(() => openWindow('koa'), 900);
+ }
+
const dropALine = document.getElementById('neighbors-contact-link');
if (dropALine) dropALine.addEventListener('click', e => { e.preventDefault(); openWindow('guestbook'); });