@nodefony/security 10.0.0-beta.2 → 10.0.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/dist/_virtual/{_@oxc-project_runtime@0.152.0 → _@oxc-project_runtime@0.155.0}/helpers/esm/decorate.js +1 -2
  2. package/dist/index.js +48 -16
  3. package/dist/nodefony/command/{security-token.js → security-mcp-token.js} +62 -24
  4. package/dist/nodefony/command/security-oauth-doctor.js +68 -0
  5. package/dist/nodefony/command/security-secrets.js +52 -29
  6. package/dist/nodefony/command/security-user-add.js +9 -3
  7. package/dist/nodefony/command/security-user-delete.js +10 -7
  8. package/dist/nodefony/command/security-user-list.js +5 -3
  9. package/dist/nodefony/command/security-user-password.js +9 -14
  10. package/dist/nodefony/config/config.js +99 -8
  11. package/dist/nodefony/config/defineModuleConfig.js +1 -2
  12. package/dist/nodefony/contracts/IAccessVoter.js +1 -2
  13. package/dist/nodefony/contracts/index.js +1 -2
  14. package/dist/nodefony/errors/AccessDeniedError.js +1 -2
  15. package/dist/nodefony/errors/ApiKeyError.js +3 -2
  16. package/dist/nodefony/errors/AuthenticationError.js +1 -2
  17. package/dist/nodefony/errors/CsrfError.js +1 -2
  18. package/dist/nodefony/errors/InsecureTransportError.js +23 -0
  19. package/dist/nodefony/errors/InvalidTargetError.js +1 -2
  20. package/dist/nodefony/errors/SsrfError.js +1 -2
  21. package/dist/nodefony/errors/ThrottledError.js +1 -2
  22. package/dist/nodefony/errors/UnverifiableTokenError.js +1 -2
  23. package/dist/nodefony/errors/WebAuthnError.js +1 -2
  24. package/dist/nodefony/errors/index.js +2 -1
  25. package/dist/nodefony/keycloak/keycloakAdmin.js +254 -0
  26. package/dist/nodefony/keycloak/keycloakRealm.js +259 -0
  27. package/dist/nodefony/keycloak/keycloakRealmInput.js +123 -0
  28. package/dist/nodefony/keycloak/scaffold.js +231 -0
  29. package/dist/nodefony/keycloak/security-keycloak-realm.js +130 -0
  30. package/dist/nodefony/scaffold/contribute.js +19 -0
  31. package/dist/nodefony/service/accessTokenVerifier.js +101 -34
  32. package/dist/nodefony/service/apiKeys.js +45 -5
  33. package/dist/nodefony/service/auditService.js +4 -5
  34. package/dist/nodefony/service/authFlow.js +118 -16
  35. package/dist/nodefony/service/authorization.js +1 -2
  36. package/dist/nodefony/service/cors.js +1 -2
  37. package/dist/nodefony/service/csrf.js +1 -2
  38. package/dist/nodefony/service/firewall.js +116 -25
  39. package/dist/nodefony/service/keycloak.js +208 -0
  40. package/dist/nodefony/service/oauth2.js +403 -28
  41. package/dist/nodefony/service/securityHeaders.js +1 -2
  42. package/dist/nodefony/service/tokenService.js +94 -27
  43. package/dist/nodefony/service/totp.js +55 -11
  44. package/dist/nodefony/service/webAuthn.js +24 -7
  45. package/dist/nodefony/service/webhooks.js +4 -5
  46. package/dist/nodefony/src/RoleHierarchyWalker.js +1 -2
  47. package/dist/nodefony/src/SecuredArea.js +15 -5
  48. package/dist/nodefony/src/accountBinding.js +96 -0
  49. package/dist/nodefony/src/admin/SecurityAdminApi.js +71 -42
  50. package/dist/nodefony/src/admin/WebhookAdminApi.js +23 -7
  51. package/dist/nodefony/src/admin/adminAudit.js +1 -3
  52. package/dist/nodefony/src/admin/userRevocationCascade.js +148 -20
  53. package/dist/nodefony/src/apikey/apiKeyFormat.js +1 -2
  54. package/dist/nodefony/src/audit/MemoryAuditStore.js +1 -2
  55. package/dist/nodefony/src/audit/auditBridge.js +1 -2
  56. package/dist/nodefony/src/audit/auditFilters.js +1 -2
  57. package/dist/nodefony/src/audit/auditStoreRegistry.js +1 -2
  58. package/dist/nodefony/src/audit/readAuditContext.js +1 -2
  59. package/dist/nodefony/src/audit/recordAudit.js +1 -2
  60. package/dist/nodefony/src/authenticator/AnonymousAuthenticator.js +1 -2
  61. package/dist/nodefony/src/authenticator/ApiKeyAuthenticator.js +3 -2
  62. package/dist/nodefony/src/authenticator/ExternalJwtAuthenticator.js +14 -59
  63. package/dist/nodefony/src/authenticator/ExternalSubjectResolver.js +180 -0
  64. package/dist/nodefony/src/authenticator/FirewallRealtimeAuthenticator.js +80 -19
  65. package/dist/nodefony/src/authenticator/JwtAuthenticator.js +92 -16
  66. package/dist/nodefony/src/authenticator/SessionAuthenticator.js +9 -5
  67. package/dist/nodefony/src/authenticator/UserPasswordAuthenticator.js +14 -5
  68. package/dist/nodefony/src/authenticator/authenticatorRegistry.js +5 -12
  69. package/dist/nodefony/src/authenticator/bearer.js +1 -2
  70. package/dist/nodefony/src/authenticator/externalSubject.js +1 -2
  71. package/dist/nodefony/src/authenticator/peekIssuer.js +1 -2
  72. package/dist/nodefony/src/boot/publicRoutesNotice.js +26 -0
  73. package/dist/nodefony/src/crypto/secretCipher.js +1 -2
  74. package/dist/nodefony/src/csp.js +1 -2
  75. package/dist/nodefony/src/csrfToken.js +1 -2
  76. package/dist/nodefony/src/entryPoint.js +38 -0
  77. package/dist/nodefony/src/net/ssrfGuard.js +1 -2
  78. package/dist/nodefony/src/net/transportFailure.js +57 -0
  79. package/dist/nodefony/src/oauth/clientCredentials.js +39 -0
  80. package/dist/nodefony/src/oauth/httpJson.js +3 -3
  81. package/dist/nodefony/src/oauth/metadata.js +28 -12
  82. package/dist/nodefony/src/oauth/oauth2Client.js +61 -35
  83. package/dist/nodefony/src/oauth/oauthProviderRegistry.js +40 -8
  84. package/dist/nodefony/src/oauth/providerDiagnosis.js +282 -0
  85. package/dist/nodefony/src/oauth/providerRoles.js +78 -0
  86. package/dist/nodefony/src/oauth/providers/github.js +48 -12
  87. package/dist/nodefony/src/oauth/providers/oidc.js +90 -8
  88. package/dist/nodefony/src/openToSignup.js +46 -0
  89. package/dist/nodefony/src/realtime/UserRealtimeToken.js +17 -3
  90. package/dist/nodefony/src/realtime/frameAuthorizer.js +1 -2
  91. package/dist/nodefony/src/rolesWithin.js +57 -0
  92. package/dist/nodefony/src/sessionAuthentication.js +25 -0
  93. package/dist/nodefony/src/sessionIdentity.js +29 -3
  94. package/dist/nodefony/src/throttle/LoginThrottler.js +1 -2
  95. package/dist/nodefony/src/token/AnonymousToken.js +1 -2
  96. package/dist/nodefony/src/token/JwtKeystore.js +89 -48
  97. package/dist/nodefony/src/token/MemoryTokenStore.js +1 -2
  98. package/dist/nodefony/src/token/RemoteJwtVerifier.js +46 -16
  99. package/dist/nodefony/src/token/UserToken.js +1 -2
  100. package/dist/nodefony/src/token/jwtRuntime.js +1 -2
  101. package/dist/nodefony/src/token/scopeGrants.js +109 -0
  102. package/dist/nodefony/src/token/secretFile.js +60 -4
  103. package/dist/nodefony/src/token/tokenCriteria.js +1 -2
  104. package/dist/nodefony/src/token/tokenFilters.js +1 -2
  105. package/dist/nodefony/src/token/tokenSort.js +1 -2
  106. package/dist/nodefony/src/token/tokenStatus.js +1 -2
  107. package/dist/nodefony/src/token/tokenStoreRegistry.js +1 -2
  108. package/dist/nodefony/src/totp/MemoryTotpSecretStore.js +1 -2
  109. package/dist/nodefony/src/totp/totpCipher.js +1 -2
  110. package/dist/nodefony/src/totp/totpCrypto.js +1 -2
  111. package/dist/nodefony/src/totp/totpOperations.js +1 -2
  112. package/dist/nodefony/src/totp/totpSecretStoreRegistry.js +1 -2
  113. package/dist/nodefony/src/transport/CredentialTransportPolicy.js +50 -0
  114. package/dist/nodefony/src/voter/RoleVoter.js +1 -2
  115. package/dist/nodefony/src/voter/ScopeVoter.js +1 -2
  116. package/dist/nodefony/src/voter/voterRegistry.js +1 -2
  117. package/dist/nodefony/src/webauthn/MemoryWebAuthnCredentialStore.js +1 -2
  118. package/dist/nodefony/src/webauthn/webAuthnCredentialStoreRegistry.js +1 -2
  119. package/dist/nodefony/src/webhook/MemoryWebhookStore.js +1 -2
  120. package/dist/nodefony/src/webhook/WebhookDispatcher.js +1 -2
  121. package/dist/nodefony/src/webhook/webhookCipher.js +1 -2
  122. package/dist/nodefony/src/webhook/webhookDelivery.js +1 -2
  123. package/dist/nodefony/src/webhook/webhookFilters.js +1 -2
  124. package/dist/nodefony/src/webhook/webhookSignature.js +1 -2
  125. package/dist/nodefony/src/webhook/webhookSort.js +1 -2
  126. package/dist/nodefony/src/webhook/webhookStoreRegistry.js +1 -2
  127. package/dist/types/index.d.ts +26 -6
  128. package/dist/types/nodefony/command/{security-token.d.ts → security-mcp-token.d.ts} +16 -6
  129. package/dist/types/nodefony/command/security-oauth-doctor.d.ts +23 -0
  130. package/dist/types/nodefony/command/security-secrets.d.ts +2 -0
  131. package/dist/types/nodefony/command/security-user-delete.d.ts +4 -3
  132. package/dist/types/nodefony/command/security-user-password.d.ts +4 -4
  133. package/dist/types/nodefony/config/config.d.ts +64 -1
  134. package/dist/types/nodefony/contracts/IAuthenticator.d.ts +1 -1
  135. package/dist/types/nodefony/contracts/IFirewallDescription.d.ts +42 -1
  136. package/dist/types/nodefony/contracts/IOAuthProvider.d.ts +48 -0
  137. package/dist/types/nodefony/contracts/ISecuredArea.d.ts +22 -0
  138. package/dist/types/nodefony/contracts/ITotpSecret.d.ts +4 -1
  139. package/dist/types/nodefony/contracts/ITotpSecretStore.d.ts +7 -1
  140. package/dist/types/nodefony/contracts/IWebAuthnCredential.d.ts +4 -1
  141. package/dist/types/nodefony/contracts/IWebAuthnCredentialStore.d.ts +6 -0
  142. package/dist/types/nodefony/errors/ApiKeyError.d.ts +3 -1
  143. package/dist/types/nodefony/errors/InsecureTransportError.d.ts +20 -0
  144. package/dist/types/nodefony/errors/index.d.ts +1 -0
  145. package/dist/types/nodefony/keycloak/keycloakAdmin.d.ts +154 -0
  146. package/dist/types/nodefony/keycloak/keycloakRealm.d.ts +138 -0
  147. package/dist/types/nodefony/keycloak/keycloakRealmInput.d.ts +92 -0
  148. package/dist/types/nodefony/keycloak/scaffold.d.ts +98 -0
  149. package/dist/types/nodefony/keycloak/security-keycloak-realm.d.ts +43 -0
  150. package/dist/types/nodefony/scaffold/contribute.d.ts +15 -0
  151. package/dist/types/nodefony/service/accessTokenVerifier.d.ts +35 -14
  152. package/dist/types/nodefony/service/apiKeys.d.ts +13 -2
  153. package/dist/types/nodefony/service/authFlow.d.ts +35 -3
  154. package/dist/types/nodefony/service/firewall.d.ts +17 -3
  155. package/dist/types/nodefony/service/keycloak.d.ts +115 -0
  156. package/dist/types/nodefony/service/oauth2.d.ts +145 -9
  157. package/dist/types/nodefony/service/tokenService.d.ts +7 -1
  158. package/dist/types/nodefony/service/totp.d.ts +28 -4
  159. package/dist/types/nodefony/service/webAuthn.d.ts +23 -1
  160. package/dist/types/nodefony/src/SecuredArea.d.ts +4 -0
  161. package/dist/types/nodefony/src/accountBinding.d.ts +82 -0
  162. package/dist/types/nodefony/src/admin/userRevocationCascade.d.ts +72 -12
  163. package/dist/types/nodefony/src/authenticator/ExternalJwtAuthenticator.d.ts +2 -26
  164. package/dist/types/nodefony/src/authenticator/ExternalSubjectResolver.d.ts +99 -0
  165. package/dist/types/nodefony/src/authenticator/FirewallRealtimeAuthenticator.d.ts +17 -1
  166. package/dist/types/nodefony/src/authenticator/JwtAuthenticator.d.ts +37 -1
  167. package/dist/types/nodefony/src/authenticator/UserPasswordAuthenticator.d.ts +11 -3
  168. package/dist/types/nodefony/src/boot/publicRoutesNotice.d.ts +16 -0
  169. package/dist/types/nodefony/src/entryPoint.d.ts +37 -0
  170. package/dist/types/nodefony/src/net/transportFailure.d.ts +22 -0
  171. package/dist/types/nodefony/src/oauth/clientCredentials.d.ts +54 -0
  172. package/dist/types/nodefony/src/oauth/httpJson.d.ts +0 -8
  173. package/dist/types/nodefony/src/oauth/metadata.d.ts +24 -1
  174. package/dist/types/nodefony/src/oauth/oauth2Client.d.ts +50 -1
  175. package/dist/types/nodefony/src/oauth/oauthProviderRegistry.d.ts +46 -2
  176. package/dist/types/nodefony/src/oauth/providerDiagnosis.d.ts +117 -0
  177. package/dist/types/nodefony/src/oauth/providerRoles.d.ts +58 -0
  178. package/dist/types/nodefony/src/oauth/providers/oidc.d.ts +34 -1
  179. package/dist/types/nodefony/src/openToSignup.d.ts +36 -0
  180. package/dist/types/nodefony/src/realtime/UserRealtimeToken.d.ts +7 -1
  181. package/dist/types/nodefony/src/realtime/realtimeContracts.d.ts +6 -0
  182. package/dist/types/nodefony/src/rolesWithin.d.ts +27 -0
  183. package/dist/types/nodefony/src/sessionAuthentication.d.ts +14 -0
  184. package/dist/types/nodefony/src/sessionIdentity.d.ts +22 -0
  185. package/dist/types/nodefony/src/token/JwtKeystore.d.ts +47 -5
  186. package/dist/types/nodefony/src/token/RemoteJwtVerifier.d.ts +29 -2
  187. package/dist/types/nodefony/src/token/scopeGrants.d.ts +77 -0
  188. package/dist/types/nodefony/src/token/secretFile.d.ts +22 -0
  189. package/dist/types/nodefony/src/transport/CredentialTransportPolicy.d.ts +47 -0
  190. package/docs/api-keys.md +182 -175
  191. package/docs/audit.md +141 -141
  192. package/docs/authenticators.md +129 -96
  193. package/docs/authorization.md +116 -69
  194. package/docs/cors.md +64 -64
  195. package/docs/csrf.md +77 -72
  196. package/docs/external-jwt.md +83 -11
  197. package/docs/firewall.md +119 -83
  198. package/docs/headers.md +82 -82
  199. package/docs/index.md +16 -8
  200. package/docs/keycloak.md +835 -0
  201. package/docs/login-page.md +361 -0
  202. package/docs/oauth2.md +291 -166
  203. package/docs/obtenir-un-jeton.md +131 -34
  204. package/docs/tokens.md +197 -140
  205. package/docs/totp.md +177 -136
  206. package/docs/webauthn.md +157 -154
  207. package/docs/webhooks.md +128 -125
  208. package/keycloak/themes/nodefony/account/resources/css/nodefony.css +66 -0
  209. package/keycloak/themes/nodefony/account/resources/img/favicon.ico +0 -0
  210. package/keycloak/themes/nodefony/account/resources/img/logo.png +0 -0
  211. package/keycloak/themes/nodefony/account/theme.properties +14 -0
  212. package/keycloak/themes/nodefony/admin/resources/css/nodefony.css +66 -0
  213. package/keycloak/themes/nodefony/admin/resources/img/favicon.ico +0 -0
  214. package/keycloak/themes/nodefony/admin/resources/img/logo.png +0 -0
  215. package/keycloak/themes/nodefony/admin/theme.properties +12 -0
  216. package/keycloak/themes/nodefony/email/html/template.ftl +73 -0
  217. package/keycloak/themes/nodefony/email/messages/messages_en.properties +2 -0
  218. package/keycloak/themes/nodefony/email/messages/messages_fr.properties +3 -0
  219. package/keycloak/themes/nodefony/email/resources/img/logo.png +0 -0
  220. package/keycloak/themes/nodefony/email/theme.properties +8 -0
  221. package/keycloak/themes/nodefony/login/messages/messages_en.properties +22 -0
  222. package/keycloak/themes/nodefony/login/messages/messages_fr.properties +25 -0
  223. package/keycloak/themes/nodefony/login/resources/css/login.css +1141 -0
  224. package/keycloak/themes/nodefony/login/resources/css/nodefony.css +688 -0
  225. package/keycloak/themes/nodefony/login/resources/css/skins/blueprint.css +70 -0
  226. package/keycloak/themes/nodefony/login/resources/css/skins/console.css +57 -0
  227. package/keycloak/themes/nodefony/login/resources/css/skins/dots.css +67 -0
  228. package/keycloak/themes/nodefony/login/resources/css/skins/enterprise.css +84 -0
  229. package/keycloak/themes/nodefony/login/resources/css/skins/horizon.css +158 -0
  230. package/keycloak/themes/nodefony/login/resources/css/skins/ledger.css +224 -0
  231. package/keycloak/themes/nodefony/login/resources/css/skins/minimal.css +63 -0
  232. package/keycloak/themes/nodefony/login/resources/css/skins/photo-card.css +72 -0
  233. package/keycloak/themes/nodefony/login/resources/img/favicon.ico +0 -0
  234. package/keycloak/themes/nodefony/login/resources/img/logo.png +0 -0
  235. package/keycloak/themes/nodefony/login/template.ftl +423 -0
  236. package/keycloak/themes/nodefony/login/theme.properties +17 -0
  237. package/keycloak/themes/nodefony/welcome/resources/css/nodefony.css +32 -0
  238. package/keycloak/themes/nodefony/welcome/resources/img/logo.png +0 -0
  239. package/keycloak/themes/nodefony/welcome/theme.properties +11 -0
  240. package/keycloak/themes/nodefony-blueprint/login/theme.properties +12 -0
  241. package/keycloak/themes/nodefony-console/login/theme.properties +12 -0
  242. package/keycloak/themes/nodefony-dots/login/theme.properties +12 -0
  243. package/keycloak/themes/nodefony-enterprise/login/theme.properties +12 -0
  244. package/keycloak/themes/nodefony-horizon/login/theme.properties +12 -0
  245. package/keycloak/themes/nodefony-ledger/login/theme.properties +12 -0
  246. package/keycloak/themes/nodefony-minimal/login/theme.properties +12 -0
  247. package/keycloak/themes/nodefony-photo-card/login/theme.properties +12 -0
  248. package/package.json +19 -17
  249. package/dist/_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js +0 -6
@@ -0,0 +1,224 @@
1
+ /* ═══ nodefony/login/skins/ledger.css — habillage « Fiche » ═══
2
+ Outil interne ou back-office : la connexion est une formalité de
3
+ registre, lue d'un coup d'œil, sans carte ni décor. Feuille en deux
4
+ colonnes, étapes numérotées à gauche, formulaire à droite.
5
+
6
+ Mise en page : `bare`.
7
+ Chargée APRÈS `login.css` et AVANT la feuille de l'application
8
+ (`loginPage.skin: "ledger"`) : elle ne redéfinit que des variables
9
+ `--nf-login-*` et la disposition de sa mise en page — jamais le balisage.
10
+ Aucune photo n'est fournie : elle vient de l'application
11
+ (`--nf-login-hero-image`). Le jeu CLAIR est écrit deux fois, à l'identique,
12
+ comme dans `login.css`. */
13
+ :root {
14
+ /* Deux volets : la carte prend une plus grande part de l'écran. */
15
+ --nf-login-card-min: 720px;
16
+ --nf-login-card-ratio: 62vw;
17
+ --nf-login-card-width: 940px;
18
+ --nf-login-title-size: 30px;
19
+ color-scheme: dark;
20
+ }
21
+ @media (prefers-color-scheme: light) {
22
+ :root:not([data-theme="dark"]) {
23
+ --nf-login-on-brand: #ffffff;
24
+ --nf-login-accent: #0067ba;
25
+ --nf-login-ok: #1f8a5b;
26
+ --nf-login-warn: #8a5a00;
27
+ --nf-login-crit: #c4321a;
28
+ --nf-login-bg: #f6f7f9;
29
+ --nf-login-surface: #f6f7f9;
30
+ --nf-login-raised: #eceef2;
31
+ --nf-login-line: #dfe3e8;
32
+ --nf-login-line-strong: #c6ccd4;
33
+ --nf-login-heading: #111317;
34
+ --nf-login-text: #343a40;
35
+ --nf-login-muted: #5d646d;
36
+ --nf-login-field: #ffffff;
37
+ --nf-login-crit-bg: #fff3f0;
38
+ --nf-login-ok-bg: #edf8f2;
39
+ color-scheme: light;
40
+ }
41
+ }
42
+ :root[data-theme="light"] {
43
+ --nf-login-on-brand: #ffffff;
44
+ --nf-login-accent: #0067ba;
45
+ --nf-login-ok: #1f8a5b;
46
+ --nf-login-warn: #8a5a00;
47
+ --nf-login-crit: #c4321a;
48
+ --nf-login-bg: #f6f7f9;
49
+ --nf-login-surface: #f6f7f9;
50
+ --nf-login-raised: #eceef2;
51
+ --nf-login-line: #dfe3e8;
52
+ --nf-login-line-strong: #c6ccd4;
53
+ --nf-login-heading: #111317;
54
+ --nf-login-text: #343a40;
55
+ --nf-login-muted: #5d646d;
56
+ --nf-login-field: #ffffff;
57
+ --nf-login-crit-bg: #fff3f0;
58
+ --nf-login-ok-bg: #edf8f2;
59
+ color-scheme: light;
60
+ }
61
+
62
+ /* ── La feuille : titre et étapes à gauche, formulaire à droite, un filet entre les deux ── */
63
+ body[data-layout="bare"] .nf-strip {
64
+ border-bottom-color: var(--nf-login-line);
65
+ }
66
+ .nf-stage {
67
+ padding: 56px 24px;
68
+ gap: 0;
69
+ }
70
+ body[data-layout="bare"] .nf-card {
71
+ display: grid;
72
+ grid-template-columns: 260px 1fr;
73
+ grid-template-rows: auto 1fr;
74
+ border: 0;
75
+ border-radius: 0;
76
+ }
77
+ .nf-head {
78
+ grid-column: 1;
79
+ grid-row: 1;
80
+ display: grid;
81
+ gap: 0;
82
+ padding: 0 36px 0 0;
83
+ }
84
+ /* Le bandeau porte déjà la marque : la feuille ne la répète pas. */
85
+ body[data-layout="bare"] .nf-head .nf-brand {
86
+ display: none;
87
+ }
88
+ .nf-sub {
89
+ order: 1;
90
+ margin: 0 0 10px;
91
+ font: 700 10px/1 var(--nf-login-mono);
92
+ letter-spacing: 0.8px;
93
+ text-transform: uppercase;
94
+ color: var(--nf-login-muted);
95
+ }
96
+ h1 {
97
+ order: 2;
98
+ line-height: 1.08;
99
+ letter-spacing: -0.025em;
100
+ }
101
+
102
+ /* Étapes numérotées, en colonne : un registre, pas des onglets. */
103
+ body[data-layout="bare"] .nf-steps {
104
+ grid-column: 1;
105
+ grid-row: 2;
106
+ flex-direction: column;
107
+ gap: 0;
108
+ margin: 32px 36px 0 0;
109
+ padding: 0;
110
+ border-bottom: 0;
111
+ border-top: 1px solid var(--nf-login-line);
112
+ counter-reset: step;
113
+ }
114
+ .nf-steps li {
115
+ display: flex;
116
+ align-items: center;
117
+ gap: 12px;
118
+ margin: 0;
119
+ padding: 11px 0;
120
+ border-bottom: 1px solid var(--nf-login-line);
121
+ counter-increment: step;
122
+ }
123
+ .nf-steps li::before {
124
+ content: counter(step, decimal-leading-zero);
125
+ display: grid;
126
+ place-items: center;
127
+ width: 28px;
128
+ height: 20px;
129
+ border: 1px solid var(--nf-login-line-strong);
130
+ border-radius: 4px;
131
+ color: var(--nf-login-muted);
132
+ }
133
+ .nf-steps li[aria-current="step"] {
134
+ border-bottom-color: var(--nf-login-line);
135
+ }
136
+ .nf-steps li[aria-current="step"]::before {
137
+ border-color: var(--nf-login-accent);
138
+ background: var(--nf-login-accent);
139
+ color: var(--nf-login-bg);
140
+ }
141
+ .nf-steps li.done::before {
142
+ content: "✓";
143
+ border-color: var(--nf-login-ok);
144
+ color: var(--nf-login-ok);
145
+ }
146
+
147
+ .nf-body {
148
+ grid-column: 2;
149
+ grid-row: 1 / 3;
150
+ padding: 0 0 0 44px;
151
+ border-left: 1px solid var(--nf-login-line);
152
+ }
153
+ .nf-btn.primary {
154
+ width: auto;
155
+ justify-self: start;
156
+ min-width: 180px;
157
+ padding: 0 22px;
158
+ }
159
+
160
+ /* Pied : une ligne de registre, faits à gauche, signature à droite. */
161
+ .nf-foot {
162
+ width: min(
163
+ clamp(
164
+ var(--nf-login-card-min),
165
+ var(--nf-login-card-ratio),
166
+ var(--nf-login-card-width)
167
+ ),
168
+ 100%
169
+ );
170
+ grid-template-columns: 1fr auto;
171
+ justify-items: start;
172
+ align-items: center;
173
+ margin-top: 40px;
174
+ padding-top: 16px;
175
+ border-top: 1px solid var(--nf-login-line);
176
+ }
177
+ .nf-facts {
178
+ justify-content: flex-start;
179
+ }
180
+
181
+ @media (max-width: 760px) {
182
+ .nf-stage {
183
+ padding: 32px 20px;
184
+ }
185
+ body[data-layout="bare"] .nf-card {
186
+ grid-template-columns: 1fr;
187
+ grid-template-rows: auto;
188
+ }
189
+ .nf-head {
190
+ grid-column: 1;
191
+ grid-row: auto;
192
+ padding: 0;
193
+ }
194
+ body[data-layout="bare"] .nf-steps {
195
+ grid-column: 1;
196
+ grid-row: auto;
197
+ flex-direction: row;
198
+ flex-wrap: wrap;
199
+ gap: 0 18px;
200
+ margin: 24px 0 0;
201
+ border-top: 0;
202
+ border-bottom: 1px solid var(--nf-login-line);
203
+ }
204
+ .nf-steps li {
205
+ padding: 0 0 10px;
206
+ margin-bottom: -1px;
207
+ border-bottom: 2px solid transparent;
208
+ }
209
+ .nf-steps li[aria-current="step"] {
210
+ border-bottom-color: var(--nf-login-accent);
211
+ }
212
+ .nf-body {
213
+ grid-column: 1;
214
+ grid-row: auto;
215
+ padding: 24px 0 0;
216
+ border-left: 0;
217
+ }
218
+ .nf-btn.primary {
219
+ width: 100%;
220
+ }
221
+ .nf-foot {
222
+ grid-template-columns: 1fr;
223
+ }
224
+ }
@@ -0,0 +1,63 @@
1
+ /* ═══ nodefony/login/skins/minimal.css — habillage « Épuré » ═══
2
+ Produit qui veut s'effacer : pas de carte, beaucoup d'air, titre plus
3
+ grand.
4
+
5
+ Mise en page : `bare`.
6
+ Chargée APRÈS `login.css` et AVANT la feuille de l'application
7
+ (`loginPage.skin: "minimal"`) : elle ne redéfinit que des variables
8
+ `--nf-login-*` et la disposition de sa mise en page — jamais le balisage.
9
+ Aucune photo n'est fournie : elle vient de l'application
10
+ (`--nf-login-hero-image`). Le jeu CLAIR est écrit deux fois, à l'identique,
11
+ comme dans `login.css`. */
12
+ :root {
13
+ --nf-login-home-green: #7cc46c;
14
+ --nf-login-title-size: 30px;
15
+ --nf-login-card-width: 460px;
16
+ color-scheme: dark;
17
+ }
18
+ @media (prefers-color-scheme: light) {
19
+ :root:not([data-theme="dark"]) {
20
+ --nf-login-home-green: #3f7a35;
21
+ --nf-login-on-brand: #ffffff;
22
+ --nf-login-accent: #0067ba;
23
+ --nf-login-ok: #1f8a5b;
24
+ --nf-login-warn: #8a5a00;
25
+ --nf-login-crit: #c4321a;
26
+ --nf-login-bg: #ffffff;
27
+ --nf-login-surface: #ffffff;
28
+ --nf-login-raised: #f1f5fa;
29
+ --nf-login-line: #e3e9f2;
30
+ --nf-login-line-strong: #cfd8e6;
31
+ --nf-login-heading: #0e1726;
32
+ --nf-login-text: #2b3a52;
33
+ --nf-login-muted: #5b6b84;
34
+ --nf-login-field: #ffffff;
35
+ --nf-login-crit-bg: #fff3f0;
36
+ --nf-login-ok-bg: #edf8f2;
37
+ --nf-login-title-size: 30px;
38
+ --nf-login-card-width: 460px;
39
+ color-scheme: light;
40
+ }
41
+ }
42
+ :root[data-theme="light"] {
43
+ --nf-login-home-green: #3f7a35;
44
+ --nf-login-on-brand: #ffffff;
45
+ --nf-login-accent: #0067ba;
46
+ --nf-login-ok: #1f8a5b;
47
+ --nf-login-warn: #8a5a00;
48
+ --nf-login-crit: #c4321a;
49
+ --nf-login-bg: #ffffff;
50
+ --nf-login-surface: #ffffff;
51
+ --nf-login-raised: #f1f5fa;
52
+ --nf-login-line: #e3e9f2;
53
+ --nf-login-line-strong: #cfd8e6;
54
+ --nf-login-heading: #0e1726;
55
+ --nf-login-text: #2b3a52;
56
+ --nf-login-muted: #5b6b84;
57
+ --nf-login-field: #ffffff;
58
+ --nf-login-crit-bg: #fff3f0;
59
+ --nf-login-ok-bg: #edf8f2;
60
+ --nf-login-title-size: 30px;
61
+ --nf-login-card-width: 460px;
62
+ color-scheme: light;
63
+ }
@@ -0,0 +1,72 @@
1
+ /* ═══ nodefony/login/skins/photo-card.css — habillage « Photo — carte console » ═══
2
+ La photo de l'application en fond de page, voilée ; la carte console
3
+ reste pleine et lisible au-dessus. Sans photo, fond plein.
4
+
5
+ Mise en page : `card` · fond décoré (`<body data-backdrop>`).
6
+ Chargée APRÈS `login.css` et AVANT la feuille de l'application
7
+ (`loginPage.skin: "photo-card"`) : elle ne redéfinit que des variables
8
+ `--nf-login-*` et la disposition de sa mise en page — jamais le balisage.
9
+ Aucune photo n'est fournie : elle vient de l'application
10
+ (`--nf-login-hero-image`). Le jeu CLAIR est écrit deux fois, à l'identique,
11
+ comme dans `login.css`. */
12
+ :root {
13
+ --nf-login-home-green: #7cc46c;
14
+ --nf-login-backdrop: var(--nf-login-hero-image);
15
+ --nf-login-backdrop-size: cover;
16
+ --nf-login-backdrop-position: center 40%;
17
+ --nf-login-veil: rgba(10, 14, 20, 0.55);
18
+ --nf-login-card-shadow: 0 20px 50px rgba(0, 0, 0, 0.45);
19
+ color-scheme: dark;
20
+ }
21
+ @media (prefers-color-scheme: light) {
22
+ :root:not([data-theme="dark"]) {
23
+ --nf-login-home-green: #3f7a35;
24
+ --nf-login-on-brand: #ffffff;
25
+ --nf-login-accent: #0067ba;
26
+ --nf-login-ok: #1f8a5b;
27
+ --nf-login-warn: #8a5a00;
28
+ --nf-login-crit: #c4321a;
29
+ --nf-login-bg: #fafbfd;
30
+ --nf-login-surface: #ffffff;
31
+ --nf-login-raised: #f1f5fa;
32
+ --nf-login-line: #e3e9f2;
33
+ --nf-login-line-strong: #cfd8e6;
34
+ --nf-login-heading: #0e1726;
35
+ --nf-login-text: #2b3a52;
36
+ --nf-login-muted: #5b6b84;
37
+ --nf-login-field: #ffffff;
38
+ --nf-login-crit-bg: #fff3f0;
39
+ --nf-login-ok-bg: #edf8f2;
40
+ --nf-login-backdrop: var(--nf-login-hero-image);
41
+ --nf-login-backdrop-size: cover;
42
+ --nf-login-backdrop-position: center 40%;
43
+ --nf-login-veil: rgba(245, 246, 248, 0.18);
44
+ --nf-login-card-shadow: 0 20px 50px rgba(10, 30, 50, 0.28);
45
+ color-scheme: light;
46
+ }
47
+ }
48
+ :root[data-theme="light"] {
49
+ --nf-login-home-green: #3f7a35;
50
+ --nf-login-on-brand: #ffffff;
51
+ --nf-login-accent: #0067ba;
52
+ --nf-login-ok: #1f8a5b;
53
+ --nf-login-warn: #8a5a00;
54
+ --nf-login-crit: #c4321a;
55
+ --nf-login-bg: #fafbfd;
56
+ --nf-login-surface: #ffffff;
57
+ --nf-login-raised: #f1f5fa;
58
+ --nf-login-line: #e3e9f2;
59
+ --nf-login-line-strong: #cfd8e6;
60
+ --nf-login-heading: #0e1726;
61
+ --nf-login-text: #2b3a52;
62
+ --nf-login-muted: #5b6b84;
63
+ --nf-login-field: #ffffff;
64
+ --nf-login-crit-bg: #fff3f0;
65
+ --nf-login-ok-bg: #edf8f2;
66
+ --nf-login-backdrop: var(--nf-login-hero-image);
67
+ --nf-login-backdrop-size: cover;
68
+ --nf-login-backdrop-position: center 40%;
69
+ --nf-login-veil: rgba(245, 246, 248, 0.18);
70
+ --nf-login-card-shadow: 0 20px 50px rgba(10, 30, 50, 0.28);
71
+ color-scheme: light;
72
+ }