From b299caf43388e0cd303a9c68374345e65c0eebe2 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Wed, 25 Feb 2026 15:47:58 -0800 Subject: [PATCH] refactor: standardize module component UI across all rApps Consistent nav headers, button styles, and layout patterns across calendar, cart, choices, data, forum, funds, inbox, maps, network, notes, providers, trips, vote, and work modules. Co-Authored-By: Claude Opus 4.6 --- modules/cal/components/folk-calendar-view.ts | 20 ++--- modules/cart/components/folk-cart-shop.ts | 8 +- .../components/folk-choices-dashboard.ts | 8 +- .../data/components/folk-analytics-view.ts | 21 ++--- .../forum/components/folk-forum-dashboard.ts | 34 ++++---- modules/funds/components/folk-funds-app.ts | 32 +++---- modules/funds/components/funds.css | 43 ---------- modules/inbox/components/folk-inbox-client.ts | 10 +-- modules/maps/components/folk-map-viewer.ts | 30 +++---- .../network/components/folk-graph-viewer.ts | 8 +- modules/notes/components/folk-notes-app.ts | 38 ++++----- .../components/folk-provider-directory.ts | 8 +- .../trips/components/folk-route-planner.ts | 12 +-- .../trips/components/folk-trips-planner.ts | 23 ++--- .../vote/components/folk-vote-dashboard.ts | 28 +++---- modules/work/components/folk-work-board.ts | 26 +++--- website/public/shell.css | 83 +++++++++++++++++++ 17 files changed, 229 insertions(+), 203 deletions(-) diff --git a/modules/cal/components/folk-calendar-view.ts b/modules/cal/components/folk-calendar-view.ts index 133dd50..5886d3d 100644 --- a/modules/cal/components/folk-calendar-view.ts +++ b/modules/cal/components/folk-calendar-view.ts @@ -79,13 +79,13 @@ class FolkCalendarView extends HTMLElement { :host { display: block; font-family: system-ui, -apple-system, sans-serif; color: #e0e0e0; } * { box-sizing: border-box; } - .header { display: flex; gap: 8px; margin-bottom: 16px; align-items: center; } - .nav-btn { padding: 6px 12px; border-radius: 6px; border: 1px solid #444; background: #1e1e2e; color: #ccc; cursor: pointer; font-size: 16px; } - .nav-btn:hover { border-color: #666; } - .header-title { font-size: 18px; font-weight: 600; flex: 1; text-align: center; } - .toggle-btn { padding: 6px 12px; border-radius: 6px; border: 1px solid #444; background: #1e1e2e; color: #ccc; cursor: pointer; font-size: 12px; } + .rapp-nav { display: flex; gap: 8px; margin-bottom: 16px; align-items: center; min-height: 36px; } + .rapp-nav__back { padding: 4px 10px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.1); background: transparent; color: #94a3b8; cursor: pointer; font-size: 16px; } + .rapp-nav__back:hover { color: #e2e8f0; border-color: rgba(255,255,255,0.2); } + .rapp-nav__title { font-size: 15px; font-weight: 600; flex: 1; text-align: center; color: #e2e8f0; } + .toggle-btn { padding: 4px 10px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.1); background: transparent; color: #94a3b8; cursor: pointer; font-size: 12px; } .toggle-btn.active { border-color: #6366f1; color: #6366f1; } - .create-btn { padding: 6px 14px; border-radius: 6px; border: none; background: #6366f1; color: #fff; font-weight: 600; cursor: pointer; font-size: 12px; } + .rapp-nav__btn { padding: 6px 14px; border-radius: 6px; border: none; background: #4f46e5; color: #fff; font-weight: 600; cursor: pointer; font-size: 12px; } .weekdays { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; margin-bottom: 4px; } .weekday { text-align: center; font-size: 11px; color: #666; padding: 4px; font-weight: 600; } @@ -119,11 +119,11 @@ class FolkCalendarView extends HTMLElement { ${this.error ? `
${this.esc(this.error)}
` : ""} -
- - ${monthName} ${year} +
+ + ${monthName} ${year} - +
${this.sources.length > 0 ? `
diff --git a/modules/cart/components/folk-cart-shop.ts b/modules/cart/components/folk-cart-shop.ts index f5b6b2a..c38abc6 100644 --- a/modules/cart/components/folk-cart-shop.ts +++ b/modules/cart/components/folk-cart-shop.ts @@ -49,8 +49,8 @@ class FolkCartShop extends HTMLElement { this.shadow.innerHTML = ` -
-

\u{1F6D2} Community Shop

+
+ Shop
diff --git a/modules/choices/components/folk-choices-dashboard.ts b/modules/choices/components/folk-choices-dashboard.ts index d5af20b..911e6ce 100644 --- a/modules/choices/components/folk-choices-dashboard.ts +++ b/modules/choices/components/folk-choices-dashboard.ts @@ -55,8 +55,8 @@ class FolkChoicesDashboard extends HTMLElement { this.shadow.innerHTML = ` -
-

\u2611 Choices

+
+ Choices diff --git a/modules/data/components/folk-analytics-view.ts b/modules/data/components/folk-analytics-view.ts index e723d43..799ec2a 100644 --- a/modules/data/components/folk-analytics-view.ts +++ b/modules/data/components/folk-analytics-view.ts @@ -37,9 +37,7 @@ class FolkAnalyticsView extends HTMLElement {
-
-

Privacy-First Analytics

-

Zero-knowledge, cookieless, self-hosted analytics for the r* ecosystem. Know how your tools are used without compromising anyone's privacy.

-
+

Zero-knowledge, cookieless, self-hosted analytics for the r* ecosystem. Know how your tools are used without compromising anyone's privacy.

@@ -108,14 +103,14 @@ class FolkAnalyticsView extends HTMLElement {
-
Tracking the r* Ecosystem
+
Tracked Apps
${(stats.apps || []).map((a: string) => `${a}`).join("")}
`; diff --git a/modules/forum/components/folk-forum-dashboard.ts b/modules/forum/components/folk-forum-dashboard.ts index 08b4986..4694cb5 100644 --- a/modules/forum/components/folk-forum-dashboard.ts +++ b/modules/forum/components/folk-forum-dashboard.ts @@ -164,15 +164,19 @@ class FolkForumDashboard extends HTMLElement { @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } - .toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } + .rapp-nav { display: flex; gap: 8px; margin-bottom: 16px; align-items: center; min-height: 36px; } + .rapp-nav__back { padding: 4px 10px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.1); background: transparent; color: #94a3b8; cursor: pointer; font-size: 13px; } + .rapp-nav__back:hover { color: #e2e8f0; border-color: rgba(255,255,255,0.2); } + .rapp-nav__title { font-size: 15px; font-weight: 600; flex: 1; color: #e2e8f0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } + .rapp-nav__btn { padding: 6px 14px; border-radius: 6px; border: none; background: #4f46e5; color: #fff; font-weight: 600; cursor: pointer; font-size: 13px; } + .rapp-nav__btn:hover { background: #6366f1; } button { - padding: 6px 14px; border-radius: 4px; border: 1px solid #555; - background: #2a4a7a; color: #e0e0e0; cursor: pointer; font-size: 13px; + padding: 6px 14px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.1); + background: transparent; color: #94a3b8; cursor: pointer; font-size: 13px; } - button:hover { background: #3a5a9a; } - button.danger { background: #7a2a2a; } - button.danger:hover { background: #9a3a3a; } - button.secondary { background: #333; } + button:hover { color: #e2e8f0; border-color: rgba(255,255,255,0.2); } + button.danger { background: rgba(239,68,68,0.15); border-color: rgba(239,68,68,0.3); color: #ef4444; } + button.danger:hover { background: rgba(239,68,68,0.25); } input, select { background: #2a2a3e; border: 1px solid #444; color: #e0e0e0; @@ -229,9 +233,9 @@ class FolkForumDashboard extends HTMLElement { private renderList(): string { return ` -
-

\uD83D\uDCAC Forum Instances

- +
+ Forum Instances +
${this.loading ? '
Loading...
' : ""} @@ -259,8 +263,9 @@ class FolkForumDashboard extends HTMLElement { if (!inst) return ""; return ` -
- +
+ + ${this.esc(inst.name)} ${inst.status !== "destroyed" ? `` : ""}
@@ -303,8 +308,9 @@ class FolkForumDashboard extends HTMLElement { private renderCreate(): string { return ` -
- +
+ + Deploy New Forum
diff --git a/modules/funds/components/folk-funds-app.ts b/modules/funds/components/folk-funds-app.ts index e6b0a9b..a581669 100644 --- a/modules/funds/components/folk-funds-app.ts +++ b/modules/funds/components/folk-funds-app.ts @@ -193,23 +193,23 @@ class FolkFundsApp extends HTMLElement { return `
-
-

rFunds

-

Token Bonding Flow Funnel

-

- Design transparent resource flows with sufficiency-based cascading. - Funnels fill to their threshold, then overflow routes surplus to the next layer — - ensuring every level has enough before abundance cascades forward. -

-
- Try the Demo → +
+ Flows +
+ Demo ${authed - ? `` - : `Sign in to create flows` + ? `` + : `Sign in to create flows` }
+
+ Design transparent resource flows with sufficiency-based cascading. + Funnels fill to their threshold, then overflow routes surplus to the next layer — + ensuring every level has enough before abundance cascades forward. +
+
@@ -316,10 +316,10 @@ class FolkFundsApp extends HTMLElement { return `
-
- ← All Flows -

${this.esc(this.flowName || "Flow Detail")}

- ${this.isDemo ? 'Demo' : ""} +
+ ← Flows + ${this.esc(this.flowName || "Flow Detail")} + ${this.isDemo ? 'Demo' : ""}
diff --git a/modules/funds/components/funds.css b/modules/funds/components/funds.css index 78d02aa..b099487 100644 --- a/modules/funds/components/funds.css +++ b/modules/funds/components/funds.css @@ -1,9 +1,4 @@ /* ── Funds module theme ───────────────────────────────── */ -body[data-theme="light"] main { - background: #0f172a; - min-height: calc(100vh - 56px); - padding: 0; -} /* ── Shared utility classes ──────────────────────────── */ .funds-loading { text-align: center; color: #64748b; padding: 48px 16px; font-size: 14px; } @@ -12,34 +7,6 @@ body[data-theme="light"] main { /* ── Landing page ────────────────────────────────────── */ .funds-landing { max-width: 960px; margin: 0 auto; padding: 24px 20px 64px; } -.funds-hero { - text-align: center; - padding: 56px 20px 48px; - border-bottom: 1px solid #1e293b; - margin-bottom: 48px; -} -.funds-hero__title { - font-size: 42px; font-weight: 800; margin: 0 0 8px; - background: linear-gradient(135deg, #0ea5e9, #6366f1, #ec4899); - -webkit-background-clip: text; -webkit-text-fill-color: transparent; - background-clip: text; -} -.funds-hero__subtitle { font-size: 18px; color: #94a3b8; margin: 0 0 16px; font-weight: 500; } -.funds-hero__desc { font-size: 15px; color: #64748b; line-height: 1.7; max-width: 560px; margin: 0 auto 28px; } -.funds-hero__desc em { color: #fbbf24; font-style: normal; font-weight: 600; } -.funds-hero__actions { display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap; } -.funds-hero__cta { - display: inline-block; padding: 10px 24px; border-radius: 8px; - background: #4f46e5; color: #fff; text-decoration: none; font-weight: 600; font-size: 14px; - border: none; cursor: pointer; transition: background 0.2s; -} -.funds-hero__cta:hover { background: #6366f1; } -.funds-hero__cta--secondary { - background: transparent; border: 1px solid #4f46e5; color: #a5b4fc; -} -.funds-hero__cta--secondary:hover { background: rgba(79,70,229,0.15); } -.funds-hero__auth-hint { font-size: 13px; color: #64748b; } - /* Features grid */ .funds-features { margin-bottom: 48px; } .funds-features__grid { @@ -106,16 +73,6 @@ body[data-theme="light"] main { /* ── Detail view ─────────────────────────────────────── */ .funds-detail { max-width: 1100px; margin: 0 auto; padding: 16px 20px 64px; } -.funds-detail__header { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; } -.funds-detail__back { - color: #64748b; text-decoration: none; font-size: 13px; padding: 4px 0; -} -.funds-detail__back:hover { color: #e2e8f0; } -.funds-detail__title { font-size: 22px; font-weight: 700; color: #e2e8f0; margin: 0; flex: 1; } -.funds-detail__badge { - font-size: 11px; font-weight: 600; color: #fbbf24; background: rgba(251,191,36,0.15); - border: 1px solid rgba(251,191,36,0.3); border-radius: 4px; padding: 2px 8px; -} /* ── Tabs ────────────────────────────────────────────── */ .funds-tabs { diff --git a/modules/inbox/components/folk-inbox-client.ts b/modules/inbox/components/folk-inbox-client.ts index d43ad5f..1df423f 100644 --- a/modules/inbox/components/folk-inbox-client.ts +++ b/modules/inbox/components/folk-inbox-client.ts @@ -90,11 +90,11 @@ class FolkInboxClient extends HTMLElement { -
-

\u{1F3ED} Provider Directory

+
+ Provider Directory
diff --git a/modules/trips/components/folk-route-planner.ts b/modules/trips/components/folk-route-planner.ts index 65fa8e7..5391ac6 100644 --- a/modules/trips/components/folk-route-planner.ts +++ b/modules/trips/components/folk-route-planner.ts @@ -409,9 +409,9 @@ class FolkRoutePlanner extends HTMLElement {
-
-

rTrips — Route Planner

-

Plan paths between destinations. Fit conic arcs and find where routes intersect.

+
+ Route Planner + Plan paths between destinations. Fit conic arcs and find where routes intersect.
diff --git a/modules/trips/components/folk-trips-planner.ts b/modules/trips/components/folk-trips-planner.ts index 0a28dfb..54b93ef 100644 --- a/modules/trips/components/folk-trips-planner.ts +++ b/modules/trips/components/folk-trips-planner.ts @@ -69,11 +69,12 @@ class FolkTripsPlanner extends HTMLElement { :host { display: block; font-family: system-ui, -apple-system, sans-serif; color: #e0e0e0; } * { box-sizing: border-box; } - .header { display: flex; gap: 8px; margin-bottom: 16px; align-items: center; } - .nav-btn { padding: 6px 14px; border-radius: 6px; border: 1px solid #444; background: #1e1e2e; color: #ccc; cursor: pointer; font-size: 13px; } - .header-title { font-size: 18px; font-weight: 600; margin-left: 8px; flex: 1; } - .create-btn { padding: 8px 16px; border-radius: 8px; border: none; background: #14b8a6; color: #fff; font-weight: 600; cursor: pointer; font-size: 13px; } - .create-btn:hover { background: #0d9488; } + .rapp-nav { display: flex; gap: 8px; margin-bottom: 16px; align-items: center; min-height: 36px; } + .rapp-nav__back { padding: 4px 10px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.1); background: transparent; color: #94a3b8; cursor: pointer; font-size: 13px; } + .rapp-nav__back:hover { color: #e2e8f0; border-color: rgba(255,255,255,0.2); } + .rapp-nav__title { font-size: 15px; font-weight: 600; flex: 1; color: #e2e8f0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } + .rapp-nav__btn { padding: 6px 14px; border-radius: 6px; border: none; background: #14b8a6; color: #fff; font-weight: 600; cursor: pointer; font-size: 13px; } + .rapp-nav__btn:hover { background: #0d9488; } .trip-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; } .trip-card { background: #1e1e2e; border: 1px solid #333; border-radius: 10px; padding: 16px; cursor: pointer; transition: border-color 0.2s; } @@ -114,9 +115,9 @@ class FolkTripsPlanner extends HTMLElement { private renderList(): string { return ` -
- \u2708\uFE0F My Trips - +
+ My Trips +
${this.trips.length > 0 ? `
${this.trips.map(t => ` @@ -141,9 +142,9 @@ class FolkTripsPlanner extends HTMLElement { if (!this.trip) return '
Loading...
'; const t = this.trip; return ` -
- - \u2708\uFE0F ${this.esc(t.title)} +
+ + ${this.esc(t.title)} ${t.status || "PLANNING"}
diff --git a/modules/vote/components/folk-vote-dashboard.ts b/modules/vote/components/folk-vote-dashboard.ts index a9f01c3..fce8e08 100644 --- a/modules/vote/components/folk-vote-dashboard.ts +++ b/modules/vote/components/folk-vote-dashboard.ts @@ -145,14 +145,10 @@ class FolkVoteDashboard extends HTMLElement { :host { display: block; font-family: system-ui, -apple-system, sans-serif; color: #e0e0e0; } * { box-sizing: border-box; } - .nav { display: flex; gap: 8px; margin-bottom: 20px; align-items: center; } - .nav-btn { - padding: 6px 14px; border-radius: 6px; border: 1px solid #444; - background: #1e1e2e; color: #ccc; cursor: pointer; font-size: 13px; - } - .nav-btn:hover { border-color: #666; } - .nav-btn.active { border-color: #6366f1; color: #a5b4fc; } - .nav-title { font-size: 18px; font-weight: 600; margin-left: 8px; } + .rapp-nav { display: flex; gap: 8px; margin-bottom: 16px; align-items: center; min-height: 36px; } + .rapp-nav__back { padding: 4px 10px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.1); background: transparent; color: #94a3b8; cursor: pointer; font-size: 13px; } + .rapp-nav__back:hover { color: #e2e8f0; border-color: rgba(255,255,255,0.2); } + .rapp-nav__title { font-size: 15px; font-weight: 600; flex: 1; color: #e2e8f0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .card { background: #1e1e2e; border: 1px solid #333; border-radius: 10px; @@ -213,8 +209,8 @@ class FolkVoteDashboard extends HTMLElement { private renderSpaces(): string { return ` -