/* Self-contained colors + explicit dark-mode overrides, since Gin's dark mode (html.gin--dark-mode) is enabled by default here. */ #figli-dashboard-app { --figli-bg: #ffffff; --figli-bg-alt: #f5f6f8; --figli-text: #1a1a1a; --figli-text-light: #6b7280; --figli-border: #dcdee2; --figli-error: #c9312b; --figli-positive: #1a7f37; --figli-warning: #b8860b; font-family: Inter, -apple-system, sans-serif; max-width: 1200px; margin: 1rem 0; color: var(--figli-text); } html.gin--dark-mode #figli-dashboard-app { --figli-bg: #232426; --figli-bg-alt: #2c2d30; --figli-text: #e8e9ea; --figli-text-light: #a1a5ab; --figli-border: #3d3e42; --figli-error: #ff6b6b; --figli-positive: #4ade80; --figli-warning: #f0b429; } #figli-dashboard-app h2 { font-size: 1.1rem; font-weight: 600; margin: 0 0 0.25rem; color: var(--figli-text); } #figli-dashboard-app .figli-note { color: var(--figli-text-light); font-size: 0.8rem; margin-bottom: 1rem; } #figli-dashboard-app .figli-error { background: #fde8e8; border: 1px solid #f4a3a3; color: #7a1a1a; padding: 0.75rem 1rem; border-radius: 6px; } /* --- Summary cards --- */ #figli-dashboard-app .figli-summary-row { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-bottom: 2rem; } #figli-dashboard-app .figli-summary-card { flex: 1 1 200px; background: var(--figli-bg-alt); border: 1px solid var(--figli-border); border-radius: 8px; padding: 0.85rem 1rem; } #figli-dashboard-app .figli-summary-label { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.02em; color: var(--figli-text-light); margin-bottom: 0.3rem; } #figli-dashboard-app .figli-summary-value { font-size: 1.4rem; font-weight: 700; font-variant-numeric: tabular-nums; } #figli-dashboard-app .figli-summary-value.is-positive { color: var(--figli-positive); } #figli-dashboard-app .figli-summary-value.is-negative { color: var(--figli-error); } #figli-dashboard-app .figli-summary-card.is-alert { border-color: var(--figli-error); } /* --- Compte selector (dashboard par compte) --- */ #figli-dashboard-app .figli-compte-selector { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 1.25rem; } #figli-dashboard-app .figli-compte-selector label { font-size: 0.85rem; font-weight: 600; color: var(--figli-text-light); } #figli-dashboard-app .figli-compte-selector select { font-size: 1rem; font-weight: 600; padding: 0.4rem 0.6rem; border: 1px solid var(--figli-border); border-radius: 6px; background: var(--figli-bg); color: var(--figli-text); } /* Signalement filter (Lignes signalées section) -- same multiselect widget as /lignes' Compte/Type filters (home.css), duplicated here rather than shared, see this project's established convention for dashboard.js/dashboard-compte.js vs home.js. */ #figli-dashboard-app .figli-filter-row { display: flex; align-items: center; gap: 0.25rem; } #figli-dashboard-app .figli-filter-clear { background: transparent; border: none; color: var(--figli-text-light); cursor: pointer; font-size: 0.8rem; line-height: 1; padding: 0.15rem; } #figli-dashboard-app .figli-filter-clear:hover { color: var(--figli-error); } #figli-dashboard-app .figli-multiselect { position: relative; } #figli-dashboard-app .figli-multiselect-trigger { font-size: 0.85rem; padding: 0.2rem 0.4rem; background: var(--figli-bg); color: var(--figli-text); border: 1px solid var(--figli-border); border-radius: 4px; width: 12rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: default; } #figli-dashboard-app .figli-multiselect-arrow { float: right; color: var(--figli-text-light); } #figli-dashboard-app .figli-multiselect-panel { display: none; position: absolute; top: 100%; left: 0; z-index: 20; min-width: 100%; white-space: nowrap; background: var(--figli-bg); color: var(--figli-text); border: 1px solid var(--figli-border); border-radius: 4px; padding: 0.3rem 0.5rem; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); } #figli-dashboard-app .figli-multiselect:hover .figli-multiselect-panel { display: block; } #figli-dashboard-app .figli-multiselect-option { display: flex !important; flex-direction: row !important; align-items: center; gap: 0.35rem; font-size: 0.8rem; font-weight: 400; padding: 0.15rem 0; } /* --- Reconciliation tables (reste à verser, sur-versé, non liés) --- */ #figli-dashboard-app .figli-recon-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; } #figli-dashboard-app .figli-recon-table th { text-align: left; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.02em; color: var(--figli-text-light); padding: 0.3rem 0.6rem; border-bottom: 1px solid var(--figli-border); } #figli-dashboard-app .figli-recon-table td { padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--figli-border); font-variant-numeric: tabular-nums; } #figli-dashboard-app .figli-recon-table td.is-negative { color: var(--figli-error); font-weight: 600; } #figli-dashboard-app .figli-recon-table tbody tr:hover { background: var(--figli-bg-alt); } #figli-dashboard-app .figli-recon-table tfoot td { font-weight: 700; border-bottom: none; border-top: 2px solid var(--figli-border); } #figli-dashboard-app .figli-recon-table a { color: inherit; text-decoration: underline; text-decoration-color: var(--figli-border); } /* Signalée rows: same amber left-edge accent as /lignes (box-shadow, not border, so it doesn't fight the row's existing bottom border). */ #figli-dashboard-app .figli-recon-table tr.figli-flag-row td:first-child { box-shadow: inset 4px 0 0 var(--figli-warning); } #figli-dashboard-app .figli-flag-badge { display: inline-block; padding: 0.05rem 0.4rem; margin: 0 0 0 0.4rem; border-radius: 8px; font-size: 0.68rem; font-weight: 600; background: color-mix(in srgb, var(--figli-warning) 15%, transparent); color: var(--figli-warning); white-space: nowrap; } /* --- Year bars chart (évolution du solde, entrées vs versements) --- */ #figli-dashboard-app .figli-year-chart { display: flex; align-items: stretch; gap: 0.5rem; height: 14rem; } #figli-dashboard-app .figli-year-col { flex: 1; display: flex; flex-direction: column; align-items: center; min-width: 1.5rem; } #figli-dashboard-app .figli-year-track { position: relative; flex: 1; width: 100%; } #figli-dashboard-app .figli-year-track::before { content: ''; position: absolute; top: 50%; left: 0; right: 0; height: 1px; background: var(--figli-border); } #figli-dashboard-app .figli-year-bars { position: absolute; inset: 0; display: flex; justify-content: center; gap: 2px; } /* Slot stays in normal flex flow (so justify-content/gap on .figli-year-bars above still lays several bars out side by side) and gives the bar a definite height (100% of the track) to anchor against. The bar itself must be position: absolute, not relative -- with relative, an explicit height opts it out of the flex stretch default, so it renders flex-start (top) aligned *first*, and the top/bottom: 50% from barStyle() only *offsets* that already-top position instead of anchoring the edge to the middle -- the visible bug this replaces (bars pinned near the top instead of growing from the zero line). */ #figli-dashboard-app .figli-year-bar-slot { position: relative; width: 0.9rem; height: 100%; } #figli-dashboard-app .figli-year-bar { position: absolute; left: 0; right: 0; min-height: 2px; border-radius: 2px; } @media (prefers-reduced-motion: no-preference) { #figli-dashboard-app .figli-year-bar { transition: height 0.3s ease; } } #figli-dashboard-app .figli-year-label { font-size: 0.78rem; color: var(--figli-text-light); margin-top: 0.4rem; } /* --- Chart sections --- */ #figli-dashboard-app .figli-chart-section { background: var(--figli-bg); border: 1px solid var(--figli-border); border-radius: 8px; padding: 1.25rem 1.5rem 1.5rem; margin-bottom: 1.5rem; } /* --- Horizontal bar chart (solde par compte, par type, top clients) --- */ #figli-dashboard-app .figli-hbar-chart { display: flex; flex-direction: column; gap: 0.5rem; } #figli-dashboard-app .figli-hbar-row { display: grid; grid-template-columns: 11rem 1fr 7rem; align-items: center; gap: 0.75rem; } #figli-dashboard-app .figli-hbar-label { font-size: 0.82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } #figli-dashboard-app .figli-hbar-track { position: relative; height: 0.9rem; background: var(--figli-bg-alt); border-radius: 4px; overflow: hidden; } #figli-dashboard-app .figli-hbar-track.is-diverging { overflow: visible; } #figli-dashboard-app .figli-hbar-zero { position: absolute; top: -2px; bottom: -2px; left: 50%; width: 1px; background: var(--figli-border); } #figli-dashboard-app .figli-hbar-fill { position: absolute; top: 0; bottom: 0; border-radius: 3px; min-width: 2px; } @media (prefers-reduced-motion: no-preference) { #figli-dashboard-app .figli-hbar-fill { transition: width 0.3s ease; } } #figli-dashboard-app .figli-hbar-value { font-size: 0.8rem; font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; } /* Compact variant -- same chart, narrower fixed columns and smaller text so it fits inside a small-multiples grid card (see .figli-year-hbar-grid below) instead of the full-width layout. */ #figli-dashboard-app .figli-hbar-chart.is-compact { gap: 0.3rem; } #figli-dashboard-app .figli-hbar-chart.is-compact .figli-hbar-row { grid-template-columns: 5.5rem 1fr 3.5rem; gap: 0.4rem; } #figli-dashboard-app .figli-hbar-chart.is-compact .figli-hbar-label { font-size: 0.72rem; } #figli-dashboard-app .figli-hbar-chart.is-compact .figli-hbar-track { height: 0.65rem; } #figli-dashboard-app .figli-hbar-chart.is-compact .figli-hbar-value { font-size: 0.7rem; } /* Total line under an h-bar-chart (currently just Charges structurelles par client, main chart and each per-année card) -- separate from the chart component itself, plain right-aligned text matching .figli-hbar-value's alignment/tabular-nums so the total lines up visually with the bars' own value column above it. */ #figli-dashboard-app .figli-chart-total { margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px solid var(--figli-border); text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; } #figli-dashboard-app .figli-chart-total.is-compact { margin-top: 0.4rem; padding-top: 0.4rem; font-size: 0.72rem; } /* --- Year small multiples (par année, next to the all-time chart) --- */ #figli-dashboard-app .figli-year-hbar-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 0.75rem; margin-top: 1.25rem; padding-top: 1.25rem; border-top: 1px solid var(--figli-border); } #figli-dashboard-app .figli-year-hbar-card { background: var(--figli-bg-alt); border: 1px solid var(--figli-border); border-radius: 6px; padding: 0.65rem 0.75rem; } #figli-dashboard-app .figli-year-hbar-title { font-size: 0.78rem; font-weight: 700; color: var(--figli-text-light); margin-bottom: 0.5rem; } /* --- Vertical bar chart (CA par année) --- */ #figli-dashboard-app .figli-vbar-chart { display: flex; align-items: flex-end; gap: 1rem; height: 12rem; padding-top: 1.5rem; } #figli-dashboard-app .figli-vbar-col { flex: 1; display: flex; flex-direction: column; align-items: center; height: 100%; } #figli-dashboard-app .figli-vbar-value { font-size: 0.75rem; font-weight: 600; margin-bottom: 0.3rem; white-space: nowrap; } #figli-dashboard-app .figli-vbar-track { flex: 1; width: 100%; display: flex; align-items: flex-end; } #figli-dashboard-app .figli-vbar-fill { width: 100%; background: var(--figli-positive); border-radius: 4px 4px 0 0; min-height: 2px; } @media (prefers-reduced-motion: no-preference) { #figli-dashboard-app .figli-vbar-fill { transition: height 0.3s ease; } } #figli-dashboard-app .figli-vbar-label { font-size: 0.78rem; color: var(--figli-text-light); margin-top: 0.4rem; } /* --- Trend grid (small multiples, one per compte) --- */ #figli-dashboard-app .figli-trend-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: 1rem; } #figli-dashboard-app .figli-trend-card { background: var(--figli-bg-alt); border: 1px solid var(--figli-border); border-radius: 6px; padding: 0.75rem; } #figli-dashboard-app .figli-trend-title { font-size: 0.85rem; font-weight: 600; margin-bottom: 0.5rem; } #figli-dashboard-app .figli-mini-trend { display: flex; align-items: stretch; gap: 0.2rem; height: 4.5rem; } #figli-dashboard-app .figli-mini-bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; } #figli-dashboard-app .figli-mini-bar-track { position: relative; flex: 1; width: 100%; } #figli-dashboard-app .figli-mini-bar-track::before { content: ''; position: absolute; top: 50%; left: 0; right: 0; height: 1px; background: var(--figli-border); } #figli-dashboard-app .figli-mini-bar-fill { position: absolute; left: 1px; right: 1px; border-radius: 2px; } #figli-dashboard-app .figli-mini-bar-fill.is-positive { bottom: 50%; background: var(--figli-positive); } #figli-dashboard-app .figli-mini-bar-fill.is-negative { top: 50%; background: var(--figli-error); } #figli-dashboard-app .figli-mini-bar-label { font-size: 0.65rem; color: var(--figli-text-light); margin-top: 0.25rem; }