Go-live, ecosplay realm-as-code, and full theme coverage
Go-live:
- Switch keycloak from start-dev to start --import-realm (production
mode with auto-build at boot, no Dockerfile needed yet).
- Set KC_HOSTNAME=https://auth.e-cosplay.fr and KC_PROXY_HEADERS=
xforwarded so Keycloak emits correct issuer URLs and trusts
Caddy's X-Forwarded-* headers.
- Replace deprecated KEYCLOAK_ADMIN env vars with KC_BOOTSTRAP_ADMIN_*.
- Bind the public port to 127.0.0.1 only (Caddy is colocated).
- Add a Keycloak healthcheck against /health/ready on the management
port (9000) using bash /dev/tcp; init container now waits on
service_healthy instead of service_started.
Architecture:
- New realms/ecosplay-realm.json mounted into /opt/keycloak/data/import
and imported on first boot. Defines the dedicated 'ecosplay' realm
(separate from master) with French i18n, brute-force protection,
strong password policy, SES SMTP, and an OIDC client 'ecosplay-web'
pointing at e-cosplay.fr (confidential + PKCE S256).
Theme coverage:
- themes/ecosplay/account: PatternFly v5 overlay (parent=keycloak.v2)
bringing the neo-brutalist colors, thick borders, italic uppercase
typography, and offset hard shadows to the user account console.
- themes/ecosplay/email: branded HTML wrapper template (table layout
with inline styles for email-client safety) plus a matching plain
text wrapper. All Keycloak emails now ship with the E-Cosplay
identity without needing per-template overrides.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:22:40 +02:00
|
|
|
/* ============================================================
|
|
|
|
|
E-Cosplay neo-brutalist overlay for the v2 (PatternFly) account console
|
|
|
|
|
============================================================ */
|
|
|
|
|
|
|
|
|
|
:root {
|
|
|
|
|
--pf-v5-global--primary-color--100: #4f46e5;
|
|
|
|
|
--pf-v5-global--primary-color--200: #4338ca;
|
|
|
|
|
--pf-v5-global--primary-color--light-100: #6366f1;
|
|
|
|
|
--pf-v5-global--link--Color: #4f46e5;
|
|
|
|
|
--pf-v5-global--link--Color--hover: #111827;
|
|
|
|
|
--pf-v5-global--BackgroundColor--100: #fbfbfb;
|
|
|
|
|
--pf-v5-global--BackgroundColor--200: #ffffff;
|
|
|
|
|
--pf-v5-global--BorderColor--100: #111827;
|
|
|
|
|
--pf-v5-global--FontFamily--text: ui-sans-serif, system-ui, -apple-system,
|
|
|
|
|
"Segoe UI", Roboto, sans-serif;
|
|
|
|
|
--pf-v5-global--FontFamily--heading: ui-sans-serif, system-ui, -apple-system,
|
|
|
|
|
"Segoe UI", Roboto, sans-serif;
|
|
|
|
|
--pf-v5-global--FontFamily--monospace: ui-monospace, "SFMono-Regular",
|
|
|
|
|
Menlo, monospace;
|
|
|
|
|
--pf-v5-global--FontWeight--bold: 900;
|
|
|
|
|
--pf-v5-global--BorderRadius--sm: 0;
|
|
|
|
|
--pf-v5-global--BorderRadius--lg: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html,
|
|
|
|
|
body,
|
|
|
|
|
.pf-v5-c-page,
|
|
|
|
|
.pf-v5-c-page__main {
|
|
|
|
|
background-color: #fbfbfb !important;
|
|
|
|
|
font-style: italic;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Header band */
|
|
|
|
|
.pf-v5-c-masthead {
|
|
|
|
|
background-color: #111827 !important;
|
|
|
|
|
border-bottom: 4px solid #4f46e5 !important;
|
2026-04-10 14:45:31 +02:00
|
|
|
min-height: 88px !important;
|
Go-live, ecosplay realm-as-code, and full theme coverage
Go-live:
- Switch keycloak from start-dev to start --import-realm (production
mode with auto-build at boot, no Dockerfile needed yet).
- Set KC_HOSTNAME=https://auth.e-cosplay.fr and KC_PROXY_HEADERS=
xforwarded so Keycloak emits correct issuer URLs and trusts
Caddy's X-Forwarded-* headers.
- Replace deprecated KEYCLOAK_ADMIN env vars with KC_BOOTSTRAP_ADMIN_*.
- Bind the public port to 127.0.0.1 only (Caddy is colocated).
- Add a Keycloak healthcheck against /health/ready on the management
port (9000) using bash /dev/tcp; init container now waits on
service_healthy instead of service_started.
Architecture:
- New realms/ecosplay-realm.json mounted into /opt/keycloak/data/import
and imported on first boot. Defines the dedicated 'ecosplay' realm
(separate from master) with French i18n, brute-force protection,
strong password policy, SES SMTP, and an OIDC client 'ecosplay-web'
pointing at e-cosplay.fr (confidential + PKCE S256).
Theme coverage:
- themes/ecosplay/account: PatternFly v5 overlay (parent=keycloak.v2)
bringing the neo-brutalist colors, thick borders, italic uppercase
typography, and offset hard shadows to the user account console.
- themes/ecosplay/email: branded HTML wrapper template (table layout
with inline styles for email-client safety) plus a matching plain
text wrapper. All Keycloak emails now ship with the E-Cosplay
identity without needing per-template overrides.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:22:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-masthead__brand,
|
|
|
|
|
.pf-v5-c-masthead__main {
|
|
|
|
|
color: #ffffff !important;
|
|
|
|
|
font-weight: 900 !important;
|
|
|
|
|
text-transform: uppercase !important;
|
|
|
|
|
letter-spacing: 0.15em !important;
|
|
|
|
|
font-style: italic !important;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-10 14:45:31 +02:00
|
|
|
/* Inject brand logo into the masthead via background-image */
|
|
|
|
|
.pf-v5-c-masthead__brand::before {
|
|
|
|
|
content: "";
|
|
|
|
|
display: inline-block;
|
|
|
|
|
width: 64px;
|
|
|
|
|
height: 64px;
|
|
|
|
|
margin-right: 16px;
|
|
|
|
|
background: #ffffff url("../img/logo.jpg") center/contain no-repeat;
|
|
|
|
|
border: 3px solid #4f46e5;
|
|
|
|
|
box-shadow: 4px 4px 0 rgba(0, 0, 0, 1);
|
|
|
|
|
vertical-align: middle;
|
|
|
|
|
}
|
|
|
|
|
|
Go-live, ecosplay realm-as-code, and full theme coverage
Go-live:
- Switch keycloak from start-dev to start --import-realm (production
mode with auto-build at boot, no Dockerfile needed yet).
- Set KC_HOSTNAME=https://auth.e-cosplay.fr and KC_PROXY_HEADERS=
xforwarded so Keycloak emits correct issuer URLs and trusts
Caddy's X-Forwarded-* headers.
- Replace deprecated KEYCLOAK_ADMIN env vars with KC_BOOTSTRAP_ADMIN_*.
- Bind the public port to 127.0.0.1 only (Caddy is colocated).
- Add a Keycloak healthcheck against /health/ready on the management
port (9000) using bash /dev/tcp; init container now waits on
service_healthy instead of service_started.
Architecture:
- New realms/ecosplay-realm.json mounted into /opt/keycloak/data/import
and imported on first boot. Defines the dedicated 'ecosplay' realm
(separate from master) with French i18n, brute-force protection,
strong password policy, SES SMTP, and an OIDC client 'ecosplay-web'
pointing at e-cosplay.fr (confidential + PKCE S256).
Theme coverage:
- themes/ecosplay/account: PatternFly v5 overlay (parent=keycloak.v2)
bringing the neo-brutalist colors, thick borders, italic uppercase
typography, and offset hard shadows to the user account console.
- themes/ecosplay/email: branded HTML wrapper template (table layout
with inline styles for email-client safety) plus a matching plain
text wrapper. All Keycloak emails now ship with the E-Cosplay
identity without needing per-template overrides.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:22:40 +02:00
|
|
|
/* Cards */
|
|
|
|
|
.pf-v5-c-card {
|
|
|
|
|
background-color: #ffffff !important;
|
|
|
|
|
border: 4px solid #111827 !important;
|
|
|
|
|
border-radius: 0 !important;
|
|
|
|
|
box-shadow: 8px 8px 0 rgba(0, 0, 0, 1) !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-card__title,
|
|
|
|
|
.pf-v5-c-card__title-text {
|
|
|
|
|
text-transform: uppercase !important;
|
|
|
|
|
font-style: italic !important;
|
|
|
|
|
font-weight: 900 !important;
|
|
|
|
|
letter-spacing: -0.02em !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Headings */
|
|
|
|
|
h1,
|
|
|
|
|
h2,
|
|
|
|
|
h3,
|
|
|
|
|
.pf-v5-c-title,
|
|
|
|
|
.pf-v5-c-content h1,
|
|
|
|
|
.pf-v5-c-content h2,
|
|
|
|
|
.pf-v5-c-content h3 {
|
|
|
|
|
text-transform: uppercase !important;
|
|
|
|
|
font-style: italic !important;
|
|
|
|
|
font-weight: 900 !important;
|
|
|
|
|
letter-spacing: -0.025em !important;
|
|
|
|
|
color: #111827 !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Form labels */
|
|
|
|
|
.pf-v5-c-form__label,
|
|
|
|
|
.pf-v5-c-form__label-text {
|
|
|
|
|
text-transform: uppercase !important;
|
|
|
|
|
font-weight: 900 !important;
|
|
|
|
|
letter-spacing: 0.1em !important;
|
|
|
|
|
font-size: 11px !important;
|
|
|
|
|
color: #111827 !important;
|
|
|
|
|
font-style: normal !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Inputs */
|
|
|
|
|
.pf-v5-c-form-control,
|
|
|
|
|
.pf-v5-c-form-control input,
|
|
|
|
|
input.pf-v5-c-form-control,
|
|
|
|
|
.pf-v5-c-text-input-group__text-input {
|
|
|
|
|
border: 4px solid #111827 !important;
|
|
|
|
|
border-radius: 0 !important;
|
|
|
|
|
background-color: #ffffff !important;
|
|
|
|
|
color: #111827 !important;
|
|
|
|
|
font-weight: 700 !important;
|
|
|
|
|
font-style: normal !important;
|
|
|
|
|
padding: 12px 14px !important;
|
|
|
|
|
height: auto !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-form-control:focus,
|
|
|
|
|
.pf-v5-c-form-control:focus-within {
|
|
|
|
|
background-color: #fef9c3 !important;
|
|
|
|
|
box-shadow: 6px 6px 0 #4f46e5 !important;
|
|
|
|
|
outline: none !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Buttons */
|
|
|
|
|
.pf-v5-c-button {
|
|
|
|
|
border-radius: 0 !important;
|
|
|
|
|
border: 4px solid #111827 !important;
|
|
|
|
|
font-weight: 900 !important;
|
|
|
|
|
text-transform: uppercase !important;
|
|
|
|
|
letter-spacing: 0.12em !important;
|
|
|
|
|
font-style: italic !important;
|
|
|
|
|
padding: 14px 24px !important;
|
|
|
|
|
transition: all 0.15s ease !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-button.pf-m-primary {
|
|
|
|
|
background-color: #4f46e5 !important;
|
|
|
|
|
color: #ffffff !important;
|
|
|
|
|
box-shadow: 6px 6px 0 rgba(0, 0, 0, 1) !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-button.pf-m-primary:hover {
|
|
|
|
|
background-color: #4338ca !important;
|
|
|
|
|
box-shadow: none !important;
|
|
|
|
|
transform: translate(4px, 4px) !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-button.pf-m-secondary {
|
|
|
|
|
background-color: #ffffff !important;
|
|
|
|
|
color: #111827 !important;
|
|
|
|
|
box-shadow: 6px 6px 0 rgba(0, 0, 0, 1) !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-button.pf-m-secondary:hover {
|
|
|
|
|
background-color: #facc15 !important;
|
|
|
|
|
box-shadow: none !important;
|
|
|
|
|
transform: translate(4px, 4px) !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-button.pf-m-danger {
|
|
|
|
|
background-color: #dc2626 !important;
|
|
|
|
|
color: #ffffff !important;
|
|
|
|
|
box-shadow: 6px 6px 0 rgba(0, 0, 0, 1) !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-button.pf-m-link {
|
|
|
|
|
color: #4f46e5 !important;
|
|
|
|
|
border: 0 !important;
|
|
|
|
|
box-shadow: none !important;
|
|
|
|
|
text-decoration: underline !important;
|
|
|
|
|
text-underline-offset: 4px !important;
|
|
|
|
|
text-decoration-thickness: 3px !important;
|
|
|
|
|
padding: 4px 8px !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-button.pf-m-link:hover {
|
|
|
|
|
color: #111827 !important;
|
|
|
|
|
transform: none !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Nav */
|
|
|
|
|
.pf-v5-c-nav__link {
|
|
|
|
|
font-weight: 900 !important;
|
|
|
|
|
text-transform: uppercase !important;
|
|
|
|
|
letter-spacing: 0.1em !important;
|
|
|
|
|
font-style: italic !important;
|
|
|
|
|
border-left: 4px solid transparent !important;
|
|
|
|
|
border-radius: 0 !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-nav__link.pf-m-current,
|
|
|
|
|
.pf-v5-c-nav__link:hover {
|
|
|
|
|
border-left-color: #4f46e5 !important;
|
|
|
|
|
background-color: #fef9c3 !important;
|
|
|
|
|
color: #111827 !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Alerts */
|
|
|
|
|
.pf-v5-c-alert {
|
|
|
|
|
border: 4px solid #111827 !important;
|
|
|
|
|
border-radius: 0 !important;
|
|
|
|
|
box-shadow: 6px 6px 0 rgba(0, 0, 0, 1) !important;
|
|
|
|
|
font-weight: 800 !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-alert.pf-m-success {
|
|
|
|
|
background-color: #bbf7d0 !important;
|
|
|
|
|
}
|
|
|
|
|
.pf-v5-c-alert.pf-m-warning {
|
|
|
|
|
background-color: #fde68a !important;
|
|
|
|
|
}
|
|
|
|
|
.pf-v5-c-alert.pf-m-danger {
|
|
|
|
|
background-color: #fecaca !important;
|
|
|
|
|
}
|
|
|
|
|
.pf-v5-c-alert.pf-m-info {
|
|
|
|
|
background-color: #c7d2fe !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Tables */
|
|
|
|
|
.pf-v5-c-table {
|
|
|
|
|
border: 4px solid #111827 !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pf-v5-c-table thead th {
|
|
|
|
|
background-color: #111827 !important;
|
|
|
|
|
color: #ffffff !important;
|
|
|
|
|
text-transform: uppercase !important;
|
|
|
|
|
font-weight: 900 !important;
|
|
|
|
|
letter-spacing: 0.1em !important;
|
|
|
|
|
font-style: italic !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Links */
|
|
|
|
|
a {
|
|
|
|
|
color: #4f46e5 !important;
|
|
|
|
|
}
|
|
|
|
|
a:hover {
|
|
|
|
|
color: #111827 !important;
|
|
|
|
|
text-decoration-thickness: 3px !important;
|
|
|
|
|
}
|