Signal/docs/tailwind-theme-v1.md
2026-05-12 05:10:00 -04:00

10 KiB

STTIL Brand — Tailwind Theme v1

Date: April 2026 Source tokens: design-tokens-v1.json Accent family: Tangerine (replaces copper)


1. CSS Custom Properties

Add to your global CSS (e.g., globals.css, base.css, or <style> in _document):

@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@600;700&family=Inter:wght@400;500&family=JetBrains+Mono:wght@400;500&display=swap');

:root {
  /* ── Teal scale ── */
  --teal-50:  #EEF8F8;
  --teal-100: #CBE9E9;
  --teal-200: #97D3D3;
  --teal-300: #5BBBBB;
  --teal-400: #2EA3A3;
  --teal-500: #1A8A8A;
  --teal-600: #147A7A;
  --teal-700: #0F5E5E;
  --teal-800: #0A4444;
  --teal-900: #072E2E;
  --teal-950: #041A1A;

  /* ── Tangerine scale ── */
  --tng-50:  #FFF4EE;
  --tng-100: #FFE4CC;
  --tng-200: #FFC090;
  --tng-300: #FFB070;
  --tng-400: #F07840;
  --tng-500: #E06028;
  --tng-600: #C04E1C;
  --tng-700: #903A14;
  --tng-800: #6A2A0C;
  --tng-900: #3E1808;

  /* ── Neutral scale ── */
  --n-0:   #FFFFFF;
  --n-50:  #F4F9F9;
  --n-100: #E5EEEE;
  --n-200: #C8D8D8;
  --n-300: #A3BEBE;
  --n-400: #7A9E9E;
  --n-500: #5A7E7E;
  --n-600: #426060;
  --n-700: #2E4444;
  --n-800: #1C2C2C;
  --n-900: #111A1A;

  /* ── Semantic ── */
  --success-100: #C8EDD8;
  --success-500: #1A7A4E;
  --success-600: #146040;
  --warning-100: #FDECD5;
  --warning-400: #D97B35;
  --warning-600: #A85A18;
  --error-100:   #F8CCCC;
  --error-500:   #C83030;
  --error-600:   #A02020;
  --info-100:    #C8E0EE;
  --info-500:    #1A6A9A;
  --purple-100:  #E2D8F0;
  --purple-500:  #7A5EA0;

  /* ── Sparkle tokens ── */
  --warm-white:              #FFFAF6;
  --tng-glow-dark:           0 0 24px rgba(240,120,64,0.30), 0 2px 10px rgba(4,26,26,0.70);
  --tng-glow-light:          0 0 16px rgba(224,96,40,0.20), 0 2px 8px rgba(0,0,0,0.08);
  --priority-row-dark:       rgba(224,104,48,0.09);
  --priority-row-light:      rgba(224,96,40,0.05);
  --tng-shimmer-border:      1px solid rgba(240,120,64,0.35);

  /* ── Semantic UI (dark mode defaults) ── */
  --bg-page:         var(--teal-950);
  --bg-card:         var(--teal-900);
  --bg-elevated:     var(--teal-800);
  --text-heading:    var(--warm-white);
  --text-primary:    #F0F4F4;
  --text-secondary:  var(--teal-300);
  --text-muted:      #5A8080;
  --border:          var(--teal-700);
  --brand:           var(--teal-400);
  --accent:          var(--tng-400);
  --accent-text:     var(--tng-300);
  --card-shadow:     0 2px 10px rgba(4,26,26,0.60);
}

/* ── Light mode overrides ── */
.light, [data-theme="light"] {
  --bg-page:         var(--n-50);
  --bg-card:         var(--n-0);
  --bg-elevated:     var(--n-100);
  --text-heading:    #0A3030;
  --text-primary:    #1C2E2E;
  --text-secondary:  var(--n-500);
  --text-muted:      var(--n-400);
  --border:          var(--n-200);
  --brand:           var(--teal-600);
  --accent:          var(--tng-500);
  --accent-text:     var(--tng-500);
  --card-shadow:     0 2px 8px rgba(7,46,46,0.09);
}

2. Tailwind Config Extension

tailwind.config.js (or tailwind.config.ts):

const { fontFamily } = require('tailwindcss/defaultTheme')

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ['./src/**/*.{js,ts,jsx,tsx,html}'],
  darkMode: 'class',
  theme: {
    extend: {
      colors: {
        teal: {
          50:  '#EEF8F8',
          100: '#CBE9E9',
          200: '#97D3D3',
          300: '#5BBBBB',
          400: '#2EA3A3',
          500: '#1A8A8A',
          600: '#147A7A',
          700: '#0F5E5E',
          800: '#0A4444',
          900: '#072E2E',
          950: '#041A1A',
        },
        tng: {
          50:  '#FFF4EE',
          100: '#FFE4CC',
          200: '#FFC090',
          300: '#FFB070',
          400: '#F07840',
          500: '#E06028',
          600: '#C04E1C',
          700: '#903A14',
          800: '#6A2A0C',
          900: '#3E1808',
        },
        neutral: {
          0:   '#FFFFFF',
          50:  '#F4F9F9',
          100: '#E5EEEE',
          200: '#C8D8D8',
          300: '#A3BEBE',
          400: '#7A9E9E',
          500: '#5A7E7E',
          600: '#426060',
          700: '#2E4444',
          800: '#1C2C2C',
          900: '#111A1A',
        },
        success: { 100: '#C8EDD8', 500: '#1A7A4E', 600: '#146040' },
        warning: { 100: '#FDECD5', 400: '#D97B35', 600: '#A85A18' },
        error:   { 100: '#F8CCCC', 500: '#C83030', 600: '#A02020' },
        info:    { 100: '#C8E0EE', 500: '#1A6A9A' },
        purple:  { 100: '#E2D8F0', 500: '#7A5EA0' },
      },
      fontFamily: {
        heading: ["'Plus Jakarta Sans'", ...fontFamily.sans],
        body:    ["'Inter'",             ...fontFamily.sans],
        mono:    ["'JetBrains Mono'",    ...fontFamily.mono],
      },
      fontSize: {
        'data': ['0.875rem', { lineHeight: '1.4', fontWeight: '500' }],
      },
      boxShadow: {
        'tng-glow':       '0 0 24px rgba(240,120,64,0.30), 0 2px 10px rgba(4,26,26,0.70)',
        'tng-glow-light': '0 0 16px rgba(224,96,40,0.20), 0 2px 8px rgba(0,0,0,0.08)',
        'card-dark':      '0 2px 10px rgba(4,26,26,0.60)',
        'card-light':     '0 2px 8px rgba(7,46,46,0.09)',
      },
    },
  },
  plugins: [],
}

3. Sample Component Classes

Page backgrounds

<!-- Dark mode default -->
<body class="bg-teal-950 text-white font-body">

<!-- Light mode -->
<body class="bg-neutral-50 text-[#1C2E2E] font-body light">

Cards

<!-- Standard card -->
<div class="bg-teal-900 border border-teal-700 rounded-xl p-5 shadow-card-dark">

<!-- Light mode card -->
<div class="bg-white border border-neutral-200 rounded-xl p-5 shadow-card-light">

<!-- Priority card (tangerine glow — one per view) -->
<div class="bg-teal-900 border border-tng-400 rounded-xl p-5 shadow-tng-glow">

Buttons

<!-- Primary -->
<button class="bg-teal-400 hover:bg-teal-500 text-[#FFFAF6] font-body font-medium
               px-4 py-2 rounded-lg transition-colors">
  Initiate Outreach
</button>

<!-- Tangerine high-urgency (one per view) -->
<button class="border border-tng-400 text-tng-300 hover:bg-tng-400/10
               font-body font-medium px-4 py-2 rounded-lg transition-colors">
  ⚡ Initiate PA →
</button>

<!-- Ghost -->
<button class="border border-teal-700 text-teal-300 hover:border-teal-500
               font-body px-4 py-2 rounded-lg transition-colors">
  View
</button>

Status badges

<!-- Active -->
<span class="inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-medium
             bg-success-100 text-success-600">
  ✓ Active
</span>

<!-- PA Required (tangerine) -->
<span class="inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-medium
             bg-tng-100 text-tng-700 border border-tng-700/20">
  ⚡ PA Required
</span>

<!-- Denied -->
<span class="inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-medium
             bg-error-100 text-error-600">
  ✕ Denied
</span>

Worklist table

<table class="w-full border-collapse">
  <thead>
    <tr class="bg-teal-800">
      <th class="px-5 py-2.5 text-left text-[10.5px] font-semibold uppercase tracking-widest
                 text-[#5A8080]">Patient ID</th>
      <!-- ... -->
    </tr>
  </thead>
  <tbody>
    <!-- Priority row -->
    <tr class="border-b border-teal-700/40 bg-[rgba(224,104,48,0.09)]
               hover:bg-[rgba(224,104,48,0.14)] transition-colors">
      <td class="px-5 py-3 font-mono font-bold text-tng-300">PT-00142</td>
      <!-- ... -->
    </tr>

    <!-- Standard row -->
    <tr class="border-b border-teal-700/40 hover:bg-teal-400/5 transition-colors">
      <td class="px-5 py-3 font-mono font-bold text-teal-300">PT-00387</td>
      <!-- ... -->
    </tr>
  </tbody>
</table>

Sidebar nav

<aside class="w-60 bg-teal-900 border-r border-teal-700 flex flex-col min-h-screen">
  <!-- Wordmark -->
  <div class="px-5 py-6 border-b border-teal-700/50">
    <p class="font-heading font-bold text-[17px] text-[#FFFAF6] tracking-[-0.01em]">
      Signal CGM
    </p>
    <p class="text-[11px] text-teal-300 mt-1">by STTIL Solutions</p>
  </div>

  <!-- Active nav item -->
  <a href="#" class="flex items-center gap-2.5 px-5 py-2.5 text-[13.5px] font-medium
                     text-[#FFFAF6] border-l-[3px] border-tng-400 bg-teal-800/50">
    ≡ All Patients
  </a>

  <!-- Inactive nav item -->
  <a href="#" class="flex items-center gap-2.5 px-5 py-2.5 text-[13.5px] text-neutral-400
                     border-l-[3px] border-transparent
                     hover:text-teal-400 hover:bg-teal-400/5 transition-colors">
    ⚠ Expiring Soon
  </a>
</aside>

Charts (data series)

<!-- Use teal-500 as primary series, tng-400 as the key comparison metric -->
<!-- Example: Chart.js dataset colors -->
<script>
  datasets: [
    { label: 'Proactive Outreach', borderColor: '#1A8A8A', backgroundColor: 'rgba(26,138,138,0.12)' },
    { label: 'Appeals / Denials',  borderColor: '#F07840', backgroundColor: 'rgba(240,120,64,0.12)' },
  ]
</script>

Call-out boxes (docs / pitch decks)

<!-- Tangerine call-out (one key insight per section) -->
<div class="bg-tng-100 border-l-4 border-tng-500 rounded-r-lg px-4 py-3">
  <p class="font-semibold text-tng-700 text-sm mb-1">PA affirmation rate: 92%</p>
  <p class="text-tng-700 text-sm">Suppliers above 90% qualify for PA exemption from June 1, 2026.</p>
</div>

4. Adding a New Payer Rule Status Color

  1. Add semantic tokens to design-tokens-v1.json under color.semantic
  2. Add to tailwind.config.js under theme.extend.colors
  3. Add CSS custom properties in globals.css
  4. Create badge variant in your Badge component following the icon + label pattern
  5. Update signal-cgm-brand-extension-v1.md Section 5 (status table)

5. Light / Dark Mode Toggle

React / Next.js:

// Toggle class on <html> element
document.documentElement.classList.toggle('light')

// Or use next-themes:
// <ThemeProvider attribute="class" defaultTheme="dark">

Vanilla JS:

document.body.classList.toggle('light')
// or
document.documentElement.dataset.theme = 'light' // matches [data-theme="light"]

Dark mode is the operational default for Signal CGM. Light mode is for export, print, and presentation contexts.