diff --git a/assets/fonts/InterVariable.woff2 b/assets/fonts/InterVariable.woff2 new file mode 100644 index 0000000..5a8d3e7 Binary files /dev/null and b/assets/fonts/InterVariable.woff2 differ diff --git a/assets/fonts/JetBrainsMono-Bold.woff2 b/assets/fonts/JetBrainsMono-Bold.woff2 new file mode 100644 index 0000000..4917f43 Binary files /dev/null and b/assets/fonts/JetBrainsMono-Bold.woff2 differ diff --git a/assets/fonts/JetBrainsMono-Regular.woff2 b/assets/fonts/JetBrainsMono-Regular.woff2 new file mode 100644 index 0000000..40da427 Binary files /dev/null and b/assets/fonts/JetBrainsMono-Regular.woff2 differ diff --git a/assets/responsive.css b/assets/responsive.css index 29e4612..5406068 100644 --- a/assets/responsive.css +++ b/assets/responsive.css @@ -1,4 +1,70 @@ -/* Reset default margins and padding */ +/* ── Fonts (self-hosted) ─────────────────────────────────────────────────── */ + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 100 900; /* variable font : toutes les graisses dans un fichier */ + font-display: swap; + src: url("/fonts/InterVariable.woff2") format("woff2-variations"), + url("/fonts/InterVariable.woff2") format("woff2"); +} + +@font-face { + font-family: "JetBrains Mono"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url("/fonts/JetBrainsMono-Regular.woff2") format("woff2"); +} + +@font-face { + font-family: "JetBrains Mono"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url("/fonts/JetBrainsMono-Bold.woff2") format("woff2"); +} + +/* Override Radix Themes default font + smoothing global */ +:root, +.radix-themes { + --default-font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, + "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + --heading-font-family: "Inter", system-ui, sans-serif; + --code-font-family: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, + Consolas, monospace; + --strong-font-family: var(--default-font-family); + --quote-font-family: var(--default-font-family); +} + +body { + font-family: var(--default-font-family); + /* Activations Inter : cv11 = 1 sans empattement, ss01 = a/g modernes, + cv02 = G plus carré. Affiche un rendu plus net en UI. */ + font-feature-settings: "cv11", "ss01", "cv02"; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; +} + +/* Chiffres à largeur fixe (tabular nums) — KPI, tables de notes/absences, + * timestamps de logs. Aligne verticalement même en mélangeant 1 et 8. */ +.tabular, +.log-content, +.log-ts, +.doc-content table td, +.doc-content table th { + font-variant-numeric: tabular-nums; +} + +/* Tighten letter-spacing on headings — Inter looks crisper this way. */ +h1, h2, h3, h4, h5, h6, +.rt-Heading { + letter-spacing: -0.011em; + font-feature-settings: "cv11", "ss01", "ss03"; +} + +/* ── Reset default margins and padding ───────────────────────────────────── */ * { box-sizing: border-box; } @@ -181,7 +247,7 @@ img { /* ── Logs viewer (page /logs) ──────────────────────────────────────────── */ .log-content { - font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; + font-family: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 0.78rem; line-height: 1.55; color: #cbd5e1; @@ -243,7 +309,7 @@ img { padding: 0.1rem 0.35rem; border-radius: 4px; font-size: 0.88em; - font-family: ui-monospace, SFMono-Regular, Menlo, monospace; + font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace; } .doc-content pre { background-color: #1e293b; diff --git a/eptm_dashboard/eptm_dashboard.py b/eptm_dashboard/eptm_dashboard.py index b225038..3499a0b 100644 --- a/eptm_dashboard/eptm_dashboard.py +++ b/eptm_dashboard/eptm_dashboard.py @@ -29,6 +29,14 @@ app = rx.App( rx.el.meta(name="apple-mobile-web-app-capable", content="yes"), rx.el.meta(name="apple-mobile-web-app-status-bar-style", content="default"), rx.el.meta(name="apple-mobile-web-app-title", content="EPTM"), + # Préchargement des fonts (évite le FOIT, rendu instantané) + rx.el.link( + rel="preload", + href="/fonts/InterVariable.woff2", + as_="font", + type="font/woff2", + crossorigin="anonymous", + ), ], ) diff --git a/eptm_dashboard/pages/accueil.py b/eptm_dashboard/pages/accueil.py index dc6de9f..2bb5702 100644 --- a/eptm_dashboard/pages/accueil.py +++ b/eptm_dashboard/pages/accueil.py @@ -157,7 +157,7 @@ class AccueilState(AuthState): def _kpi_card(label: str, value: rx.Var) -> rx.Component: return rx.box( rx.text(label, size="1", color="#555555"), - rx.text(value, size="8", font_weight="700", line_height="1.1"), + rx.text(value, size="8", font_weight="700", line_height="1.1", class_name="tabular"), background_color="white", border="1px solid #dee2e6", border_radius="8px", diff --git a/eptm_dashboard/pages/classe.py b/eptm_dashboard/pages/classe.py index 11d83c3..376fc42 100644 --- a/eptm_dashboard/pages/classe.py +++ b/eptm_dashboard/pages/classe.py @@ -667,7 +667,7 @@ def _classe_searchable_select() -> rx.Component: def _kpi_mini(label: str, value, color: str = "#37474f") -> rx.Component: return rx.box( rx.text(label, size="1", color="#888"), - rx.text(value, size="5", font_weight="700", color=color), + rx.text(value, size="5", font_weight="700", color=color, class_name="tabular"), padding="0.5rem 0.75rem", background_color="#f8f9fa", border_radius="6px", diff --git a/eptm_dashboard/pages/fiche.py b/eptm_dashboard/pages/fiche.py index 024e4ee..3a665cb 100644 --- a/eptm_dashboard/pages/fiche.py +++ b/eptm_dashboard/pages/fiche.py @@ -1178,7 +1178,7 @@ def _apprenti_searchable_select() -> rx.Component: def _kpi_card(label: str, value, color: str = "#37474f") -> rx.Component: return rx.box( rx.text(label, size="1", color="#666"), - rx.text(value, size="7", font_weight="700", color=color), + rx.text(value, size="7", font_weight="700", color=color, class_name="tabular"), padding="1rem", background_color="white", border_radius="8px",