# Guia Técnico para Desenvolvedores
## PharmData Design System - Implementação com Tailwind CSS + HTMX + Flask

> **Objetivo**: Traduzir o Design System PharmData em código pronto para uso com stack moderna e minimalista

---

## Índice

1. [Setup Inicial](#setup-inicial)
2. [Tailwind Configuration](#tailwind-configuration)
3. [Tokens Farmacêuticos](#tokens-farmacêuticos)
4. [Componentes](#componentes)
5. [Exemplos de Telas](#exemplos-de-telas)
6. [HTMX Patterns](#htmx-patterns)
7. [Flask Integration](#flask-integration)
8. [Acessibilidade & Segurança](#acessibilidade-e-segurança)

---

## Setup Inicial

### Estrutura de Projeto Recomendada

```
pharmdata-app/
├── app/
│   ├── static/
│   │   ├── css/
│   │   │   ├── tailwind-input.css      # Source para Tailwind
│   │   │   └── output.css              # Compiled Tailwind
│   │   └── js/
│   │       └── htmx.min.js
│   ├── templates/
│   │   ├── base.html                   # Template base
│   │   ├── components/                 # Componentes reutilizáveis
│   │   └── pages/                      # Páginas completas
│   ├── routes/
│   └── __init__.py
├── tailwind.config.js
├── package.json
└── requirements.txt
```

### Dependências

**package.json**:
```json
{
  "name": "pharmdata-frontend",
  "scripts": {
    "dev": "npx tailwindcss -i ./app/static/css/tailwind-input.css -o ./app/static/css/output.css --watch",
    "build": "npx tailwindcss -i ./app/static/css/tailwind-input.css -o ./app/static/css/output.css --minify"
  },
  "devDependencies": {
    "tailwindcss": "^3.4.0"
  }
}
```

**requirements.txt**:
```
Flask==3.0.0
Flask-HTMX==0.3.2
```

---

## Tailwind Configuration

### tailwind.config.js Completo

Copie este arquivo na raiz do projeto:

```javascript
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./app/templates/**/*.html",
    "./app/static/js/**/*.js",
  ],

  darkMode: false, // PharmData não usa dark mode na v2.0

  theme: {
    extend: {

      // ========== CORES INSTITUCIONAIS ==========
      colors: {
        // Primary
        'emerald-abyss': '#0B2D2A',
        'graphite-depth': '#1F2937',

        // Secondary
        'soft-steel': '#374151',
        'teal-intense': '#2AA198',

        // Backgrounds
        'arctic-mist': '#E9ECEF',
        'cloud': '#F5F8FA',
        'soft-arctic': '#E5E8EB',

        // Accent
        'mint-signal': '#B7E4D5',

        // Status Semânticos
        'success': '#10B981',
        'success-light': '#D1FAE5',
        'warning': '#E65100',
        'warning-light': '#FFF3E0',
        'error': '#EF4444',
        'error-light': '#FEE2E2',
        'info': '#3B82F6',
        'info-light': '#DBEAFE',

        // ========== DROPS - PHARMACEUTICAL CATEGORIES ==========
        'dec': {
          bg: '#FCE4EC',
          text: '#AD1457',
        },
        'sub': {
          bg: '#E3F2FD',
          text: '#1565C0',
        },
        'lab': {
          bg: '#FFF3E0',
          text: '#EF6C00',
        },
        'cnc': {
          bg: '#E8F5E9',
          text: '#2E7D32',
        },
        'fofa': {
          bg: '#F3E5F5',
          text: '#7B1FA2',
        },
        'via': {
          bg: '#EFEBE9',
          text: '#5D4037',
        },

        // ========== DROPS - WORKFLOW STATUS ==========
        'status-draft': {
          bg: '#F5F5F5',
          text: '#616161',
        },
        'status-review': {
          bg: '#FFF8E1',
          text: '#F57C00',
        },
        'status-approved': {
          bg: '#E8F5E9',
          text: '#4CAF50',
        },
        'status-rejected': {
          bg: '#FFEBEE',
          text: '#EF5350',
        },

        // ========== DROPS - DATA QUALITY ==========
        'quality-complete': {
          bg: '#E8F5E9',
          text: '#4CAF50',
        },
        'quality-partial': {
          bg: '#FFF8E1',
          text: '#FFCA28',
        },
        'quality-missing': {
          bg: '#FFEBEE',
          text: '#EF5350',
        },
        'quality-enriched': {
          bg: '#E3F2FD',
          text: '#1565C0',
        },

        // ========== DROPS - DATA SOURCES ==========
        'source-spor': {
          bg: '#E3F2FD',
          text: '#1565C0',
        },
        'source-snomed': {
          bg: '#FFF3E0',
          text: '#E65100',
        },
        'source-anvisa': {
          bg: '#E8F5E9',
          text: '#1B5E20',
        },
        'source-fda': {
          bg: '#E8EAF6',
          text: '#283593',
        },
      },

      // ========== TIPOGRAFIA ==========
      fontFamily: {
        'display': ['EB Garamond', 'Georgia', 'Times New Roman', 'serif'],
        'sans': ['IBM Plex Sans', 'system-ui', '-apple-system', 'sans-serif'],
        'mono': ['IBM Plex Mono', 'Courier New', 'monospace'],
      },

      fontSize: {
        'xs': ['0.75rem', { lineHeight: '1.5' }],      // 12px - Caption
        'sm': ['0.875rem', { lineHeight: '1.5' }],     // 14px - Label
        'base': ['1rem', { lineHeight: '1.6' }],       // 16px - Body
        'md': ['1.125rem', { lineHeight: '1.4' }],     // 18px - H3
        'xl': ['1.5rem', { lineHeight: '1.3' }],       // 24px - H2
        '2xl': ['2rem', { lineHeight: '1.2' }],        // 32px - H1
      },

      fontWeight: {
        'regular': '400',
        'medium': '500',
        'semibold': '600',
        'bold': '700',
      },

      letterSpacing: {
        'tighter': '-0.01em',
        'tight': '-0.005em',
        'normal': '0',
        'wide': '0.01em',
        'wider': '0.015em',
      },

      // ========== ESPAÇAMENTO ==========
      spacing: {
        '2xs': '0.25rem',   // 4px
        'xs': '0.5rem',     // 8px
        'sm': '0.75rem',    // 12px
        'md': '1rem',       // 16px
        'lg': '1.5rem',     // 24px
        'xl': '2rem',       // 32px
        '2xl': '3rem',      // 48px
      },

      // ========== BORDAS E RAIOS ==========
      borderRadius: {
        'sm': '4px',
        'md': '8px',
        'lg': '12px',
        'xl': '16px',
        'pill': '9999px',
      },

      // ========== SOMBRAS ==========
      boxShadow: {
        'xs': '0 1px 2px 0 rgba(11, 45, 42, 0.05)',
        'sm': '0 1px 3px 0 rgba(11, 45, 42, 0.1), 0 1px 2px -1px rgba(11, 45, 42, 0.1)',
        'md': '0 4px 6px -1px rgba(11, 45, 42, 0.1), 0 2px 4px -2px rgba(11, 45, 42, 0.1)',
        'lg': '0 10px 15px -3px rgba(11, 45, 42, 0.15), 0 4px 6px -4px rgba(11, 45, 42, 0.1)',
        'xl': '0 20px 25px -5px rgba(11, 45, 42, 0.2), 0 8px 10px -6px rgba(11, 45, 42, 0.1)',
      },

      // ========== BREAKPOINTS ==========
      screens: {
        'mobile': '640px',
        'tablet': '1024px',
        'desktop': '1280px',
      },
    },
  },

  plugins: [
    // Plugin customizado para classes semânticas
    function({ addComponents }) {
      addComponents({

        // ========== HEADINGS ==========
        '.text-h1': {
          fontFamily: 'var(--font-display)',
          fontSize: '2rem',
          fontWeight: '600',
          lineHeight: '1.2',
          letterSpacing: '-0.01em',
          color: '#0B2D2A',
        },
        '.text-h2': {
          fontFamily: 'var(--font-display)',
          fontSize: '1.5rem',
          fontWeight: '600',
          lineHeight: '1.3',
          letterSpacing: '-0.005em',
          color: '#0B2D2A',
        },
        '.text-h3': {
          fontFamily: 'IBM Plex Sans, sans-serif',
          fontSize: '1.125rem',
          fontWeight: '600',
          lineHeight: '1.4',
          color: '#1F2937',
        },

        // ========== BODY TEXT ==========
        '.text-body': {
          fontFamily: 'IBM Plex Sans, sans-serif',
          fontSize: '1rem',
          fontWeight: '400',
          lineHeight: '1.6',
          color: '#1F2937',
        },
        '.text-label': {
          fontFamily: 'IBM Plex Sans, sans-serif',
          fontSize: '0.875rem',
          fontWeight: '500',
          lineHeight: '1.4',
          letterSpacing: '0.01em',
          color: '#1F2937',
        },
        '.text-caption': {
          fontFamily: 'IBM Plex Sans, sans-serif',
          fontSize: '0.75rem',
          fontWeight: '400',
          lineHeight: '1.5',
          letterSpacing: '0.015em',
          color: '#374151',
        },

        // ========== BUTTONS ==========
        '.btn': {
          display: 'inline-flex',
          alignItems: 'center',
          justifyContent: 'center',
          gap: '0.5rem',
          padding: '0.5rem 1rem',
          borderRadius: '8px',
          fontWeight: '500',
          transition: 'all 0.2s ease',
          cursor: 'pointer',
          border: 'none',
        },
        '.btn-primary': {
          backgroundColor: '#2AA198',
          color: 'white',
          '&:hover': {
            backgroundColor: '#0B2D2A',
          },
        },
        '.btn-secondary': {
          backgroundColor: 'transparent',
          color: '#1F2937',
          border: '1px solid #E5E8EB',
          '&:hover': {
            backgroundColor: '#E9ECEF',
          },
        },
        '.btn-ghost': {
          backgroundColor: 'transparent',
          color: '#2AA198',
          '&:hover': {
            backgroundColor: 'rgba(42, 161, 152, 0.05)',
          },
        },

        // ========== CARDS ==========
        '.card': {
          backgroundColor: 'white',
          borderRadius: '12px',
          border: '1px solid #E5E8EB',
          padding: '1.5rem',
          transition: 'all 0.3s ease',
        },
        '.card:hover': {
          boxShadow: '0 4px 6px -1px rgba(11, 45, 42, 0.1)',
        },

        // ========== INPUTS ==========
        '.input': {
          width: '100%',
          padding: '0.5rem 0.75rem',
          borderRadius: '8px',
          border: '1px solid #E5E8EB',
          fontSize: '1rem',
          fontFamily: 'IBM Plex Sans, sans-serif',
          transition: 'all 0.2s ease',
          '&:focus': {
            outline: 'none',
            borderColor: '#2AA198',
            boxShadow: '0 0 0 3px rgba(42, 161, 152, 0.1)',
          },
        },

      })
    },
  ],
}
```

### tailwind-input.css

Crie `app/static/css/tailwind-input.css`:

```css
@import url('https://fonts.googleapis.com/css2?family=EB+Garamond:wght@400;500;600;700&family=IBM+Plex+Sans:wght@400;500;600&family=IBM+Plex+Mono:wght@400&display=swap');

@tailwind base;
@tailwind components;
@tailwind utilities;

/* Custom CSS Variables */
:root {
  --font-display: 'EB Garamond', Georgia, serif;
  --font-sans: 'IBM Plex Sans', system-ui, sans-serif;
  --font-mono: 'IBM Plex Mono', 'Courier New', monospace;
}

/* Font Smoothing */
* {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Base styles */
@layer base {
  body {
    @apply bg-cloud text-graphite-depth font-sans;
  }

  h1 { @apply text-h1; }
  h2 { @apply text-h2; }
  h3 { @apply text-h3; }
  p { @apply text-body; }
}
```

---

## Tokens Farmacêuticos

### Classes Semânticas para Drops

Crie `app/static/css/pharmdata-tokens.css`:

```css
/* ============================================
   PHARMDATA TOKENS - Pharmaceutical Categories
   Classes semânticas para tokens farmacêuticos
   ============================================ */

/* ========== BASE DROP STYLES ========== */
.token-base {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 500;
  border: 1px solid;
  transition: all 0.2s ease;
}

/* ========== PHARMACEUTICAL CATEGORIES ========== */

/* DEC - Denominação Comercial */
.token-dec {
  @apply token-base;
  background: #FCE4EC;
  color: #AD1457;
  border-color: rgba(173, 20, 87, 0.2);
}
.token-dec:hover {
  background: rgba(173, 20, 87, 0.1);
}

/* SUB - Substância Ativa */
.token-sub {
  @apply token-base;
  background: #E3F2FD;
  color: #1565C0;
  border-color: rgba(21, 101, 192, 0.2);
}
.token-sub:hover {
  background: rgba(21, 101, 192, 0.1);
}

/* LAB - Laboratório */
.token-lab {
  @apply token-base;
  background: #FFF3E0;
  color: #EF6C00;
  border-color: rgba(239, 108, 0, 0.2);
}
.token-lab:hover {
  background: rgba(239, 108, 0, 0.1);
}

/* CNC - Concentração */
.token-cnc {
  @apply token-base;
  background: #E8F5E9;
  color: #2E7D32;
  border-color: rgba(46, 125, 50, 0.2);
}
.token-cnc:hover {
  background: rgba(46, 125, 50, 0.1);
}

/* FOFA - Forma Farmacêutica */
.token-fofa {
  @apply token-base;
  background: #F3E5F5;
  color: #7B1FA2;
  border-color: rgba(123, 31, 162, 0.2);
}
.token-fofa:hover {
  background: rgba(123, 31, 162, 0.1);
}

/* FAP - Forma de Apresentação */
.token-fap {
  @apply token-base;
  background: #E0F2F1;
  color: #00695C;
  border-color: rgba(0, 105, 92, 0.2);
}
.token-fap:hover {
  background: rgba(0, 105, 92, 0.1);
}

/* VIA - Via de Administração */
.token-via {
  @apply token-base;
  background: #EFEBE9;
  color: #5D4037;
  border-color: rgba(93, 64, 55, 0.2);
}
.token-via:hover {
  background: rgba(93, 64, 55, 0.1);
}

/* EMB - Embalagem */
.token-emb {
  @apply token-base;
  background: #E8EAF6;
  color: #303F9F;
  border-color: rgba(48, 63, 159, 0.2);
}
.token-emb:hover {
  background: rgba(48, 63, 159, 0.1);
}

/* CAP - Capacidade */
.token-cap {
  @apply token-base;
  background: #FFFDE7;
  color: #F57F17;
  border-color: rgba(245, 127, 23, 0.2);
}
.token-cap:hover {
  background: rgba(245, 127, 23, 0.1);
}

/* CHG - Enriquecimento */
.token-chg {
  @apply token-base;
  background: #FAFAFA;
  color: #616161;
  border-color: rgba(97, 97, 97, 0.2);
}
.token-chg:hover {
  background: rgba(97, 97, 97, 0.1);
}

/* UNK - Não Reconhecido */
.token-unk {
  @apply token-base;
  background: #FFEBEE;
  color: #C62828;
  border-color: rgba(198, 40, 40, 0.2);
}
.token-unk:hover {
  background: rgba(198, 40, 40, 0.1);
}

/* ========== WORKFLOW STATUS ========== */

.token-draft {
  @apply token-base;
  background: transparent;
  color: #9E9E9E;
  border-color: rgba(158, 158, 158, 0.3);
}
.token-draft:hover {
  background: rgba(158, 158, 158, 0.05);
}

.token-review {
  @apply token-base;
  background: transparent;
  color: #FFA726;
  border-color: rgba(255, 167, 38, 0.3);
}
.token-review:hover {
  background: rgba(255, 167, 38, 0.05);
}

.token-approved {
  @apply token-base;
  background: transparent;
  color: #4CAF50;
  border-color: rgba(76, 175, 80, 0.3);
}
.token-approved:hover {
  background: rgba(76, 175, 80, 0.05);
}

.token-rejected {
  @apply token-base;
  background: transparent;
  color: #EF5350;
  border-color: rgba(239, 83, 80, 0.3);
}
.token-rejected:hover {
  background: rgba(239, 83, 80, 0.05);
}

/* ========== DATA QUALITY ========== */

.token-complete {
  @apply token-base;
  background: transparent;
  color: #4CAF50;
  border-color: rgba(76, 175, 80, 0.3);
}

.token-partial {
  @apply token-base;
  background: transparent;
  color: #FFCA28;
  border-color: rgba(255, 202, 40, 0.3);
}

.token-missing {
  @apply token-base;
  background: transparent;
  color: #EF5350;
  border-color: rgba(239, 83, 80, 0.3);
}

.token-enriched {
  @apply token-base;
  background: transparent;
  color: #1565C0;
  border-color: rgba(21, 101, 192, 0.3);
}

/* ========== DATA SOURCES ========== */

.token-spor {
  @apply token-base;
  background: #E3F2FD;
  color: #1565C0;
  border-color: rgba(21, 101, 192, 0.2);
}

.token-snomed {
  @apply token-base;
  background: #FFF3E0;
  color: #E65100;
  border-color: rgba(230, 81, 0, 0.2);
}

.token-anvisa {
  @apply token-base;
  background: #E8F5E9;
  color: #1B5E20;
  border-color: rgba(27, 94, 32, 0.2);
}

.token-fda {
  @apply token-base;
  background: #E8EAF6;
  color: #283593;
  border-color: rgba(40, 53, 147, 0.2);
}
```

### Snippets HTML de Uso

```html
<!-- Pharmaceutical Categories -->
<span class="token-dec">DEC-123456</span>
<span class="token-sub">SUB-082615</span>
<span class="token-lab">LAB-BAYER</span>
<span class="token-cnc">100mg/mL</span>
<span class="token-fofa">Comprimido</span>
<span class="token-via">Oral</span>

<!-- Workflow Status -->
<span class="token-draft">Draft</span>
<span class="token-review">In Review</span>
<span class="token-approved">Approved</span>
<span class="token-rejected">Rejected</span>

<!-- Data Quality -->
<span class="token-complete">Complete</span>
<span class="token-partial">Partial</span>
<span class="token-missing">Missing</span>
<span class="token-enriched">Enriched</span>

<!-- Data Sources -->
<span class="token-spor">SPOR/EMA</span>
<span class="token-snomed">SNOMED CT</span>
<span class="token-anvisa">ANVISA</span>
<span class="token-fda">FDA</span>
```

---

**Próximas seções**: Componentes, Exemplos de Telas, HTMX Patterns, Flask Integration e Compliance Map.

Este documento será expandido nas próximas etapas.
