Commit Graph

263 Commits

Author SHA1 Message Date
martbost 4991fe96e8 Ad reporting + featured rotates one link + clear campaign form on submit
- Ad reporting (auto-approved ads need a safety valve): new reports.js store
  (dual-mode) + ad_reports table + POST /api/report-ad; a "⚠ report" control on
  served ad slots opens a reason prompt and notifies the admin by email
  (siteConfig.adminEmail / ADMIN_EMAIL).
- Featured links now show ONE link at a time and cycle (true rotation), instead
  of listing all links at once.
- Campaign form now clears EVERY field on submit (target/creative/title/etc.).
  A leftover target URL was carrying into the next campaign — the same reason a
  video short was saved with the wrong (massifly) CTA target.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:57:12 -05:00
martbost ea1b2ea0ac Campaign budget field contextual + earnings full-history link
- Hide the free-form "Budget (credits)" field for fixed-cost campaign types
  (Featured = day-slot priced, Verified visits = flat pack) where spend is derived.
- Overview "Recent payouts" gets a "full history ->" link to the Earnings pane,
  which already lists every on-chain payout/referral/purchase with verify links
  (it just wasn't discoverable from the Overview mini-chart).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:44:00 -05:00
martbost 958bd5ac20 Live members-area updates: SSE toasts + cha-ching/pop sounds, no refresh needed
- The members area subscribes to the chain event stream (/api/feed/live) and
  reacts to anything relevant to the member: a payout received (cha-ching + toast
  + auto-refresh), a referral qualifying, a passed-up payout (missed), a settled
  purchase, a new activation in the line. No page refresh required.
- New chat message -> "pop" sound + toast + badge; ping heartbeat (20s) now
  returns chatUnread and pops on an increase.
- Sounds are synthesized via Web Audio (no asset files, CSP-safe).
- Surge badge: nudge the name down (ribbonY .779 -> .805) to center on its ribbon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:36:47 -05:00
martbost 7fbf9add37 Align downline rows into a grid (name | contact | date | action)
Each row was an independent flex line, so variable-width emails threw the date
column out of alignment across rows. Now a CSS grid with a shared template keeps
the date and Message columns lined up; long names/emails truncate; responsive
stack on narrow screens.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:28:20 -05:00
martbost 1363bd7b0b Fix: buy links wallet first; achievement milestones use live buyerCount
- Buying now ensures the wallet is LINKED to the account before the purchase
  (one signature if not linked). Without it, a wallet only connected for the
  faucet bought successfully but credits resolved against member id 0 and never
  showed until a manual link. Matches the "buying links your wallet" promise.
- Dashboard computed achievement milestones from buyerCount BEFORE reading it
  from chain (always 0), so Surge/Circuit/Nexus never unlocked even when
  qualification advanced. Moved the milestone block after the chain read.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:24:26 -05:00
martbost d275822cd4 Fix "undefined joined your line" in Overview recent-activity
The referral row read r.email but dashboard referral objects carry r.name
(username or masked email). Use r.name with an escape + fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:09:32 -05:00
martbost 204aa6a723 Rehearsal faucet: self-serve test-POL so members can actually buy
Fresh wallets hold 0 POL on the rehearsal chain, so nobody could complete a buy.
- Oracle: the mock POL/USD feed had gone ~49h stale (quoteWei reverted "Stale
  oracle" -> catalog costWei null -> packages showed "paused"). Refreshed it and
  installed a 15-min heartbeat cron so it stays fresh; quotes now return.
- New /api/my/faucet (rehearsal-only, rate-limited) tops a connected wallet up to
  10 test-POL via anvil_setBalance (no key). "Get test POL" card in the Wallet
  pane wires it. Members can now fund, buy, and see payouts move on the ledger.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 07:02:48 -05:00
martbost 85a6ac5bb0 Wallet: fix Trust Wallet chain-add + personal_sign ("invalid method parameters")
- wallet_addEthereumChain omits blockExplorerUrls when the config explorer is
  empty (rehearsal has none) — an empty-string URL made Trust Wallet reject the
  add with "invalid method parameters", blocking new users from adding the chain.
- personal_sign now hex-encodes the SIWE message (Trust Wallet requires hex;
  MetaMask took raw). Signed bytes are identical so server recovery is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 06:58:12 -05:00
martbost 7caff0eea2 Unblock testing: message-your-sponsor entries, video pause-on-blur, tour polish
- Sponsor messaging is now reachable everywhere a new referral looks: a
  "Message your sponsor" card on My line, the Overview quick action, and a
  pinned "Message your sponsor" row atop the Messages drawer (even with no
  thread yet). Chat stores the sponsor from the dashboard.
- Watch-to-earn video + Shorts now PAUSE when the tab/window loses focus and
  resume on return, so a viewer must stay on the page for the watch to count.
- Welcome tour hides its frame on completion (no white about:blank panel).
  NOTE: rmcircle.team allows framing (frame-ancestors *); the blank was just
  the post-dwell blank state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 06:34:49 -05:00
martbost 5b1a60f653 Fix profile persistence + badge ribbon alignment; 24h sessions
- BUG: /api/me never returned avatarUrl/bio/socials/lineBanner fields, so the
  Profile pane repopulated empty on reload — data WAS saved, just not surfaced.
  Now returned so avatar, bio, and social links persist visibly.
- Achievement badge: member name drops the "@" and sits on a per-badge ribbonY
  (spark .728 / surge .779 / circuit .713 / nexus .709), gold with dark outline.
- Sessions now expire in 24h (was 30d) so members re-login daily and see the
  login ad each day.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 06:13:19 -05:00
martbost a634f83a8e Shorts = portrait-only reel; Watch videos = landscape; badge name in gold
- Videos now carry client-detected pixel dimensions (videoW/videoH) captured at
  campaign create (upload or direct link). serveVideo takes an orientation filter:
  Shorts reel (/shorts) serves portrait (height>width); the Watch videos tab
  serves landscape, including legacy/unknown-dimension videos so nothing is orphaned.
- shorts.js requests the portrait feed and has a client guard that skips any
  landscape video that slips through. Create form shows the detected orientation.
- Achievement badge share image: member name now renders in gold with a dark
  outline (was low-contrast dark ink) and sits centered on the ribbon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 05:41:17 -05:00
martbost 5e3f2540f4 Sponsor chat entry: move off the bottom-right FAB into the left sidebar
The bottom-right bubble is the site's AI support chat — only one belongs there.
Sponsor/downline messaging now lives in the lower sidebar under Team → Messages
(unread badge on the link), opening the same threads drawer. Removed the FAB.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 05:33:20 -05:00
martbost ade0a13064 Sponsor Chat: two-way member<->sponsor messaging (presence, availability, mute)
Evolves the one-way broadcast into real support threads, keeping broadcast alongside.
- messages.js: kind='chat' rides sponsor_messages; sendChat/thread/threadList/
  markChatRead/chatUnread; broadcast inbox + login modal scoped to kind='broadcast'
- accounts.js: presence (last_seen), chat availability toggle, per-member mutes;
  sponsorOf() + isDownlineOf() resolvers
- server.js: /api/my/chat/{send,thread,threads,available,mute} + /api/my/ping
  heartbeat; dashboard emits chatUnread/chatAvailable/sponsor; auth = direct
  sponsor up, any downline down, or an existing thread; email only when offline
  and not mid-chat
- my.html/my.js/site.css: slide-in chat drawer (threads list + live thread,
  4s poll), presence dot, Message buttons on direct rows, Message-my-sponsor
  quick action, availability switch in Profile
- db.js: additive migrations (kind, pair index, chat_available, chat_mutes)
- chatbot.js: canned answer + AI fact for Sponsor Chat

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 05:24:23 -05:00
martbost 23136f4ba0 Ornate achievement badges (Spark/Surge/Circuit/Nexus) — kie.ai mint-teal trophies + name overlay
- Named the milestone ladder: Spark (payouts) / Surge (first buyer) / Circuit (L2) / Nexus (L3)
- Overview badges strip now shows the ornate badge art (locked = dimmed); milestone stepper renamed
- Share button composites the badge template with the member's @username on the ribbon (JPEG, same-origin canvas)
- Badge art in public/badges/ (optimized JPG ~300KB each)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 14:11:44 -05:00
martbost 3c0e94f20f Badge emblems, profile social links, and SEO/OG social previews
- Achievement badge share-image now draws a milestone emblem (⚡🎯⭐🏆) in the medal
- Profile: Facebook/X/YouTube/Instagram/TikTok/Telegram/LinkedIn/Website links, shown on the public bio page
- OG + Twitter Card tags on homepage/ledger/contract (hero banner as share image)
- Per-member OG tags server-injected into /wall/<username> so shared bio links preview with name/bio/avatar
- robots.txt + sitemap.xml; .txt/.xml MIME types

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 12:21:53 -05:00
martbost 5c99753f45 Banner kit: add crisp vector 320x50 mobile leaderboard (SVG) — full 7-size IAB set
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 10:21:27 -05:00
martbost 1912d2b251 Banner kit: add 468x60, 160x600, 120x600 (kie.ai) — 6 IAB sizes now in Promo tools
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 10:20:34 -05:00
martbost 6423d57f60 InstantAdPay banner kit (kie.ai): hero + leaderboard + rectangle in Promo tools
- 3 brand banners generated via kie.ai (mint-on-dark Web3 aesthetic), served from /banners/
- Promo tools Banners card now shows the kit with copy-image-URL

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 09:35:06 -05:00
martbost cb2542fca5 Verified visits (7th ad format): guaranteed unique human-visit packs
- Buy N verified visits flat up-front; each is a distinct member, dwell + captcha verified
- Verified visits earn sub-tab: open site (new tab), dwell, human-check, earn
- Per-viewer dedup (visit_seen unique), daily cap, completes at N; single-use tokens

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 09:21:59 -05:00
martbost f30a462ca8 Featured rotation -> day-slot booking: 10 slots/day, pick your start day, live occupancy
- Per-day occupancy shown in composer (Today 1/10, Tomorrow 2/10, …), full days unpickable
- Book a specific start day + duration; every covered day must have an open slot
- Slot cap turns dilution disclosure into a hard ceiling; featured skips frame-check (new-tab)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 09:16:24 -05:00
martbost c5dd5c685b Paid shorts: full-screen vertical video feed over the video inventory, earn per watched short
- /shorts page: no-seek full-screen player, server-clock watch, credit + swipe to next
- Reuses /api/my/videos + /api/my/videowatch (same fraud model, daily cap, self-exclusion)
- Linked from Earn credits > Watch videos

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 09:02:29 -05:00
martbost b7e9fdf656 Wall view interaction: click banner, countdown, then a viewed checkmark (per-position, persisted)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 09:00:14 -05:00
martbost 37a2b97bfd Featured rotation format: duration-priced link rotation with disclosed dilution
- New 'featured' type: headline + link + 1/2/7 day run, flat up-front price (40cr/day)
- Composer discloses dilution (N links share the rotation, yours makes N+1) before buying
- Overview featured strip shows the live rotation; expires automatically

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:58:22 -05:00
martbost b25b4c67fe Buy more views: top up any campaign's budget, reactivates spent/paused ones (+NAS extend)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:53:35 -05:00
martbost 1aab52ca90 Profile build-out (avatar + bio) + shareable bio page with QR
- Profile pane: avatar upload + bio, with a link to your public page
- Wall becomes a bio page: avatar, bio, scannable join QR, line ladder, join CTA
- qrcode npm dep; /api/qr renders SVG QR server-side (CSP-clean img)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:49:20 -05:00
martbost 9e05711f4e Achievement badges + milestone credit bonuses
- Idempotent one-time credit bonus per milestone (payouts/firstBuyer/level2/level3): 10/25/50/100 cr
- Overview badges strip (unlockable medals) with canvas share-to-image (username overlaid)
- Newly-unlocked milestones toast the bonus on next dashboard load

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:43:50 -05:00
martbost 7701a29169 Sponsor to downline messaging: lineage view, daily broadcast (email+inbox), login modal
- Downline resolver (3 levels); email visible for directs only, username+ID deeper
- Broadcast composer (rich editor) to directs or full downline, 1/day cap, sends email + on-site inbox
- Upline messages inbox in My line; unmissable sign-in modal for unread, ack marks read
- messages.js dual-mode store; sponsor_messages table; sanitizeRich reused

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:39:06 -05:00
martbost 57bba0111a NAS syndication adapter (feature-flagged off): push banner/text to Network Ad Space, reconcile delivery into unified credit pool
- nas.js: direct-MySQL writer mirroring CTB's proven payments+sponsorads path (approved:1, pid 1/2, catid 5, remaining counts DOWN)
- Create-time push for banner/text; pause/resume mirrors to NAS deactivate/topUp
- reconcileNas() 5-min loop: reads served, charges delta credits to the shared budget, stops NAS ad when budget dry
- Campaign row shows IAP + '+N net' network views (differentiated stats)
- Inert unless NAS_DB_* env is set; zero prod impact until enabled
- Also: rename Inbox sub-tab to 'Inbox Ads'

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:11:32 -05:00
martbost 860aedabf6 Video ads (watch-to-earn): duration-tiered pricing, escape-proof player, per-view charge
- New 'video' campaign type; MP4/WebM upload or direct https link + required-watch tier (10/30/60s → 3/7/12 cr per view; viewer earns 1/2/4)
- Composer: video fields, tier dropdown, live price hint
- Earn credits > Watch videos sub-tab: no-seek player, server-clock watch floor, daily cap, self-exclusion, single-use tokens
- media-src CSP for direct-link/hosted video; video skips frame-check

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 08:03:01 -05:00
martbost 49508c2a13 Banner ads: required IAB size picker (width/height stored, shown in row, maps to NAS)
Also lands dormant server-side scaffolding for video ads (type, tiers, validation) — not yet exposed in UI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 07:51:28 -05:00
martbost b3be71135d Merge solo Inbox into Earn credits as a sub-tab; unread badge on Earn menu item
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 07:41:41 -05:00
martbost 1ee0b5626e Viral welcome tour + line banner + wall, milestone stepper, rich solo editor, CTA-gated reads
- Welcome tour (3 levels x 10s) unlocks welcome credits; line banner in Profile; public /wall/<username>
- 'Your next move' redesigned as a milestone stepper
- Solo composer: BV-style rich editor (H2/H3, inline image+video, undo/redo, raw text)
- Solo read reward now requires clicking through to the advertiser, not just dwelling
- Sanitizer: inline media whitelist + script/style stripped whole

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 07:30:49 -05:00
martbost 718d7f2d0e Built-in transaction viewer: every ledger row verifiable at /tx/<hash>, explorer link when configured
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-06 05:37:29 -05:00
martbost 1c31679b6c Login ads as post-signin interstitials: Open Ad in new tab, timer here, Go to Dashboard
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 16:28:57 -05:00
martbost 2cc2855488 Rich solo composer: WYSIWYG editor, sanitized HTML bodies, media uploads, CTA labels
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 15:38:46 -05:00
martbost f6a3befe09 Onsite solo ads: inbox delivery with read rewards, composer, homepage format live
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 15:25:00 -05:00
martbost 15b036b940 Earn viewer v2: full-screen URL visits with countdown, human check, explicit return
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 07:23:30 -05:00
martbost fee86d296a Overview v3: plated stat cards, trend chips, payout bars, credit donut, view ring, delivery chart
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 06:41:01 -05:00
martbost e22021c266 Member identity, promo tools, back-office color, seeded inventory
Real people, not numbers: usernames (unique, profile pane to set them),
shown across the ledger, activity, rosters, and the sidebar chip; vanity
invite links (/join/<username>) with late chain binding intact. Promo tools
pane ships Branded Voice share posts and an email swipe personalized with
each member's link. The earn viewer excludes a member's own campaigns, so
nobody earns from their own spend. Back office gains the cyan/violet/amber
accent family over the green base. Three house campaigns seeded so every
surface shows live inventory. Assets v=20260905i.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 06:28:17 -05:00
martbost 28ed925443 View-fraud protection + real ad placement surfaces
Earning views now run on single-use server-issued tokens: the view only
counts when the full dwell elapses on the server clock; instant, forged,
replayed, and stale posts are all rejected, and the client countdown
pauses whenever the tab loses visibility or focus. New placements: login
ads on the sign-in screen (the per-day format's real home), a banner slot
in the back-office Overview, a text slot in the member sidebar, and a
member-ads banner on the homepage. Assets v=20260905g.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 06:15:27 -05:00
martbost 7331eac244 Back-office polish: Overview command center, quick actions, pane motion
Overview gains a recent-activity mini-feed (chain events + line joins) and
a quick-actions card jumping straight to buy/earn/campaigns plus one-tap
invite copy. Panes fade in (reduced-motion safe). First slice of the
back-office polish pass. Assets v=20260905f.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 06:09:37 -05:00
martbost a4c7028c0e Buy packages pane inside the member back office
Members buy directly from the dashboard: live-priced tiles in a dedicated
menu section, wallet flow with buy-time sponsor resolution, dashboard
refresh on settle. No more round-trip to the homepage. Assets v=20260905e.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 06:07:33 -05:00
martbost cdeb59ed7f Earn-and-spend credit economy + private rehearsal chain cutover
Members earn credits by attention (spec 8b): daily 5-ad set with dwell
timing and a too-fast guard, then a claimable daily batch. Earned credits
now FUND campaigns: banner/text budgets draw earned-first (free members can
advertise on welcome credits alone), purchased credits and the on-chain
burn queue only cover the remainder; earned-only campaigns pause when the
pool runs dry. New Earn credits section in the member menu with the viewer.
Explorer links degrade gracefully for the private chain (contract page
points at the audited Amoy verification). Site flipped to the anvil
rehearsal chain at rpc.instantadpay.com: unlimited test POL, no more
faucets. E2E: welcome->views->claim->earned-funded campaign->charged
serving, all green. Assets v=20260905d.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 05:59:42 -05:00
martbost d5bb74db7a Welcome credits (spec 8b earned pool v1) + official rehearsal rate card
Every account gets welcomeCredits (25, rate-card configurable) via an
idempotent lazy grant on dashboard load, so existing members receive theirs
retroactively. earned_credits table with JSON fallback; Overview stat shows
the purchased/welcome split. Chatbot facts and canned answers synced;
homepage free-membership list mentions the welcome batch. Rate card
promoted from placeholder to decided and persisted in the volume.
Spending integration for the earned pool is the next engine build.
Assets v=20260905b.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 05:48:42 -05:00
martbost 013a88b7d0 Fix: relay tx receipts through the server (CSP blocked direct RPC polls)
After a wallet sent a transaction, waitTx polled the public RPC straight
from the browser, which connect-src 'self' blocks (Firefox NetworkError,
reported by Marty on Activate; the activation itself landed on-chain).
New /api/tx/<hash> relays eth_getTransactionReceipt via the server's RPC
pool, so the browser only ever talks to us and the mainnet flip needs no
CSP changes. Assets v=20260905a.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 05:40:56 -05:00
martbost f848112e2d Member area rebuilt as a back-office shell
Fixed left sidebar (iconed menu with active accent, site links, user chip,
logout), sticky top bar with per-section title and rehearsal notice,
content region per pane. Mobile gets a hamburger off-canvas drawer that
closes on selection. Marketing nav no longer wraps the member area;
signed-out visitors get a centered auth page. All flows and pane IDs
preserved; verified on desktop and 390px. Assets v=20260904r.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 04:55:20 -05:00
martbost c10af1d1e7 Members area menu: Overview / My line / Campaigns / Earnings / Wallet
Hash-routed pane tabs replace the single scrolling page. Overview keeps the
stat cards, next-move guidance, and levels; My line holds the invite/share
kit and roster; Campaigns gains a pre-purchase gate card; Earnings gains a
pre-activation explainer; Wallet gathers account, credits, link, activate,
logout. Deep links (/my#campaigns) land on the right pane. Browser-verified
tab exclusivity, hash sync, deep links, and 390px overflow. Assets
v=20260904q.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 16:39:23 -05:00
martbost 537b11cfde Mobile overflow fixes: qual-bar marker, grid shrink guard, wrap guards
Level-3 progress marker right-aligns inside the card (was centered past the
edge). Grid/flank/story children get min-width:0 so the calculator's
tablewrap scrolls internally instead of widening the page 7px. Invite link
and pitch preview wrap anywhere; ticker gets layout+paint containment;
img max-width guard. Verified at 390px across all four pages with sticky
nav intact. Assets v=20260904p.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 16:11:35 -05:00
martbost 8ef50b183e Fix: chat panel now starts minimized and collapses
The panel's display:flex overrode the browser's default [hidden] styling,
so it rendered open from first paint and the close button was inert. Added
a global [hidden]{display:none!important} guard so the attribute always
wins. Browser-verified: loads minimized, opens, closes, toggles. Assets
v=20260904l.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 16:00:49 -05:00
martbost 547bff0d05 Fix: email-only members were locked out of the members area
refreshNavWallet assumed every signed-in session has a wallet address and
threw on null for email-only members; the catch returned null and render()
treated the member as signed out even though the session and cookie were
valid. Nav now shows the email (or member badge) when no wallet is linked.
Verified with a full browser cycle: session landing, logout, fresh code
sign-in. Assets v=20260904k.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 15:27:08 -05:00