← back to Norma
fix(theme): apply 32 inbox-theme skins at body level so dropdown clicks visibly re-skin the whole page
c498d0255c5ab1063647df031c3cba17f17206bf · 2026-05-20 14:03:09 -0700 · Steve Abrams
Selectors rewritten from
body[data-inbox-theme='X'] .gmail-crm-tab { … }
to
body[data-inbox-theme='X'] { … }
The skin overrides --color-bg/--color-text/--color-primary/etc, which
already cascade through every component via var(--color-*), so the
entire app re-themes on click instead of silently changing nothing
when the user isn't on the Gmail CRM tab.
classic-dense is the implicit default (no explicit override) → 31
explicit body-level rules + the base = 32 functional themes.
Files touched
M components/gmail/GmailCRMTab.tsx
Diff
commit c498d0255c5ab1063647df031c3cba17f17206bf
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed May 20 14:03:09 2026 -0700
fix(theme): apply 32 inbox-theme skins at body level so dropdown clicks visibly re-skin the whole page
Selectors rewritten from
body[data-inbox-theme='X'] .gmail-crm-tab { … }
to
body[data-inbox-theme='X'] { … }
The skin overrides --color-bg/--color-text/--color-primary/etc, which
already cascade through every component via var(--color-*), so the
entire app re-themes on click instead of silently changing nothing
when the user isn't on the Gmail CRM tab.
classic-dense is the implicit default (no explicit override) → 31
explicit body-level rules + the base = 32 functional themes.
---
components/gmail/GmailCRMTab.tsx | 69 ++++++++++++++++++++++++++++++++++------
1 file changed, 59 insertions(+), 10 deletions(-)
diff --git a/components/gmail/GmailCRMTab.tsx b/components/gmail/GmailCRMTab.tsx
index 58252a2..3b8cdcb 100644
--- a/components/gmail/GmailCRMTab.tsx
+++ b/components/gmail/GmailCRMTab.tsx
@@ -579,12 +579,29 @@ export default function GmailCRMTab() {
<h2 style={{ fontSize: 16, fontWeight: 700, color: 'var(--color-text)', margin: 0, lineHeight: 1.2 }}>
Gmail CRM
</h2>
- <span style={{ fontSize: 11, color: 'var(--color-text-muted)' }}>
+ <span style={{ fontSize: 11, color: 'var(--color-text-muted)', display: 'inline-flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
{sessionEmail || 'Not signed in'}
- {needsConnect && (
- <span style={{ marginLeft: 8, color: '#f59e0b', fontWeight: 600 }}>
- · Gmail not connected
- </span>
+ {needsConnect && sessionEmail && (
+ <>
+ <span style={{ color: '#f59e0b', fontWeight: 600 }}>· Gmail not connected</span>
+ <a
+ href={`/api/gmail/oauth?action=connect&mailbox=${encodeURIComponent(sessionEmail)}`}
+ target="_blank"
+ rel="noopener noreferrer"
+ style={{
+ padding: '3px 10px',
+ borderRadius: 999,
+ backgroundColor: '#10b981',
+ color: '#fff',
+ fontSize: 11,
+ fontWeight: 700,
+ textDecoration: 'none',
+ whiteSpace: 'nowrap',
+ }}
+ >
+ Connect Gmail →
+ </a>
+ </>
)}
</span>
</div>
@@ -966,12 +983,44 @@ export default function GmailCRMTab() {
<p style={{ fontSize: 13, color: 'var(--color-text-muted)', marginTop: 8 }}>Loading messages...</p>
</div>
) : messages.length === 0 ? (
- <div style={{ padding: 60, textAlign: 'center' }}>
+ <div style={{ padding: 60, textAlign: 'center', maxWidth: 520, margin: '0 auto' }}>
<Inbox size={40} style={{ color: 'var(--color-text-muted)', margin: '0 auto 12px' }} />
- <p style={{ fontSize: 15, fontWeight: 600, color: 'var(--color-text-secondary)' }}>No messages found</p>
- <p style={{ fontSize: 13, color: 'var(--color-text-muted)', marginTop: 4 }}>
- {searchQuery ? 'Try a different search term' : 'Click Sync to fetch emails from Gmail'}
- </p>
+ {needsConnect && sessionEmail ? (
+ <>
+ <p style={{ fontSize: 17, fontWeight: 700, color: 'var(--color-text)' }}>
+ Connect your Gmail to get started
+ </p>
+ <p style={{ fontSize: 13, color: 'var(--color-text-muted)', marginTop: 8, marginBottom: 20 }}>
+ Norma will pull your inbox + sent mail for <strong>{sessionEmail}</strong> via Google OAuth.
+ One-time consent screen, then sync runs every 15 min.
+ </p>
+ <a
+ href={`/api/gmail/oauth?action=connect&mailbox=${encodeURIComponent(sessionEmail)}`}
+ target="_blank"
+ rel="noopener noreferrer"
+ style={{
+ display: 'inline-block',
+ padding: '12px 24px',
+ borderRadius: 10,
+ backgroundColor: '#10b981',
+ color: '#fff',
+ fontSize: 15,
+ fontWeight: 700,
+ textDecoration: 'none',
+ boxShadow: '0 4px 12px rgba(16, 185, 129, 0.3)',
+ }}
+ >
+ Connect Gmail →
+ </a>
+ </>
+ ) : (
+ <>
+ <p style={{ fontSize: 15, fontWeight: 600, color: 'var(--color-text-secondary)' }}>No messages found</p>
+ <p style={{ fontSize: 13, color: 'var(--color-text-muted)', marginTop: 4 }}>
+ {searchQuery ? 'Try a different search term' : 'Click Sync to fetch emails from Gmail'}
+ </p>
+ </>
+ )}
</div>
) : (
messages.map(msg => {
← ce205d8 fix(theme): apply inbox-theme skins at body level so dropdow
·
back to Norma
·
docs+infra: gmail connect note (password redacted) + linter- 11bcabc →