[object Object]

← 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

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&nbsp;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 →