:root {
  color-scheme: light;
  --bg: #f4f5f7;
  --panel: #ffffff;
  --text: #14161c;
  --muted: #6b7280;
  --accent: #2f6fed;
  --border: #e9eaee;
  --gold: #d99a1f;
  --gold-soft: #f5b942;
  --green: #0a8f3c;
  --red: #d1372e;
  --shadow-sm: 0 1px 2px rgba(20, 22, 28, 0.04), 0 1px 4px rgba(20, 22, 28, 0.05);
  --shadow-md: 0 2px 6px rgba(20, 22, 28, 0.05), 0 8px 20px rgba(20, 22, 28, 0.06);
  --radius: 10px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}

/* Full-bleed sticky app bar with a centered inner column, so the bar itself spans
   the viewport while its contents stay aligned with the page below it. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
}
.topbar-inner {
  max-width: 1080px;
  margin-inline: auto;
  padding: 0 2rem;
  height: 56px;
  display: flex;
  align-items: center;
  gap: 2rem;
}
.page {
  display: block;
  max-width: 1080px;
  margin-inline: auto;
  padding: 1.75rem 2rem 4rem;
}

.brand {
  font-size: 0.95rem;
  font-weight: 600;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  letter-spacing: -0.01em;
  flex-shrink: 0;
}
/* Het merk is een tegel, geen losse vorm: iets groter dan de tekst en met een
   eigen schaduwtje leest het als een app-icoon in plaats van als een plaatje dat
   toevallig voor de titel staat. */
.logo-icon {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 6px;
  box-shadow: 0 1px 2px rgba(20, 22, 28, 0.14);
}

.topbar-right { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; }
/* Vervangt de synchronisatieknop in een statische bouw: geen knop, wel het
   antwoord op de vraag die je erbij zou stellen. */
.built-at {
  font-size: 0.72rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.value-pill {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  white-space: nowrap;
  cursor: help;
}
.value-pill-main { font-size: 0.85rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.value-pill-sub { font-size: 0.75rem; color: var(--muted); font-variant-numeric: tabular-nums; }

@media (max-width: 860px) {
  .topbar-inner { gap: 1.25rem; }
  .value-pill { display: none; }
}




h2 {
  font-size: 0.95rem;
  font-weight: 600;
  margin: 2.25rem 0 0.85rem;
  letter-spacing: -0.005em;
}
/* A panel's first heading sits right under the app bar, so it doesn't need the
   separating space that headings between sections do. */
.tab-panel > section:first-child > h2 { margin-top: 0; }
.hint { font-weight: normal; font-size: 0.8rem; color: var(--muted); }

button {
  background: var(--accent);
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.9rem;
}
button:disabled { background: var(--border); cursor: not-allowed; }

/* Icoonknopje in plaats van een brede knop met tekst: in de app-balk telt elke
   pixel, en de betekenis zit in het pijltje plus de tooltip. */
#syncButton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  padding: 0;
  border-radius: 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--muted);
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
#syncButton:hover:not(:disabled) { color: var(--text); border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); }
#syncButton:disabled { color: var(--border); background: var(--panel); cursor: not-allowed; }
#syncButton svg { width: 1rem; height: 1rem; }

/* Welk icoon zichtbaar is, wordt gestuurd door een klasse op de knop en niet door
   het hidden-attribuut: dat werkt niet op SVG-elementen (de browserregel
   [hidden]{display:none} geldt alleen voor HTML), waardoor pijltje en vinkje
   anders tegelijk zichtbaar zijn. */
#syncButton .spinner, #syncButton .sync-done { display: none; }
#syncButton.is-busy .spinner { display: block; }
#syncButton.is-busy .sync-icon { display: none; }
#syncButton.is-done .sync-done { display: block; }
#syncButton.is-done .sync-icon { display: none; }
#syncButton.is-done {
  color: var(--green);
  background: color-mix(in srgb, var(--green) 10%, transparent);
  border-color: color-mix(in srgb, var(--green) 35%, var(--border));
}
.spinner {
  width: 0.85rem;
  height: 0.85rem;
  border: 2px solid color-mix(in srgb, currentColor 30%, transparent);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.banner {
  background: var(--panel);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  padding: 0.75rem 1rem;
  border-radius: 8px;
  margin-bottom: 1rem;
  font-size: 0.9rem;
  box-shadow: var(--shadow-sm);
}
.banner.warning { border-left-color: #e0a030; }
.banner.error {
  border-left-color: var(--red);
  background: color-mix(in srgb, var(--red) 4%, var(--panel));
}

.sync-form { display: flex; align-items: center; }

/* Wel voorgelezen, niet zichtbaar: het icoonknopje geeft de uitkomst visueel,
   maar een schermlezer heeft er tekst voor nodig. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.85rem;
  margin-bottom: 1rem;
}

.charts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1rem;
}
.chart-box {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem;
  box-shadow: var(--shadow-sm);
}
.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.15s ease;
}
.card:hover { box-shadow: var(--shadow-md); }
.card.forecast {
  background: color-mix(in srgb, var(--gold-soft) 5%, var(--panel));
  border-color: color-mix(in srgb, var(--gold) 30%, var(--border));
}
.card.forecast .value { color: color-mix(in srgb, var(--gold) 70%, var(--text)); }
.forecast-heading { margin: 2.25rem 0 0.85rem; font-size: 0.95rem; font-weight: 600; color: color-mix(in srgb, var(--gold) 80%, var(--text)); }
.card .label { font-size: 0.72rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 500; }
.card .value { font-size: 1.5rem; font-weight: 600; letter-spacing: -0.01em; }
.card .sub { font-size: 0.78rem; color: var(--muted); }

.forecast-payment { display: flex; align-items: center; gap: 1rem; margin-top: 0.15rem; }
.forecast-payment-text { display: flex; flex-direction: column; gap: 0.2rem; }
.logo-large, .avatar-large {
  width: 3rem;
  height: 3rem;
  border-radius: 11px;
  flex-shrink: 0;
}
.logo-large {
  object-fit: contain;
  background: #fff;
  border: 1px solid var(--border);
  padding: 0.5rem;
  box-shadow: var(--shadow-sm);
}
.avatar-large {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: hsl(var(--hue), 55%, 46%);
  color: white;
  font-size: 1.2rem;
  font-weight: 600;
}

/* Inzichten als losse kaartjes in plaats van een opsomming met bolletjes: met een
   toonicoontje links en de kerncijfers vet leest elk inzicht als een bevinding op
   zich, in plaats van als een regel tekst die je makkelijk overslaat. De kleur zit
   in het icoon en een zweem achtergrond, niet in de zin zelf - dat zou het
   contrast van de tekst omlaag halen. */
.insights {
  list-style: none;
  /* Deze lijst heeft geen eigen kop, dus de ruimte erboven moet het ritme van een
     h2 nadoen - anders plakt ze tegen het blok erboven. Stond op 0 toen ze nog het
     eerste blok van het overzicht was. */
  margin: 2.25rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
  gap: 0.6rem;
}
.insight {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  padding: 0.7rem 0.85rem;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  font-size: 0.86rem;
  line-height: 1.45;
  color: color-mix(in srgb, var(--text) 90%, var(--muted));
}
.insight-text strong {
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.insight-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 1.45rem;
  height: 1.45rem;
  margin-top: 0.05rem;
  border-radius: 7px;
}
.insight-icon svg { width: 0.95rem; height: 0.95rem; }

.insight-neutral .insight-icon {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--accent);
}
.insight-warning .insight-icon {
  background: color-mix(in srgb, var(--gold) 14%, transparent);
  color: color-mix(in srgb, var(--gold) 85%, var(--text));
}
.insight-warning { border-color: color-mix(in srgb, var(--gold) 22%, var(--border)); }
.insight-positive .insight-icon {
  background: color-mix(in srgb, var(--green) 12%, transparent);
  color: var(--green);
}
.insight-positive { border-color: color-mix(in srgb, var(--green) 20%, var(--border)); }

.badges { display: flex; gap: 0.5rem; flex-wrap: wrap; margin: 0.75rem 0 0; }
.badge {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.3rem 0.7rem;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--muted);
  box-shadow: var(--shadow-sm);
  cursor: help;
}


.positive { color: var(--green); font-weight: 600; }
.negative { color: var(--red); font-weight: 600; }

/* The tabs live inside the app bar and stretch to its full height, so the active
   underline lands exactly on the bar's bottom border (hence the -1px pull). */
.tabs { display: flex; gap: 1.5rem; align-self: stretch; }
.tab-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  background: transparent;
  color: var(--muted);
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  padding: 0;
  margin-bottom: -1px;
  font-size: 0.87rem;
  font-weight: 500;
  cursor: pointer;
  transition: color 0.15s ease;
  white-space: nowrap;
}
.tab-btn.active { color: var(--text); border-bottom-color: var(--text); font-weight: 600; }
.tab-btn:hover:not(.active) { color: var(--text); }

/* Secondary tabs inside a panel (e.g. Sector / Land) - pill-shaped so they read as
   a filter on the content below, clearly subordinate to the app bar's main tabs. */
.subtabs {
  display: flex;
  gap: 0.35rem;
  margin-bottom: 1.25rem;
  flex-wrap: wrap;
}
.subtab {
  background: transparent;
  color: var(--muted);
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 0.3rem 0.8rem;
  font-size: 0.82rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.subtab:hover:not(.active) { background: var(--bg); color: var(--text); }
.subtab.active { background: var(--text); color: var(--panel); }

.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
  margin-top: 2rem;
}
.split section { margin: 0; }
.split h2 { margin-top: 0; }


table.compact { font-size: 0.85rem; }
.table-scroll { overflow-x: auto; border-radius: var(--radius); }
.table-scroll table { border-radius: var(--radius); }

.bar-list { display: flex; flex-direction: column; gap: 0.5rem; }
.bar-row {
  display: grid;
  grid-template-columns: 6.5rem 1fr 3rem;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.85rem;
}
.bar-label { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-track {
  background: var(--border);
  border-radius: 999px;
  height: 0.55rem;
  overflow: hidden;
}
.bar-fill {
  display: block;
  height: 100%;
  background: hsl(var(--hue, 220), 55%, 46%);
  border-radius: 999px;
}
.bar-pct { color: var(--muted); text-align: right; font-variant-numeric: tabular-nums; }

.donut-wrap { display: flex; align-items: center; gap: 2rem; flex-wrap: wrap; }
.donut-canvas { flex: 0 0 210px; width: 210px; height: 210px; }
.donut-legend {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1;
  min-width: 13rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.donut-legend li { display: flex; align-items: center; gap: 0.55rem; font-size: 0.85rem; }
.donut-swatch { width: 0.6rem; height: 0.6rem; border-radius: 3px; flex-shrink: 0; }
.donut-flag { font-size: 1rem; flex-shrink: 0; line-height: 1; }
.donut-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.donut-pct { color: var(--muted); font-variant-numeric: tabular-nums; font-weight: 500; }

.search-input {
  width: 100%;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.5rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel);
  color: var(--text);
  font-size: 0.87rem;
  box-shadow: var(--shadow-sm);
}
.search-input:focus { outline: none; border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }

.table-controls {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.5rem;
}
.table-controls .search-input { flex: 1; margin-bottom: 0; }

.switch {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  color: var(--muted);
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
}
.switch input { cursor: pointer; }


table {
  width: 100%;
  border-collapse: collapse;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  font-size: 0.87rem;
  box-shadow: var(--shadow-sm);
}
th, td {
  text-align: left;
  padding: 0.6rem;
  border-bottom: 1px solid var(--border);
}
th {
  color: var(--muted);
  font-weight: 500;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
th[data-sort] { cursor: pointer; user-select: none; }
th[data-sort]::after {
  content: "↕";
  margin-left: 0.3rem;
  font-size: 0.9em;
  opacity: 0.28;
}
th[data-sort]:hover::after { opacity: 0.6; }
th[data-sort].sorted-asc::after { content: "↑"; opacity: 1; color: var(--text); }
th[data-sort].sorted-desc::after { content: "↓"; opacity: 1; color: var(--text); }
tr:last-child td { border-bottom: none; }
tbody tr { transition: background-color 0.1s ease; }
tbody tr:hover { background: var(--bg); }

/* Keep company names to one line - a few of them are long enough to wrap to three
   lines each, which triples every row's height and makes the table hard to scan.
   The full name stays available via the cell's title tooltip. */
.name-cell {
  max-width: 9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nowrap-cell { white-space: nowrap; }

/* Datum en bedrag onder elkaar: samen op één regel maakte dit de breedste kolom
   van de tabel en duwde die het scherm uit. */
.next-payment { display: flex; flex-direction: column; line-height: 1.3; }
.next-payment-amount { color: var(--muted); font-size: 0.8rem; }

.holding-row { cursor: pointer; }
.chevron {
  display: inline-block;
  width: 0.9rem;
  margin-right: 0.15rem;
  color: var(--muted);
  transition: transform 0.15s ease;
  flex-shrink: 0;
}
.holding-row.expanded .chevron { transform: rotate(90deg); }
.holding-row.expanded { background: var(--bg); }

.holding-detail td {
  background: var(--bg);
  padding: 0.75rem 1rem 0.75rem 2.75rem;
  cursor: default;
}
.payment-history { width: auto; min-width: 20rem; font-size: 0.85rem; background: transparent; border: none; }
.payment-history th, .payment-history td { padding: 0.35rem 0.6rem; }
.payment-history tr:last-child td { border-bottom: none; }

.empty { color: var(--muted); font-size: 0.9rem; }
code {
  background: var(--border);
  padding: 0.1rem 0.35rem;
  border-radius: 4px;
}

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 7px;
  background: hsl(var(--hue), 55%, 46%);
  color: white;
  font-size: 0.7rem;
  font-weight: 600;
  margin-right: 0.4rem;
  vertical-align: middle;
}

.logo {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 7px;
  object-fit: contain;
  background: #fff;
  border: 1px solid var(--border);
  padding: 2px;
  margin-right: 0.4rem;
  vertical-align: middle;
}

/* Keeps a logo/avatar and its ticker text as one atomic unit - without this, the
   browser can break the line between the image and the text once the column gets
   narrow (e.g. table-layout squeezing this column to fit a long company name in
   the next one), leaving the symbol text stranded on its own line below the icon. */
.symbol-cell {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.symbol-cell .logo, .symbol-cell .avatar { margin-right: 0.4rem; }

.sparkline { width: 60px; height: 20px; vertical-align: middle; }

.pill {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 500;
}
.pill-dividend { background: color-mix(in srgb, var(--green) 15%, transparent); color: var(--green); }
.pill-tax { background: color-mix(in srgb, var(--red) 12%, transparent); color: var(--red); }

.history-table tbody tr { cursor: help; }
.amount-cell { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.num-cell { text-align: right; font-variant-numeric: tabular-nums; }

/* Tweede regel in een tabelcel: de omgerekende waarde of het belastingpercentage.
   Blokweergave zodat het onder het bedrag valt en de kolom niet breder maakt. */
.cell-sub {
  display: block;
  font-size: 0.72rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
/* De valutacode hoort bij het bedrag maar mag de cijfers niet overstemmen. */
.ccy { font-size: 0.78em; color: var(--muted); font-weight: 400; }
/* Alleen zichtbaar zodra de kolommen Bruto en Bronbelasting wegvallen. */
.netto-detail { display: none; }
.history-table th:last-child, .history-table td.amount-cell { text-align: right; }
.sparkline polyline {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.tab-panel { animation-duration: 0.25s; animation-timing-function: ease-out; }
.tab-fade-in { animation-name: tabFadeIn; }
@keyframes tabFadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* --- Totaalrendement ------------------------------------------------------- */

/* De toggle hoort bij de kaart, niet bij de kop: hij verandert wat de kaart toont
   en staat daarom binnen dezelfde rand. Rechts uitgelijnd op een eigen regel - met
   een float ging hij op een smal scherm over "Nu waard" heen liggen, want een
   float reserveert geen ruimte in het raster eronder. */
/* Kop met de schakelaar rechts ernaast, op dezelfde lijn. */
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.section-head h2 { min-width: 0; }
.return-switch {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-shrink: 0;
  font-size: 0.78rem;
  color: var(--muted);
  white-space: nowrap;
}

.payback {
  margin: 1.1rem 0 0.4rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}
.payback-head { display: flex; justify-content: space-between; align-items: baseline; }
.payback-pct { font-size: 1.35rem; font-weight: 600; color: var(--gold); font-variant-numeric: tabular-nums; }
.payback-bar {
  height: 8px;
  margin: 0.45rem 0 0.4rem;
  border-radius: 999px;
  background: var(--bg);
  border: 1px solid var(--border);
  overflow: hidden;
}
.payback-bar span { display: block; height: 100%; width: 0; background: var(--gold); border-radius: inherit; transition: width 0.6s; }
.payback-sub { margin: 0; font-size: 0.8rem; color: var(--muted); }

.return-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2.5rem;
  margin-bottom: 1.2rem;
}
/* Eén raster voor beide stappen in plaats van twee kolommen naast elkaar: zo
   liggen de labels op één lijn, de cijfers op één lijn en de onderschriften op
   één lijn. Met flex zouden de twee blokken op hun midden uitlijnen, en omdat ze
   niet even hoog hoeven te zijn stond "Nu waard" dan hoger dan "Ingelegd".
   display:contents laat de kinderen van elke stap zelf rastercellen worden. */
.return-flow {
  display: grid;
  grid-template-columns: auto auto auto;
  column-gap: 1rem;
  align-items: baseline;
}
.return-flow > .return-step { display: contents; }
.return-flow > .return-step:first-of-type > * { grid-column: 1; }
.return-flow > .return-step:last-of-type > * { grid-column: 3; }
/* Afstammelingsselector, geen kindselector: met display:contents blijven deze
   elementen kinderen van .return-step in de DOM, ook al zijn ze rastercellen. */
.return-flow .return-label { grid-row: 1; padding-bottom: 0.3rem; }
.return-flow .return-value { grid-row: 2; }
.return-flow .return-sub { grid-row: 3; padding-top: 0.3rem; }
.return-arrow {
  grid-column: 2;
  grid-row: 2;
  align-self: baseline;
  color: var(--muted);
  font-size: 1.1rem;
}
.return-part { display: flex; flex-direction: column; gap: 0.3rem; }
.return-label {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.775rem;
  color: var(--muted);
  white-space: nowrap;
}
.return-value {
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.015em;
}
.return-value small { margin-left: 0.35rem; font-size: 0.78rem; }
.return-sub { font-size: 0.72rem; color: var(--muted); white-space: nowrap; }
.return-swatch { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
.return-swatch.is-price { background: var(--green); }
.return-swatch.is-dividend { background: var(--gold); }

/* De twee delen en hun som staan los van het "ingelegd -> nu"-paar: dat is de
   uitkomst, dit is de verklaring ervan. */
.return-split {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  padding-left: 2.5rem;
  border-left: 1px solid var(--border);
}
.return-part.is-total .return-value { font-size: 1.5rem; }

/* Samenvatting van koers en dividend in de uitklapregel van een positie. */
.holding-market {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.5rem;
  margin: 0 0 0.8rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.82rem;
}
.holding-market span { color: var(--muted); }
.holding-market b { color: var(--text); font-variant-numeric: tabular-nums; margin-left: 0.3rem; }
/* Zelfde strook als hierboven, maar voor gegevens die niet elke positie heeft. */
.holding-extra {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.4rem;
  align-items: center;
  margin-bottom: 0.9rem;
  font-size: 0.8rem;
  color: var(--muted);
}
.holding-extra b { color: var(--text); margin-left: 0.3rem; }
.holding-extra .sparkline { width: 60px; height: 20px; margin-left: 0.4rem; vertical-align: middle; }
/* Een afgesloten positie: dezelfde regel, maar zonder de nadruk van iets dat nog
   kan bewegen - net als de grijze balken in de rendementsgrafiek. */
.holding-market.is-closed b:not(.positive):not(.negative) { color: var(--muted); }

/* Een verouderde koersmomentopname mag niet wegvallen in de grijze voetnoot. */
.curve-note .stale { color: var(--red); font-weight: 500; }

/* --- Inkomsten per maand -------------------------------------------------- */

.curve-box { padding-top: 1rem; }

.curve-totals {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 2.75rem;
  margin-bottom: 1.1rem;
}
.curve-total { display: flex; flex-direction: column; gap: 0.3rem; }
.curve-total-label {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  /* Even hoog als een label mét kleurblokje, anders ligt het label van de
     volgende betaling twee pixels lager dan de twee ernaast. */
  min-height: 14px;
  /* Geen kapitalen met letterafstand meer: twee van die labels naast elkaar boven
     de grafiek schreeuwen harder dan de cijfers eronder, en die zijn het punt. */
  font-size: 0.775rem;
  color: var(--muted);
}
/* Het blokje herhaalt precies de vulling van de balken eronder. */
.curve-swatch {
  width: 10px;
  height: 14px;
  border-radius: 2px;
  background: hsl(222, 55%, 46%);
  flex-shrink: 0;
}
.curve-swatch.is-soft { background: hsla(222, 55%, 46%, 0.40); }
/* Op een telefoon past "afgelopen 12 maanden" niet naast het cijfer zonder over
   drie regels te breken; daar staat de korte vorm. */
.label-short { display: none; }
.curve-total-value {
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
/* De valuta hoort bij het getal maar hoeft niet mee te schreeuwen. */
/* Derde regel onder beide kopcijfers. Allebei moeten ze hem hebben, ook als er
   weinig te zeggen valt: zonder die regel liggen de twee kolommen niet gelijk. */
.curve-total-sub {
  font-size: 0.74rem;
  color: var(--muted);
  min-height: 1.1em;
}
.curve-total-sub.is-figure strong { color: var(--text); font-weight: 600; }

.curve-total-value small {
  margin-left: 0.3rem;
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--muted);
}
/* De volgende betaling gaat rechts staan en duwt de twee totalen naar links: het
   is dezelfde inkomstenstroom, maar een andere schaal - vandaar de scheidslijn. */
.curve-next {
  margin-left: auto;
  padding-left: 1.6rem;
  border-left: 1px solid var(--border);
}
.curve-next-body { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.1rem; }
.curve-next-body > div { display: flex; flex-direction: column; }
.curve-next-symbol { font-size: 1.05rem; font-weight: 600; line-height: 1.2; }
.curve-next-sub { font-size: 0.78rem; color: var(--muted); white-space: nowrap; }

#incomeCurve { height: 340px; }

.curve-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  list-style: none;
  margin: 0.6rem 0 0;
  padding: 0;
}
.curve-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  /* Eén regel: logo, ticker en kleurstip horen bij elkaar en mogen nooit los van
     elkaar afbreken. */
  white-space: nowrap;
  padding: 0.25rem 0.55rem 0.25rem 0.3rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
}
.curve-chip:hover { background: var(--bg); }
.curve-chip .logo, .curve-chip .avatar { width: 18px; height: 18px; font-size: 0.6rem; }
.curve-chip-dot { width: 7px; height: 7px; border-radius: 50%; }
/* Posities die je niet meer aanhoudt: ze horen in de grafiek thuis omdat ze je wél
   dividend betaald hebben, maar ze zeggen niets meer over wat er nog komt. Grijs
   zet ze op hun plaats zonder ze te verbergen. Niet helemaal ontkleurd, zodat het
   bolletje nog naar zijn eigen blok in de stapel blijft wijzen. */
.curve-chip.is-sold { filter: grayscale(0.9); color: var(--muted); }
.curve-chip.is-sold:hover { filter: grayscale(0.35); color: var(--text); }

/* Uitgeschakeld blijft leesbaar maar duidelijk inactief - wegkleuren tot onzichtbaar
   zou de knop onvindbaar maken om weer aan te zetten. */
.curve-chip.is-off { opacity: 0.4; }
.curve-chip.is-off .curve-chip-dot { background: var(--border) !important; }

.curve-note {
  margin: 0.7rem 0 0;
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--muted);
}

/* Tooltip van de inkomstengrafiek: een maand kan een handvol posities bevatten,
   dus die krijgen een eigen rasterregel in plaats van ECharts' losse tekstregels. */
.tt-head {
  font-weight: 600;
  margin-bottom: 0.35rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--border);
}
.tt-head em, .tt-row em { font-style: normal; color: var(--muted); font-size: 0.9em; }
.tt-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.09rem 0;
}
.tt-row span { flex: 1; }
.tt-row b, .tt-foot b { font-variant-numeric: tabular-nums; }
.tt-foot {
  display: flex;
  justify-content: space-between;
  gap: 1.2rem;
  margin-top: 0.35rem;
  padding-top: 0.3rem;
  border-top: 1px solid var(--border);
}
.tt-foot.subtle { border-top: 0; padding-top: 0; margin-top: 0.1rem; color: var(--muted); }

/* --- Belgische dividendvrijstelling ---------------------------------------- */

.exemption {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem 1rem;
  box-shadow: var(--shadow-sm);
  margin: 0 0 1.5rem;
}
.exemption h2 { margin: 0 0 0.5rem; }
.exemption-intro {
  margin: 0 0 1.1rem;
  max-width: 68ch;
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--muted);
}
.exemption-intro strong { color: var(--text); }
.exemption-intro em { font-style: normal; color: var(--text); }

.exemption-years { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.9rem; }
.exemption-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.35rem;
}
.exemption-label { font-weight: 600; font-variant-numeric: tabular-nums; }
.exemption-figure { font-size: 0.85rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.exemption-figure strong { color: var(--text); }
/* Het lopende jaar is waar je nog iets aan kan doen; de rest is naslag. */
.exemption-year:not(.is-current) { opacity: 0.72; }

.exemption-bar {
  position: relative;
  height: 8px;
  border-radius: 999px;
  background: var(--bg);
  overflow: hidden;
}
.exemption-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  border-radius: 999px;
  background: var(--accent);
}
/* Doorschijnend voor wat nog moet komen - hetzelfde onderscheid als de balken in
   de inkomstengrafiek, zodat je het niet opnieuw hoeft te leren. */
.exemption-fill.is-expected { background: color-mix(in srgb, var(--accent) 40%, transparent); }

.exemption-foot { margin-top: 0.35rem; font-size: 0.78rem; color: var(--muted); }
.exemption-note {
  margin: 1.1rem 0 0;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border);
  font-size: 0.75rem;
  color: var(--muted);
}

/* ECharts meet zijn container op het moment dat het initialiseert; een div zonder
   hoogte levert dus een lege grafiek op. Chart.js regelde dat zelf via een
   beeldverhouding op het canvas, hier moet de hoogte van de CSS komen. */
.echart { width: 100%; height: 280px; }
.donut-canvas .echart { height: 100%; }
.sankey-box .echart { height: 440px; }
#simulatorChart { height: 300px; }

.simulator-controls {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
  margin-bottom: 1rem;
}
.simulator-controls label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.85rem;
  color: var(--muted);
}
.simulator-controls label.switch { flex-direction: row; align-items: center; }
.simulator-controls input[type="number"] {
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel);
  color: var(--text);
  font-size: 0.9rem;
}

.simulator-headline {
  font-size: 0.95rem;
  font-weight: 600;
  color: color-mix(in srgb, var(--gold) 70%, var(--text));
  padding: 0.75rem 1rem;
  background: color-mix(in srgb, var(--gold-soft) 8%, var(--panel));
  border: 1px dashed color-mix(in srgb, var(--gold) 45%, var(--border));
  border-radius: 8px;
  margin: 0 0 1rem;
}
.simulator-headline.negative {
  color: color-mix(in srgb, var(--red) 75%, var(--text));
  background: color-mix(in srgb, var(--red) 6%, var(--panel));
  border-color: color-mix(in srgb, var(--red) 40%, var(--border));
}

/* Bovenaan de inhoud, niet boven de app-balk: daar duwde hij de hele navigatie
   omlaag en leek de melding los van de pagina te zweven. Hier staat hij op de
   plek waar ook de andere meldingen verschijnen, binnen dezelfde kolom.
   De :not(:empty)-regel voorkomt witruimte wanneer er niets te melden is - de
   container staat altijd in de DOM en wordt pas door JS gevuld. */
#paydayBanners {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
#paydayBanners:not(:empty) { margin-bottom: 1rem; }
/* Reads as a transaction row rather than a shouty alert: white panel like every
   other card, one green accent edge to say "money in", and the amount right-aligned
   where the eye already looks for figures in the tables. */
.payday-banner {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.75rem 0.9rem;
  background: var(--panel);
  border: 1px solid var(--border);
  border-left: 3px solid var(--green);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  animation: paydaySlideIn 0.3s ease;
}
@keyframes paydaySlideIn {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

.payday-media { display: flex; flex-shrink: 0; }
.logo.payday-logo, .avatar.payday-logo {
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 9px;
  font-size: 0.85rem;
  margin-right: 0;
}

.payday-text { flex: 1; min-width: 0; }
.payday-title { font-size: 0.9rem; display: flex; align-items: baseline; gap: 0.45rem; min-width: 0; }
.payday-title strong { font-weight: 600; flex-shrink: 0; }
.payday-name {
  color: var(--muted);
  font-size: 0.85rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.payday-calc {
  color: var(--muted);
  font-size: 0.8rem;
  margin-top: 0.1rem;
  font-variant-numeric: tabular-nums;
}

.payday-amounts { text-align: right; flex-shrink: 0; }
.payday-amount {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--green);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.payday-change { margin-left: 0.4rem; font-size: 0.8rem; font-weight: 600; }
.payday-base {
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 0.1rem;
  font-variant-numeric: tabular-nums;
}

.payday-banner-close {
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: 0.95rem;
  cursor: pointer;
  padding: 0.3rem;
  line-height: 1;
  border-radius: 6px;
  flex-shrink: 0;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.payday-banner-close:hover { background: var(--bg); color: var(--text); }


/* ==========================================================================
   Mobiele aanpassingen - bewust helemaal onderaan.
   Een media query verhoogt de specificiteit niet: stond dit boven de gewone
   regels, dan won bij gelijke specificiteit simpelweg de laatste. Onderaan
   houden betekent dat deze overschrijvingen altijd echt overschrijven.
   ========================================================================== */

@media (max-width: 680px) {
  /* Twee rijen in plaats van drie: merk en knoppen samen bovenaan, de tabs op een
     eigen rij die zijwaarts kan schuiven als er ooit een tab bijkomt. Scheelt een
     derde van de hoogte voordat je iets van je portefeuille ziet. */
  .topbar-inner {
    height: auto;
    flex-wrap: wrap;
    padding: 0.55rem 1rem;
    gap: 0.5rem 0.75rem;
  }
  .brand { order: 1; font-size: 0.9rem; }
  .topbar-right { order: 2; margin-left: auto; gap: 0.4rem; }
  .tabs {
    order: 3;
    flex-basis: 100%;
    gap: 1.1rem;
    overflow-x: auto;
    scrollbar-width: none;
    margin-bottom: -0.55rem;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tab-btn { padding-bottom: 0.5rem; }


  .page { padding: 1.25rem 1rem 3rem; }

  /* Zoekveld en schakelaar naast elkaar liet van het zoekveld nog een derde over. */
  .table-controls { flex-direction: column; align-items: flex-start; gap: 0.6rem; }
  .table-controls .search-input { width: 100%; }
}

/* De Posities-tabel telt negen kolommen. Op een telefoon paste alleen Symbool en
   Naam op het scherm en stond elk cijfer buiten beeld, achter drie schermbreedtes
   zijwaarts scrollen. Onder deze breedte wordt elke rij daarom een kaart: symbool
   als kop, de rest als label-waardeparen. De tabelstructuur zelf blijft intact,
   dus sorteren, filteren en uitklappen werken onveranderd. */
@media (max-width: 700px) {
  /* Alleen bij Posities: die tabel is hieronder kaarten geworden en heeft geen
     schuifruimte meer nodig. Geschiedenis blijft een tabel en houdt de zijne. */
  #tab-holdings .table-scroll { overflow-x: visible; }

  /* Geschiedenis compacter, zodat vier kolommen wél op een telefoon passen. */
  #historyTable { font-size: 0.8rem; }
  #historyTable th, #historyTable td { padding: 0.5rem 0.4rem; }
  #historyTable .avatar, #historyTable .logo { width: 1.15rem; height: 1.15rem; margin-right: 0.3rem; }
  #historyTable .pill { padding: 0.1rem 0.4rem; font-size: 0.7rem; }

  /* Alleen de directe rijen en cellen van deze tabel. Een uitgeklapte rij bevat
     zijn eigen betalingsgeschiedenis-tabel, en zonder ">" zouden die cellen hier
     mee omgebouwd worden tot losse blokken. */
  #holdingsTable,
  #holdingsTable > tbody,
  #holdingsTable > tbody > tr,
  #holdingsTable > tbody > tr > td {
    display: block;
    width: auto;
  }
  #holdingsTable { border: none; box-shadow: none; background: transparent; }
  #holdingsTable > thead { display: none; }

  #holdingsTable > tbody > tr.holding-row {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    margin-bottom: 0.6rem;
    padding: 0.2rem 0.9rem 0.6rem;
  }
  #holdingsTable > tbody > tr.holding-row.expanded { background: var(--panel); }

  #holdingsTable > tbody > tr > td {
    border-bottom: none;
    padding: 0.3rem 0;
    text-align: left;
  }

  /* Symbool en naam vormen samen de kop van de kaart. */
  #holdingsTable > tbody > tr > td:first-child {
    padding-top: 0.7rem;
    font-weight: 600;
    font-size: 0.95rem;
  }
  #holdingsTable > tbody > tr > td.name-cell {
    max-width: none;
    color: var(--muted);
    font-size: 0.82rem;
    padding-top: 0;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--border);
    margin-bottom: 0.4rem;
  }

  /* De overige cellen krijgen hun kolomnaam ernaast te zien. */
  #holdingsTable > tbody > tr > td[data-label]:not(.name-cell) {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    font-variant-numeric: tabular-nums;
  }
  #holdingsTable > tbody > tr > td[data-label]:not(.name-cell)::before {
    content: attr(data-label);
    color: var(--muted);
    font-size: 0.8rem;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
  }

  #holdingsTable > tbody > tr.holding-detail {
    display: block;
    margin: -0.6rem 0 0.6rem;
  }
  #holdingsTable > tbody > tr.holding-detail > td {
    display: block;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.75rem;
  }
  .payment-history { min-width: 0; }

  /* Vier kolommen naast elkaar (logo, tekst, bedrag, kruisje) knijpen de tekst op
     een telefoon tot een kolom van een paar woorden breed. Hier gaat het bedrag
     daarom op een eigen regel eronder. */
  .payday-banner { flex-wrap: wrap; row-gap: 0.5rem; }
  .payday-media { order: 1; }
  /* min-width:0 is hier de sleutel: zonder dat mag een flex-item niet kleiner
     worden dan zijn inhoud, en wipt de tekst naar een eigen regel onder het logo. */
  .payday-text { order: 2; flex: 1 1 0; min-width: 0; }
  .payday-banner-close { order: 3; align-self: flex-start; }
  .payday-amounts { order: 4; flex: 1 0 100%; text-align: left; }
  .payday-base { display: inline; margin-left: 0.5rem; }
  .payday-title { flex-wrap: wrap; gap: 0 0.4rem; }
  .payday-name { white-space: normal; overflow: visible; }


  /* Vijf kolommen passen niet op 375px: de netto-kolom viel buiten beeld, en dat
     is nu juist het cijfer waarvoor deze tabel bestaat. Bruto en belasting gaan
     onder het nettobedrag staan. */
  #historyTable th:nth-child(3), #historyTable td:nth-child(3),
  #historyTable th:nth-child(4), #historyTable td:nth-child(4) { display: none; }
  #historyTable td:first-child, #historyTable th:first-child { white-space: nowrap; }
  #historyTable .netto-detail { display: block; }

  /* Moet na de display:block-regels staan én de klasse meenemen: anders wint die
     bij gelijke specificiteit op volgorde, en staat elke geschiedenis permanent
     open ondanks het hidden-attribuut. */
  #holdingsTable > tbody > tr.holding-detail[hidden] { display: none; }

  /* Op een telefoon is de breedte de beperking, niet de hoogte: een grafiek van
     280px hoog in een kolom van ~330px wordt bijna vierkant en daardoor gedrongen.
     De Sankey krijgt juist méér hoogte, want zijn knooppunten stapelen verticaal
     en zouden anders over elkaar vallen. */
  .echart { height: 230px; }
  /* De inkomstencurve houdt hier juist hoogte: 24 gestapelde balken in een smalle
     kolom worden anders een streepjescode. */
  #incomeCurve { height: 300px; }
  /* Twee kolommen naast elkaar in plaats van onder elkaar: de twee getallen horen
     bij elkaar als de twee helften van de grafiek, en gestapeld verliezen ze dat. */
  /* Onder elkaar: de scheidslijn links klopt niet meer zodra alles stapelt. */
  .return-split {
    padding: 0.9rem 0 0;
    border-left: 0;
    border-top: 1px solid var(--border);
    width: 100%;
  }
  .return-value { font-size: 1.2rem; }
  .return-part.is-total .return-value { font-size: 1.3rem; }

  .curve-totals { gap: 1rem 1.4rem; }
  .curve-total { flex: 1 1 0; min-width: 0; }
  .curve-total-label { font-size: 0.7rem; gap: 0.35rem; }
  .curve-total-value { font-size: 1.35rem; }
  .curve-swatch { width: 8px; height: 12px; }
  .label-long { display: none; }
  .label-short { display: inline; }
  /* Onder elkaar wordt een linkerrand een streep in het niets; hij gaat naar boven
     mee zodat de scheiding blijft kloppen met de leesrichting. */
  .curve-next {
    /* Moet na .curve-total staan: die zet flex-basis op 0, en een width van 100%
       wint daar niet van - alleen een eigen flex-shorthand doet dat. */
    flex: 1 0 100%;
    margin-left: 0;
    padding: 0.9rem 0 0;
    border-left: 0;
    border-top: 1px solid var(--border);
  }
  .sankey-box .echart { height: 460px; }
  #simulatorChart { height: 250px; }
  /* De ring gaat boven de legende staan en mag de volle breedte gebruiken. */
  .donut-canvas { flex: 0 0 auto; width: 100%; height: 240px; }
}

/* Pictogrammen en de filterknop bestaan alleen op een telefoon. */
.tab-icon { display: none; width: 20px; height: 20px; }
.curve-legend-toggle { display: none; }

/* ==========================================================================
   Telefoon (ontworpen op 375px, iPhone 13 mini). Uitgangspunt: elk blok past
   in één scherm. Wat uitleg is, verdwijnt; wat een getal is, blijft. Staat
   onderaan zodat het de oudere mobiele regels hierboven overschrijft.
   ========================================================================== */
@media (max-width: 680px) {
  /* --- Bovenbalk: één dunne regel ------------------------------------- */
  .topbar-inner {
    flex-wrap: nowrap;
    padding: 0.4rem 0.9rem;
    padding-top: max(0.4rem, env(safe-area-inset-top));
  }
  .brand { font-size: 0.95rem; }
  .brand .logo-icon { width: 22px; height: 22px; }

  /* --- Tabbalk onderaan: vier gelijke vakken, pictogram boven label ---- */
  .tabs {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 110;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0;
    margin: 0;
    overflow: visible;
    box-sizing: border-box;
    width: 100%;
    background: color-mix(in srgb, var(--panel) 90%, transparent);
    -webkit-backdrop-filter: saturate(1.6) blur(16px);
    backdrop-filter: saturate(1.6) blur(16px);
    border-top: 1px solid var(--border);
    padding: 0.3rem 0.25rem max(0.35rem, env(safe-area-inset-bottom));
  }
  .tab-btn {
    flex-direction: column;
    justify-content: center;
    gap: 0.15rem;
    margin: 0;
    padding: 0.3rem 0 0.2rem;
    border: 0;
    font-size: 0.66rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    width: 100%;
    min-width: 0;
  }
  .tab-btn.active { color: var(--accent, var(--text)); border: 0; }
  .tab-icon { display: block; }

  .page { padding: 0.75rem 0.75rem calc(4.6rem + env(safe-area-inset-bottom)); overflow-x: clip; }
  section { margin-bottom: 0; }
  h2 { font-size: 1rem; margin: 1.1rem 0 0.5rem; }
  .tab-panel > section:first-child h2, .tab-panel > h2:first-child { margin-top: 0.2rem; }
  /* Toelichtingen achter een kop zijn op een telefoon vooral ruis. */
  h2 .hint { display: none; }
  .chart-box { padding: 0.8rem; }
  .banner { font-size: 0.8rem; padding: 0.6rem 0.75rem; margin-bottom: 0.6rem; }

  /* --- Overzicht ------------------------------------------------------- */
  /* Drie kerncijfers naast elkaar in plaats van onder elkaar. */
  .curve-totals {
    display: grid;
    grid-template-columns: minmax(0,1fr) minmax(0,1fr) minmax(0,1.1fr);
    gap: 0.6rem;
    margin-bottom: 0.4rem;
  }
  .curve-total { min-width: 0; }
  .curve-total-label { font-size: 0.64rem; letter-spacing: 0.02em; }
  .curve-total-label .label-short, .curve-total-label .label-long { display: none; }
  .curve-total-value { font-size: 1.15rem; }
  .curve-total-value small { font-size: 0.6rem; }
  .curve-total-sub { font-size: 0.66rem; }
  .curve-next {
    flex: none;
    margin: 0;
    padding: 0 0 0 0.6rem;
    border-top: 0;
    border-left: 1px solid var(--border);
  }
  .curve-next-body { gap: 0.4rem; }
  .curve-next .logo-large, .curve-next .avatar-large { width: 26px; height: 26px; font-size: 0.75rem; border-radius: 7px; }
  .curve-next-symbol { font-size: 0.95rem; }
  .curve-next-sub { font-size: 0.64rem; line-height: 1.25; display: block; white-space: normal; }
  .curve-next-body > div { min-width: 0; }

  #incomeCurve { height: 250px; }
  .curve-box .curve-note { display: none; }

  /* Legende ingeklapt achter een knop: 16 chips namen een half scherm in. */
  .curve-legend-toggle {
    display: inline-flex;
    margin-top: 0.3rem;
    padding: 0.3rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: 0.72rem;
  }
  .curve-legend { display: none; }
  .curve-legend.is-open { display: flex; }
  .curve-chip { font-size: 0.72rem; padding: 0.15rem 0.45rem 0.15rem 0.2rem; }
  .curve-chip .logo, .curve-chip .avatar { width: 15px; height: 15px; }

  /* Inzichten: zijwaarts vegen, één kaart tegelijk. */
  .insights {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.5rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    margin: 0.7rem 0 0;
    padding: 0 0 0.2rem;
  }
  .insights::-webkit-scrollbar { display: none; }
  .insight {
    flex: 0 0 86%;
    scroll-snap-align: center;
    padding: 0.65rem 0.75rem;
    font-size: 0.82rem;
    line-height: 1.4;
  }
  .badges { margin-top: 0.5rem; }

  /* --- Posities: een lijst, geen stapel kaarten ------------------------ */
  .table-controls { flex-direction: row; align-items: center; gap: 0.6rem; margin-bottom: 0.5rem; }
  .table-controls .search-input { flex: 1; width: auto; margin: 0; padding: 0.45rem 0.7rem; font-size: 16px; }
  .table-controls .switch { font-size: 0.72rem; white-space: nowrap; }

  #holdingsTable {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
  }
  #holdingsTable > tbody > tr.holding-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 0.75rem;
    align-items: center;
    margin: 0;
    padding: 0.5rem 0.75rem;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    background: transparent;
    cursor: pointer;
  }
  #holdingsTable > tbody > tr > td { padding: 0; border: 0; margin: 0; }
  #holdingsTable > tbody > tr > td:first-child {
    grid-column: 1; grid-row: 1;
    padding: 0; font-size: 0.92rem; font-weight: 600;
  }
  #holdingsTable .chevron { display: none; }
  #holdingsTable > tbody > tr > td.name-cell {
    grid-column: 1; grid-row: 2;
    padding: 0 0 0 1.75rem; margin: 0; border: 0;
    font-size: 0.72rem; color: var(--muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  /* Ingeklapt: alleen waarde en totaalrendement, rechts. */
  #holdingsTable > tbody > tr.holding-row > td[data-label]:not(.name-cell) { display: none; }
  #holdingsTable > tbody > tr.holding-row > td[data-label="Waarde"]:not(.name-cell),
  #holdingsTable > tbody > tr.holding-row > td[data-label="Totaalrendement"]:not(.name-cell) {
    display: block;
    grid-column: 2;
    text-align: right;
    font-variant-numeric: tabular-nums;
  }
  #holdingsTable > tbody > tr.holding-row > td[data-label="Waarde"]:not(.name-cell) { grid-row: 1; font-size: 0.92rem; font-weight: 600; }
  #holdingsTable > tbody > tr.holding-row > td[data-label="Totaalrendement"]:not(.name-cell) { grid-row: 2; font-size: 0.72rem; }
  #holdingsTable > tbody > tr.holding-row > td[data-label]::before { display: none; }
  #holdingsTable > tbody > tr.holding-row > td[data-label="Totaalrendement"] .cell-sub { display: none; }

  /* Uitgeklapt: alle cijfers in twee kolommen onder de kop. */
  #holdingsTable > tbody > tr.holding-row.expanded {
    grid-template-columns: 1fr 1fr;
    row-gap: 0.45rem;
    background: color-mix(in srgb, var(--bg) 60%, var(--panel));
  }
  #holdingsTable > tbody > tr.holding-row.expanded > td:first-child,
  #holdingsTable > tbody > tr.holding-row.expanded > td.name-cell { grid-column: 1 / -1; grid-row: auto; }
  #holdingsTable > tbody > tr.holding-row.expanded > td.name-cell { padding-left: 1.75rem; margin-top: -0.4rem; }
  #holdingsTable > tbody > tr.holding-row.expanded > td[data-label]:not(.name-cell) {
    display: block;
    grid-column: auto; grid-row: auto;
    text-align: left;
    font-size: 0.85rem; font-weight: 500;
  }
  #holdingsTable > tbody > tr.holding-row.expanded > td[data-label]:not(.name-cell)::before {
    content: attr(data-label);
    display: block;
    font-size: 0.62rem; font-weight: 500;
    color: var(--muted);
    text-transform: uppercase; letter-spacing: 0.03em;
  }
  #holdingsTable > tbody > tr.holding-row.expanded > td .cell-sub { display: block; }
  #holdingsTable > tbody > tr.holding-row.expanded * { text-align: left; }
  #holdingsTable > tbody > tr.holding-detail { margin: 0; border-bottom: 1px solid var(--border); }
  #holdingsTable > tbody > tr.holding-detail > td {
    border: 0; border-radius: 0; padding: 0.5rem 0.75rem 0.75rem;
    background: color-mix(in srgb, var(--bg) 60%, var(--panel));
    font-size: 0.8rem;
  }

  /* --- Geschiedenis ---------------------------------------------------- */
  .exemption { margin-bottom: 0.4rem; }
  .exemption-years { gap: 0.6rem; }
  .exemption-year { padding: 0; }
  .exemption-head { font-size: 0.82rem; }
  .exemption-foot { font-size: 0.72rem; }
  #historySearch { font-size: 16px; padding: 0.45rem 0.7rem; }
  #historyTable td, #historyTable th { padding: 0.45rem 0.4rem; }

  /* --- Analyse --------------------------------------------------------- */
  .return-summary { gap: 0.6rem; }
  .return-flow { column-gap: 0.6rem; row-gap: 0; }
  .return-flow .return-label { padding-bottom: 0.1rem; }
  .return-flow .return-sub { padding-top: 0.1rem; font-size: 0.66rem; }
  .note-long { display: none; }
  .exemption.chart-box, .exemption { padding: 0.8rem; }
  .exemption h2 { margin-top: 0; }
  .exemption-years { margin: 0; }
  .return-value { font-size: 1.1rem; }
  /* Koers + dividend = samen als een optelsom onder elkaar: label links, bedrag
     rechts uitgelijnd, zodat de getallen op één kolom staan. */
  .return-split { display: flex; flex-direction: column; gap: 0.45rem; padding-top: 0.7rem; }
  .return-part {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 0.75rem;
    row-gap: 0.05rem;
    align-items: baseline;
  }
  .return-part .return-label { grid-column: 1; grid-row: 1; font-size: 0.8rem; color: var(--text); display: flex; align-items: center; gap: 0.4rem; }
  .return-part .return-sub { grid-column: 1; grid-row: 2; font-size: 0.68rem; }
  .return-part .return-sub:empty { display: none; }
  .return-part .return-value { grid-column: 2; grid-row: 1 / span 2; align-self: center; text-align: right; font-size: 1.05rem; font-variant-numeric: tabular-nums; }
  .return-part.is-total { padding-top: 0.45rem; border-top: 1px solid var(--border); }
  .return-part.is-total .return-label { font-weight: 600; padding-left: calc(10px + 0.4rem); }
  .return-part.is-total .return-value { font-size: 1.2rem; }
  /* Percentage onder het bedrag, zodat alle bedragen rechts op één lijn eindigen. */
  .return-part.is-total .return-value small { display: block; font-size: 0.72rem; margin: 0.1rem 0 0; }
  .return-part .return-sub { padding-left: calc(10px + 0.4rem); }
  .return-label { font-size: 0.64rem; }
  .payback { margin-top: 0.7rem; padding-top: 0.6rem; }
  .payback-pct { font-size: 1.1rem; }
  .payback-sub { font-size: 0.72rem; }
  .return-box .curve-note { font-size: 0.7rem; }

  /* Ring en legende naast elkaar, zodat het blok in één scherm past. */
  .donut-wrap { flex-wrap: nowrap; gap: 0.9rem; }
  .donut-canvas { flex: 0 0 140px; width: 140px; height: 140px; }
  .donut-legend { gap: 0.3rem; flex: 1; min-width: 0; }
  .donut-legend li { font-size: 0.74rem; gap: 0.4rem; }

  .sankey-box .echart { height: 420px; }
  #simulatorChart { height: 200px; }
  .simulator-controls { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0.5rem; }
  .simulator-controls label { font-size: 0.66rem; line-height: 1.2; }
  .simulator-controls label.switch { grid-column: 1 / -1; font-size: 0.75rem; }
  .simulator-controls input[type="number"] { width: 100%; font-size: 16px; padding: 0.35rem 0.5rem; }
  .simulator-headline { font-size: 0.85rem; padding: 0.6rem 0.75rem; margin: 0.6rem 0; }
}
