Skip to main content

oefenhub_generiek_01_berichten_overzicht_v3_3.html

Korte beschrijving

Deze HTML-mockup toont het generieke berichtenoverzicht waarin een gebruiker privéberichten kan terugvinden, filteren en openen. De view ondersteunt dynamische berichtgegevens zoals afzender, onderwerp, snippets, datums en ongelezen status, met een duidelijke ingang om een nieuw privébericht te starten.

Gerelateerde documentatie

Bestand

Broncode

/mockups_html/generiek/oefenhub_generiek_01_berichten_overzicht_v3_3.html
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OefenHub - Berichten</title>
<link href="./oefenhub_shared_logo.css" rel="stylesheet">
<style>
:root {
--blue-1: #8fd0ff;
--blue-2: #5bb3ff;
--blue-3: #1f82e9;
--blue-4: #0d5db8;
--text: #114f95;
--muted: #5f7ea5;
--line: rgba(17,79,149,.12);
--orange-1: #ffbb4d;
--orange-2: #ff9620;
--orange-3: #f87400;
--green-1: #8adf67;
--green-2: #57ba3c;
--green-3: #2c9348;
--yellow-1: #ffd04e;
--yellow-2: #f6aa07;
--red-text: #b74d4d;
--shadow: 0 12px 28px rgba(35, 100, 177, 0.12);
--shadow-soft: 0 8px 18px rgba(35, 100, 177, 0.08);
--card-bg: linear-gradient(180deg, rgba(255,255,255,.96), rgba(243,249,255,.96));
--card-border: 1px solid rgba(170,204,238,.62);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { overflow-x: hidden; }
body {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
color: var(--text);
background:
radial-gradient(circle at 8% 14%, rgba(255,255,255,.68) 0 12%, transparent 13%),
radial-gradient(circle at 18% 10%, rgba(255,255,255,.45) 0 9%, transparent 10%),
radial-gradient(circle at 86% 17%, rgba(255,255,255,.58) 0 11%, transparent 12%),
linear-gradient(180deg, #7ec2f8 0%, #bfe2fd 15%, #edf7ff 34%, #f7fbff 100%);
min-height: 100vh;
overflow-x: hidden;
}

.wrap {
width: min(1220px, calc(100% - 30px));
margin: 0 auto;
}

.header {
padding: 10px 0 12px;
background: linear-gradient(180deg, rgba(100,171,238,.92), rgba(120,192,248,.85));
border-bottom: 1px solid rgba(255,255,255,.38);
box-shadow: 0 8px 20px rgba(28, 100, 177, .08);
}

.header-row {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 10px;
}

.brand {
display: flex;
flex-direction: column;
align-items: flex-start;
min-width: 250px;
}

.welcome-text {
font-size: 12px;
color: rgba(17,79,149,.82);
font-weight: 700;
margin-top: -10px;
margin-left: 53px;
}

.nav-pills {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
flex-wrap: nowrap;
white-space: nowrap;
}

.nav-item {
position: relative;
display: inline-flex;
align-items: center;
}

.pill {
border: 0;
border-radius: 12px;
padding: 10px 16px;
color: #fff;
font-size: 14px;
font-weight: 900;
box-shadow: var(--shadow-soft);
line-height: 1;
cursor: pointer;
flex: 0 0 auto;
transition: transform .18s ease, filter .18s ease;
}
.pill.orange { background: linear-gradient(180deg, #ffbb4d, #ff7f12); }
.pill.blue { background: linear-gradient(180deg, #2f88ea, #176acc); }
.pill.yellow { background: linear-gradient(180deg, #ffd04d, #f4ab08); }
.pill.green { background: linear-gradient(180deg, #8adf67, #58ba3d); }
.pill:hover { filter: brightness(1.06); transform: translateY(-1px); }

.pill.has-chevron {
display: inline-flex;
align-items: center;
gap: 6px;
padding-right: 14px;
}

.pill-caret {
font-size: 12px;
line-height: 1;
transform: translateY(1px);
}

.dropdown-menu {
position: absolute;
top: calc(100% + 8px);
left: 0;
width: 306px;
background: linear-gradient(180deg, rgba(255,255,255,.97), rgba(244,250,255,.98));
border-radius: 20px;
box-shadow: 0 12px 24px rgba(35,100,177,.16);
border: 1px solid rgba(170, 204, 238, .55);
padding: 10px 12px;
z-index: 40;
opacity: 0;
visibility: hidden;
transform: translateY(-4px);
transition: opacity .18s ease, transform .18s ease, visibility .18s ease;
}

.dropdown-menu::before {
content: "";
position: absolute;
top: -10px;
left: 36px;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid rgba(255,255,255,.97);
filter: drop-shadow(0 -1px 0 rgba(170, 204, 238, .45));
}

.nav-item:hover .dropdown-menu,
.nav-item:focus-within .dropdown-menu,
.nav-item.open .dropdown-menu {
opacity: 1;
visibility: visible;
transform: translateY(0);
}

.menu-list { display: flex; flex-direction: column; gap: 0; }

.menu-link {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 9px;
padding: 8px 11px;
border-radius: 13px;
text-decoration: none;
color: #18518f;
font-size: 15px;
font-weight: 900;
box-shadow: inset 0 -1px 0 rgba(17,79,149,.10);
transition: background .18s ease, transform .18s ease;
}
.menu-link:last-child { box-shadow: none; }
.menu-link:hover,
.menu-link.is-active { background: linear-gradient(180deg, #edf5ff, #dcecff); }
.menu-link:hover { transform: translateX(2px); }

.menu-icon {
width: 23px;
height: 23px;
border-radius: 7px;
display: grid;
place-items: center;
color: #fff;
font-size: 14px;
font-weight: 900;
box-shadow: inset 0 1px 1px rgba(255,255,255,.35), 0 4px 8px rgba(0,0,0,.10);
}
.menu-icon.green { background: linear-gradient(180deg, #8add68, #4baa35); }
.menu-icon.blue { background: linear-gradient(180deg, #49a4ff, #1f7fe2); }
.menu-icon.yellow { background: linear-gradient(180deg, #ffd45a, #f0b000); color: #8a5d00; }
.menu-icon.purple { background: linear-gradient(180deg, #8d6cff, #6147d8); }

.menu-arrow {
color: #18518f;
font-size: 22px;
line-height: 1;
font-weight: 700;
}

.header-actions {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 10px;
min-width: 120px;
}

.mail-btn,
.profile-chip {
border: 0;
box-shadow: var(--shadow-soft);
cursor: pointer;
transition: transform .18s ease, background .18s ease;
}

.mail-btn {
position: relative;
width: 40px;
height: 40px;
border-radius: 999px;
background: linear-gradient(180deg, #ffffff, #eef6ff);
color: var(--blue-4);
font-size: 17px;
}

.mail-btn.is-active {
box-shadow: 0 0 0 3px rgba(255,255,255,.46), var(--shadow-soft);
}

.badge {
position: absolute;
right: -2px;
bottom: -2px;
min-width: 18px;
height: 18px;
padding: 0 5px;
border-radius: 999px;
background: #e23838;
color: #fff;
font-size: 11px;
font-weight: 800;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid #fff;
}

.profile-chip {
display: inline-flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 999px;
background: linear-gradient(180deg, #ffffff, #edf6ff);
padding: 0;
}

.mail-btn:hover,
.profile-chip:hover {
background: linear-gradient(180deg, #ffffff, #e4f1ff);
transform: translateY(-1px);
}

.avatar {
width: 28px;
height: 28px;
border-radius: 999px;
display: grid;
place-items: center;
color: #fff;
font-size: 13px;
font-weight: 900;
background: linear-gradient(180deg, #ffb247, #ff8120);
}

main.wrap {
padding: 22px 0 42px;
}

.breadcrumb-bar {
display: flex;
align-items: center;
gap: 8px;
margin: 0 0 14px;
color: rgba(17,79,149,.78);
font-size: 13px;
font-weight: 700;
}

.breadcrumb-bar a {
color: rgba(17,79,149,.76);
text-decoration: none;
}

.breadcrumb-bar a:hover {
color: var(--blue-4);
text-decoration: underline;
}

.breadcrumb-bar span {
color: rgba(17,79,149,.46);
font-weight: 900;
}

.messages-shell {
background: var(--card-bg);
border: var(--card-border);
border-radius: 30px;
box-shadow: var(--shadow);
padding: 20px 22px 22px;
margin-bottom: 0;
}

.intro-card {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 18px;
align-items: start;
padding: 0 0 16px;
margin-bottom: 16px;
border-bottom: 1px solid rgba(170,204,238,.46);
}

.page-title-wrap h1 {
margin: 0 0 8px;
font-size: 22px;
line-height: 1.12;
color: #0d5db8;
}

.page-title-wrap p {
margin: 0;
max-width: 760px;
font-size: 14px;
line-height: 1.55;
color: #18599e;
}

.create-btn {
border: 0;
border-radius: 999px;
padding: 0 20px;
min-height: 40px;
font-size: 14px;
font-weight: 900;
white-space: nowrap;
background: linear-gradient(180deg, #ffbc4b, #ff9621);
color: #ffffff;
box-shadow: 0 10px 18px rgba(255,153,34,.22), inset 0 1px 0 rgba(255,255,255,.35);
cursor: pointer;
transition: transform .18s ease, filter .18s ease;
}
.create-btn:hover { transform: translateY(-1px); filter: brightness(1.02); }
.create-btn:active { transform: translateY(0); }

.tools-card {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: center;
margin-bottom: 16px;
padding: 0;
}

.searchbox {
flex: 1 1 320px;
min-width: 220px;
display: flex;
align-items: center;
gap: 10px;
min-height: 42px;
border-radius: 14px;
padding: 0 14px;
background: rgba(255,255,255,.95);
border: 1px solid rgba(170,204,238,.62);
}

.searchbox input {
width: 100%;
border: 0;
outline: 0;
background: transparent;
color: var(--blue-4);
font-size: 14px;
min-width: 0;
}

.filter-group {
flex: 0 0 auto;
width: fit-content;
max-width: 100%;
display: inline-flex;
align-items: center;
gap: 6px;
padding: 5px;
border-radius: 14px;
background: rgba(255,255,255,.95);
border: 1px solid rgba(170,204,238,.62);
white-space: nowrap;
}

.filter-chip {
border: 0;
background: transparent;
color: var(--text);
border-radius: 10px;
padding: 8px 11px;
font-size: 13px;
font-weight: 800;
cursor: pointer;
white-space: nowrap;
flex: 0 0 auto;
}

.filter-chip.active {
background: linear-gradient(180deg, rgba(91,179,255,.18), rgba(91,179,255,.08));
color: #0d5db8;
}

.messages-layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 248px;
gap: 16px;
align-items: start;
}

.messages-main,
.messages-side {
min-width: 0;
}

.messages-side {
display: grid;
gap: 10px;
align-content: start;
}

.summary-row {
display: grid;
grid-template-columns: 1fr;
gap: 10px;
}

.summary-card {
background: var(--card-bg);
border-radius: 18px;
border: var(--card-border);
padding: 12px;
box-shadow: var(--shadow-soft);
}

.summary-label {
font-size: 11px;
font-weight: 900;
text-transform: uppercase;
letter-spacing: .04em;
color: #6f8eb3;
margin-bottom: 4px;
}

.summary-value {
font-size: 20px;
font-weight: 900;
color: #0d5db8;
line-height: 1.05;
margin-bottom: 2px;
}

.summary-sub {
font-size: 12px;
line-height: 1.35;
color: #2866aa;
}

.messages-list { display: grid; gap: 10px; }

.message-card {
position: relative;
display: grid;
grid-template-columns: auto minmax(0, 1fr);
gap: 12px;
align-items: start;
border-radius: 22px;
padding: 10px 16px;
background: var(--card-bg);
border: var(--card-border);
box-shadow: var(--shadow-soft);
cursor: pointer;
transition: border-color .15s ease, box-shadow .15s ease, background .15s ease, transform .15s ease;
}

.message-card.private {
background: linear-gradient(180deg, rgba(255,251,241,.96), rgba(255,255,255,.96));
}

.message-card.system {
background: linear-gradient(180deg, rgba(238,246,255,.96), rgba(255,255,255,.96));
}

.message-card:hover {
border-color: rgba(104, 164, 224, .72);
box-shadow: 0 10px 22px rgba(38, 88, 160, .14);
transform: translateY(-1px);
}

.message-card.private:hover {
background: linear-gradient(180deg, rgba(255,245,224,.98), rgba(255,255,255,.98));
}

.message-card.system:hover {
background: linear-gradient(180deg, rgba(229,240,255,.98), rgba(255,255,255,.98));
}

.message-card.read .sender,
.message-card.read .subject,
.message-card.read .snippet {
font-weight: 500;
}

.message-card.unread .sender,
.message-card.unread .subject,
.message-card.unread .snippet {
font-weight: 800;
color: #143f73;
}

.message-icon {
width: 42px;
height: 42px;
border-radius: 14px;
display: grid;
place-items: center;
color: #fff;
font-size: 20px;
font-weight: 900;
margin-top: 2px;
box-shadow: 0 8px 16px rgba(17,79,149,.10);
}
.message-icon.info { background: linear-gradient(180deg, #5fb4ff 0%, #3a92f1 100%); }
.message-icon.warn { background: linear-gradient(180deg, #ffbf66 0%, #f39c27 100%); }
.message-icon.person { background: linear-gradient(180deg, #74cf92 0%, #44b76d 100%); }

.message-actions {
position: absolute;
top: 9px;
right: 12px;
display: inline-flex;
gap: 6px;
align-items: center;
}

.icon-btn {
width: 28px;
height: 28px;
border-radius: 999px;
border: 1px solid rgba(170,204,238,.62);
background: rgba(255,255,255,.96);
color: var(--blue-4);
display: grid;
place-items: center;
font-size: 14px;
cursor: pointer;
box-shadow: 0 4px 10px rgba(17,79,149,.08);
}

.icon-btn.delete { color: #b74d4d; }
.icon-btn:hover { background: #f6f9ff; }

.icon-btn.disabled {
color: #b4bccb;
border-color: rgba(17,79,149,.08);
background: rgba(246,248,252,.96);
cursor: not-allowed;
box-shadow: none;
opacity: 1;
}
.icon-btn.disabled:hover { background: rgba(246,248,252,.96); }

.message-meta {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px 10px;
margin-bottom: 4px;
padding-right: 80px;
}

.type-tag {
display: inline-flex;
align-items: center;
min-height: 24px;
padding: 0 10px;
border-radius: 999px;
font-size: 12px;
font-weight: 900;
}
.type-tag.system { background: #dceeff; color: #216ab9; }
.type-tag.private { background: #e3f7ea; color: #23804a; }

.sender {
font-size: 14px;
font-weight: 800;
color: #24384d;
}

.message-date {
font-size: 13px;
color: #73859a;
}

.subject {
margin: 0 0 4px;
font-size: 14px;
font-weight: 800;
line-height: 1.25;
color: #1f2f42;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.snippet {
margin: 0;
font-size: 13px;
line-height: 1.45;
color: #5d7087;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.messages-pagination {
display: flex;
align-items: center;
justify-content: space-between;
gap: 14px;
flex-wrap: wrap;
margin-top: 14px;
padding: 12px 16px;
border-radius: 18px;
background: var(--card-bg);
border: var(--card-border);
box-shadow: var(--shadow-soft);
}

.pagination-left,
.pagination-right {
display: inline-flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}

.pagination-label {
font-size: 13px;
font-weight: 800;
color: var(--muted);
}

.page-select {
min-width: 88px;
height: 36px;
padding: 0 12px;
border-radius: 12px;
border: 1px solid rgba(170,204,238,.62);
background: #fff;
color: var(--text);
font: inherit;
font-size: 14px;
font-weight: 700;
}

.pagination-btn {
min-width: 38px;
height: 36px;
padding: 0 12px;
border-radius: 12px;
border: 1px solid rgba(170,204,238,.62);
background: rgba(255,255,255,.98);
color: var(--blue-4);
font: inherit;
font-size: 14px;
font-weight: 800;
box-shadow: 0 4px 10px rgba(17,79,149,.06);
cursor: pointer;
}

.pagination-btn.active {
background: linear-gradient(180deg, #5eb8ff 0%, #2f8fec 100%);
color: #fff;
border-color: transparent;
box-shadow: 0 8px 18px rgba(47,143,236,.22);
}

.pagination-btn.nav[disabled] {
opacity: .45;
cursor: not-allowed;
box-shadow: none;
}

.pagination-total {
font-size: 13px;
font-weight: 700;
color: var(--muted);
}

.site-footer {
width: 100%;
margin-top: 26px;
background: linear-gradient(180deg, rgba(255,255,255,.86), rgba(255,255,255,.96));
border-top: 1px solid rgba(17,79,149,.10);
box-shadow: var(--shadow);
border-radius: 26px 26px 0 0;
padding: 0;
overflow: visible;
}

.site-footer .wrap {
padding: 22px 0 18px;
}

.footer-grid {
display: grid;
grid-template-columns: 1.1fr 1fr 1fr;
gap: 36px;
align-items: start;
}

.footer-col h4 {
margin: 0 0 12px;
font-size: 15px;
color: #0d5db8;
font-weight: 900;
padding-bottom: 8px;
border-bottom: 1px solid rgba(17,79,149,.14);
}

.footer-col p {
margin: 0;
font-size: 13px;
line-height: 1.55;
color: var(--muted);
font-weight: 600;
}

.footer-links {
display: flex;
flex-direction: column;
gap: 10px;
}

.footer-links a {
color: #18518f;
text-decoration: none;
font-size: 13px;
font-weight: 700;
transition: color .18s ease;
}

.footer-links a:hover {
color: var(--blue-4);
text-decoration: underline;
}

.footer-bottom {
margin-top: 18px;
padding-top: 14px;
border-top: 1px solid rgba(17,79,149,.10);
display: flex;
justify-content: space-between;
gap: 12px;
align-items: center;
flex-wrap: wrap;
font-size: 12px;
color: var(--muted);
font-weight: 600;
}

@media (max-width: 1100px) {
.header-row { grid-template-columns: 1fr; gap: 14px; }
.brand { justify-self: center; align-items: center; min-width: 0; }
.welcome-text { margin-left: 0; margin-top: -6px; }
.header-actions { justify-content: center; }
.nav-pills { overflow-x: auto; justify-content: flex-start; padding-bottom: 2px; width: 100%; }
.messages-layout { grid-template-columns: 1fr; }
.messages-side { order: 2; }
.summary-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.footer-grid { grid-template-columns: 1fr; gap: 24px; }
}

@media (max-width: 900px) {
.dropdown-menu { width: 266px; }
}

@media (max-width: 760px) {
.wrap { width: min(100%, calc(100% - 18px)); }
main.wrap { padding-top: 18px; }
.messages-shell { padding: 18px; border-radius: 24px; }
.intro-card { grid-template-columns: 1fr; padding: 0 0 16px; }
.create-btn { justify-self: start; }
.tools-card { gap: 8px; }
.searchbox { flex: 1 1 100%; min-width: 0; order: 3; }
.filter-group { order: 1; overflow-x: auto; }
.summary-row { grid-template-columns: 1fr; }
.message-meta { padding-right: 68px; }
.messages-pagination { align-items: stretch; }
.pagination-left,
.pagination-right { width: 100%; justify-content: space-between; }
.pagination-right { justify-content: flex-start; }
.site-footer .wrap { padding: 20px 0 16px; }
.footer-bottom { justify-content: flex-start; }
}
</style>
</head>
<body>
<header class="header">
<div class="wrap">
<div class="header-row">
<div class="brand">
<div class="brand-logo" aria-label="OefenHub logo" role="img"></div>
<div class="welcome-text">Welkom terug, Emma</div>
</div>

<div class="nav-pills">
<div class="nav-item" data-menu="rekenen-menu">
<button class="pill orange has-chevron" type="button" aria-expanded="false" aria-controls="rekenen-menu">🔢 Rekenen<span class="pill-caret"></span></button>
<div class="dropdown-menu" id="rekenen-menu">
<div class="menu-list">
<a href="#" class="menu-link is-active"><span class="menu-icon green"></span><span>Optellen</span><span class="menu-arrow"></span></a>
<a href="#" class="menu-link"><span class="menu-icon blue"></span><span>Aftrekken</span></a>
<a href="#" class="menu-link"><span class="menu-icon yellow">×</span><span>Vermenigvuldigen</span></a>
<a href="#" class="menu-link"><span class="menu-icon purple">÷</span><span>Delen</span></a>
</div>
</div>
</div>
<button class="pill blue">📖 Taal</button>
<button class="pill blue">🇬🇧 Engels</button>
<button class="pill yellow">✏️ Spelling</button>
<button class="pill green">🌍 Topografie</button>
</div>

<div class="header-actions">
<button class="mail-btn is-active" aria-label="Berichten">✉️<span class="badge">3</span></button>
<button class="profile-chip" aria-label="Profiel"><span class="avatar">E</span></button>
</div>
</div>
</div>
</header>

<main class="wrap">
<nav class="breadcrumb-bar" aria-label="Breadcrumb">
<a href="#">Home</a>
<span></span>
<strong>Berichten</strong>
</nav>

<section class="messages-shell" aria-labelledby="page-title">
<div class="intro-card">
<div class="page-title-wrap">
<h1 id="page-title">Berichten</h1>
<p>Bekijk hier je systeemberichten en privéberichten. Gebruik de filters om snel te wisselen tussen alles, systeemberichten en privéberichten.</p>
</div>
<button class="create-btn" type="button">Nieuw privébericht</button>
</div>

<section class="tools-card" aria-label="Berichten zoeken en filteren">
<label aria-label="Zoek in berichten" class="searchbox">
<span>🔎</span>
<input class="search-input" placeholder="Zoek op afzender, onderwerp of tekstfragment" type="text" />
</label>
<div aria-label="Filter op type" class="filter-group">
<button class="filter-chip active" type="button">Alles</button>
<button class="filter-chip" type="button">Systeem</button>
<button class="filter-chip" type="button">Privé</button>
</div>
<div aria-label="Filter op status" class="filter-group">
<button class="filter-chip active" type="button">Alle statussen</button>
<button class="filter-chip" type="button">Ongelezen</button>
</div>
</section>

<div class="messages-layout">
<div class="messages-main">
<section aria-label="Berichtenoverzicht" class="messages-list">
<article aria-label="Open bericht: Nieuwe subcategorie beschikbaar op jouw niveau" class="message-card system unread" role="button" tabindex="0">
<div class="message-icon warn">!</div>
<div>
<div class="message-meta">
<span class="type-tag system">Systeem</span>
<span class="sender">Systeem</span>
<span class="message-date">Vandaag · 14:26</span>
</div>
<h2 class="subject">Nieuwe subcategorie beschikbaar op jouw niveau</h2>
<p class="snippet">Er is een nieuwe subcategorie toegevoegd binnen Rekenen die past bij jouw huidige niveau...</p>
</div>
<div class="message-actions">
<button aria-label="Markeer als gelezen" class="icon-btn" title="Markeer als gelezen" type="button"></button>
<button aria-label="Een systeembericht kan niet verwijderd worden" class="icon-btn delete disabled" disabled title="Een systeembericht kan niet verwijderd worden" type="button">🗑</button>
</div>
</article>

<article aria-label="Open bericht: Goed bezig met optellen" class="message-card private unread" role="button" tabindex="0">
<div class="message-icon person">👤</div>
<div>
<div class="message-meta">
<span class="type-tag private">Privé</span>
<span class="sender">Sanne de Vries</span>
<span class="message-date">Vandaag · 12:08</span>
</div>
<h2 class="subject">Goed bezig met optellen</h2>
<p class="snippet">Ik zag dat je al meerdere oefeningen hebt afgerond. Probeer straks ook eens aftrekken...</p>
</div>
<div class="message-actions">
<button aria-label="Markeer als gelezen" class="icon-btn" title="Markeer als gelezen" type="button"></button>
<button aria-label="Verwijder bericht" class="icon-btn delete" title="Verwijder bericht" type="button">🗑</button>
</div>
</article>

<article aria-label="Open bericht: Iemand kijkt live met je mee" class="message-card system unread" role="button" tabindex="0">
<div class="message-icon info">i</div>
<div>
<div class="message-meta">
<span class="type-tag system">Systeem</span>
<span class="sender">Systeem</span>
<span class="message-date">Gisteren · 18:41</span>
</div>
<h2 class="subject">Iemand kijkt live met je mee</h2>
<p class="snippet">Je docent heeft live meekijken gestart. Als je in een oefening zat, zie je deze melding later terug...</p>
</div>
<div class="message-actions">
<button aria-label="Markeer als gelezen" class="icon-btn" title="Markeer als gelezen" type="button"></button>
<button aria-label="Een systeembericht kan niet verwijderd worden" class="icon-btn delete disabled" disabled title="Een systeembericht kan niet verwijderd worden" type="button">🗑</button>
</div>
</article>

<article aria-label="Open bericht: Zullen we straks oefenen?" class="message-card private read" role="button" tabindex="0">
<div class="message-icon person">👤</div>
<div>
<div class="message-meta">
<span class="type-tag private">Privé</span>
<span class="sender">Mees Jansen</span>
<span class="message-date">17 mrt 2026 · 16:02</span>
</div>
<h2 class="subject">Zullen we straks oefenen?</h2>
<p class="snippet">Ik ben ook bezig met Rekenen. Misschien kunnen we straks dezelfde soort sommen doen...</p>
</div>
<div class="message-actions">
<button aria-label="Markeer als ongelezen" class="icon-btn" title="Markeer als ongelezen" type="button"></button>
<button aria-label="Verwijder bericht" class="icon-btn delete" title="Verwijder bericht" type="button">🗑</button>
</div>
</article>

<article aria-label="Open bericht: Koppelverzoek geaccepteerd" class="message-card system read" role="button" tabindex="0">
<div class="message-icon info">i</div>
<div>
<div class="message-meta">
<span class="type-tag system">Systeem</span>
<span class="sender">Systeem</span>
<span class="message-date">15 mrt 2026 · 09:17</span>
</div>
<h2 class="subject">Koppelverzoek geaccepteerd</h2>
<p class="snippet">Een ouder of verzorger heeft het koppelverzoek geaccepteerd en kan nu je voortgang bekijken...</p>
</div>
<div class="message-actions">
<button aria-label="Markeer als ongelezen" class="icon-btn" title="Markeer als ongelezen" type="button"></button>
<button aria-label="Een systeembericht kan niet verwijderd worden" class="icon-btn delete disabled" disabled title="Een systeembericht kan niet verwijderd worden" type="button">🗑</button>
</div>
</article>
</section>

<div class="messages-pagination" aria-label="Paginering berichten">
<div class="pagination-left">
<label class="pagination-label" for="message-count">Toon aantal berichten:</label>
<select class="page-select" id="message-count" name="message-count">
<option selected>5</option>
<option>10</option>
<option>15</option>
</select>
<span class="pagination-total">1–5 van 20 berichten</span>
</div>
<div class="pagination-right">
<button class="pagination-btn nav" type="button" disabled aria-label="Vorige pagina"></button>
<button class="pagination-btn active" type="button" aria-current="page">1</button>
<button class="pagination-btn" type="button">2</button>
<button class="pagination-btn" type="button">3</button>
<button class="pagination-btn" type="button">4</button>
<button class="pagination-btn nav" type="button" aria-label="Volgende pagina"></button>
</div>
</div>
</div>

<aside class="messages-side" aria-label="Berichteninformatie">
<div class="summary-row">
<div class="summary-card">
<div class="summary-label">Ongelezen</div>
<div class="summary-value">3</div>
<div class="summary-sub">2 systeemberichten en 1 privébericht wachten nog op aandacht.</div>
</div>
<div class="summary-card">
<div class="summary-label">Systeemberichten</div>
<div class="summary-value">12</div>
<div class="summary-sub">Meldingen en updates vanuit OefenHub.</div>
</div>
<div class="summary-card">
<div class="summary-label">Privéberichten</div>
<div class="summary-value">8</div>
<div class="summary-sub">Berichten van gekoppelde gebruikers of vrienden.</div>
</div>
<div class="summary-card">
<div class="summary-label">Bewaartermijn</div>
<div class="summary-value">3 mnd</div>
<div class="summary-sub">Privéberichten blijven 3 maanden bewaard.</div>
</div>
</div>
</aside>
</div>
</section>
</main>

<footer class="site-footer">
<div class="wrap">
<div class="footer-grid">
<div class="footer-col">
<h4>OefenHub</h4>
<p>OefenHub helpt kinderen spelenderwijs schoolvakken oefenen, herhalen en beter begrijpen. Alles overzichtelijk op één plek.</p>
</div>
<div class="footer-col">
<h4>Handige Links</h4>
<div class="footer-links">
<a href="#">Over OefenHub</a>
<a href="#">Contact</a>
<a href="#">Privacybeleid</a>
</div>
</div>
<div class="footer-col">
<h4>Snel naar</h4>
<div class="footer-links">
<a href="#">Profiel</a>
<a href="#">Berichten</a>
<a href="#">Meld een probleem</a>
</div>
</div>
</div>
<div class="footer-bottom">
<span>© 2026 OefenHub</span>
</div>
</div>
</footer>

<script>
(function () {
const navItems = document.querySelectorAll('.nav-item[data-menu]');
navItems.forEach(function (item) {
const trigger = item.querySelector('button');
if (!trigger) return;

trigger.addEventListener('click', function (event) {
event.preventDefault();
const isOpen = item.classList.contains('open');
navItems.forEach(function (other) {
other.classList.remove('open');
const btn = other.querySelector('button');
if (btn) btn.setAttribute('aria-expanded', 'false');
});
if (!isOpen) {
item.classList.add('open');
trigger.setAttribute('aria-expanded', 'true');
}
});
});

document.addEventListener('click', function (event) {
navItems.forEach(function (item) {
if (!item.contains(event.target)) {
item.classList.remove('open');
const btn = item.querySelector('button');
if (btn) btn.setAttribute('aria-expanded', 'false');
}
});
});
})();
</script>
<script>
(function () {
const input = document.querySelector('.search-input');
if (!input) return;
const full = 'Zoek op afzender, onderwerp of tekstfragment';
const short = 'Zoeken';
function updatePlaceholder() {
input.placeholder = window.innerWidth <= 900 ? short : full;
}
updatePlaceholder();
window.addEventListener('resize', updatePlaceholder);
})();
</script>
</body>
</html>