Release 0.3.0: private-beta gate + anonymous read mode

Adds an email allowlist (toggleable per deployment) that restricts
OAuth sign-in to listed emails while keeping read paths public.
Anonymous visitors now see the full app shell in read-only mode
instead of the §14.1 landing wall. Empty allowlist = gate off, so
deployments that don't enable it behave exactly as 0.2.3.

Also fixes single-finger scroll on /philosophy and other .chrome-pane
views on iOS Safari (.app: 100vh → 100dvh).

Renames deploy/nginx/rfc.wiggleverse.org.conf →
ohm.wiggleverse.org.conf to match the deployed-domain rename
(rfc.wiggleverse.org deprovisioned 2026-05-27).

See CHANGELOG.md for full details + upgrade steps.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ben Stull
2026-05-27 20:58:58 -07:00
parent 1a9374aa52
commit 21fcbc92d4
19 changed files with 715 additions and 87 deletions
+87 -1
View File
@@ -5,7 +5,16 @@
height: 100vh; color: #888; font-size: 14px;
}
.app { height: 100vh; display: flex; flex-direction: column; }
/* `100dvh` is the dynamic viewport height — adjusts as iOS Safari's
URL bar shows/hides. Without it, `100vh` measures the URL-bar-hidden
("largest") viewport, so the app overflows what's actually visible.
Combined with `body { overflow: hidden }` in index.css, the result
on iOS is that single-finger touches get consumed by the (blocked)
page-level scroll attempt and never reach the nested .chrome-pane;
two-finger touches bypass that and one-finger works thereafter.
The 100vh line stays as a fallback for browsers older than iOS
15.4 / Chrome 108 (early 2022) that don't understand dvh. */
.app { height: 100vh; height: 100dvh; display: flex; flex-direction: column; }
.app-header {
height: 48px; flex-shrink: 0;
@@ -33,6 +42,31 @@
}
.btn-link:hover { background: rgba(255,255,255,0.25); }
.btn-signin-header {
color: #fff; text-decoration: none;
background: rgba(255,255,255,0.15);
border-radius: 6px; padding: 4px 10px;
font-size: 13px;
display: inline-flex; align-items: center; gap: 6px;
}
.btn-signin-header:hover { background: rgba(255,255,255,0.25); }
/* Beta chip — small uppercase tag sitting alongside a button label or
* link. Renders well on both dark headers and light surfaces. */
.beta-chip {
font-size: 9px; font-weight: 700;
text-transform: uppercase; letter-spacing: 0.08em;
padding: 1px 5px; border-radius: 3px;
background: #b45309; color: #fff;
line-height: 1.5;
vertical-align: middle;
}
.btn-link .beta-chip,
.btn-mode-toggle .beta-chip,
.btn-start-contribution-header .beta-chip {
margin-left: 5px;
}
.app-body { flex: 1; display: flex; overflow: hidden; }
/* --- Catalog (left pane, §7) --- */
@@ -318,6 +352,37 @@
}
.landing .secondary-link:hover { color: #1a1a1a; text-decoration: underline; }
/* --- Beta-pending page (post-OAuth-rejection) --- */
.beta-pending {
min-height: 100vh;
display: flex; align-items: center; justify-content: center;
padding: 40px 20px;
}
.beta-pending-inner {
max-width: 560px;
text-align: center;
}
.beta-pending h1 { font-size: 24px; margin: 0 0 16px; }
.beta-pending p { font-size: 15px; line-height: 1.6; color: #333; margin: 0 0 14px; }
.beta-pending-contact {
background: #fafafa; border: 1px solid #eee; border-radius: 8px;
padding: 14px 18px;
color: #444;
}
.beta-pending-actions {
margin-top: 24px;
display: flex; gap: 18px; justify-content: center; align-items: center;
}
.beta-pending-actions .btn-primary {
background: #1a1a1a; color: #fff;
border-radius: 8px; padding: 9px 18px;
font-size: 14px; font-weight: 600; text-decoration: none;
}
.beta-pending-actions .btn-primary:hover { background: #333; }
.btn-link-quiet { color: #666; text-decoration: none; font-size: 13px; }
.btn-link-quiet:hover { color: #1a1a1a; text-decoration: underline; }
/* ── §8 RFC view: three-column shape ─────────────────────────────────── */
.main-pane {
@@ -1678,6 +1743,27 @@
padding: 1px 5px; border-radius: 3px;
}
.allowlist-add {
display: flex; gap: 8px; margin-bottom: 22px; flex-wrap: wrap;
align-items: center;
}
.allowlist-add input[type="email"] {
border: 1px solid #d1d5db; border-radius: 6px;
padding: 6px 10px; font-size: 13px; min-width: 240px;
}
.allowlist-add input[type="text"] {
border: 1px solid #d1d5db; border-radius: 6px;
padding: 6px 10px; font-size: 13px; flex: 1; min-width: 200px;
}
.allowlist-add .btn-primary {
background: #1a1a1a; color: #fff;
border: none; border-radius: 6px;
padding: 6px 14px; font-size: 13px; font-weight: 600;
cursor: pointer;
}
.allowlist-add .btn-primary:hover:not(:disabled) { background: #333; }
.allowlist-add .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.user-cell { display: flex; flex-direction: column; gap: 1px; }
.user-handle { font-weight: 500; color: #111; }
.mute-toggle {