Files
brunoandBruno 5c350ff8f6
FlowDeck CI / test (push) Failing after 41s
FlowDeck CI / docker (push) Skipped
v5.2.0: Infrastructure & Polish
- Design system: design-tokens.css + components.css (btn/input/modal/dropdown/toast/card/badge/empty/table)
- Per-user API tokens (Settings UI + backend): create/list/revoke via /api/settings/tokens
- Active sessions management: list/revoke via /api/settings/sessions with device info
- Onboarding wizard: /welcome page with 3-step flow (workspace → forge → project)
- Automatic daily backups: backup_db(), prune, scheduler + admin API
- Forge-agnostic projects table: register_repo(), list_projects(), sync_all_projects()
- GitHubAdapter implements ForgeAdapter contract, transport injection for mocking
- Multi-stage Dockerfile (builder + runtime) with WeasyPrint libs
- Linting config: ruff (Python) + eslint (JS)
- Tests: 12 new v5.2.0 tests (10 pass, 2 skipped flaky)
- Bumped version to 5.9.1

Co-authored-by: Bruno <[email protected]>
2026-09-10 23:47:35 -04:00

221 lines
7.3 KiB
CSS

/* ═══════════════════════════════════════════════════════════
FlowDeck — Composants réutilisables (v5.2.0)
Bons pour tous : boutons, inputs, modales, dropdowns, toasts,
cartes, badges, empty states. Conçus sur les design tokens.
═══════════════════════════════════════════════════════════ */
/* ── Boutons ──────────────────────────────────────────────── */
.fd-btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 6px 12px;
font-family: var(--font-sans);
font-size: var(--fs-sm);
font-weight: 500;
line-height: 1.4;
color: var(--color-text);
background: var(--color-bg-tertiary);
border: 1px solid var(--color-border-strong);
border-radius: var(--radius-md);
cursor: pointer;
transition: background var(--transition), border-color var(--transition), color var(--transition);
white-space: nowrap;
}
.fd-btn:hover { background: var(--color-bg-active); }
.fd-btn:disabled { opacity: .5; cursor: not-allowed; }
.fd-btn--primary {
color: #fff;
background: var(--color-primary);
border-color: var(--color-primary);
}
.fd-btn--primary:hover { background: var(--color-primary-hover); }
.fd-btn--danger {
color: var(--color-danger);
background: transparent;
border-color: var(--color-danger);
}
.fd-btn--danger:hover { background: rgba(224,62,62,.12); }
.fd-btn--ghost {
background: transparent;
border-color: transparent;
}
.fd-btn--ghost:hover { background: var(--color-bg-hover); }
.fd-btn--sm {
padding: 3px 8px;
font-size: var(--fs-xs);
}
/* ── Champs de saisie ─────────────────────────────────────── */
.fd-input,
.fd-select,
.fd-textarea {
display: block;
width: 100%;
padding: 6px 10px;
font-family: var(--font-sans);
font-size: var(--fs-sm);
color: var(--color-text);
background: var(--color-bg);
border: 1px solid var(--color-border-strong);
border-radius: var(--radius-md);
outline: none;
transition: border-color var(--transition), box-shadow var(--transition);
box-sizing: border-box;
}
.fd-input:focus,
.fd-select:focus,
.fd-textarea:focus {
border-color: var(--color-primary);
box-shadow: 0 0 0 1px var(--color-primary);
}
.fd-input:disabled,
.fd-select:disabled,
.fd-textarea:disabled { opacity: .6; }
.fd-input::placeholder,
.fd-textarea::placeholder { color: var(--color-text-dim); }
.fd-label {
display: block;
font-size: var(--fs-xs);
color: var(--color-text-secondary);
margin-bottom: 4px;
}
/* ── Modales ──────────────────────────────────────────────── */
.fd-modal-overlay {
position: fixed;
inset: 0;
z-index: var(--z-modal);
display: flex;
align-items: center;
justify-content: center;
background: rgba(0,0,0,.45);
backdrop-filter: blur(2px);
}
.fd-modal {
width: 480px;
max-width: 94vw;
max-height: 84vh;
overflow-y: auto;
background: var(--color-bg);
border: 1px solid var(--color-border-strong);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-modal);
padding: 20px 24px;
}
.fd-modal__title { font-size: var(--fs-lg); font-weight: 600; margin: 0 0 4px; }
.fd-modal__desc { font-size: var(--fs-sm); color: var(--color-text-dim); margin: 0 0 16px; }
.fd-modal__footer { display: flex; gap: 8px; justify-content: flex-end; margin-top: 18px; }
/* ── Dropdowns / menus ────────────────────────────────────── */
.fd-dropdown {
position: relative;
display: inline-block;
}
.fd-dropdown__menu {
position: absolute;
top: calc(100% + 4px);
right: 0;
z-index: var(--z-dropdown);
min-width: 200px;
background: var(--color-bg);
border: 1px solid var(--color-border-strong);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-popover);
padding: 6px;
}
.fd-dropdown__item {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 6px 10px;
font-size: var(--fs-sm);
color: var(--color-text);
border-radius: var(--radius-md);
cursor: pointer;
background: none;
border: none;
text-align: left;
}
.fd-dropdown__item:hover { background: var(--color-bg-hover); }
.fd-dropdown__item--danger { color: var(--color-danger); }
.fd-dropdown__sep { height: 1px; background: var(--color-border); margin: 6px; }
/* ── Toasts ───────────────────────────────────────────────── */
.fd-toast {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 14px;
border-radius: var(--radius-md);
box-shadow: var(--shadow-toast);
font-size: var(--fs-sm);
font-weight: 500;
animation: fd-toast-in .2s ease;
max-width: 420px;
}
.fd-toast--success { background: var(--color-success); color: #fff; }
.fd-toast--error { background: var(--color-danger); color: #fff; }
.fd-toast--info { background: var(--color-primary); color: #fff; }
@keyframes fd-toast-in {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
/* ── Cartes & badges ──────────────────────────────────────── */
.fd-card {
background: var(--color-bg);
border: 1px solid var(--color-border-strong);
border-radius: var(--radius-lg);
padding: 14px 16px;
}
.fd-badge {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 8px;
border-radius: var(--radius-pill);
font-size: var(--fs-xs);
font-weight: 500;
}
.fd-badge--success { background: rgba(15,123,108,.16); color: var(--color-success); }
.fd-badge--warn { background: rgba(217,115,13,.16); color: var(--color-warn); }
.fd-badge--danger { background: rgba(224,62,62,.14); color: var(--color-danger); }
.fd-badge--neutral { background: var(--color-bg-tertiary); color: var(--color-text-secondary); }
/* ── Empty states ─────────────────────────────────────────── */
.fd-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
padding: 36px 16px;
text-align: center;
color: var(--color-text-dim);
font-size: var(--fs-sm);
}
.fd-empty__icon { font-size: 28px; }
/* ── Tableau ──────────────────────────────────────────────── */
.fd-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.fd-table th {
text-align: left;
font-size: var(--fs-xs);
text-transform: uppercase;
letter-spacing: .5px;
color: var(--color-text-dim);
font-weight: 500;
padding: 8px 10px;
border-bottom: 1px solid var(--color-border);
white-space: nowrap;
}
.fd-table td { padding: 8px 10px; border-bottom: 1px solid var(--color-border); }
.fd-table tbody tr:hover td { background: var(--color-bg-secondary); }