Files
VacatureRadar/static/css/auth.css
T
2026-07-26 04:13:42 +02:00

574 lines
11 KiB
CSS

/* VacatureRadar — Authenticatieschermen (login, wachtwoordherstel).
* Lokale reproductie van het Stitch "Intelligence Cockpit" ontwerp.
* Bewust CDN-vrij (geen Tailwind/Google Fonts) zodat de pagina local-first blijft
* en de toegankelijkheidstest (geen externe assets) blijft slagen.
*/
/* Zelf-gehoste fonts (Geist — © Vercel/basement.studio; JetBrains Mono — OFL).
* Woff2-bestanden in static/fonts/, geen externe CDN nodig. */
@font-face {
font-family: "Geist";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("../fonts/geist-400.woff2") format("woff2");
}
@font-face {
font-family: "Geist";
font-style: normal;
font-weight: 600;
font-display: swap;
src: url("../fonts/geist-600.woff2") format("woff2");
}
@font-face {
font-family: "Geist";
font-style: normal;
font-weight: 900;
font-display: swap;
src: url("../fonts/geist-900.woff2") format("woff2");
}
@font-face {
font-family: "JetBrains Mono";
font-style: normal;
font-weight: 500;
font-display: swap;
src: url("../fonts/jetbrains-mono-500.woff2") format("woff2");
}
:root {
/* Kleuren overgenomen uit het project (tokens.css, lichte thema). */
/* Surfaces */
--surface: #e6eff2;
--surface-dim: #cadadd;
--surface-container-lowest: #ffffff;
--surface-container-low: #edf4f5;
--surface-container: #f5f9fa;
--surface-container-high: #e3edef;
--surface-container-highest: #d6e3e5;
--on-surface: #12262b;
--on-surface-variant: #475e63;
--outline: #64787d;
--outline-variant: #b7c9cc;
/* Brand / primary (cyaan) */
--primary: #007c83;
--on-primary: #ffffff;
--primary-container: #007c83;
--primary-fixed-dim: #006b71;
/* Secondary + semantic */
--secondary-container: #d6f5e7;
--on-secondary-container: #087a55;
--error: #a82d27;
--on-error: #ffffff;
--error-container: #fbe6e4;
--on-error-container: #7a1f1a;
--success: #087a55;
--success-container: #d6f5e7;
--on-success-container: #053d2c;
/* Type */
--font-sans: "Geist", "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
/* Shape */
--r-input: 4px;
--r-card: 8px;
--r-pill: 999px;
/* Rhythm */
--stack-sm: 8px;
--stack-md: 16px;
--stack-lg: 24px;
--shadow-card: 0 4px 12px rgba(0, 0, 0, 0.05);
}
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
}
body.auth-page {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 24px 16px;
font-family: var(--font-sans);
color: var(--on-surface);
background-color: var(--surface);
background-image: radial-gradient(var(--surface-container-highest) 0.5px, transparent 0.5px);
background-size: 24px 24px;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
.auth-shell {
width: 100%;
max-width: 28rem; /* 448px, komt overeen met max-w-md */
}
/* Merkidentiteit boven de kaart */
.auth-brand {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 32px;
text-align: center;
}
.auth-brand-logo {
display: block;
width: min(274px, 78vw);
height: auto;
margin-bottom: 18px;
}
.auth-brand-name {
margin: 0;
font-size: 30px;
line-height: 38px;
letter-spacing: -0.02em;
font-weight: 900;
color: var(--primary);
}
.auth-brand-tagline {
margin: 6px 0 0;
font-size: 11px;
line-height: 18px;
font-weight: 700;
letter-spacing: .12em;
text-transform: uppercase;
color: var(--on-surface-variant);
}
/* Kaart */
.auth-card {
background: var(--surface-container-lowest);
border: 1px solid var(--outline-variant);
border-radius: var(--r-card);
box-shadow: var(--shadow-card);
padding: 24px;
}
@media (min-width: 640px) {
.auth-card {
padding: 40px;
}
}
.auth-card h1,
.auth-card h2.auth-heading {
margin: 0 0 24px;
font-size: 20px;
line-height: 28px;
letter-spacing: -0.01em;
font-weight: 600;
color: var(--on-surface);
}
.auth-lead {
margin: -12px 0 24px;
font-size: 14px;
line-height: 20px;
color: var(--on-surface-variant);
}
/* Formulier */
.auth-form {
display: flex;
flex-direction: column;
gap: 24px;
}
.field {
display: flex;
flex-direction: column;
}
.field-label-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.field > label,
.field-label-row > label {
font-family: var(--font-mono);
font-size: 12px;
line-height: 16px;
letter-spacing: 0.02em;
font-weight: 500;
color: var(--on-surface-variant);
}
.field > label {
margin-bottom: 8px;
}
.field-link {
font-family: var(--font-mono);
font-size: 11px;
line-height: 14px;
letter-spacing: 0.02em;
color: var(--primary);
text-decoration: none;
}
.field-link:hover {
text-decoration: underline;
}
.input-wrap {
position: relative;
display: flex;
align-items: center;
}
.auth-input {
width: 100%;
padding: 10px 16px;
font-family: var(--font-sans);
font-size: 14px;
line-height: 20px;
color: var(--on-surface);
background: var(--surface-container-low);
border: 1px solid var(--outline-variant);
border-radius: var(--r-input);
outline: none;
transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.input-wrap .auth-input {
padding-right: 44px;
}
.auth-input::placeholder {
color: var(--outline);
}
.auth-input:focus {
border-color: var(--primary);
box-shadow: 0 0 0 2px rgba(0, 124, 131, 0.2);
}
.auth-input[aria-invalid="true"] {
border-color: var(--error);
}
.pw-toggle {
position: absolute;
right: 6px;
display: inline-flex;
align-items: center;
justify-content: center;
width: 34px;
height: 34px;
padding: 0;
border: none;
background: transparent;
color: var(--outline);
border-radius: var(--r-input);
cursor: pointer;
}
.pw-toggle:hover {
color: var(--on-surface-variant);
background: var(--surface-container-high);
}
.pw-toggle .icon {
width: 18px;
height: 18px;
}
.field-error {
margin-top: 6px;
font-size: 12px;
line-height: 16px;
color: var(--error);
}
/* Knoppen */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
padding: 12px 24px;
font-family: var(--font-sans);
font-size: 16px;
font-weight: 600;
border-radius: var(--r-input);
border: 1px solid transparent;
cursor: pointer;
transition: background-color 0.15s ease, transform 0.1s ease, border-color 0.15s ease;
}
.btn:active {
transform: scale(0.98);
}
.btn .icon {
width: 18px;
height: 18px;
}
.btn-primary {
background: var(--primary-container);
color: var(--on-primary);
}
.btn-primary:hover {
background: var(--primary);
}
.btn-sso {
background: var(--surface);
color: var(--on-surface);
border-color: var(--outline-variant);
font-size: 14px;
font-weight: 400;
gap: 12px;
}
.btn-sso:hover {
background: var(--surface-container-high);
}
.btn-sso svg {
width: 20px;
height: 20px;
}
.btn .spinner {
width: 18px;
height: 18px;
animation: auth-spin 0.8s linear infinite;
}
@keyframes auth-spin {
to {
transform: rotate(360deg);
}
}
/* Scheidingslijn */
.auth-separator {
position: relative;
text-align: center;
padding: 4px 0;
}
.auth-separator::before {
content: "";
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 1px;
background: var(--outline-variant);
}
.auth-separator span {
position: relative;
padding: 0 8px;
background: var(--surface-container-lowest);
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.02em;
text-transform: uppercase;
color: var(--on-surface-variant);
}
/* Demo / secundaire actie */
.auth-secondary {
margin-top: 32px;
padding-top: 24px;
border-top: 1px solid var(--outline-variant);
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
}
.auth-secondary p {
margin: 0;
font-size: 14px;
color: var(--on-surface-variant);
}
.btn-ghost {
display: inline-flex;
align-items: center;
gap: 6px;
width: auto;
padding: 6px 14px;
border: none;
background: transparent;
border-radius: var(--r-pill);
font-family: var(--font-mono);
font-size: 12px;
letter-spacing: 0.02em;
color: var(--primary);
cursor: pointer;
transition: background-color 0.15s ease;
}
.btn-ghost:hover {
background: rgba(0, 124, 131, 0.12);
}
.btn-ghost .icon {
width: 18px;
height: 18px;
}
.btn-ghost.inline-form {
margin: 0;
}
/* Meldingen */
.auth-alert {
display: flex;
align-items: flex-start;
gap: 10px;
margin-bottom: 20px;
padding: 12px 14px;
border-radius: var(--r-input);
font-size: 14px;
line-height: 20px;
}
.auth-alert .icon {
width: 18px;
height: 18px;
flex: 0 0 auto;
margin-top: 1px;
}
.auth-alert.is-error {
background: var(--error-container);
color: var(--on-error-container);
}
.auth-alert.is-success {
background: var(--success-container);
color: var(--on-success-container);
}
.auth-alert.is-info {
background: var(--secondary-container);
color: var(--on-secondary-container);
}
/* Voettekst */
.auth-footer {
margin-top: 32px;
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
}
.auth-footer-links {
display: flex;
align-items: center;
gap: 16px;
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.02em;
}
.auth-footer-links a {
color: var(--on-surface-variant);
text-decoration: none;
transition: color 0.15s ease;
}
.auth-footer-links a:hover {
color: var(--primary);
}
.auth-footer-links .sep {
color: var(--outline-variant);
}
.auth-badge {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 4px 12px;
border-radius: var(--r-pill);
background: var(--secondary-container);
color: var(--on-secondary-container);
}
.auth-badge .icon {
width: 16px;
height: 16px;
}
.auth-badge span {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.08em;
text-transform: uppercase;
}
/* Terug-link op subpagina's */
.auth-back {
display: inline-flex;
align-items: center;
gap: 6px;
margin-top: 20px;
font-family: var(--font-mono);
font-size: 12px;
letter-spacing: 0.02em;
color: var(--on-surface-variant);
text-decoration: none;
}
.auth-back:hover {
color: var(--primary);
}
.auth-back .icon {
width: 16px;
height: 16px;
transform: rotate(180deg);
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
@media (prefers-reduced-motion: reduce) {
.btn,
.btn:active,
.btn .spinner,
.btn-ghost,
.auth-input {
transition: none;
animation: none;
transform: none;
}
}