Author SHA1 Message Date
marinostrusandClaude Opus 5.5 8b7fa3f716 Donker thema toevoegen via gebruikersmenu rechtsboven
Klik op je naam rechtsboven om een menu te openen met een schakelaar
voor het donkere thema. De keuze wordt per browser onthouden.

- global.css: donkere kleurvariabelen, alleen op scherm (afdrukken blijft licht)
- base.html: gebruikersmenu met themaschakelaar
- vaste witte achtergronden en pastelkleuren op enkele pagina's
  volgen nu het thema

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:08:30 +02:00
marijn 684db2ec82 Upload files to "static" 2026-10-14 14:39:51 +00:00
marijn 857f9c8f8b Update static/pivot_logo_old.png 2026-10-14 14:38:57 +00:00
12 changed files with 163 additions and 20 deletions

No files matched your search

+103 -8
View File
@@ -37,11 +37,85 @@
--shadow: 0 1px 3px rgba(15, 23, 42, .08), 0 4px 12px rgba(15, 23, 42, .05);
--shadow-lg: 0 10px 30px rgba(15, 23, 42, .18);
/* Overige vlakken */
--header-bg: var(--primary-color);
--row-hover: #f8fbfe;
--badge-bg: #e2e8f0; --badge-text: #334155;
--overlay: rgba(255, 255, 255, .85);
--header-height: 64px;
--page-width: 1200px;
--font: "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
}
/* ---------- 1b. Donker thema (aan/uit via het gebruikersmenu rechtsboven) ---------- */
/* Alleen op scherm: afdrukken gebeurt altijd in het lichte thema */
@media screen {
html[data-theme="dark"] {
color-scheme: dark;
--primary-color: #3a8cc9;
--primary-dark: #2d73a8;
--primary-light: #17324a;
--background-color: #0f172a;
--surface: #1e293b;
--surface-muted: #172033;
--border: #334155;
--border-strong: #475569;
--text: #e2e8f0;
--text-muted: #94a3b8;
--success-bg: #14361f; --success-text: #86efac;
--warning-bg: #3a300b; --warning-text: #fde047;
--danger-bg: #3f1515; --danger-text: #fca5a5;
--info-bg: #172a4d; --info-text: #93c5fd;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
--shadow: 0 1px 3px rgba(0, 0, 0, .4), 0 4px 12px rgba(0, 0, 0, .25);
--shadow-lg: 0 10px 30px rgba(0, 0, 0, .6);
--header-bg: #13304a;
--row-hover: #243349;
--badge-bg: #334155; --badge-text: #e2e8f0;
--overlay: rgba(15, 23, 42, .85);
}
html[data-theme="dark"] .flash-message,
html[data-theme="dark"] .flash-message.success,
html[data-theme="dark"] .flash-message.error,
html[data-theme="dark"] .flash-message.danger,
html[data-theme="dark"] .flash-message.warning { border-color: var(--border); }
html[data-theme="dark"] .dash-section-title.admin::after { background: var(--danger-bg); }
html[data-theme="dark"] .tile.tile-tools .tile-icon,
html[data-theme="dark"] .tile.tile-tools .tile-links a:hover { background: #123b38; }
html[data-theme="dark"] .tile.tile-tools h3,
html[data-theme="dark"] .tile.tile-tools .tile-links a:hover { color: #5eead4; }
html[data-theme="dark"] .tile.tile-scholengroep .tile-icon,
html[data-theme="dark"] .tile.tile-scholengroep .tile-links a:hover { background: #2e1f52; }
html[data-theme="dark"] .tile.tile-scholengroep h3,
html[data-theme="dark"] .tile.tile-scholengroep .tile-links a:hover { color: #c4b5fd; }
html[data-theme="dark"] .google-btn { background: var(--surface); color: var(--text); border-color: var(--border-strong); }
html[data-theme="dark"] .google-btn:hover { background: var(--surface-muted); }
html[data-theme="dark"] body.auth-page { background: var(--background-color); }
html[data-theme="dark"] mark { background: #854d0e; color: #fef9c3; }
/* Pagina's met eigen pastelkleuren (gemarkeerde rijen, legendes, filters) */
html[data-theme="dark"] .tellers .let,
html[data-theme="dark"] .filters button.let { background: var(--warning-bg); border-color: #854d0e; }
html[data-theme="dark"] .filters button.let[aria-pressed="true"] { background: #854d0e; color: #fef9c3; }
html[data-theme="dark"] td.leeg,
html[data-theme="dark"] tr.flagged td,
html[data-theme="dark"] table.aw .vandaag,
html[data-theme="dark"] td.inv input.gewijzigd,
html[data-theme="dark"] .panel.directie,
html[data-theme="dark"] .panel.vraag { background: #2e2710 !important; border-color: #854d0e; }
html[data-theme="dark"] tr.rij-fout td { background: #3a1a1a; }
html[data-theme="dark"] button.st:not(.aanwezig):not(.afwezig) { background: var(--surface-muted); border-color: var(--border-strong); color: var(--text-muted); }
html[data-theme="dark"] #personeelBody tr.g-account td, html[data-theme="dark"] .legende i.account { background: #14361f; border-color: #166534; }
html[data-theme="dark"] #personeelBody tr.g-alias td, html[data-theme="dark"] .legende i.alias { background: #3a2a10; border-color: #9a5b13; }
html[data-theme="dark"] #personeelBody tr.g-geen td, html[data-theme="dark"] .legende i.geen { background: #3a1a1a; border-color: #991b1b; }
}
/* ---------- 2. Basis ---------- */
*, *::before, *::after { box-sizing: border-box; }
@@ -84,7 +158,7 @@ a { color: var(--primary-color); }
align-items: center;
gap: 16px;
padding: 0 24px;
background: var(--primary-color);
background: var(--header-bg);
color: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, .15);
}
@@ -130,10 +204,29 @@ a { color: var(--primary-color); }
}
.home-btn, .header-btn { background: rgba(255, 255, 255, .16); color: #fff; }
.home-btn:hover, .header-btn:hover { background: rgba(255, 255, 255, .28); }
.logout-btn { background: #fff; color: var(--danger); }
.logout-btn { background: var(--surface); color: var(--danger); }
.logout-btn:hover { background: var(--danger-bg); }
.app-header form { margin: 0; }
/* Gebruikersmenu (klik op je naam rechtsboven) */
.user-menu { position: relative; }
.user-menu-btn { opacity: 1; font-weight: 500; }
.user-menu-btn .caret { font-size: 10px; opacity: .8; }
.user-menu-panel {
display: none;
position: absolute; right: 0; top: calc(100% + 8px);
z-index: 1100;
min-width: 260px;
padding: 6px 14px;
background: var(--surface); color: var(--text);
border: 1px solid var(--border); border-radius: var(--radius);
box-shadow: var(--shadow-lg);
}
.user-menu.open .user-menu-panel { display: block; }
.user-menu-head { padding: 8px 0 10px; border-bottom: 1px solid var(--border); font-size: 13px; color: var(--text-muted); overflow-wrap: anywhere; }
.user-menu-head strong { display: block; color: var(--text); font-size: 14px; }
.user-menu-panel .switch-row { font-size: 14px; font-weight: 500; cursor: pointer; }
/* ---------- 4. Pagina-layout ---------- */
.app-main {
flex: 1;
@@ -187,7 +280,7 @@ select, textarea {
font: inherit;
font-size: 15px;
color: var(--text);
background: #fff;
background: var(--surface);
border: 1px solid var(--border-strong);
border-radius: var(--radius-sm);
transition: border-color .15s, box-shadow .15s;
@@ -260,7 +353,7 @@ button:disabled, .btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-secondary { background: #475569; }
.btn-secondary:hover { background: #334155; }
.btn-light { background: #fff; color: var(--text); border-color: var(--border-strong); }
.btn-light { background: var(--surface); color: var(--text); border-color: var(--border-strong); }
.btn-light:hover { background: var(--surface-muted); }
.btn-success { background: var(--success); }
.btn-success:hover { background: #15803d; }
@@ -291,7 +384,7 @@ button:disabled, .btn:disabled { opacity: .5; cursor: not-allowed; }
border-radius: var(--radius);
margin-top: 12px;
}
table { width: 100%; border-collapse: collapse; background: #fff; text-align: left; }
table { width: 100%; border-collapse: collapse; background: var(--surface); text-align: left; }
th, td { padding: 11px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }
th {
background: var(--surface-muted);
@@ -299,7 +392,7 @@ th {
color: var(--text-muted); white-space: nowrap;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: #f8fbfe; }
tbody tr:hover { background: var(--row-hover); }
td.actions, th.actions { text-align: right; white-space: nowrap; }
td.actions form { display: inline; margin: 0; }
td.actions > * + * { margin-left: 6px; }
@@ -324,7 +417,7 @@ td.center, th.center { text-align: center; }
display: inline-flex; align-items: center; gap: 4px;
padding: 3px 10px; border-radius: 999px;
font-size: 12.5px; font-weight: 600; white-space: nowrap;
background: #e2e8f0; color: #334155;
background: var(--badge-bg); color: var(--badge-text);
}
.badge-success { background: var(--success-bg); color: var(--success-text); }
.badge-warning { background: var(--warning-bg); color: var(--warning-text); }
@@ -448,7 +541,7 @@ td.center, th.center { text-align: center; }
position: fixed; inset: 0;
z-index: 9999;
flex-direction: column; justify-content: center; align-items: center; gap: 16px;
background: rgba(255, 255, 255, .85);
background: var(--overlay);
backdrop-filter: blur(2px);
}
.spinner {
@@ -563,6 +656,8 @@ body.auth-page { background: linear-gradient(160deg, #eaf2f9 0%, var(--backgroun
/* ---------- 17. Responsief ---------- */
@media (max-width: 900px) {
.brand-school, .header-user { display: none; }
.user-menu-btn { display: inline-flex; }
.user-menu-btn .user-naam { display: none; }
}
@media (max-width: 720px) {
.app-header {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 KiB

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

+1 -1
View File
@@ -7,7 +7,7 @@
<style>
/* Bewerken-knop altijd zichtbaar: laatste kolom blijft rechts staan bij horizontaal scrollen */
.lln-tabel td.actions, .lln-tabel th.actions {
position: sticky; right: 0; background: #fff; white-space: nowrap;
position: sticky; right: 0; background: var(--surface); white-space: nowrap;
box-shadow: -6px 0 6px -6px rgba(15, 23, 42, .15);
}
.lln-tabel th.actions { background: var(--surface-muted); }
+1 -1
View File
@@ -21,7 +21,7 @@
tr.lln.open td:first-child::before { transform: rotate(90deg); }
tr.detail td { background: var(--surface-muted); padding: 10px 14px 14px 44px; }
.day-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.day-chip { display: inline-flex; gap: 6px; align-items: center; padding: 4px 10px; border-radius: 999px; background: #fff;
.day-chip { display: inline-flex; gap: 6px; align-items: center; padding: 4px 10px; border-radius: 999px; background: var(--surface);
border: 1px solid var(--border); font-size: 13px; }
.day-chip .dd { font-weight: 700; color: var(--danger-text); }
.count-badge { display: inline-block; min-width: 34px; text-align: center; padding: 3px 10px; border-radius: 999px; font-weight: 700;
+50 -2
View File
@@ -4,6 +4,10 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}PIVOT{% endblock %} – {{ school_name_short|upper or 'PIVOT' }}</title>
<script>
/* Thema meteen toepassen (vóór het tekenen) zodat de pagina niet eerst licht oplicht */
try { if (localStorage.getItem('pivot.thema') === 'donker') document.documentElement.dataset.theme = 'dark'; } catch (e) { /* geen opslag */ }
</script>
<link rel="icon" type="image/png" href="{{ url_for('static', filename='pivot_mark.png') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='global.css') }}">
{% block head %}{% endblock %}
@@ -44,7 +48,7 @@
onchange="if (this.value) location.href = this.value">
<option value="" selected>🏫 {{ school.naam }} ⇄</option>
{% for s in andere_scholen %}
<option value="{{ url_for('scholen.wissel', code=s.code) }}" style="color:#1e293b">{{ s.naam }}</option>
<option value="{{ url_for('scholen.wissel', code=s.code) }}" style="color:var(--text)">{{ s.naam }}</option>
{% endfor %}
</select>
{% else %}
@@ -52,7 +56,22 @@
{% endif %}
{% endif %}
{% if session.get('user') %}
<span class="header-user">👤 {{ session.get('user') }}</span>
<div class="user-menu" id="user-menu">
<button type="button" class="header-btn header-user user-menu-btn" id="user-menu-btn"
aria-haspopup="true" aria-expanded="false" aria-controls="user-menu-panel" title="Gebruikersmenu">
👤 <span class="user-naam">{{ session.get('user') }}</span> <span class="caret">▼</span>
</button>
<div class="user-menu-panel" id="user-menu-panel">
<div class="user-menu-head">Aangemeld als <strong>{{ session.get('user') }}</strong></div>
<label class="switch-row" for="thema-schakelaar">
<span>🌙 Donker thema</span>
<span class="switch">
<input type="checkbox" id="thema-schakelaar">
<span class="slider"></span>
</span>
</label>
</div>
</div>
{% endif %}
<form action="{{ url_for('auth.logout') }}" method="get">
<button type="submit" class="logout-btn">Uitloggen</button>
@@ -134,6 +153,35 @@
});
}, 6000);
// Gebruikersmenu rechtsboven + donker thema aan/uit (onthouden in deze browser)
(function () {
const menu = document.getElementById('user-menu');
if (!menu) return;
const knop = document.getElementById('user-menu-btn');
const schakelaar = document.getElementById('thema-schakelaar');
function zetOpen(open) {
menu.classList.toggle('open', open);
knop.setAttribute('aria-expanded', open);
}
knop.addEventListener('click', function (e) {
e.stopPropagation();
zetOpen(!menu.classList.contains('open'));
});
document.addEventListener('click', function (e) {
if (!menu.contains(e.target)) zetOpen(false);
});
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') zetOpen(false);
});
schakelaar.checked = document.documentElement.dataset.theme === 'dark';
schakelaar.addEventListener('change', function () {
if (schakelaar.checked) document.documentElement.dataset.theme = 'dark';
else delete document.documentElement.dataset.theme;
try { localStorage.setItem('pivot.thema', schakelaar.checked ? 'donker' : 'licht'); } catch (err) { /* negeren */ }
});
})();
// Escape sluit open modals
document.addEventListener('keydown', function (e) {
if (e.key !== 'Escape') return;
+1 -1
View File
@@ -23,7 +23,7 @@
.modus-keuze small { display: block; color: var(--text-muted); font-weight: 400; }
.tellers { display: flex; flex-wrap: wrap; gap: 10px; margin: 6px 0 14px; }
.teller-knop { all: unset; cursor: pointer; display: inline-flex; gap: 8px; align-items: center; padding: 8px 14px;
border-radius: var(--radius); border: 1px solid var(--border); background: #fff; font-weight: 600; font-size: 14px; }
border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface); font-weight: 600; font-size: 14px; }
.teller-knop.actief { border-color: var(--primary-color); box-shadow: 0 0 0 2px rgba(30,111,165,.18); }
.teller-knop .n { font-size: 18px; }
tr.rij-fout td { background: #fff7f7; }
+1 -1
View File
@@ -23,7 +23,7 @@
.modus-keuze small { display: block; color: var(--text-muted); font-weight: 400; }
.tellers { display: flex; flex-wrap: wrap; gap: 10px; margin: 6px 0 14px; }
.teller-knop { all: unset; cursor: pointer; display: inline-flex; gap: 8px; align-items: center; padding: 8px 14px;
border-radius: var(--radius); border: 1px solid var(--border); background: #fff; font-weight: 600; font-size: 14px; }
border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface); font-weight: 600; font-size: 14px; }
.teller-knop.actief { border-color: var(--primary-color); box-shadow: 0 0 0 2px rgba(30,111,165,.18); }
.teller-knop .n { font-size: 18px; }
tr.rij-fout td { background: #fff7f7; }
+1 -1
View File
@@ -23,7 +23,7 @@
#personeelBody tr.g-account td { background: #e8f7ee; }
#personeelBody tr.g-alias td { background: #fff1e0; }
#personeelBody tr.g-geen td { background: #fdeaea; }
#personeelBody tr[class*="g-"] input.adres, #personeelBody tr[class*="g-"] select.rol { background: #fff; }
#personeelBody tr[class*="g-"] input.adres, #personeelBody tr[class*="g-"] select.rol { background: var(--surface); }
.legende { display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: center; margin: -6px 0 14px; font-size: .88em; color: var(--text-muted); }
.legende button.kleurfilter { all: unset; box-sizing: border-box; cursor: pointer; display: inline-flex; align-items: center;
gap: 6px; padding: 4px 10px; border-radius: 999px; border: 1px solid transparent; }
+1 -1
View File
@@ -11,7 +11,7 @@
.nav-bar form { display: flex; gap: 6px; margin: 0; }
.nav-bar input[type=date] { width: auto; }
.seg { display: inline-flex; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); overflow: hidden; }
.seg a { padding: 8px 14px; text-decoration: none; color: var(--text); font-weight: 600; font-size: 14px; background: #fff; }
.seg a { padding: 8px 14px; text-decoration: none; color: var(--text); font-weight: 600; font-size: 14px; background: var(--surface); }
.seg a.on { background: var(--primary-color); color: #fff; }
.day { margin-bottom: 20px; }
.day-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 10px; }
+3 -3
View File
@@ -8,18 +8,18 @@
{% block extra_css %}
<style>
.soort-switch { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
.soort-switch a { padding: 8px 14px; border-radius: 999px; border: 1px solid var(--border); background: #fff; text-decoration: none; color: var(--text); font-weight: 600; font-size: 14px; }
.soort-switch a { padding: 8px 14px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface); text-decoration: none; color: var(--text); font-weight: 600; font-size: 14px; }
.soort-switch a.on { background: var(--primary-color); border-color: var(--primary-color); color: #fff; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.grid3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0 16px; }
@media (max-width: 640px) { .grid2, .grid3 { grid-template-columns: 1fr; } }
.dagdeel { display: flex; gap: 6px; flex-wrap: wrap; }
.dagdeel label { display: inline-flex; align-items: center; gap: 6px; padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: #fff; cursor: pointer; font-weight: 500; }
.dagdeel label { display: inline-flex; align-items: center; gap: 6px; padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); cursor: pointer; font-weight: 500; }
.dagdeel input:checked + span { font-weight: 700; color: var(--primary-color); }
.klassen-box { border: 1px solid var(--border); border-radius: var(--radius); padding: 10px; background: var(--surface-muted); }
.klassen-box input[type=search] { margin-bottom: 8px; }
.klassen { display: flex; flex-wrap: wrap; gap: 6px; max-height: 210px; overflow-y: auto; }
.klas { display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border: 1px solid var(--border); border-radius: 999px; background: #fff; font-size: 13px; font-weight: 600; cursor: pointer; user-select: none; }
.klas { display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); font-size: 13px; font-weight: 600; cursor: pointer; user-select: none; }
.klas input { width: 14px; height: 14px; }
.klas.on { background: var(--primary-light); border-color: var(--primary-color); color: var(--primary-color); }
.gekozen { font-size: 13px; color: var(--text-muted); margin-top: 6px; }
+1 -1
View File
@@ -21,7 +21,7 @@
.code-panel { margin-top: 18px; border: 2px solid var(--success); border-radius: var(--radius-lg); background: var(--success-bg); padding: 20px; text-align: center; }
.big-code { font-family: ui-monospace, Consolas, monospace; font-size: 40px; font-weight: 800; letter-spacing: 6px; color: var(--success-text); margin: 6px 0 4px; }
.code-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 6px; margin-top: 12px; }
.code-grid span { font-family: ui-monospace, Consolas, monospace; background: #fff; border: 1px solid var(--border); border-radius: 6px; padding: 6px; font-size: 15px; }
.code-grid span { font-family: ui-monospace, Consolas, monospace; background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 6px; font-size: 15px; }
details summary { cursor: pointer; color: var(--text-muted); font-size: 14px; margin-top: 12px; }
.exception-active { margin-top: 14px; }
.pick-list { list-style: none; margin: 10px 0 0; padding: 0; }