Files
flowdeck/static/css/my_tasks.css
T
bruno 1d1cdbd618
FlowDeck CI / test (push) Failing after 3h13m58s
FlowDeck CI / lint (push) Successful in 2m12s
FlowDeck CI / docker (push) Skipped
fix: side peek des bases repasse en vanilla JS + largeur 1100px standard (v7.49.0)
- Panneau peek: les bindings Alpine (x-data absent du conteneur) rendaient
  loovverture et le redimensionnement inoperants -> cblage direct sur le document.
- Helper unique window.fdWirePeekResize (app.js): pointer capture, 300px-90vw,
  clic=fermer, largeur persiste fd_peek_width partagee entre les 4 peeks.
- database-table-container margin:0 (tableau colle a gauche, marge Library).
- .lib-container remonte dans app.css (trash etait pleine largeur), .db-index 1100px.
- ObsiGate verifie sans code: creation .xlsx OK (openpyxl, #186).
2026-10-05 22:47:36 -04:00

647 lines
26 KiB
CSS

/* ══════════════════════════════════════════════════════════════════════
* FlowDeck — My Tasks (tableau de bord transverse façon Notion)
* Préfixe `mt-`, conteneur `#my-tasks-app` (rendu par app/routers/my_tasks.py,
* comportement par static/js/my_tasks.js).
* ══════════════════════════════════════════════════════════════════════ */
.my-tasks-app { max-width: 1100px; margin: 0 auto; padding: 20px 24px 64px; }
/* ── En-tête ──────────────────────────────────────────────────────────── */
.mt-head {
display: flex; align-items: center; justify-content: space-between;
gap: 12px; margin-bottom: 16px;
}
.mt-head h1 {
margin: 0; font-size: 24px; font-weight: 700; color: var(--text-primary);
}
.mt-count-total { font-size: 13px; color: var(--text-secondary); }
/* ── Barre d'outils ─────────────────────────────────────────────────── */
.mt-toolbar {
display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
justify-content: space-between; margin-bottom: 10px;
}
.mt-toolbar-left,
.mt-toolbar-right {
display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
}
.mt-view-tabs { display: flex; gap: 2px; align-items: center; }
.mt-view-tab {
display: flex; align-items: center; gap: 6px;
padding: 6px 12px; font-size: 13px; font-weight: 500;
color: var(--text-secondary); background: transparent;
border: none; border-radius: 6px; cursor: pointer;
text-decoration: none; white-space: nowrap; transition: all .12s;
}
.mt-view-tab:hover { color: var(--text-primary); background: var(--bg-hover); }
.mt-view-tab.active { color: var(--text-primary); background: var(--bg-active); }
.mt-select {
font: inherit; font-size: 13px; padding: 5px 8px; border-radius: 6px;
border: 1px solid var(--border);
background: var(--bg-primary); color: var(--text-primary);
}
.mt-toggle {
font-size: 13px; color: var(--text-secondary);
display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
}
.mt-new-btn,
.mt-empty-btn {
font: inherit; font-size: 13px; font-weight: 600;
padding: 6px 14px; border-radius: 6px; border: none; cursor: pointer;
text-decoration: none; display: inline-block;
background: var(--accent, #2383e2); color: #fff;
}
.mt-new-btn:hover,
.mt-empty-btn:hover { filter: brightness(1.08); }
/* ── Sources connectées ─────────────────────────────────────────────── */
.mt-sources {
display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
padding: 8px 0 14px; margin-bottom: 16px;
border-bottom: 1px solid var(--border, #eee);
}
.mt-sources-label { font-size: 12px; color: var(--text-dim, #999); margin-right: 4px; }
.mt-source-chip {
font-size: 12px; padding: 3px 9px; border-radius: 20px; text-decoration: none;
border: 1px solid var(--border, #e3e3e0);
color: var(--text, #333); background: var(--bg-primary, #fff);
}
.mt-source-chip.pending { border-style: dashed; color: var(--text-dim, #999); }
.mt-source-chip:hover { border-color: var(--accent, #2383e2); }
.mt-sources-warn { font-size: 12px; color: #c9820a; }
/* ── Vue tableau ──────────────────────────────────────────────────────────
* Lignes en `div` (et non `<table>`) : meme choix que Library, qui le permet
* d'afficher les actions de ligne UNIQUEMENT au survol (`.hover-only`).
*/
.mt-table { width: 100%; }
.mt-thead {
display: flex; align-items: center; border-bottom: 1px solid var(--border);
}
.mt-th {
display: flex; align-items: center; padding: 6px 8px;
font-size: 12px; font-weight: 500; color: var(--text-dim);
white-space: nowrap; user-select: none;
}
.mt-row {
display: flex; align-items: center; height: 38px;
border-bottom: 1px solid var(--border); transition: background .1s;
}
.mt-row:last-child { border-bottom: none; }
.mt-row:hover { background: var(--bg-hover); }
.mt-cell {
display: flex; align-items: center; padding: 0 8px;
height: 100%; overflow: hidden;
}
.mt-cell-name { flex: 1; min-width: 0; gap: 6px; }
.mt-cell-status,
.mt-cell-due { width: 165px; flex-shrink: 0; }
.mt-cell-src { width: 210px; flex-shrink: 0; }
.mt-icon {
font-size: 15px; flex-shrink: 0; width: 20px; text-align: center;
display: inline-flex; align-items: center; justify-content: center;
}
.mt-title-text {
font-size: 13px; color: var(--text-primary); cursor: text;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
min-width: 0; flex: 1 1 auto;
}
.mt-title-text:hover { text-decoration: underline; }
.mt-title-input {
font: inherit; width: 100%; padding: 3px 6px; border-radius: 4px;
border: 1px solid var(--accent);
background: var(--bg-primary); color: var(--text-primary);
}
.mt-status-select,
.mt-due-input {
font: inherit; font-size: 13px; padding: 4px 6px; border-radius: 5px;
border: 1px solid var(--border);
background: var(--bg-primary); color: var(--text-primary);
max-width: 100%; width: 100%;
}
.mt-due-overdue { border-color: #e05252; color: #e05252; }
.mt-due-today { border-color: #c9820a; color: #c9820a; font-weight: 600; }
.mt-chip {
font-size: 12px; padding: 3px 8px; border-radius: 5px; text-decoration: none;
background: var(--bg-hover); color: var(--text-secondary);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mt-chip:hover { color: var(--accent); }
.mt-static { font-size: 13px; color: var(--text-secondary); }
/* ── Bouton « Open » + actions visibles au survol ──────────────────────────
* Mêmes valeurs que `.btn-open` / `.hover-only` de Library
* (`app/templates/library.html`) : même aspect, même révélation au survol.
*/
.mt-hover-only { opacity: 0; transition: opacity .12s; flex-shrink: 0; }
.mt-row:hover .mt-hover-only,
.mt-row:focus-within .mt-hover-only { opacity: 1; }
.mt-open-btn {
display: inline-flex; align-items: center; gap: 4px;
padding: 3px 8px; border: 1px solid var(--border); border-radius: 4px;
font-size: 11px; font-weight: 500; color: var(--text-primary);
background: var(--bg-tertiary); cursor: pointer; white-space: nowrap;
transition: all .1s; flex-shrink: 0; text-decoration: none; margin-left: auto;
}
.mt-open-btn:hover { background: var(--bg-active); }
.mt-open-btn svg { width: 12px; height: 12px; }
@media (hover: none) {
/* Écrans tactiles : pas de survol, l'action doit rester visible. */
.mt-hover-only { opacity: 1; }
}
/* ── Side peek (panneau latéral, sur le modèle de Library) ───────────────
* `?embed=1` charge l'éditeur du document dans l'iframe, comme le peek de
* Library : on lit la tâche sans quitter le tableau de bord.
*/
.mt-peek {
position: fixed; top: 0; right: 0; width: 560px; max-width: 90vw;
height: 100vh; z-index: 500; display: flex; flex-direction: column;
background: var(--bg-modal); border-left: 1px solid var(--border);
box-shadow: -8px 0 32px rgba(0, 0, 0, .25);
transform: translateX(100%); transition: transform .2s cubic-bezier(.16, 1, .3, 1);
}
.mt-peek.open { transform: translateX(0); }
.mt-peek-handle {
position: absolute; left: -4px; top: 0; width: 8px; height: 100%;
cursor: col-resize; z-index: 501;
}
.mt-peek-head {
display: flex; align-items: center; gap: 4px; flex-shrink: 0;
padding: 12px 16px; border-bottom: 1px solid var(--border);
}
.mt-peek-title {
flex: 1; min-width: 0; font-size: 15px; font-weight: 600;
color: var(--text-primary); display: flex; align-items: center; gap: 8px;
overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.mt-peek-btn {
background: transparent; border: none; color: var(--text-secondary);
cursor: pointer; padding: 6px; border-radius: 4px;
display: inline-flex; align-items: center;
}
.mt-peek-btn:hover { background: var(--bg-hover); color: var(--text-primary); }
.mt-peek-btn svg { width: 15px; height: 15px; }
.mt-peek-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mt-peek-body iframe { flex: 1; width: 100%; border: none; min-height: 0; }
.mt-peek-loading {
padding: 40px; text-align: center; color: var(--text-dim); font-size: 13px;
}
@media (max-width: 768px) {
.mt-peek { width: 100vw; max-width: 100vw; }
}
/* ── Vue kanban ─────────────────────────────────────────────────────── */
.mt-board { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 12px; }
.mt-col {
min-width: 240px; flex: 1 0 240px; padding: 10px; border-radius: 10px;
background: var(--bg-secondary, #f7f7f5);
}
.mt-col-head { font-size: 12px; font-weight: 600; color: var(--text-dim, #777); margin-bottom: 8px; }
.mt-count { opacity: .6; font-weight: 400; }
.mt-col-body { display: flex; flex-direction: column; gap: 6px; min-height: 60px; }
.mt-card {
display: flex; flex-direction: column; gap: 4px; padding: 9px 10px;
border: 1px solid var(--border, #e3e3e0); border-radius: 7px;
background: var(--bg-primary, #fff); font-size: 13px; cursor: grab;
}
.mt-card:active { cursor: grabbing; opacity: .7; }
.mt-card-title { font-weight: 500; }
.mt-card-due,
.mt-card-src { font-size: 11px; color: var(--text-dim, #999); }
.mt-card-src { opacity: .8; }
/* ── Vue calendrier ─────────────────────────────────────────────────── */
.mt-cal {
border: 1px solid var(--border, #eee); border-radius: 10px; overflow: hidden;
}
.mt-cal-head {
display: flex; align-items: center; justify-content: center; gap: 12px;
padding: 10px; border-bottom: 1px solid var(--border, #eee);
}
.mt-cal-title { font-size: 14px; font-weight: 600; text-transform: capitalize; }
.mt-cal-nav {
padding: 2px 9px; border: 1px solid var(--border, #e3e3e0); border-radius: 5px;
background: var(--bg-primary, #fff); color: var(--text, #333);
font-size: 15px; cursor: pointer;
}
.mt-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.mt-cal-dow {
padding: 6px 0; text-align: center; font-size: 11px;
color: var(--text-dim, #999); border-bottom: 1px solid var(--border, #eee);
}
.mt-cal-cell {
min-height: 92px; padding: 5px 6px; font-size: 12px;
border-right: 1px solid var(--border, #f0f0f0);
border-bottom: 1px solid var(--border, #f0f0f0);
}
.mt-cal-cell.out { opacity: .4; }
.mt-cal-cell.today { background: var(--bg-hover, rgba(35, 131, 226, .07)); }
.mt-cal-day { margin-bottom: 4px; font-size: 11px; color: var(--text-dim, #999); }
.mt-cal-ev:hover { background: var(--bg-hover); }
.mt-cal-ev:hover .mt-cal-open { opacity: 1; }
/* ── Calendrier : sélecteur de vue + 4 vues supplémentaires ───────────── */
.mt-cal-body { padding: 8px; }
.mt-cal-tabs {
display: flex; gap: 2px; padding: 6px 8px 0;
border-bottom: 1px solid var(--border);
}
.mt-cal-tab {
padding: 5px 11px; font-size: 12.5px; font-weight: 500;
color: var(--text-secondary); background: transparent;
border: none; border-bottom: 2px solid transparent;
cursor: pointer; transition: all .12s;
}
.mt-cal-tab:hover { color: var(--text-primary); }
.mt-cal-tab.active { color: var(--text-primary); border-bottom-color: var(--accent); }
/* Événement : titre + bouton d'ouverture révélé au survol. */
.mt-cal-ev {
display: flex; align-items: center; gap: 4px;
margin-bottom: 3px; padding: 2px 5px; border-radius: 4px;
background: var(--bg-hover); font-size: 12px; min-width: 0;
}
.mt-cal-ev.drag { cursor: grab; }
.mt-cal-ev-text {
flex: 1; min-width: 0; overflow: hidden;
text-overflow: ellipsis; white-space: nowrap;
}
.mt-cal-open {
flex-shrink: 0; display: inline-flex; align-items: center;
padding: 1px; border: none; border-radius: 3px; cursor: pointer;
background: transparent; color: var(--text-secondary);
}
.mt-cal-open svg { width: 11px; height: 11px; display: block; }
.mt-cal-open:hover { background: var(--bg-active); color: var(--text-primary); }
/* Vue année : 12 mini-mois. */
.mt-cal-year {
display: grid; grid-template-columns: repeat(4, 1fr);
gap: 14px; padding: 10px;
}
.mt-cal-mini-title {
font-size: 12px; font-weight: 600; color: var(--text-secondary);
text-transform: capitalize; margin-bottom: 5px;
}
.mt-cal-mini-grid {
display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px;
}
.mt-cal-mini-dow {
font-size: 9px; color: var(--text-dim); text-align: center; padding: 1px 0;
}
.mt-cal-mini-day {
font: inherit; font-size: 10.5px; padding: 3px 0; border: none;
border-radius: 4px; cursor: pointer; position: relative;
background: transparent; color: var(--text-primary);
}
.mt-cal-mini-day:hover { background: var(--bg-hover); }
.mt-cal-mini-day.out { visibility: hidden; }
.mt-cal-mini-day.today { background: var(--accent); color: #fff; }
.mt-cal-mini-day.busy::after {
content: ''; position: absolute; left: 50%; bottom: 1px;
width: 3px; height: 3px; margin-left: -1.5px; border-radius: 50%;
background: var(--accent);
}
.mt-cal-mini-day.today.busy::after { background: #fff; }
/* Vue semaine : 7 colonnes. */
.mt-cal-week {
display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px;
background: var(--border); min-height: 180px;
}
.mt-cal-wcol { background: var(--bg-primary); padding: 6px; min-width: 0; }
.mt-cal-wcol.today { background: var(--bg-hover); }
.mt-cal-wcol-head {
font-size: 11px; font-weight: 600; color: var(--text-secondary);
margin-bottom: 6px; padding-bottom: 4px; border-bottom: 1px solid var(--border);
}
.mt-cal-wcol-body { display: flex; flex-direction: column; gap: 3px; }
.mt-cal-wempty { font-size: 12px; color: var(--text-dim); text-align: center; }
/* Vue jour : liste détaillée. */
.mt-cal-dayview { padding: 10px 12px 14px; }
.mt-cal-dayview-head {
font-size: 12px; color: var(--text-secondary); margin-bottom: 10px;
}
.mt-cal-dayview-empty {
font-size: 13px; color: var(--text-dim); padding: 26px 0; text-align: center;
}
.mt-cal-task {
display: flex; align-items: center; gap: 10px;
padding: 7px 8px; border-bottom: 1px solid var(--border);
}
.mt-cal-task:hover { background: var(--bg-hover); }
.mt-cal-task-title {
flex: 1; min-width: 0; font-size: 13px; color: var(--text-primary);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mt-cal-task-src, .mt-cal-task-status { font-size: 12px; color: var(--text-dim); }
.mt-cal-task-status { width: 130px; flex-shrink: 0; }
/* Vue planning : colonnes = statuts, lignes = jours. */
.mt-cal-plan { overflow-x: auto; max-height: 60vh; overflow-y: auto; }
.mt-cal-plan-row { display: flex; align-items: stretch; min-width: 520px; }
.mt-cal-plan-row.head { position: sticky; top: 0; z-index: 2; background: var(--bg-primary); }
.mt-cal-plan-gutter {
width: 44px; flex-shrink: 0; padding: 4px 6px;
font-size: 11px; color: var(--text-dim); text-align: right;
border-bottom: 1px solid var(--border);
}
.mt-cal-plan-col-title {
flex: 1; min-width: 0; padding: 4px 8px;
font-size: 11px; font-weight: 600; color: var(--text-secondary);
border-bottom: 1px solid var(--border);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mt-cal-plan-cell {
flex: 1; min-width: 0; padding: 3px 5px;
border-bottom: 1px solid var(--border);
border-left: 1px solid var(--border);
}
.mt-cal-plan-row.today .mt-cal-plan-gutter {
color: var(--accent); font-weight: 700;
}
@media (max-width: 768px) {
.mt-cal-year { grid-template-columns: repeat(2, 1fr); }
}
/* ── États vides ──────────────────────────────────────────────────────────
* Bloc centré dans la surface disponible : invite de conversion
* (`.my-tasks-empty`, rendu serveur) comme états vides du tableau de bord
* (`.mt-empty`, rendu client). Même gabarit pour que les deux se ressemblent.
*/
.my-tasks-empty,
.mt-empty {
display: flex; flex-direction: column; align-items: center;
text-align: center; padding: 72px 24px 80px;
max-width: 620px; margin: 0 auto;
}
.my-tasks-empty-icon,
.mt-empty-icon {
display: flex; align-items: center; justify-content: center;
width: 64px; height: 64px; margin-bottom: 20px; font-size: 30px;
border-radius: 50%;
background: var(--bg-hover, rgba(0, 0, 0, .04));
border: 1px solid var(--border, #e3e3e0);
}
.my-tasks-empty h2,
.mt-empty h2 {
margin: 0 0 10px; font-size: 19px; font-weight: 600; color: var(--text-primary, #333);
}
.my-tasks-empty p,
.mt-empty p {
margin: 0 0 8px; font-size: 14px; line-height: 1.6;
color: var(--text-secondary, #666);
}
.my-tasks-empty-hint,
.mt-empty-hint {
font-size: 13px; color: var(--text-dim, #888);
}
.my-tasks-empty-steps,
.mt-empty-steps {
margin: 20px 0 0; padding: 14px 18px; list-style: none;
display: inline-flex; flex-direction: column; gap: 8px; text-align: left;
border: 1px solid var(--border, #e3e3e0);
border-radius: 10px; background: var(--bg-secondary, #fafafa);
font-size: 13px; color: var(--text-secondary, #666);
}
.my-tasks-empty-steps li,
.mt-empty-steps li { display: flex; align-items: flex-start; gap: 9px; }
.my-tasks-empty-steps .n,
.mt-empty-steps .n {
flex-shrink: 0; width: 20px; height: 20px; margin-top: -1px;
display: flex; align-items: center; justify-content: center;
border-radius: 50%; background: var(--bg-primary, #fff);
border: 1px solid var(--border-strong, #d3d3d0);
font-size: 11px; font-weight: 700; color: var(--text-dim, #999);
}
.my-tasks-empty-btn,
.mt-empty-btn {
display: inline-block; margin-top: 22px; padding: 9px 20px; border-radius: 8px;
background: var(--accent, #2383e2); color: #fff;
font-size: 14px; font-weight: 600; text-decoration: none; border: none;
cursor: pointer; font-family: inherit;
}
.my-tasks-empty-btn:hover,
.mt-empty-btn:hover { background: var(--accent-hover, #1a6bc0); filter: none; }
/* ── Modale « nouvelle tâche » (multi-destinations) ─────────────────── */
.mt-modal-overlay {
position: fixed; inset: 0; z-index: 1000; padding-top: 12vh;
display: flex; align-items: flex-start; justify-content: center;
background: rgba(0, 0, 0, .4);
}
.mt-modal {
width: 460px; max-width: 92vw; overflow: hidden; border-radius: 12px;
background: var(--bg-primary, #fff); box-shadow: 0 18px 60px rgba(0, 0, 0, .25);
}
.mt-modal-head {
display: flex; align-items: center; justify-content: space-between;
padding: 14px 16px; font-size: 14px; font-weight: 600;
border-bottom: 1px solid var(--border, #eee);
}
.mt-modal-close {
border: none; background: none; color: var(--text-dim, #888);
font-size: 14px; cursor: pointer;
}
.mt-modal-body {
display: flex; flex-direction: column; gap: 12px;
max-height: 55vh; overflow-y: auto; padding: 16px;
}
.mt-field {
display: flex; flex-direction: column; gap: 4px;
font-size: 12px; color: var(--text-dim, #888);
}
.mt-field input {
font: inherit; font-size: 14px; padding: 7px 9px; border-radius: 6px;
border: 1px solid var(--border, #e3e3e0);
background: var(--bg-primary, #fff); color: var(--text, #333);
}
.mt-modal-group {
margin-top: 4px; font-size: 11px; text-transform: uppercase;
letter-spacing: .5px; color: var(--text-dim, #999);
}
.mt-dest {
display: flex; align-items: center; gap: 8px; padding: 6px 8px;
border-radius: 6px; font-size: 13px; cursor: pointer;
}
.mt-dest:hover { background: var(--bg-hover, rgba(0, 0, 0, .04)); }
.mt-modal-foot {
display: flex; justify-content: flex-end; gap: 8px;
padding: 12px 16px; border-top: 1px solid var(--border, #eee);
}
.mt-btn-cancel,
.mt-btn-primary {
font: inherit; font-size: 13px; padding: 7px 16px; border-radius: 6px;
border: 1px solid var(--border, #e3e3e0); background: transparent;
color: var(--text, #333); cursor: pointer;
}
.mt-btn-primary {
border-color: transparent; background: var(--accent, #2383e2);
color: #fff; font-weight: 600;
}
/* ── Modale « Convertir en base de tâches » (task_db_link.js) ─────────── */
.tdb-overlay {
position: fixed; inset: 0; z-index: 1000; padding-top: 10vh;
display: flex; align-items: flex-start; justify-content: center;
background: rgba(0, 0, 0, .4);
}
.tdb-modal {
width: 520px; max-width: 94vw; overflow: hidden; border-radius: 12px;
background: var(--bg-modal, var(--bg-primary, #fff));
box-shadow: 0 18px 60px rgba(0, 0, 0, .25); color: var(--text-primary, #333);
}
.tdb-head {
display: flex; align-items: center; justify-content: space-between;
padding: 14px 16px; font-size: 14px; font-weight: 600;
border-bottom: 1px solid var(--border, #eee);
}
.tdb-close {
border: none; background: none; color: var(--text-dim, #888);
font-size: 14px; cursor: pointer;
}
.tdb-intro {
padding: 12px 16px 0; font-size: 12.5px; line-height: 1.5;
color: var(--text-secondary, #666);
}
.tdb-intro a { color: var(--accent, #2383e2); }
.tdb-body { display: flex; flex-direction: column; gap: 14px; padding: 14px 16px; }
.tdb-role-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 5px; }
.tdb-role-head label { font-size: 13px; font-weight: 600; }
.tdb-role-hint { font-size: 11.5px; color: var(--text-dim, #999); }
.tdb-role-body { display: flex; gap: 8px; }
.tdb-select,
.tdb-new-name {
font: inherit; font-size: 13px; padding: 6px 8px; border-radius: 6px;
border: 1px solid var(--border, #e3e3e0);
background: var(--bg-primary, #fff); color: var(--text-primary, #333);
}
.tdb-select { flex: 1 1 auto; min-width: 0; }
.tdb-new-name { flex: 1 1 auto; min-width: 0; }
.tdb-warn {
margin: 0 16px 4px; padding: 8px 10px; border-radius: 6px; font-size: 12px;
background: rgba(201, 130, 10, .12); color: #c9820a;
}
.tdb-foot {
display: flex; align-items: center; gap: 8px;
padding: 12px 16px; border-top: 1px solid var(--border, #eee);
}
.tdb-spacer { flex: 1; }
.tdb-btn,
.tdb-btn-primary,
.tdb-btn-danger {
font: inherit; font-size: 13px; padding: 7px 16px; border-radius: 6px;
border: 1px solid var(--border, #e3e3e0); background: transparent;
color: var(--text-primary, #333); cursor: pointer;
}
.tdb-btn-primary {
border-color: transparent; background: var(--accent, #2383e2);
color: #fff; font-weight: 600;
}
.tdb-btn-primary:disabled { opacity: .5; cursor: not-allowed; }
.tdb-btn-danger { color: #e5484d; border-color: rgba(229, 72, 77, .4); }
/* ── Page « /db » : liste des bases du workspace ─────────────────────────
* En-tête recentré (page de destination du bouton « Ouvrir mes bases »),
* grille de cartes à gauche pour rester lisible sur les longues listes.
*/
.db-index { padding: 40px 24px 64px; max-width: 1100px; margin: 0 auto; }
.db-index-head {
display: flex; align-items: center; justify-content: center;
flex-wrap: wrap; gap: 10px; margin-bottom: 6px; text-align: center;
}
.db-index-head h1 { margin: 0; font-size: 24px; }
.db-index-ws {
font-size: 12px; color: var(--text-dim, #999);
padding: 2px 9px; border-radius: 20px;
border: 1px solid var(--border, #e3e3e0);
}
.db-index-sub {
max-width: 640px; margin: 0 auto 26px; text-align: center;
font-size: 13.5px; line-height: 1.6; color: var(--text-secondary, #666);
}
.db-index-sub a { color: var(--accent, #2383e2); }
.db-grid {
display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px;
}
.db-card {
display: flex; flex-direction: column; gap: 6px;
padding: 16px 16px; border-radius: 12px; text-decoration: none;
border: 1px solid var(--border, #e3e3e0);
background: var(--bg-primary, #fff); color: var(--text, #333);
transition: border-color .12s, box-shadow .12s, transform .12s;
}
.db-card:hover {
border-color: var(--accent, #2383e2);
box-shadow: 0 4px 16px rgba(0, 0, 0, .09);
transform: translateY(-1px);
}
.db-card-head { display: flex; align-items: center; gap: 8px; }
.db-card-icon { font-size: 19px; }
.db-card-name {
flex: 1; min-width: 0; font-size: 14px; font-weight: 600;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.db-card-badge {
flex-shrink: 0; font-size: 11px; font-weight: 600;
padding: 2px 8px; border-radius: 20px;
}
.db-card-badge.ok { background: rgba(0, 200, 100, .14); color: #00a35a; }
.db-card-badge.warn { background: rgba(201, 130, 10, .14); color: #c9820a; }
.db-card-meta { font-size: 11.5px; color: var(--text-dim, #999); }
.db-card-hint { font-size: 12px; line-height: 1.45; color: var(--text-secondary, #666); }
/* État vide de `/db` : bloc centré dans la surface disponible. */
.db-empty {
display: flex; flex-direction: column; align-items: center;
text-align: center; padding: 72px 24px 80px;
max-width: 620px; margin: 0 auto;
}
.db-empty-icon {
display: flex; align-items: center; justify-content: center;
width: 64px; height: 64px; margin-bottom: 20px; font-size: 30px;
border-radius: 50%;
background: var(--bg-hover, rgba(0, 0, 0, .04));
border: 1px solid var(--border, #e3e3e0);
}
.db-empty h1 { margin: 0 0 10px; font-size: 19px; font-weight: 600; }
.db-empty p {
margin: 0 0 8px; font-size: 14px; line-height: 1.6;
color: var(--text-secondary, #666);
}
.db-empty-hint { max-width: 520px; font-size: 13px; }
.db-empty-hint code {
padding: 1px 5px; border-radius: 4px; font-size: 12px;
background: var(--bg-hover, rgba(0, 0, 0, .05));
}
/* ── Bouton « Convertir en base de tâches » (barre de la base) ────────── */
.db-task-db-btn {
display: inline-flex; align-items: center; gap: 6px;
padding: 5px 11px; border-radius: 6px;
border: 1px solid var(--border, #e3e3e0);
background: transparent; color: var(--text-secondary, #555);
font-size: 12.5px; font-weight: 500; cursor: pointer; white-space: nowrap;
}
.db-task-db-btn:hover {
border-color: var(--accent, #2383e2);
color: var(--accent, #2383e2);
background: var(--bg-hover, rgba(35, 131, 226, .07));
}
.mt-source-fix {
font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 20px;
border: 1px solid rgba(201, 130, 10, .45); background: transparent;
color: #c9820a; cursor: pointer;
}
.mt-source-fix:hover { background: rgba(201, 130, 10, .12); }
.db-section-title {
margin: 38px 0 4px; font-size: 15px; font-weight: 600; color: var(--text, #333);
text-align: center;
}
.db-section-sub {
max-width: 640px; margin: 0 auto 14px; text-align: center;
font-size: 12.5px; line-height: 1.55; color: var(--text-dim, #888);
}