:root {
  /* The quietest fill that still says "button": a translucent ink wash, so it
     sits at the same strength on a card, a modal or the page itself. */
  --btn-quiet: rgba(13, 27, 42, 0.05);
  /* Drawn rather than native: a native select puts its arrow hard against the
     right edge and renders 2px taller than a text input, so neither the
     toolbar filters nor the form's two columns would line up. Defined here so
     every select in the app, on either page, uses the one arrow. */
  --select-chevron: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23415a77' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  --bg: #e0e1dd;
  --panel: #f7f8f9;
  --border: #c8cfd8;
  --text: #0d1b2a;
  --text-muted: #415a77;
  --primary: #1b263b;
  --primary-hover: #0d1b2a;
  --primary-light: #dde4ec;
  --green: #71875a;
  --green-bg: #e9eee0;
  --amber: #b5822e;
  --amber-bg: #f5ead2;
  --danger: #a85a3f;
  --danger-bg: #f3e2d9;
  --danger-hover: #ecd2c5;
  --radius: 12px;
  --shadow: 0 1px 3px rgba(13, 27, 42, 0.07), 0 8px 24px rgba(13, 27, 42, 0.05);
  --font-titel: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-data: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --topbar-bg: #0d1b2a;
  --topbar-text: #e0e1dd;
  --topbar-muted: #778da9;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-data);
  background: var(--bg);
  color: var(--text);
}

h1, h2, h3,
.stat-label, .label, .badge, .timeline-type,
.klant-form label, .modal h2, .btn {
  font-family: var(--font-titel);
}

.app { display: flex; flex-direction: column; height: 100vh; }
#app[hidden] { display: none; }

/* ---------- Topbar ---------- */
.topbar {
  display: flex;
  align-items: stretch;
  gap: 24px;
  padding: 16px 28px;
  background: var(--topbar-bg);
  border-bottom: 1px solid var(--topbar-bg);
  position: relative;
}
.topbar h1 { font-size: 17px; margin: 0 0 2px; font-weight: 700; color: var(--topbar-text); flex-shrink: 0; }
.topbar-brand { width: auto; flex-shrink: 0; display: flex; align-items: flex-start; gap: 14px; align-self: flex-start; margin-top: -16px; }
.topbar-title-group { display: flex; flex-direction: column; flex: 1; }
/* Shared with the task list's subtitle so the two headers cannot drift. */
.topbar-fisem-date, .tasks-subtitle { color: #EEEEEE; font-size: 12px; margin: 0 0 20px; }
.fisem-date-value { font-size: calc(1em + 1px); font-weight: 700; }
.logo-wrap { display: flex; align-items: flex-start; flex-shrink: 0; }
.logo { height: 115px; width: auto; object-fit: contain; display: block; }

.topbar-credit {
  margin: 0 0 -14px;
  font-family: var(--font-data);
  font-size: 11.5px;
  color: var(--topbar-muted);
  white-space: nowrap;
}
.topbar-credit a { color: var(--topbar-muted); text-decoration: underline; }
.topbar-credit a:hover { color: var(--topbar-text); }

.user-info {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-family: var(--font-data);
  font-size: 11.5px;
  white-space: nowrap;
}
.user-info-label { color: var(--topbar-muted); font-weight: 400; }
.user-info-value { color: #ffffff; font-weight: 300; }

/* Bottom-aligned, so a label that wraps onto two lines ("In Progress")
   does not push its own figure below the row of the others. */
.stats { display: flex; align-items: flex-end; gap: 22px; margin-top: auto; padding-bottom: 10px; }
/* Label above its figure, both centred on each other: the two are rarely the
   same width ("Owners Balance" over "€ 8.552,09"). */
.stat { display: flex; flex-direction: column; align-items: center; text-align: center; }
.stat-value { font-size: 16px; font-weight: 700; color: var(--topbar-text); }
.stat-label { font-size: 12px; color: var(--topbar-muted); }
.stat-value.ok { color: #a9d18e; }
.stat-value.bad { color: #e29a7d; }

.btn {
  border: none;
  border-radius: 8px;
  padding: 9px 16px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, transform .05s;
  /* Some of these are <a> rather than <button> (a link to another page), and
     without this they pick up the underline from the global link style and no
     longer match the buttons beside them. */
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* An explicit display beats the browser's [hidden] rule, so every button that
   relies on the hidden attribute — Users and Logs for a non-admin, among
   others — would otherwise stay on screen. */
.btn[hidden], .tab-btn[hidden], .icon-btn[hidden] { display: none; }
.btn:active { transform: scale(0.97); }
.btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.btn-primary { background: var(--primary); color: white; }
.btn-primary:hover { background: var(--primary-hover); }
/* A light fill rather than nothing at all: on a panel this pale, a transparent
   button reads as a label until you happen to hover it. */
.btn-ghost { background: var(--btn-quiet); color: var(--text-muted); }
.btn-ghost:hover { background: var(--primary-light); }
.topbar-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 20px; flex-shrink: 0; }
.topbar-buttons { display: flex; gap: 8px; padding-bottom: 10px; margin-top: auto; }
/* For an admin, Users and Logs take the place of the credit and the user
   line; everyone else keeps those two lines and never sees the buttons. A
   class on <body> rather than [hidden], because .user-info sets its own
   display and would win over the attribute. */
.topbar-admin { display: none; gap: 8px; }
.topbar-admin .btn { padding: 7px 12px; font-size: 13px; }
body.is-admin .topbar-admin { display: flex; }
body.is-admin .topbar-credit,
body.is-admin .user-info { display: none; }
/* Slightly tighter than a body button: there are up to five of these, and at
   1200px wide the header was spilling over the edge. */
.topbar-buttons .btn { padding: 7px 12px; font-size: 13px; }
.btn-hamburger { display: none; }
.mobile-account-menu { display: none; }
.btn-topbar-secondary { background: rgba(255, 255, 255, 0.1); color: var(--topbar-text); }
.btn-topbar-secondary:hover { background: rgba(255, 255, 255, 0.18); }
.btn-topbar-blue { background: #3a6ea5; color: #ffffff; }
.btn-topbar-blue:hover { background: #4a80ba; }
.btn-danger { background: var(--danger-bg); color: var(--danger); }
.btn-danger:hover { background: var(--danger-hover); }
.btn-small { padding: 6px 10px; font-size: 12.5px; }

/* ---------- Reserve fund warning ---------- */
.reserve-warning {
  background: var(--danger-bg);
  color: var(--danger);
  padding: 10px 28px;
  font-size: 13px;
  font-weight: 600;
}

/* ---------- Tabbar ---------- */
.tabbar {
  display: flex;
  gap: 4px;
  padding: 10px 28px 0;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
}
.tab-btn {
  border: none;
  text-decoration: none;
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font-titel);
  font-size: 12.5px;
  font-weight: 600;
  padding: 10px 14px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.tab-btn:hover { color: var(--text); }
.tab-btn.actief { color: var(--primary); border-bottom-color: var(--primary); }

/* ---------- Layout ---------- */
.main { flex: 1; display: flex; overflow: hidden; }
.content { flex: 1; overflow-y: auto; padding: 24px 28px; }

.kpi-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; margin-bottom: 22px; }
.kpi-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px 18px;
}
.kpi-card .kpi-label { font-size: 11.5px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .3px; font-family: var(--font-titel); }
.kpi-card .kpi-value { font-size: 22px; font-weight: 700; margin-top: 6px; }
.kpi-card .kpi-sub { font-size: 11.5px; color: var(--text-muted); margin-top: 4px; }
.kpi-card.ok .kpi-value { color: var(--green); }
.kpi-card.bad .kpi-value { color: var(--danger); }

/* Three columns with the title in the middle one, so it is centred on the card
   itself however much sits to either side of it. */
.section-toolbar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; margin-bottom: 30px; gap: 12px; }
.toolbar-side { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
.toolbar-right { justify-content: flex-end; }
/* Centred heading: it takes the space left of the toolbar's buttons and
   centres inside it, so a card with no buttons centres over its full width. */
.section-toolbar h3 { margin: 0; text-align: center; }
/* The tinted plate behind a card title. On an inner element rather than the
   heading itself: the heading has to keep filling the row to stay centred,
   while the plate must hug the text. */
.section-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 16px;
  border-radius: 8px;
  background: var(--primary-light);
}
.section-toolbar h2 { margin: 0; font-size: 18px; }
/* No longer pushes the heading left — the heading itself now takes the
   space and centres in it. */
.section-toolbar .spacer { flex: 0 0 0; }
.section-toolbar select {
  height: 34px;
  font-family: var(--font-data);
  font-size: 12.5px;
  padding: 0 10px;
  border-radius: 8px;
  border: 1px solid var(--border);
  outline: none;
  color: var(--text);
  background-color: var(--panel);
  max-width: 260px;
}
.section-toolbar select:focus { border-color: var(--primary); }

.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px 20px;
  margin-bottom: 18px;
}
.card h3 { margin: 0 0 12px 0; font-size: 14px; text-transform: uppercase; letter-spacing: .4px; color: var(--text-muted); }

/* ---------- Data table ---------- */
.data-table { width: 100%; border-collapse: collapse; }
.data-table th {
  text-align: left;
  font-family: var(--font-titel);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .3px;
  color: var(--text-muted);
  padding: 7px 5px 6px 5px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.data-table th.sortable { cursor: pointer; user-select: none; }
.data-table th.sortable:hover { color: var(--text); }
.data-table td {
  padding: 6px 5px;
  font-size: 12.5px;
  border-bottom: 1px solid var(--border);
  /* Top, not middle: a description that wraps to two lines would otherwise
     leave its date, document and amounts floating halfway down the row. */
  vertical-align: top;
}
.data-table tbody tr:hover td { background: var(--bg); }
.data-table tbody tr:hover + .row-detail td { background: var(--bg); }
.data-table tbody tr:has(+ .row-detail:hover) td { background: var(--bg); }
.data-table tbody tr.row-clickable { cursor: pointer; }
.data-table tr:last-child td { border-bottom: none; }
.data-table td.num, .data-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.data-table td.center, .data-table th.center { text-align: center; }
.data-table td.fit, .data-table th.fit { width: 1%; white-space: nowrap; padding-left: 20px; }
.data-table td.actions { text-align: right; white-space: nowrap; }
.data-table .over-budget { color: var(--danger); font-weight: 700; }
.data-table .under-budget { color: var(--green); }
.row-detail td { padding: 6px 5px 9px 5px; color: var(--amber); font-size: 12px; font-weight: 600; border-top: 1px dotted var(--border); border-bottom: 1px solid var(--border); }
.row-detail .note-icon { margin-right: 6px; vertical-align: -2px; flex-shrink: 0; }
tr:has(+ .row-detail) td { border-bottom: none; }
.empty-row td { color: var(--text-muted); text-align: center; padding: 24px 0; }
.totals-row td {
  font-weight: 700;
  background: none;
  border-top: 2px solid var(--border);
  border-bottom: none;
  padding: 6px 5px;
}
.data-table tbody tr.totals-row:hover td { background: none; }
.data-table tr.row-negative td { color: #de0000; }
/* No red hover: a negative amount is ordinary in all three tables that use this
   class — a discount, a credit, a liability — so the row hovers in the same
   grey as every other row. The red figure says enough on its own. */
.group-title-row td {
  font-weight: 700;
  padding: 15px 5px 6px;
  border-bottom: 1px solid var(--border);
}
.water-table .group-title-row td {
  font-size: 15.5px;
  font-family: var(--font-titel);
  font-weight: 700;
  text-align: center;
  vertical-align: middle;
  background: #EEEEEE;
}
.water-table .totals-row td {
  padding-bottom: 25px;
}
.water-table tbody tr.group-title-row:hover td { background: #EEEEEE; }

/* Water Consumption and Water Meter Readings each split into one table per
   meter (separate <table> elements stacked in separate cards), so
   table-layout:auto would size each independently from its own content and
   the tables could drift out of alignment with each other. Fixed widths,
   shared via these classes, keep every meter's table lined up the same way. */
.water-table { table-layout: fixed; }
.water-table th:nth-child(1), .water-table td:nth-child(1) { width: 85px; }
.water-table th:nth-child(2), .water-table td:nth-child(2) { width: 100px; }
.water-table th:nth-child(3), .water-table td:nth-child(3) { width: 85px; }
.water-table th:nth-child(4), .water-table td:nth-child(4) { width: 95px; }
.water-table th:nth-child(5), .water-table td:nth-child(5) { width: 145px; }
.water-table th:nth-child(6), .water-table td:nth-child(6) { width: 145px; }
.water-table th:nth-child(7), .water-table td:nth-child(7) { width: 55px; }
.water-table th:nth-child(8), .water-table td:nth-child(8) { width: 190px; }
.water-table th:nth-child(9), .water-table td:nth-child(9) { width: 100px; }
.water-table th:nth-child(10), .water-table td:nth-child(10) { width: 85px; }
.water-table th:nth-child(11), .water-table td:nth-child(11) { width: 80px; }
.water-table th:nth-child(12), .water-table td:nth-child(12) { width: 55px; }
.water-table th:nth-child(13), .water-table td:nth-child(13) { width: 55px; }

.meter-readings-table { table-layout: fixed; }
.meter-readings-table th:nth-child(1), .meter-readings-table td:nth-child(1) { width: 56px; }
.meter-readings-table th:nth-child(2), .meter-readings-table td:nth-child(2) { width: 90px; }
.meter-readings-table th:nth-child(3), .meter-readings-table td:nth-child(3) { width: 90px; }
.meter-readings-table th:nth-child(4), .meter-readings-table td:nth-child(4) { width: 100px; }
.meter-readings-table th:nth-child(5), .meter-readings-table td:nth-child(5) { width: 100px; }
.meter-readings-table th:nth-child(6), .meter-readings-table td:nth-child(6) { width: 190px; }
.meter-readings-table th:nth-child(7), .meter-readings-table td:nth-child(7) { width: 110px; }
.meter-readings-table th:nth-child(8), .meter-readings-table td:nth-child(8) { width: 80px; }
.meter-readings-table th:nth-child(9), .meter-readings-table td:nth-child(9) { width: 60px; }

/* A .row-detail row has only 2 <td>s (an empty one + a colspan'd one), not
   9/13 — so the nth-child width rules above (which count DOM position, not
   logical column) would otherwise pin that colspan cell to whichever single
   column's width matches its position, cutting the note's divider short
   instead of letting it span the full remaining row width. */
.meter-readings-table tr.row-detail td, .water-table tr.row-detail td { width: auto; }

.card:has(.water-table), .card:has(.meter-readings-table) { overflow-x: auto; }
/* The toolbar's left cell holds it, so no auto margin is needed any more. */
.owners-filter { display: flex; align-items: center; gap: 14px; }
.owners-table th, .owners-table td { white-space: nowrap; }
/* Each block heading on the same light plate as the window's title, bold, and
   with no rule underneath: the plate sets it apart on its own. */
.owners-table .group-title {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 6px;
  background: var(--primary-light);
  font-weight: 800;
}
.owners-table .group-title-row td { border-bottom: none; }
/* A heading, not a row you can open: it does not light up under the pointer. */
.owners-table tbody tr.group-title-row:hover td { background: none; }
/* Nationality (third column) sat hard against the email beside it. */
.owners-table th:nth-child(3), .owners-table td:nth-child(3) { padding-right: 26px; }
/* No line between two owners of one apartment, and the two sit closer together
   than the rows around them: the pair is a single household, and the line
   under them is where the next apartment begins. */
.owners-table tr.same-household td { border-bottom: none; padding-bottom: 2px; }
.owners-table tr.same-household + tr td { padding-top: 2px; }
/* A block is a building: give its heading room to separate it from the one
   above, but not where it is the first thing under the column headers. */
.owners-table .group-title-row td { padding-top: 30px; }
.owners-table tbody tr:first-child td { padding-top: 12px; }
/* The apartment number is what the directory is looked up by. */
.owners-table tbody tr:not(.group-title-row) td:first-child { font-weight: 700; }
.owners-table .group-title-row td {
  font-family: var(--font-titel);
  font-weight: 600;
  font-size: 13.5px;
}
.invoices-table .group-title-row td { padding-top: 35px; }

/* ---------- Sub-tabs (e.g. within Budget) ---------- */
.subtab-bar { display: flex; gap: 6px; margin-bottom: 16px; }
.subtab-btn {
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text-muted);
  font-family: var(--font-titel);
  font-size: 12.5px;
  font-weight: 600;
  padding: 7px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.subtab-btn:hover { background: var(--bg); }
.subtab-btn.actief { background: var(--primary); color: white; border-color: var(--primary); }

.progress-bar { width: 90px; height: 6px; border-radius: 4px; background: var(--bg); overflow: hidden; flex-shrink: 0; }
.progress-bar-fill { display: block; height: 100%; background: var(--green); }
.progress-bar-fill.warn { background: #FFA500; }
.progress-bar-fill.over { background: var(--danger); }
.progress-bar-fill.cost-over { background: #de0000; }
/* The value right-aligns within the remaining space (so numbers line up
   normally) while the bar keeps a fixed width, so its left edge lines up
   across every row regardless of how wide the preceding number is. */
.pct-cell { display: flex; align-items: center; gap: 8px; }
.pct-value { flex: 1; text-align: right; font-variant-numeric: tabular-nums; }

/* Same light fill as a ghost button: an icon on its own does not read as
   something you can press. */
.icon-btn {
  background: var(--btn-quiet); border: none; cursor: pointer; color: var(--text-muted);
  font-size: 13px; padding: 3px 6px; border-radius: 6px;
}
.icon-btn:hover { background: var(--primary-light); color: var(--text); }
.icon-btn svg { display: block; }
.card-toolbar-icons { display: flex; gap: 4px; align-items: center; }

/* Fast custom tooltip (native title tooltips are slow to appear) */
[data-tooltip] { position: relative; }
[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--text);
  color: var(--panel);
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.3;
  padding: 4px 8px;
  border-radius: 5px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .1s ease;
  z-index: 60;
}
[data-tooltip]:hover::after, [data-tooltip]:focus-visible::after {
  opacity: 1;
  visibility: visible;
  transition-delay: .15s;
}

/* ---------- Info grid (o.a. detail) ---------- */
.info-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px 20px; }
.info-item .label { font-size: 11.5px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .3px; }
.info-item .value { font-size: 12px; margin-top: 2px; word-break: break-word; }
.info-item .value:empty::before { content: "—"; color: var(--border); }

.badge {
  font-size: 10.5px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: .3px;
  flex-shrink: 0;
  display: inline-block;
  /* A two-word label such as "ESTATE MANAGER" must stay on one line. */
  white-space: nowrap;
}
.badge-ok { background: var(--green-bg); color: var(--green); }
.badge-bad { background: var(--danger-bg); color: var(--danger); }
.badge-admin { background: var(--green-bg); color: var(--green); }
/* Neutral grey text: the muted blue it had made a plain user look related to
   the blue Board Member badge. */
.badge-owner { background: var(--bg); color: #5f6368; }
/* The same blue as the Rain damage chip on the task list: the navy it had
   before read as grey beside the others. */
.badge-board { background: #dbe7f5; color: #2c5f96; }
/* Distinct from a plain user: this account can change the task list. */
.badge-manager { background: var(--amber-bg); color: var(--amber); }

/* ---------- Dropzone (PDF import) ---------- */
.dropzone {
  border: 2px dashed var(--border);
  border-radius: var(--radius);
  padding: 32px 20px;
  text-align: center;
  color: var(--text-muted);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.dropzone:hover, .dropzone.dragover { border-color: var(--primary); background: var(--primary-light); }
.dropzone .dropzone-title { font-family: var(--font-titel); font-weight: 700; color: var(--text); margin-bottom: 4px; }
.dropzone .dropzone-hint { font-size: 12px; }
.dropzone input[type="file"] { display: none; }
.dropzone-disabled {
  pointer-events: none;
  cursor: not-allowed;
  opacity: 0.5;
  filter: grayscale(1);
}
.meter-thumb { height: 40px; width: auto; border-radius: 4px; display: block; }

/* Upload preview: 480px wide, matching the resolution the photo is stored at,
   so the dial is legible while the reading is typed in. Portrait frame — a
   landscape shot letterboxes inside it rather than stretching the form. */
.meter-preview {
  width: 480px;
  max-width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: contain;
  background: var(--bg);
  border-radius: 8px;
  margin: 10px 0;
  display: block;
}

.parse-review { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; margin-top: 16px; }
.parse-review label {
  display: flex; flex-direction: column; gap: 5px;
  font-size: 12.5px; color: var(--text-muted); font-weight: 600;
}
.parse-review input {
  height: 34px;
  font-family: var(--font-data);
  font-size: 12px;
  padding: 0 10px;
  border-radius: 8px;
  border: 1px solid var(--border);
  outline: none;
  color: var(--text);
}
.parse-review input.uncertain { border-color: var(--amber); background: var(--amber-bg); }
.parse-hint { font-size: 11.5px; color: var(--text-muted); margin-top: 14px; }

/* ---------- Modal ---------- */
.modal-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(13, 27, 42, 0.35);
  align-items: center; justify-content: center;
  z-index: 50;
}
.modal-overlay.open { display: flex; }
/* The generic single-entity form modal can be opened from within another
   already-open modal (e.g. editing an owner from the Owners Directory) — it
   needs to stack above, regardless of DOM order. */
#form-modal-overlay { z-index: 60; }
.modal {
  background: var(--panel);
  border-radius: 14px;
  padding: 26px 28px;
  width: 640px;
  max-width: 92vw;
  max-height: 86vh;
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(61,51,39,0.22);
}
.modal-small { width: 440px; }
.modal-large { width: 820px; }
.modal-xl { width: 900px; }
.modal-fullwidth { width: 96vw; max-width: 96vw; }
.modal h2 { margin: 0 0 16px 0; font-size: 18px; }
/* The document a row was read from belongs with the row's title, not among
   the buttons that change it. */
.form-modal-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 16px; }
.form-modal-head h2 { margin: 0; }

.modal-opvolging { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.expense-invoices-summary { margin-bottom: 14px; font-family: var(--font-data); color: var(--text); font-size: 14px; }
.expense-invoices-summary p { margin: 0; font-weight: 400; font-size: inherit; }
.expense-invoices-summary strong { font-weight: 600; font-size: inherit; }
.modal-opvolging .modal-actions {
  flex-shrink: 0;
  margin-top: 0;
  padding: 16px 28px;
  border-top: 1px solid var(--border);
}
.modal-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  padding: 22px 28px;
  border-bottom: 1px solid var(--border);
}
.modal-header-row h2 { margin: 0; }
/* The title sits in the middle of the header, the way a card title sits in the
   middle of its card. Three columns rather than a centred flex child, so the
   Close button on the right cannot pull the title off centre. */
#owners-modal-overlay .modal-header-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; }
#owners-modal-overlay .modal-header-row > :last-child { justify-self: end; }
.modal-title-block { text-align: center; }
.modal-title-block h2 { display: inline-block; }
.modal-header-actions { display: flex; align-items: center; gap: 10px; }
.modal-subtitle { margin: 4px 0 0; font-size: 12px; color: var(--text-muted); }
.modal-scroll { overflow-y: auto; padding: 20px 28px 20px; }
.modal-scroll > .card { background: none; border: none; box-shadow: none; padding: 0; margin: 0; }

.opvolging-table { width: 100%; border-collapse: collapse; }
.opvolging-table th {
  text-align: left;
  font-family: var(--font-titel);
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: .3px;
  color: var(--text-muted);
  padding: 16px 10px 8px 0;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  background: var(--panel);
  z-index: 1;
}
.opvolging-table td {
  padding: 9px 10px 9px 0;
  font-family: var(--font-data);
  font-size: 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.opvolging-table tbody tr:hover td { background: var(--bg); }
.opvolging-table tr:last-child td { border-bottom: none; }
.opvolging-table th.sortable { cursor: pointer; user-select: none; }
.opvolging-table th.sortable:hover { color: var(--text); }

/* ---------- Access logs ---------- */
.logs-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 0;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.logs-toolbar #logs-search {
  height: 34px;
  width: 260px;
  max-width: 100%;
  font-family: var(--font-data);
  font-size: 12.5px;
  padding: 0 10px;
  border-radius: 8px;
  border: 1px solid var(--border);
  outline: none;
  color: var(--text);
  background: var(--panel);
}
.logs-toolbar #logs-search:focus { border-color: var(--primary); }
.logs-total { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.logs-ua { max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.logs-pagination { justify-content: space-between; align-items: center; }
.logs-pagination #logs-page-info { font-size: 12px; color: var(--text-muted); }
.logs-pagination-buttons { display: flex; gap: 8px; }

.gebruiker-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  /* The scroll area above already leaves 20px; the form's own 18px on top of
     that left an empty band under the header. */
  padding: 2px 0 18px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 10px;
}
.gebruiker-form label {
  display: flex; flex-direction: column; gap: 5px;
  font-size: 12.5px; color: var(--text-muted); font-weight: 600;
  font-family: var(--font-titel);
}
.gebruiker-form input, .gebruiker-form select {
  height: 34px;
  font-family: var(--font-data);
  font-size: 12px;
  padding: 0 10px;
  border-radius: 8px;
  border: 1px solid var(--border);
  outline: none;
  color: var(--text);
}
.gebruiker-form input:focus, .gebruiker-form select:focus { border-color: var(--primary); }
.gebruiker-form input[name="email"] { width: 200px; }
/* The buttons ride along on the field row: Clear beside the fields it empties,
   while Update and Delete sit together at the far end. */
.gebruiker-form-actions { display: flex; align-items: center; gap: 10px; flex: 1; }
#gebruiker-form-delete { margin-left: auto; }
/* The same 34px as the inputs they sit beside, so the row reads as one. */
.gebruiker-form-actions .btn { height: 34px; padding: 0 16px; }

.klant-form { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 16px; }
.klant-form label {
  display: flex; flex-direction: column; gap: 5px;
  font-size: 12.5px; color: var(--text-muted); font-weight: 600;
}
.klant-form label.full { grid-column: 1 / -1; }
.klant-form input, .klant-form select, .klant-form textarea {
  font-family: var(--font-data);
  font-size: 12px;
  padding: 0 10px;
  border-radius: 8px;
  border: 1px solid var(--border);
  outline: none;
  color: var(--text);
}
.klant-form input, .klant-form select { height: 34px; }
.klant-form textarea { padding: 8px 10px; }
.klant-form input:focus, .klant-form select:focus, .klant-form textarea:focus { border-color: var(--primary); }

.modal-actions { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-top: 20px; }
/* Pushes everything after it to the right, so Delete sits apart in the
   bottom-left corner instead of beside Save. */
.modal-actions .spacer { flex: 1; }
.btn-danger-text { color: var(--danger); }

/* ---------- Toast ---------- */
.toast {
  position: fixed;
  bottom: 24px; left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: #0d1b2a;
  color: #e0e1dd;
  padding: 10px 18px;
  border-radius: 8px;
  font-size: 13.5px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s, transform .2s;
  z-index: 100;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---------- Login-scherm ---------- */
.login-screen {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #29314c;
  z-index: 200;
}
.login-card {
  background: var(--panel);
  border-radius: var(--radius);
  box-shadow: 0 20px 60px rgba(0,0,0,0.35);
  padding: 36px 34px;
  width: 360px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.login-logo-wrap {
  display: flex;
  justify-content: center;
  margin: -36px -34px 18px;
  padding: 22px 0 26px;
  background: var(--topbar-bg);
  border-radius: var(--radius) var(--radius) 0 0;
}
.login-logo { height: 77px; width: auto; object-fit: contain; }
.login-card h1 {
  margin: 0;
  font-size: 21px;
  text-align: center;
  color: var(--text);
}
.login-subtitle {
  margin: -6px 0 8px;
  font-size: 16px;
  text-align: center;
  color: var(--text-muted);
  font-family: var(--font-titel);
  font-weight: 600;
}
.login-card label {
  display: flex; flex-direction: column; gap: 5px;
  font-size: 12.5px; color: var(--text-muted); font-weight: 400;
  text-align: center;
}
.login-card input {
  height: 34px;
  font-family: var(--font-data);
  font-size: 13px;
  padding: 0 10px;
  border-radius: 8px;
  border: 1px solid var(--border);
  outline: none;
  color: var(--text);
}
.login-card input:focus { border-color: var(--primary); }
.login-submit { width: 100%; margin-top: -6px; }
.login-error { color: var(--danger); font-size: 12.5px; min-height: 6px; text-align: center; }
.login-disclaimer { font-size: 12.5px; color: #de0000; font-weight: 400; text-align: center; margin: 0; }

/* ---------- Meter consumption chart (modal) ---------- */
.chart-wrap { position: relative; }
.meter-chart-svg { width: 100%; height: auto; display: block; }
/* Scaled down to a phone's width the labels would be a few pixels tall, so the
   chart keeps a readable size and the card scrolls sideways instead. */
@media (max-width: 760px) {
  .chart-card { overflow-x: auto; }
  .chart-svg { min-width: 620px; }
}
.chart-gridline { stroke: var(--border); stroke-width: 1; }
.chart-axis-label { font-family: var(--font-data); font-size: 11px; fill: var(--text-muted); }
.chart-line { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.chart-marker-ring { fill: var(--panel); }
.chart-crosshair { stroke: var(--text-muted); stroke-width: 1; pointer-events: none; }
.chart-legend { display: flex; gap: 18px; justify-content: center; margin-top: 10px; }
.chart-legend-item { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text); }
.chart-legend-key { width: 16px; height: 2px; border-radius: 1px; display: inline-block; }
.chart-legend-key-bar { height: 10px; border-radius: 2px; }
.chart-year-label { font-weight: 700; fill: var(--text); }
.chart-tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--topbar-bg);
  color: var(--topbar-text);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12px;
  box-shadow: var(--shadow);
  min-width: 150px;
  z-index: 5;
}
.chart-tooltip-date { font-weight: 700; margin-bottom: 4px; }
.chart-tooltip-row { display: flex; align-items: center; gap: 6px; padding: 1px 0; }
.chart-tooltip-key { width: 12px; height: 2px; border-radius: 1px; display: inline-block; flex-shrink: 0; }
.chart-tooltip-label { color: var(--topbar-muted); flex: 1; }
.chart-tooltip-value { font-weight: 700; font-variant-numeric: tabular-nums; }

/* ---------- Mobile ---------- */
@media (max-width: 640px) {
  /* iOS Safari auto-zooms the whole page in when a focused input/select/
     textarea has a computed font-size under 16px. Every form field in this
     app is styled smaller than that for desktop density, so force 16px here
     to stop the page from zooming in on tap — without disabling the user's
     own pinch-zoom (no maximum-scale in the viewport meta tag). */
  input, select, textarea { font-size: 16px !important; }

  /* Table-related filter dropdowns (Invoices account filter, Access Logs
     user filter) read 1px smaller than the general 16px anti-zoom baseline. */
  .section-toolbar select,
  .logs-toolbar #logs-search { font-size: 14px !important; }

  /* Non-admins only ever see these upload cards grayed out and disabled
     (see applyDropzoneAccess in app.js) — on the cramped mobile layout,
     hide them entirely instead rather than showing dead UI. Admins never
     get the .dropzone-disabled class, so theirs stay visible as normal. */
  .dropzone-disabled { display: none; }

  .login-card { width: 92vw; max-width: 360px; padding: 28px 22px; }

  /* Grid instead of flex-wrap here: the logo's rendered width changes
     whenever its height is tuned, and a flex layout has no way to keep
     user-info's left edge locked to the title/subtitle column when that
     width shifts. Grid puts brand in its own column (spanning both rows)
     and title-group/actions in a shared second column, so they always
     line up regardless of logo size. */
  .topbar {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 12px;
    row-gap: 4px;
    padding: 10px 14px;
  }
  .topbar-brand { width: auto; margin-top: -10px; grid-column: 1; grid-row: 1 / span 2; align-self: start; }
  .logo { height: 99px; }
  .topbar h1 { font-size: 14px; margin: 0; }
  .topbar-fisem-date, .tasks-subtitle { font-size: 12px; margin: 2px 0 0; }
  .topbar-title-group { grid-column: 2; grid-row: 1; min-width: 0; padding-right: 44px; }
  .stats { display: none; }
  .topbar-actions { grid-column: 2; grid-row: 2; gap: 6px; align-items: flex-start; }
  .topbar-credit { display: none; }
  .user-info { font-size: 10.5px; margin-top: 6px; }

  /* Accordion menu: tabs + account buttons collapse behind a hamburger toggle,
     pinned to the top-right corner so it doesn't push the user-info line
     around — user-info then naturally falls on its own row below the title. */
  .btn-hamburger {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 5px;
    width: 38px;
    height: 38px;
    padding: 0;
    border: none;
    border-radius: 7px;
    background: rgba(255, 255, 255, 0.1);
    cursor: pointer;
    position: absolute;
    top: 10px;
    right: 14px;
  }
  .btn-hamburger span { display: block; width: 19px; height: 2.4px; background: var(--topbar-text); border-radius: 1px; }
  body.mobile-nav-open .btn-hamburger span:nth-child(1) { transform: translateY(7.4px) rotate(45deg); }
  body.mobile-nav-open .btn-hamburger span:nth-child(2) { opacity: 0; }
  body.mobile-nav-open .btn-hamburger span:nth-child(3) { transform: translateY(-7.4px) rotate(-45deg); }

  .topbar-buttons { display: none; }
  body.is-admin .topbar-admin { display: none; }
  body.is-admin .user-info { display: flex; }

  .tabbar { display: none; }
  body.mobile-nav-open .tabbar {
    display: flex;
    flex-direction: column;
    gap: 0;
    padding: 4px 0 0;
    width: 80%;
    box-shadow: 4px 0 16px rgba(13, 27, 42, 0.2);
  }
  body.mobile-nav-open .mobile-account-menu {
    display: flex;
    flex-direction: column;
    gap: 0;
    padding: 0 0 8px;
    background: var(--panel);
    border-top: 2px solid var(--border);
    width: 80%;
    box-shadow: 4px 0 16px rgba(13, 27, 42, 0.2);
  }
  body.mobile-nav-open .tab-btn {
    width: 100%;
    text-align: left;
    padding: 13px 14px;
    border-bottom: 1px solid var(--border);
    border-left: 3px solid transparent;
  }
  body.mobile-nav-open .tab-btn.actief { border-left-color: var(--primary); background: var(--primary-light); }

  /* Darken the rest of the app while the accordion drawer is open, so it
     reads as a menu overlaying the page rather than just pushing it down. */
  body.mobile-nav-open .reserve-warning,
  body.mobile-nav-open .main {
    position: relative;
    pointer-events: none;
  }
  body.mobile-nav-open .reserve-warning::after,
  body.mobile-nav-open .main::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(13, 27, 42, 0.5);
    z-index: 10;
  }

  .content { padding: 14px; }

  .kpi-grid { grid-template-columns: 1fr; gap: 10px; margin-bottom: 16px; }
  .kpi-card { padding: 12px 14px; }
  .kpi-card .kpi-value { font-size: 19px; }

  .section-toolbar { margin-bottom: 16px; }
  .section-toolbar h2 { font-size: 15px; }

  .card { padding: 12px; overflow-x: auto; }
  .card h3 { font-size: 12.5px; }
  .data-table { min-width: max-content; }
  .data-table th { font-size: 9.5px; padding: 5px 3px 4px; white-space: nowrap; }
  .data-table td { font-size: 10.5px; padding: 4px 3px; }

  .info-grid { grid-template-columns: 1fr 1fr; gap: 10px 14px; }

  .modal { padding: 18px 16px; }
  .modal-header-row, .modal-scroll { padding-left: 16px; padding-right: 16px; }
  .modal-opvolging .modal-actions { padding: 14px 16px; }
  .klant-form, .parse-review { grid-template-columns: 1fr; }
  .gebruiker-form input[name="email"] { width: 100%; }

  .modal-scroll { overflow-x: auto; }
  .opvolging-table th { font-size: 10px; padding: 12px 8px 6px 0; }
  .opvolging-table td { font-size: 10.5px; padding: 7px 8px 7px 0; }
  .logs-toolbar { flex-wrap: wrap; }
  .logs-toolbar #logs-search { width: 100%; }
  .logs-ua { max-width: 160px; }
  .logs-pagination { flex-wrap: wrap; gap: 10px; }
}

/* Every select in the app wears the same drawn arrow. Listed per context
   rather than as a bare `select` rule: each of those rules sets its own
   padding and background, which an element selector could never override.
   background-image, never the shorthand — that would wipe the arrow. */
.section-toolbar select,
.gebruiker-form select,
.klant-form select,
.logs-toolbar #logs-search {
  appearance: none;
  -webkit-appearance: none;
  background-image: var(--select-chevron);
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 12px 12px;
  padding-right: 30px;
  cursor: pointer;
}

/* ---------- change history (admin only): task list and owners directory ---------- */
.history-table { min-width: 860px; }
.history-table td { vertical-align: top; }
.history-when { white-space: nowrap; font-variant-numeric: tabular-nums; }
.history-who  { white-space: nowrap; color: var(--text-muted); }
/* The diff is the widest column and the one worth reading in full. */
.history-change { line-height: 1.45; min-width: 280px; overflow-wrap: anywhere; }
#history-modal-scroll { overflow-x: auto; }
#owner-history-scroll { overflow-x: auto; }
/* Opened from inside the owners directory, so it stacks above it. */
#owner-history-overlay { z-index: 60; }
