/* ============================================================================
   HeatPump Advisor — basiscomponenten (S11b-5a, 05-10-2026)
   ============================================================================
   De web-tegenhangers van de bouwstenen in de iOS-app, op de tokens uit
   tokens.css (appgelijke laag) en domain-tokens.css. Geen eigen kleurwaarden:
   alles komt uit een token, zodat licht/donker en de marketing-lock vanzelf
   meekantelen.

     .hpa-card        GlassCard            (kaart, hero, genest)
     .hpa-tile-icon   icoon-tegel          (design-afspraken §2)
     .hpa-stat        kengetal-tegel       (label, getal, eenheid)
     .hpa-chip        pill met 6pt-dot     (kleur is stand, niet categorie)
     .hpa-btn         primair/secundair/tertiair
     .hpa-table       tabel met statusstreep en zebra
     .hpa-empty       lege staat
     .hpa-banner      melding
     .hpa-steps       voortgangsstrip
     .hpa-disclosure  ingeklapt blok (disclaimer, uitleg)

   S11b-5 A0b (gedeelde laag) voegt onderaan toe: kengetaltegel, status- en
   herkomstchip, fasenstrip, meter, vat, gestapelde balk, uitklaprij en
   gestapelde tabel, rolpoort, lege/laad/foutstaat, mobiele actiebalk, sheet,
   toast, keuzemenu, sectienavigatie, ring, de nieuwe shell en de sectie
   Beweging (levend canvas, opt-in, pauze, rustvenster, Reduce Motion en
   Rustig).

   Levende documentatie: design-prototypes/stijlgids.html (niet gedeployed).

   Laadvolgorde: ná tokens.css, style.css en domain-tokens.css; vóór
   pagina-eigen CSS. hpa-motion.css levert de animaties, dit bestand de
   eindstanden.
   ========================================================================= */

/* ── Kaart (GlassCard) ───────────────────────────────────────────────────── */
.hpa-card {
  position: relative;
  display: block;
  /* App-recept (GlassCard): glans over de vulling, bovenrand als inset.
     Geen blur op een gewone kaart (OK-DP-3 a): alleen hero, zijbalk, sheet
     en sectienavigatie mogen blurren (prestatiebudget B5). */
  background: var(--card-gloss), var(--card-bg);
  border: var(--bw-hairline) solid var(--card-border);
  border-radius: var(--radius-card);
  box-shadow: var(--card-edge), var(--card-shadow);
  padding: var(--space-l);
  color: var(--text-primary);
  transition:
    border-color var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out),
    transform var(--duration-base) var(--ease-out);
}

@media (min-width: 768px) {
  .hpa-card { padding: var(--space-xl); }
}

/* Maximaal één hero per scherm (design-afspraken §5). */
.hpa-card--hero {
  background: var(--card-gloss), var(--card-hero-bg);
  border-color: var(--card-hero-border);
  box-shadow: var(--card-edge), var(--card-hero-shadow);
  -webkit-backdrop-filter: var(--card-blur);
  backdrop-filter: var(--card-blur);
}

/* Genest in een kaart (.glassSubCard). */
.hpa-card--sub {
  background: var(--sub-bg);
  border-color: var(--sub-border);
  border-radius: var(--radius-sub);
  box-shadow: none;
  padding: var(--space-m);
}

a.hpa-card,
.hpa-card--interactive {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

a.hpa-card:hover,
.hpa-card--interactive:hover {
  border-color: color-mix(in srgb, var(--accent-orange) 35%, var(--card-border));
  box-shadow: var(--card-edge), var(--card-shadow-hover);
  transform: translateY(-2px);
}

a.hpa-card:focus-visible,
.hpa-card--interactive:focus-visible {
  outline: none;
  box-shadow: var(--card-edge), var(--card-shadow), var(--focus-ring);
}

.hpa-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  margin-bottom: var(--space-m);
}

.hpa-card__title {
  margin: 0;
  font-size: var(--type-headline);
  font-weight: var(--weight-semibold);
  line-height: var(--lh-snug);
  color: var(--text-primary);
}

.hpa-card__subtitle {
  margin: 2px 0 0;
  font-size: var(--type-footnote);
  line-height: var(--lh-snug);
  color: var(--text-secondary);
}

/* Sectiemicrolabel (.eyebrowStyle). */
.hpa-eyebrow {
  margin: 0;
  font-size: var(--type-caption2);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ── Icoon-tegel ─────────────────────────────────────────────────────────
   Neutraal (informatie): vulling value 0,08 in dark, merk-gloed 0,12 op
   papier (Color.paperTile). Het icoon zelf draagt .hpa-icon--info of een
   domein-modifier; de tegel kleurt niet mee, behalve bij een domein.
   ------------------------------------------------------------------- */
.hpa-tile-icon {
  width: 2.5rem;
  height: 2.5rem;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sub);
  background: var(--tile-bg);
}

.hpa-tile-icon .hpa-icon { width: 1.25rem; height: 1.25rem; }
.hpa-tile-icon--lg { width: 3.5rem; height: 3.5rem; border-radius: var(--radius-input); }
.hpa-tile-icon--lg .hpa-icon { width: 1.75rem; height: 1.75rem; }

/* Icoon dat de tekstkleur van zijn drager volgt (kop, knop, lijstregel):
   zelfde recept als de navigatie-iconen in domain-tokens.css — structuur en
   vulling in currentColor, detaillijn op 74 procent. Kleur is stand: het
   icoon kleurt mee met de stand van zijn drager, niet met een eigen hue. */
:root .hpa-icon.hpa-icon--current,
:root[data-theme] .hpa-icon.hpa-icon--current {
  --icon-structure: currentColor;
  --icon-fill: currentColor;
  --icon-line: color-mix(in srgb, currentColor 74%, transparent);
}

/* Icoon midden in een regel tekst (kop, knop): schaalt met de letter. */
.hpa-icon--inline {
  width: 1.15em;
  height: 1.15em;
  vertical-align: -0.2em;
}

/* ── Kengetal ────────────────────────────────────────────────────────────
   Elk meetbaar getal: AppFont.numeric (rounded, tabular). Een domeinkleur
   mag alleen op het getal, via .hpa-value--<domein> (design-afspraken §1).
   ------------------------------------------------------------------- */
.hpa-stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  min-width: 0;
  margin: 0;
  padding: var(--space-m);
  background: var(--sub-bg);
  border: var(--bw-hairline) solid var(--sub-border);
  border-radius: var(--radius-sub);
}

.hpa-stat__label {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin: 0;
  font-size: var(--type-caption);
  line-height: var(--lh-snug);
  color: var(--text-secondary);
}

.hpa-stat__label .hpa-icon { width: 0.875rem; height: 0.875rem; }

.hpa-stat__value {
  margin: 0;
  font-family: var(--font-numeric);
  font-size: var(--type-title3);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  line-height: 1.2;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

/* Tekst in plaats van een getal (systeemtype, toelichting): rustiger. */
.hpa-stat__value--text {
  font-family: var(--font-body);
  font-size: var(--type-subheadline);
  font-weight: var(--weight-semibold);
  white-space: pre-line;
}

.hpa-stat__unit {
  margin-left: 0.15em;
  font-size: 0.7em;
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}

.hpa-value--electrical    { color: var(--domain-electrical-line); }
.hpa-value--insulation    { color: var(--domain-insulation-line); }
.hpa-value--floor         { color: var(--domain-floor-line); }
.hpa-value--roof          { color: var(--domain-roof-line); }
.hpa-value--facade        { color: var(--domain-facade-line); }
.hpa-value--glazing       { color: var(--domain-glazing-line); }
.hpa-value--ventilation   { color: var(--domain-ventilation-line); }
.hpa-value--emission      { color: var(--domain-emission-line); }
.hpa-value--dhw           { color: var(--domain-dhw-line); }
.hpa-value--thermalbridge { color: var(--domain-thermalbridge-line); }

/* ── Chip / statuspill ───────────────────────────────────────────────────
   Neutrale capsule; de stand zit in de 6pt-dot (ProjectOverviewPill).
   Alleen een actieve filter (actie) kleurt als geheel in merk-oranje.
   ------------------------------------------------------------------- */
.hpa-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  max-width: 100%;
  padding: var(--space-xs) var(--space-m);
  border: var(--bw-hairline) solid var(--chip-border);
  border-radius: var(--radius-pill);
  background: var(--chip-bg);
  color: var(--text-primary);
  font-size: var(--type-caption);
  font-weight: var(--weight-semibold);
  line-height: 1.3;
  white-space: nowrap;
}

.hpa-chip > span:not(.hpa-chip__dot) {
  overflow: hidden;
  text-overflow: ellipsis;
}

.hpa-chip .hpa-icon { width: 0.875rem; height: 0.875rem; }

.hpa-chip__dot {
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 50%;
  background: var(--text-muted);
}

.hpa-chip--ok        .hpa-chip__dot { background: var(--success-color); }
.hpa-chip--attention .hpa-chip__dot { background: var(--accent-amber); }
.hpa-chip--danger    .hpa-chip__dot { background: var(--error-color); }
.hpa-chip--progress  .hpa-chip__dot { background: var(--accent-orange); }

.hpa-chip--active {
  background: color-mix(in srgb, var(--accent-orange) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent-orange) 40%, transparent);
  color: var(--accent-text);
}

/* Tekst in een rolkleur, leesbaar in beide modi. */
.hpa-text-ok        { color: var(--success-text); }
.hpa-text-attention { color: var(--warning-text); }
.hpa-text-danger    { color: var(--danger-text); }
.hpa-text-accent    { color: var(--accent-text); }

/* Status-drager als geheel (sync-pill, focusbadge): zachte vulling + tekst. */
.hpa-tone-ok        { background: var(--color-success-bg); color: var(--success-text); }
.hpa-tone-attention { background: color-mix(in srgb, var(--accent-amber) 14%, transparent); color: var(--warning-text); }
.hpa-tone-danger    { background: var(--color-danger-bg); color: var(--danger-text); }

/* ── Knoppen ─────────────────────────────────────────────────────────────
   Primair = actie (merk-oranje, ink-tekst: Color.onBrightFill).
   Secundair = neutraal glas. Tertiair = tekstknop in leesbaar oranje.
   Minimaal 44px hoog (aanraakdoel). Geen cyaan, geen paars (§1).
   ------------------------------------------------------------------- */
.hpa-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-s);
  min-height: 44px;
  padding: 0 var(--space-l);
  border: var(--bw-hairline) solid transparent;
  border-radius: var(--radius-button);
  /* Zonder variant geen grijze UA-knop (licht #efefef, donker #6b6b6b): de
     varianten hieronder zetten hun eigen vulling en tekstkleur. */
  background: transparent;
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--type-subheadline);
  font-weight: var(--weight-semibold);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition:
    transform var(--duration-quick) var(--ease-out),
    box-shadow var(--duration-quick) var(--ease-out),
    border-color var(--duration-quick) var(--ease-out),
    background-color var(--duration-quick) var(--ease-out);
}

.hpa-btn .hpa-icon { width: 1.125rem; height: 1.125rem; }

.hpa-btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.hpa-btn:disabled,
.hpa-btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.hpa-btn--primary {
  background: linear-gradient(135deg, var(--accent-orange), var(--accent-orange-deep));
  color: var(--on-bright-fill);
  box-shadow: 0 8px 20px color-mix(in srgb, var(--accent-orange) 25%, transparent);
}

/* Specificiteit bewust ≥ die van `:root[data-theme="light"] .hpa-icon` in
   domain-tokens.css (0,3,0), anders wint daar de lichte merklijn. */
:root .hpa-btn--primary .hpa-icon,
:root[data-theme] .hpa-btn--primary .hpa-icon {
  --icon-structure: currentColor;
  --icon-fill: currentColor;
  --icon-line: currentColor;
}

.hpa-btn--primary:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 12px 28px color-mix(in srgb, var(--accent-orange) 40%, transparent);
}

.hpa-btn--primary:focus-visible {
  box-shadow: 0 8px 20px color-mix(in srgb, var(--accent-orange) 25%, transparent), var(--focus-ring);
}

.hpa-btn--secondary {
  background: var(--chip-bg);
  border-color: var(--chip-border);
  color: var(--text-primary);
}

.hpa-btn--secondary:hover:not(:disabled) {
  border-color: color-mix(in srgb, var(--accent-orange) 45%, transparent);
}

.hpa-btn--tertiary {
  background: transparent;
  color: var(--accent-text);
  padding: 0 var(--space-s);
}

.hpa-btn--tertiary:hover:not(:disabled) {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.hpa-btn--sm {
  min-height: 36px;
  padding: 0 var(--space-m);
  border-radius: var(--radius-small);
  font-size: var(--type-footnote);
}

/* ── Tabel ───────────────────────────────────────────────────────────────
   Premium Paper-tabel (design-afspraken §5/§7): sterke kop, zebra en een
   statusstreep links. De streep draagt de stand via data-stand.
   ------------------------------------------------------------------- */
.hpa-table-wrap {
  overflow-x: auto;
  border: var(--bw-hairline) solid var(--card-border);
  border-radius: var(--radius-card);
  background: var(--card-bg);
  box-shadow: var(--card-shadow);
}

.hpa-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--type-subheadline);
  color: var(--text-primary);
}

.hpa-table th {
  padding: var(--space-m) var(--space-l);
  border-bottom: var(--bw-hairline) solid var(--card-border);
  background: var(--sub-bg);
  color: var(--text-muted);
  font-size: var(--type-caption2);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  text-align: left;
  text-transform: uppercase;
  white-space: nowrap;
}

.hpa-table td {
  padding: var(--space-m) var(--space-l);
  border-bottom: var(--bw-hairline) solid var(--sub-border);
  vertical-align: middle;
}

.hpa-table tbody tr:last-child td { border-bottom: none; }

.hpa-table tbody tr:nth-child(even) td {
  background: color-mix(in srgb, var(--text-primary) 3%, transparent);
}

.hpa-table tbody tr {
  --stand-kleur: transparent;
  transition: background-color var(--duration-quick) var(--ease-out);
}

.hpa-table tbody tr td:first-child { box-shadow: inset 3px 0 0 var(--stand-kleur); }
.hpa-table tbody tr[data-stand="ok"]        { --stand-kleur: var(--success-color); }
.hpa-table tbody tr[data-stand="attention"] { --stand-kleur: var(--accent-amber); }
.hpa-table tbody tr[data-stand="danger"]    { --stand-kleur: var(--error-color); }
.hpa-table tbody tr[data-stand="progress"]  { --stand-kleur: var(--accent-orange); }
.hpa-table tbody tr[data-stand="neutral"]   { --stand-kleur: var(--chip-border); }

.hpa-table tbody tr:hover td {
  background: color-mix(in srgb, var(--accent-orange) 7%, transparent);
}

.hpa-table__primary {
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

/* Rij-link: maakt een klikbare rij ook met Tab + Enter bereikbaar. De rij
   zelf blijft klikbaar (klikdelegatie op de pagina); de link is de
   toetsenbordingang en draagt de focusring. */
.hpa-table__link {
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius-small);
}
.hpa-table__link:hover { text-decoration: underline; }
.hpa-table__link:focus-visible {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}

.hpa-table__secondary {
  margin-top: 2px;
  font-size: var(--type-footnote);
  color: var(--text-secondary);
}

.hpa-table__numeric {
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
/* .hpa-table th (0,1,1) zet text-align: left en won van de klasse alleen. */
.hpa-table th.hpa-table__numeric { text-align: right; }

/* ── Lege staat ──────────────────────────────────────────────────────── */
.hpa-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-m);
  padding: var(--space-xl) var(--space-l);
  text-align: center;
  color: var(--text-secondary);
}

.hpa-empty__title {
  margin: 0;
  font-size: var(--type-title3);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.hpa-empty__text {
  max-width: 42ch;
  margin: 0;
  font-size: var(--type-subheadline);
  line-height: var(--lh-base);
}

/* ── Melding ─────────────────────────────────────────────────────────────
   Neutraal is de standaard (informatie = neutraal; cyaan is alleen voor
   scan/live). Status-varianten krijgen een zachte vulling en een leesbare
   titel in de rolkleur.
   ------------------------------------------------------------------- */
.hpa-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-m);
  padding: var(--space-m) var(--space-l);
  border: var(--bw-hairline) solid var(--chip-border);
  border-radius: var(--radius-sub);
  background: var(--chip-bg);
  color: var(--text-primary);
  font-size: var(--type-subheadline);
  line-height: var(--lh-base);
}

.hpa-banner > .hpa-icon { width: 1.25rem; height: 1.25rem; margin-top: 2px; }
.hpa-banner__body { min-width: 0; }
.hpa-banner__title { margin: 0 0 2px; font-weight: var(--weight-semibold); }
.hpa-banner__text { margin: 0; color: var(--text-secondary); }

.hpa-banner--ok {
  background: var(--color-success-bg);
  border-color: var(--color-success-border);
}
.hpa-banner--ok .hpa-banner__title { color: var(--success-text); }

.hpa-banner--attention {
  background: color-mix(in srgb, var(--accent-amber) 12%, transparent);
  border-color: color-mix(in srgb, var(--accent-amber) 30%, transparent);
}
.hpa-banner--attention .hpa-banner__title { color: var(--warning-text); }

.hpa-banner--danger {
  background: var(--color-danger-bg);
  border-color: var(--color-danger-border);
}
.hpa-banner--danger .hpa-banner__title { color: var(--danger-text); }

/* ── Voortgangsstrip ─────────────────────────────────────────────────────
   Gedane stappen in merk-oranje (voortgang = brand, groen = kláár; §1).
   De huidige stap heeft een vette naam; nog te doen is neutraal.
   ------------------------------------------------------------------- */
.hpa-steps {
  display: flex;
  gap: var(--space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

.hpa-steps__step {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  min-width: 0;
  font-size: var(--type-caption);
  color: var(--text-muted);
}

.hpa-steps__step::before {
  content: "";
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--chip-border);
}

.hpa-steps__step--done { color: var(--text-secondary); }
.hpa-steps__step--done::before,
.hpa-steps__step--current::before {
  background: var(--accent-orange);
  transform-origin: left center;
}

.hpa-steps__step--current {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
}

.hpa-steps--complete .hpa-steps__step::before { background: var(--success-color); }

/* ── Ingeklapt blok ──────────────────────────────────────────────────── */
.hpa-disclosure {
  border-top: var(--bw-hairline) solid var(--sub-border);
  margin-top: var(--space-l);
  padding-top: var(--space-m);
  color: var(--text-secondary);
  font-size: var(--type-footnote);
  line-height: var(--lh-base);
}

.hpa-disclosure > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  min-height: 32px;
  cursor: pointer;
  list-style: none;
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
  border-radius: var(--radius-small);
}

.hpa-disclosure > summary::-webkit-details-marker { display: none; }

.hpa-disclosure > summary::before {
  content: "›";
  display: inline-block;
  width: 1em;
  text-align: center;
  transition: transform var(--duration-quick) var(--ease-out);
}

.hpa-disclosure[open] > summary::before { transform: rotate(90deg); }
.hpa-disclosure > summary:hover { color: var(--text-primary); }

.hpa-disclosure > summary:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.hpa-disclosure > :not(summary) { margin: var(--space-s) 0 0; }

/* ── Gefaseerd verschijnen ───────────────────────────────────────────────
   hpa-motion.js zet data-hpa-reveal van "pending" naar "in". De vertraging
   komt uit de positie (geen inline style: de CSP staat geen vrije
   style-attributen toe), in stappen van 60 ms tot en met het achtste kind.
   ------------------------------------------------------------------- */
.hpa-stagger > :nth-child(2) { --hpa-delay: 0.06s; }
.hpa-stagger > :nth-child(3) { --hpa-delay: 0.12s; }
.hpa-stagger > :nth-child(4) { --hpa-delay: 0.18s; }
.hpa-stagger > :nth-child(5) { --hpa-delay: 0.24s; }
.hpa-stagger > :nth-child(6) { --hpa-delay: 0.30s; }
.hpa-stagger > :nth-child(7) { --hpa-delay: 0.36s; }
.hpa-stagger > :nth-child(n+8) { --hpa-delay: 0.42s; }

/* ── Focus voor alles wat klikbaar is in de app-shell ────────────────────
   :where() geeft specificiteit nul: bestaande focusregels winnen altijd,
   dit vangt alleen wat nog geen zichtbare focus had.
   ------------------------------------------------------------------- */
:where(.app-shell) :where(a, button, select, input, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}

/* ── Reduce Motion — eindstand, geen beweging ────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .hpa-card,
  .hpa-btn,
  .hpa-table tbody tr,
  .hpa-disclosure > summary::before {
    transition: none;
  }

  a.hpa-card:hover,
  .hpa-card--interactive:hover,
  .hpa-btn--primary:hover:not(:disabled) {
    transform: none;
  }
}

/* ── Afdrukken: alles op de eindstand ────────────────────────────────────
   Een kaart die nog op "pending" staat (nooit in beeld geweest) zou anders
   onzichtbaar op papier komen. */
@media print {
  .hpa-fade-up[data-hpa-reveal] {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
}

/* ============================================================================
   App-shell (F5) — zijbalk, statusstrip, omgevingsbadge
   ============================================================================
   Herkleurt de bestaande shell uit style.css op de tokens, zonder markup te
   wijzigen. Selectors beginnen met `:root body.app-shell` zodat ze zowel de
   donkere basisregels als de lichte overrides in style.css (specificiteit
   0,4,0) winnen; één set regels voor beide modi, de tokens kantelen mee.
   ========================================================================= */
:root body.app-shell .sidebar {
  background: var(--shell-bg);
  border-right-color: var(--shell-border);
  -webkit-backdrop-filter: var(--card-blur);
  backdrop-filter: var(--card-blur);
}

:root body.app-shell .sidebar-logo,
:root body.app-shell .sidebar-footer { border-color: var(--shell-border); }
:root body.app-shell .sidebar-section-divider { background: var(--shell-border); }

:root body.app-shell .sidebar-item {
  border-radius: var(--radius-small);
  color: var(--text-secondary);
  transition:
    background-color var(--duration-quick) var(--ease-out),
    color var(--duration-quick) var(--ease-out);
}

:root body.app-shell .sidebar-item:hover {
  background: var(--chip-bg);
  color: var(--text-primary);
}

/* Actieve pagina = waar je bent: merk-oranje, in licht de leesbare tint
   (oranje op papier haalde 2:1). */
:root body.app-shell .sidebar-item.active {
  background: color-mix(in srgb, var(--accent-orange) 12%, transparent);
  color: var(--accent-text);
}

:root body.app-shell .sidebar-item:focus-visible,
:root body.app-shell .sidebar-user:focus-visible,
:root body.app-shell .sidebar-signout-btn:focus-visible,
:root body.app-shell .sidebar-changelog-btn:focus-visible,
:root body.app-shell .sidebar-toggle:focus-visible,
:root body.app-shell .sidebar-hamburger:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

:root body.app-shell .sidebar-toggle,
:root body.app-shell .sidebar-hamburger {
  background: var(--surface-raised);
  border-color: var(--card-border);
  color: var(--text-muted);
}

:root body.app-shell .sidebar-toggle:hover,
:root body.app-shell .sidebar-hamburger:hover {
  border-color: color-mix(in srgb, var(--accent-orange) 45%, transparent);
  color: var(--text-primary);
}

:root body.app-shell .sidebar-hamburger { border-radius: var(--radius-small); }

:root body.app-shell .sidebar-user {
  border-radius: var(--radius-small);
  background: var(--sub-bg);
  border-color: var(--sub-border);
}

:root body.app-shell .sidebar-avatar { border-radius: var(--radius-small); }

/* Was wit 0,35 op inkt (3:1) — nu de metadata-tint (>= 4,5:1). */
:root body.app-shell .sidebar-signout-btn {
  border-radius: var(--radius-small);
  color: var(--text-muted);
}

:root body.app-shell .sidebar-signout-btn:hover {
  background: var(--color-danger-bg);
  color: var(--danger-text);
}

:root body.app-shell .sidebar-item[data-locked]:hover::after {
  background: var(--surface-raised);
  border-color: color-mix(in srgb, var(--accent-orange) 35%, transparent);
  color: var(--accent-text);
  border-radius: var(--radius-small);
  box-shadow: var(--shadow-md);
}

/* Statusstrip naast de paginatitel ("4 Open · 1 Opvolging · 0 Achterstallig"):
   neutrale capsules, de stand zit al in de punt (style.css, cat. 4). */
:root body.app-shell .stat-pill {
  border-radius: var(--radius-pill);
  background: var(--chip-bg);
  border-color: var(--chip-border);
  box-shadow: none;
}

:root body.app-shell .stat-pill:hover { border-color: color-mix(in srgb, var(--accent-orange) 40%, transparent); }
:root body.app-shell .stat-pill:focus-visible { outline: none; box-shadow: var(--focus-ring); }
:root body.app-shell .stat-pill::before { width: 6px; height: 6px; }

:root body.app-shell .stat-pill-value {
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums;
}

/* Omgevingsbadge (lokaal / staging / fout): blijft altijd zichtbaar, maar als
   compacte capsule naast de zijbalk in plaats van over het gebruikersmenu. */
.hpa-runtime-panel {
  display: inline-flex;
  align-items: center;
  gap: var(--space-s);
  padding: var(--space-xs) var(--space-m);
  border: var(--bw-hairline) solid color-mix(in srgb, var(--on-dark-scrim) 28%, transparent);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-md);
  font: var(--weight-semibold) var(--type-caption2) / 1.4 var(--font-body);
  letter-spacing: 0.04em;
}

.hpa-runtime-panel::before {
  content: "";
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 50%;
  background: currentColor;
}

body.app-shell .hpa-runtime-panel { left: calc(var(--sidebar-width) + var(--space-m)); }
body.app-shell.sidebar-collapsed .hpa-runtime-panel { left: calc(var(--sidebar-rail) + var(--space-m)); }

@media (max-width: 1024px) {
  body.app-shell .hpa-runtime-panel { left: calc(var(--sidebar-rail) + var(--space-m)); }
}

@media (max-width: 768px) {
  body.app-shell .hpa-runtime-panel,
  body.app-shell.sidebar-collapsed .hpa-runtime-panel {
    left: var(--space-m);
    /* Boven de tabbalk van de shell (A0b), niet eroverheen. */
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));
  }
}

@media (prefers-reduced-motion: reduce) {
  :root body.app-shell .sidebar-item { transition: none; }
}

/* ============================================================================
   S11b-5 A0b — gedeelde componenten (05-10-2026)
   ============================================================================
   Uit de mockups van 05-10 (ontwerp.css §5-12), vertaald naar de A0-tokens:
   geen mockupwaarde is hier geplakt; de mapping staat in het bouwverslag
   A0b. Elke animatie van deze componenten staat in de sectie "Beweging"
   onderaan, binnen prefers-reduced-motion: no-preference. Wat hier staat is
   dus altijd de eindstand (opt-in-patroon, motion-addendum §0).
   ========================================================================= */

/* ── Hulpklassen ─────────────────────────────────────────────────────── */
.hpa-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Lijnicoon uit assets/icons/ui-icons.svg (bediening: pijl, plus, slot…).
   Lijnkleur volgt de tekst; de lijndikte zit in het symbool zelf. */
.hpa-ui {
  width: 1.25rem;
  height: 1.25rem;
  flex: none;
  display: inline-block;
  vertical-align: middle;
}
.hpa-ui--sm { width: 1rem; height: 1rem; }
.hpa-ui--lg { width: 1.5rem; height: 1.5rem; }

.hpa-btn--icon { width: 44px; padding: 0; }
.hpa-btn--icon.hpa-btn--sm { width: 36px; }

/* ── Kengetaltegel (OK-DP-2 a: ronde cijfers) ────────────────────────────
   Groter dan .hpa-stat: het kerngetal van een kaart of dashboardtegel.
   ------------------------------------------------------------------- */
.hpa-kpi {
  display: grid;
  gap: var(--space-xs);
  min-width: 0;
  padding: var(--space-l);
  background: var(--sub-bg);
  border: var(--bw-hairline) solid var(--sub-border);
  border-radius: var(--radius-sub);
}

.hpa-kpi__label {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  margin: 0;
  font-size: var(--type-footnote);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
}

.hpa-kpi__value {
  margin: 0;
  font-family: var(--font-numeric);
  font-size: var(--type-title);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--text-primary);
}

.hpa-kpi__unit {
  margin-left: 0.2em;
  font-size: 0.55em;
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}

.hpa-kpi__note {
  margin: 0;
  font-size: var(--type-caption);
  color: var(--text-muted);
}

/* ── Statuschip (ProjectStatusBadge) ─────────────────────────────────────
   Neutrale capsule, de stip draagt de stand: grijs, oranje, blauw, amber,
   groen, paars of rood (saas-fase.mjs geeft de kleur bij een status).
   ------------------------------------------------------------------- */
.hpa-status {
  --status-dot: var(--status-dot-grijs);
  display: inline-flex;
  align-items: center;
  gap: var(--space-s);
  max-width: 100%;
  padding: var(--space-xs) var(--space-m);
  border: var(--bw-hairline) solid var(--chip-border);
  border-radius: var(--radius-pill);
  background: var(--chip-bg);
  color: var(--text-primary);
  font-size: var(--type-caption);
  font-weight: var(--weight-semibold);
  line-height: 1.3;
  white-space: nowrap;
}

.hpa-status::before {
  content: "";
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 50%;
  background: var(--status-dot);
}

.hpa-status[data-kleur="oranje"] { --status-dot: var(--status-dot-oranje); }
.hpa-status[data-kleur="blauw"]  { --status-dot: var(--status-dot-blauw); }
.hpa-status[data-kleur="amber"]  { --status-dot: var(--status-dot-amber); }
.hpa-status[data-kleur="groen"]  { --status-dot: var(--status-dot-groen); }
.hpa-status[data-kleur="paars"]  { --status-dot: var(--status-dot-paars); }
.hpa-status[data-kleur="rood"]   { --status-dot: var(--status-dot-rood); }

/* Herkomstchip: waar een getal vandaan komt (RVO-schatting, kamers, invoer).
   Gestippeld = afgeleid of geschat, doorgetrokken = vastgesteld. */
.hpa-herkomst {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 2px var(--space-s);
  border: var(--bw-hairline) dashed color-mix(in srgb, var(--text-primary) 28%, transparent);
  border-radius: var(--radius-pill);
  color: var(--text-secondary);
  font-size: var(--type-caption2);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.hpa-herkomst--vast { border-style: solid; }
.hpa-herkomst .hpa-ui { width: 0.75rem; height: 0.75rem; }

/* ── Fasenstrip: vier fasen plus de stand Gestopt (OK-DP-4 a) ─────────────
   <ol class="hpa-fasen" data-fase="0-3" [data-gestopt]> met vier
   .hpa-fasen__stap. De lijn groeit met scaleX (geen layout per frame); de
   stand komt uit data-fase, dus zonder JS staat de strip al goed.
   ------------------------------------------------------------------- */
.hpa-fasen {
  --fasen-p: 0;
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}
.hpa-fasen[data-fase="1"] { --fasen-p: 0.3333; }
.hpa-fasen[data-fase="2"] { --fasen-p: 0.6667; }
.hpa-fasen[data-fase="3"] { --fasen-p: 1; }

.hpa-fasen::before,
.hpa-fasen::after {
  content: "";
  position: absolute;
  top: 12px;
  left: 12.5%;
  right: 12.5%;
  height: 3px;
  border-radius: var(--radius-pill);
}
.hpa-fasen::before { background: var(--chip-border); }
.hpa-fasen::after {
  background: linear-gradient(90deg, var(--accent-orange), var(--accent-orange-deep));
  transform-origin: left center;
  transform: scaleX(var(--fasen-p));
}

.hpa-fasen__stap {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: var(--space-xs);
  min-width: 0;
  padding: 0 var(--space-xs);
  text-align: center;
}

.hpa-fasen__stip {
  position: relative;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: var(--bw-strong) solid var(--chip-border);
  border-radius: 50%;
  background: var(--surface-raised);
  color: var(--text-muted);
}
.hpa-fasen__stip .hpa-ui { width: 14px; height: 14px; visibility: hidden; }

/* Ring om de huidige fase: eindstand onzichtbaar, de puls staat onder Beweging. */
.hpa-fasen__stip::after {
  content: "";
  position: absolute;
  inset: -6px;
  border: var(--bw-strong) solid var(--accent-orange);
  border-radius: 50%;
  opacity: 0;
}

.hpa-fasen__naam {
  font-size: var(--type-footnote);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}

.hpa-fasen__detail {
  min-height: 1.2em;
  font-size: var(--type-caption);
  color: var(--text-muted);
}

/* Randen in de leesbare stiptint (≥ 3:1 op de ondergrond, zoals de statusstip):
   in licht haalt --accent-orange daar 1,8:1, --status-dot-oranje 5,45:1. */
.hpa-fasen__stap.is-done .hpa-fasen__stip {
  background: var(--accent-orange);
  border-color: var(--status-dot-oranje);
  color: var(--on-bright-fill);
}
.hpa-fasen__stap.is-done .hpa-fasen__stip .hpa-ui { visibility: visible; }
.hpa-fasen__stap.is-current .hpa-fasen__stip {
  border-color: var(--status-dot-oranje);
  color: var(--accent-text);
  transform: scale(1.12);
}
.hpa-fasen__stap.is-current .hpa-fasen__naam { color: var(--text-primary); }

/* Afgerond is kláár: groen, niet oranje (design-afspraken §1). Rand ook hier
   in de stiptint: --success-color haalde in licht 1,97:1, --status-dot-groen 6,59:1. */
.hpa-fasen__stap:last-child.is-current .hpa-fasen__stip,
.hpa-fasen__stap:last-child.is-done .hpa-fasen__stip {
  background: var(--success-color);
  border-color: var(--status-dot-groen);
  color: var(--on-bright-fill);
}

/* Gestopt (Niet doorgezet, Gearchiveerd): de strip wordt grijs; de pagina
   toont daarnaast de rode statuschip. */
.hpa-fasen[data-gestopt]::after { background: var(--text-muted); }
.hpa-fasen[data-gestopt] .hpa-fasen__stip {
  background: var(--surface-raised);
  border-color: var(--chip-border);
  color: var(--text-muted);
  transform: none;
}

@media (max-width: 640px) {
  .hpa-fasen__naam { font-size: var(--type-caption); }
  .hpa-fasen__detail { display: none; }
}

/* ── Meter, vat en gestapelde balk ───────────────────────────────────────
   De breuk komt als --hpa-p (0..1) via saas-ui setFraction (CSSOM, mag
   onder de CSP). Het web rekent niet: de breuk is weergave van een waarde
   uit het dossier (regel 17). Domeinkleur hoort niet op een balk (§1): de
   meter is merk-oranje (voortgang) of neutraal, de gestapelde balk loopt
   een neutrale ladder; het domein staat op het icoon en het getal ernaast.
   Het vat is een vergroot domeinicoon (tapwater) en draagt dus wel de
   domeinkleur, net als de illustraties in het motion-addendum.
   ------------------------------------------------------------------- */
.hpa-meter {
  --hpa-p: 0;
  height: 8px;
  overflow: hidden;
  border-radius: var(--radius-pill);
  background: var(--chip-bg);
}

.hpa-meter__fill {
  display: block;
  width: calc(var(--hpa-p) * 100%);
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--accent-orange), var(--accent-orange-deep));
  transform-origin: left center;
}
.hpa-meter--neutraal .hpa-meter__fill { background: var(--text-muted); }

.hpa-vat {
  --hpa-p: 0;
  position: relative;
  width: 56px;
  height: 88px;
  flex: none;
  overflow: hidden;
  border: var(--bw-strong) solid var(--domain-dhw-line);
  border-radius: var(--radius-input);
  background: color-mix(in srgb, var(--domain-dhw-fill) 8%, transparent);
}

.hpa-vat__water {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--domain-dhw-fill) 34%, transparent);
  transform-origin: bottom center;
  transform: scaleY(var(--hpa-p));
}

.hpa-stack {
  display: flex;
  gap: 2px;
  height: 14px;
  overflow: hidden;
  border-radius: var(--radius-pill);
  background: var(--chip-bg);
}

.hpa-stack__deel {
  --hpa-f: 1;
  flex: var(--hpa-f) 1 0;
  min-width: 2px;
  background: color-mix(in srgb, var(--text-primary) 85%, transparent);
  transform-origin: left center;
}
.hpa-stack__deel:nth-child(2) { background: color-mix(in srgb, var(--text-primary) 62%, transparent); }
.hpa-stack__deel:nth-child(3) { background: color-mix(in srgb, var(--text-primary) 45%, transparent); }
.hpa-stack__deel:nth-child(4) { background: color-mix(in srgb, var(--text-primary) 32%, transparent); }
.hpa-stack__deel:nth-child(n+5) { background: color-mix(in srgb, var(--text-primary) 22%, transparent); }

/* Legenda bij de gestapelde balk: zelfde ladder, in dezelfde volgorde. */
.hpa-legenda {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s) var(--space-l);
  margin: var(--space-s) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--type-caption);
  color: var(--text-secondary);
}
.hpa-legenda li { display: inline-flex; align-items: center; gap: var(--space-xs); }
.hpa-legenda li::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--text-primary) 85%, transparent);
}
.hpa-legenda li:nth-child(2)::before { background: color-mix(in srgb, var(--text-primary) 62%, transparent); }
.hpa-legenda li:nth-child(3)::before { background: color-mix(in srgb, var(--text-primary) 45%, transparent); }
.hpa-legenda li:nth-child(4)::before { background: color-mix(in srgb, var(--text-primary) 32%, transparent); }
.hpa-legenda li:nth-child(n+5)::before { background: color-mix(in srgb, var(--text-primary) 22%, transparent); }

/* ── Ring (kerngetal) ────────────────────────────────────────────────────
   saas-ui ring() tekent de SVG en zet --ring-omtrek en --ring-offset. */
.hpa-ring {
  --ring-omtrek: 326.73;
  --ring-offset: 0;
  position: relative;
  display: grid;
  place-items: center;
  width: 152px;
  height: 152px;
  flex: none;
  isolation: isolate;
}

.hpa-ring__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
  fill: none;
}

.hpa-ring__track {
  stroke: color-mix(in srgb, var(--text-primary) 8%, transparent);
  stroke-width: 10;
}

.hpa-ring__bar {
  stroke: var(--accent-orange);
  stroke-width: 10;
  stroke-linecap: round;
  stroke-dasharray: var(--ring-omtrek);
  stroke-dashoffset: var(--ring-offset);
}

.hpa-ring__value {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 2px;
  line-height: 1;
  text-align: center;
}

.hpa-ring__getal {
  font-family: var(--font-numeric);
  font-size: 2.5rem;
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  color: var(--text-primary);
}

.hpa-ring__eenheid {
  font-size: var(--type-caption);
  font-weight: var(--weight-semibold);
  color: var(--text-muted);
}

@media (max-width: 640px) {
  .hpa-ring { width: 104px; height: 104px; }
  .hpa-ring__getal { font-size: 1.75rem; }
}

/* ── Tabel: uitklaprij en gestapelde vorm op telefoon ────────────────────
   Een knop met data-saas-uitklap, aria-expanded en aria-controls opent de
   rij erna (.hpa-table__detail, hidden). Op telefoon wordt .hpa-table--stack
   een lijst kaarten; elke cel toont zijn kop via data-label.
   ------------------------------------------------------------------- */
.hpa-table__toggle {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: var(--radius-small);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
}
.hpa-table__toggle:hover { background: var(--chip-bg); color: var(--text-primary); }
.hpa-table__toggle[aria-expanded="true"] .hpa-ui { transform: rotate(180deg); }

.hpa-table .hpa-table__detail td {
  background: var(--sub-bg);
  color: var(--text-secondary);
  font-size: var(--type-footnote);
  line-height: var(--lh-base);
}

@media (max-width: 640px) {
  .hpa-table--stack thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }
  .hpa-table--stack,
  .hpa-table--stack tbody,
  .hpa-table--stack tr,
  .hpa-table--stack td {
    display: block;
    width: 100%;
  }
  .hpa-table--stack tbody tr {
    padding: var(--space-m) var(--space-l);
    border-bottom: var(--bw-hairline) solid var(--sub-border);
    box-shadow: inset 3px 0 0 var(--stand-kleur);
  }
  .hpa-table--stack tbody tr[hidden] { display: none; }
  .hpa-table--stack tbody tr td:first-child { box-shadow: none; }
  .hpa-table--stack td {
    display: flex;
    justify-content: space-between;
    gap: var(--space-m);
    padding: var(--space-xs) 0;
    border: 0;
    text-align: right;
  }
  .hpa-table--stack td::before {
    content: attr(data-label);
    font-size: var(--type-caption);
    font-weight: var(--weight-semibold);
    color: var(--text-muted);
    text-align: left;
  }
  .hpa-table--stack td:not([data-label])::before { content: none; }
}

/* ── Rolpoort (OK-DP-5 a): wat je niet mag, zie je wel ───────────────────
   Per regel: mag het (vinkje) of niet (slot, met reden en wie het wel mag).
   Een vergrendelde knop blijft staan, met aria-disabled en de reden eronder.
   ------------------------------------------------------------------- */
.hpa-rolpoort { display: grid; gap: var(--space-s); }

.hpa-rolpoort__lijst {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hpa-rolpoort__regel {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-m);
  align-items: start;
  padding: var(--space-m) 0;
}
.hpa-rolpoort__regel + .hpa-rolpoort__regel { border-top: var(--bw-hairline) solid var(--sub-border); }

.hpa-rolpoort__icoon {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border: var(--bw-hairline) solid var(--chip-border);
  border-radius: var(--radius-small);
  background: var(--chip-bg);
  color: var(--text-muted);
}
.hpa-rolpoort__icoon .hpa-ui { width: 16px; height: 16px; }
.hpa-rolpoort__regel[data-mag="ja"] .hpa-rolpoort__icoon {
  border-color: transparent;
  background: var(--color-success-bg);
  color: var(--success-text);
}

.hpa-rolpoort__titel {
  display: block;
  font-size: var(--type-footnote);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.hpa-rolpoort__reden {
  display: block;
  margin-top: 2px;
  font-size: var(--type-caption);
  color: var(--text-muted);
}

.hpa-btn--locked { cursor: not-allowed; }

.hpa-lock-note {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin: var(--space-xs) 0 0;
  font-size: var(--type-caption);
  color: var(--text-muted);
}
.hpa-lock-note .hpa-ui { width: 14px; height: 14px; }

/* ── Lege, laad- en foutstaat ────────────────────────────────────────────
   .hpa-empty (A0) krijgt een grote tegel en een foutvariant; de laadstaat
   gebruikt het skelet uit hpa-motion.css en zegt "laden", nooit "berekenen".
   ------------------------------------------------------------------- */
.hpa-empty__art {
  display: grid;
  place-items: center;
  width: 72px;
  height: 72px;
  border-radius: var(--radius-card);
  background: var(--tile-bg);
  color: var(--text-secondary);
}
.hpa-empty__art .hpa-ui,
.hpa-empty__art .hpa-icon { width: 32px; height: 32px; }

.hpa-empty--fout .hpa-empty__art {
  background: var(--color-danger-bg);
  color: var(--danger-text);
}

.hpa-loading {
  display: grid;
  gap: var(--space-m);
}
.hpa-skeleton--titel { height: 1.375rem; width: 40%; }
.hpa-skeleton--blok { height: 6rem; border-radius: var(--radius-card); }

/* ── Mobiele actiebalk ───────────────────────────────────────────────────
   Op telefoon vervangt hij de tabbalk (dossier: Offerte starten, Inplannen,
   Meer). Op desktop staan dezelfde knoppen in de paginakop.
   ------------------------------------------------------------------- */
.hpa-actionbar { display: none; }

@media (max-width: 768px) {
  .hpa-actionbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-sticky);
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: var(--space-s);
    padding: var(--space-s) var(--space-l) calc(var(--space-s) + env(safe-area-inset-bottom, 0px));
    border-top: var(--bw-hairline) solid var(--shell-border);
    background: var(--shell-bg);
  }
  body:has(.hpa-actionbar:not([hidden])) .hpa-tabbar { display: none; }
  /* display: grid hierboven wint van het hidden-attribuut; een verborgen
     actiebalk (S11b-5 B0) blijft dus alleen weg met deze regel. */
  .hpa-actionbar[hidden] { display: none; }
}

/* ── Sheet ───────────────────────────────────────────────────────────────
   Zijpaneel op desktop, onderblad op telefoon. Eén van de vier vlakken die
   mogen blurren (OK-DP-3 a); het scherm erachter blurt niet.
   ------------------------------------------------------------------- */
.hpa-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal-overlay);
  background: var(--scrim);
  opacity: 0;
}
.hpa-backdrop.is-open { opacity: 1; }
.hpa-backdrop[hidden] { display: none; }
/* Zolang een sheet open is, scrolt de pagina erachter niet mee (saas-ui zet de klasse). */
:root body.hpa-sheet-open { overflow: hidden; }

.hpa-sheet {
  position: fixed;
  z-index: var(--z-modal);
  top: var(--space-xl);
  right: var(--space-xl);
  bottom: var(--space-xl);
  width: min(440px, calc(100vw - 2 * var(--space-l)));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: var(--bw-hairline) solid var(--card-hero-border);
  border-radius: var(--radius-card);
  background: var(--card-gloss), var(--surface-raised);
  box-shadow: var(--card-edge), var(--card-hero-shadow);
  -webkit-backdrop-filter: var(--card-blur);
  backdrop-filter: var(--card-blur);
  color: var(--text-primary);
  transform: translateX(calc(100% + 2 * var(--space-xl)));
}
.hpa-sheet.is-open { transform: none; }
.hpa-sheet[hidden] { display: none; }
.hpa-sheet:focus { outline: none; }

.hpa-sheet__grabber { display: none; }

.hpa-sheet__head {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  padding: var(--space-xl) var(--space-xl) var(--space-m);
}

.hpa-sheet__title {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: var(--type-title3);
  font-weight: var(--weight-semibold);
  line-height: var(--lh-snug);
}

.hpa-sheet__body {
  flex: 1;
  display: grid;
  align-content: start;
  gap: var(--space-l);
  overflow-y: auto;
  padding: 0 var(--space-xl) var(--space-xl);
}

.hpa-sheet__foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-s);
  padding: var(--space-l) var(--space-xl) var(--space-xl);
  border-top: var(--bw-hairline) solid var(--sub-border);
}

@media (max-width: 768px) {
  .hpa-sheet {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    max-height: 88vh;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    border-radius: var(--radius-card) var(--radius-card) 0 0;
    transform: translateY(105%);
  }
  .hpa-sheet.is-open { transform: none; }
  .hpa-sheet__grabber {
    display: block;
    width: 40px;
    height: 5px;
    margin: var(--space-s) auto 0;
    border-radius: var(--radius-pill);
    background: var(--chip-border);
  }
  .hpa-sheet__head { padding: var(--space-l) var(--space-l) var(--space-m); }
  .hpa-sheet__body { padding: 0 var(--space-l) var(--space-l); }
  .hpa-sheet__foot { padding: var(--space-m) var(--space-l) var(--space-l); }
  .hpa-sheet__foot .hpa-btn { flex: 1; }
}

/* ── Toast ───────────────────────────────────────────────────────────── */
.hpa-toasts {
  position: fixed;
  z-index: var(--z-toast);
  left: 50%;
  bottom: var(--space-xl);
  display: grid;
  justify-items: center;
  gap: var(--space-s);
  width: max-content;
  max-width: calc(100vw - 2 * var(--space-l));
  transform: translateX(-50%);
  pointer-events: none;
}

.hpa-toast {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  padding: var(--space-s) var(--space-l) var(--space-s) var(--space-m);
  border: var(--bw-hairline) solid var(--card-hero-border);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  box-shadow: var(--card-hero-shadow);
  color: var(--text-primary);
  font-size: var(--type-footnote);
  font-weight: var(--weight-semibold);
  pointer-events: auto;
}
.hpa-toast.is-out { opacity: 0; }

.hpa-toast__ok {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  flex: none;
  border-radius: 50%;
  background: var(--color-success-bg);
  color: var(--success-text);
}
.hpa-toast__ok .hpa-ui {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.hpa-toast__vink { stroke-dasharray: 20; stroke-dashoffset: 0; }

.hpa-toast__actie {
  min-height: 32px;
  padding: var(--space-xs) var(--space-s);
  border: 0;
  border-radius: var(--radius-small);
  background: none;
  color: var(--accent-text);
  font: inherit;
  font-weight: var(--weight-bold);
  cursor: pointer;
}
.hpa-toast__actie:hover { background: var(--chip-bg); }

@media (max-width: 768px) {
  .hpa-toasts { bottom: calc(76px + env(safe-area-inset-bottom, 0px)); }
}

/* ── Keuzemenu ───────────────────────────────────────────────────────── */
.hpa-menu {
  --menu-x: 0px;
  --menu-y: 0px;
  position: absolute;
  z-index: var(--z-tooltip);
  left: var(--menu-x);
  top: var(--menu-y);
  display: grid;
  gap: 2px;
  min-width: 240px;
  max-width: min(340px, calc(100vw - 2 * var(--space-s)));
  padding: var(--space-s);
  border: var(--bw-hairline) solid var(--card-hero-border);
  border-radius: var(--radius-input);
  background: var(--surface-raised);
  box-shadow: var(--card-hero-shadow);
  transform-origin: top left;
}
.hpa-menu.is-boven { transform-origin: bottom left; }

.hpa-menu__groep { display: grid; gap: 2px; }
.hpa-menu__groep + .hpa-menu__groep {
  margin-top: var(--space-xs);
  padding-top: var(--space-xs);
  border-top: var(--bw-hairline) solid var(--sub-border);
}

.hpa-menu__groepnaam {
  padding: var(--space-xs) var(--space-m) 2px;
  font-size: var(--type-caption2);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.hpa-menu__item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  column-gap: var(--space-s);
  width: 100%;
  min-height: 40px;
  padding: var(--space-s) var(--space-m);
  border: 0;
  border-radius: var(--radius-small);
  background: transparent;
  color: var(--text-primary);
  font: inherit;
  font-size: var(--type-footnote);
  font-weight: var(--weight-medium);
  text-align: left;
  cursor: pointer;
}
.hpa-menu__item:hover,
.hpa-menu__item:focus-visible { background: var(--chip-bg); }
.hpa-menu__item:focus-visible { outline: 2px solid var(--focus-ring-color); outline-offset: -2px; }
.hpa-menu__item[aria-checked="true"] { color: var(--accent-text); font-weight: var(--weight-bold); }
/* Vergrendeld item (OK-DP-5: wat je niet mag, zie je wel): slot, reden en een
   rustiger label dragen de stand, niet een halve dekking. De oude regel
   button[aria-disabled] in style.css (opacity 0,55) drukte de reden naar 3,3:1
   (donker) en 2,7:1 (licht); op volle dekking haalt hij ruim 4,5:1. */
.hpa-menu__item[aria-disabled="true"] { opacity: 1; color: var(--text-secondary); cursor: not-allowed; }
.hpa-menu__vink,
.hpa-menu__slot { width: 16px; height: 16px; }
.hpa-menu__reden {
  grid-column: 1 / -1;
  font-size: var(--type-caption);
  font-weight: var(--weight-regular);
  color: var(--text-muted);
}

/* ── Sectienavigatie ─────────────────────────────────────────────────────
   Plakt onder de topbalk; één van de vier vlakken die mogen blurren. De
   indicator schuift via --secnav-x en --secnav-w (saas-ui sectionNav).
   ------------------------------------------------------------------- */
.hpa-secnav {
  --secnav-x: 0px;
  --secnav-w: 0px;
  position: sticky;
  top: var(--space-s);
  z-index: var(--z-sticky);
  display: flex;
  gap: var(--space-xs);
  width: max-content;
  max-width: 100%;
  overflow-x: auto;
  padding: var(--space-xs);
  border: var(--bw-hairline) solid var(--card-border);
  border-radius: var(--radius-pill);
  background: var(--shell-bg);
  box-shadow: var(--card-shadow);
  -webkit-backdrop-filter: var(--card-blur);
  backdrop-filter: var(--card-blur);
  scrollbar-width: none;
}
.hpa-secnav::-webkit-scrollbar { display: none; }

.hpa-secnav a {
  position: relative;
  z-index: 1;
  flex: none;
  padding: var(--space-s) var(--space-l);
  border-radius: var(--radius-pill);
  color: var(--text-secondary);
  font-size: var(--type-footnote);
  font-weight: var(--weight-semibold);
  text-decoration: none;
  white-space: nowrap;
}
.hpa-secnav a:hover { color: var(--text-primary); }
.hpa-secnav a[aria-current="true"] { color: var(--accent-text); }

.hpa-secnav__indicator {
  position: absolute;
  z-index: 0;
  top: var(--space-xs);
  bottom: var(--space-xs);
  left: 0;
  width: var(--secnav-w);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--accent-orange) 14%, transparent);
  transform: translateX(var(--secnav-x));
  pointer-events: none;
}

@media (max-width: 768px) {
  .hpa-secnav { top: calc(var(--topbar-height) + var(--space-s)); }
}

/* ── Segmentkeuze (thema, beweging, kaart of tabel) ──────────────────── */
.hpa-seg {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 2px;
  padding: 3px;
  border: var(--bw-hairline) solid var(--chip-border);
  border-radius: var(--radius-small);
  background: var(--chip-bg);
}

.hpa-seg__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  min-height: 32px;
  padding: var(--space-xs) var(--space-s);
  border: 0;
  border-radius: var(--space-s);
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--type-caption);
  font-weight: var(--weight-semibold);
  cursor: pointer;
}
.hpa-seg__btn:hover { color: var(--text-primary); }
.hpa-seg__btn[aria-pressed="true"] {
  background: var(--seg-on-bg);
  box-shadow: var(--card-edge), var(--shadow-sm);
  color: var(--text-primary);
}
.hpa-seg__btn .hpa-ui { width: 1rem; height: 1rem; }

/* ── Volledige paginastaat (offline, geen toegang, fout) ─────────────── */
.hpa-center-state {
  max-width: 28rem;
  margin: clamp(var(--space-xl), 12vh, 8rem) auto 0;
}

/* ============================================================================
   Shell (S11b-5 A0b, R4) — zijbalk 248 px, topbalk en tabbalk op telefoon
   ============================================================================
   Eén bron: shell/saas-shell.html, gestempeld in de negen SaaS-pagina's en
   offline.html. De oude regels in style.css (220 px, hamburger los in de
   hoek, bottom-nav) blijven staan voor beheer.html; deze regels winnen op
   de pagina's met de nieuwe shell via :root body.app-shell.
   ------------------------------------------------------------------- */
:root body.app-shell { padding-left: var(--sidebar-width); }
:root body.app-shell.sidebar-collapsed { padding-left: var(--sidebar-rail); }
:root body.app-shell .sidebar { width: var(--sidebar-width); }
:root body.app-shell.sidebar-collapsed .sidebar { width: var(--sidebar-rail); }

/* Actieve pagina zonder te wachten op JS: de body draagt data-saas-page. */
:root body[data-saas-page="dashboard"] .sidebar-item[data-page="dashboard"],
:root body[data-saas-page="projecten"] .sidebar-item[data-page="projecten"],
:root body[data-saas-page="offertes"] .sidebar-item[data-page="offertes"],
:root body[data-saas-page="planning"] .sidebar-item[data-page="planning"],
:root body[data-saas-page="team"] .sidebar-item[data-page="team"],
:root body[data-saas-page="branding"] .sidebar-item[data-page="branding"],
:root body[data-saas-page="licenties"] .sidebar-item[data-page="licenties"] {
  background: color-mix(in srgb, var(--accent-orange) 12%, transparent);
  color: var(--accent-text);
}

.sidebar-group-label {
  margin: var(--space-m) var(--space-m) var(--space-xs);
  padding: 0 var(--space-m);
  font-size: var(--type-caption2);
  font-weight: var(--weight-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text-muted);
}

.sidebar-count {
  min-width: 22px;
  margin-left: auto;
  padding: 1px var(--space-s);
  border: var(--bw-hairline) solid var(--chip-border);
  border-radius: var(--radius-pill);
  background: var(--chip-bg);
  color: var(--text-secondary);
  font-family: var(--font-numeric);
  font-size: var(--type-caption2);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.sidebar-count[hidden] { display: none; }

/* Vergrendeld item: het slot en een rustiger label dragen de stand, niet een
   halve dekking op het hele item. Met opacity 0,8 zakte het label in licht
   naar 3,7:1 (text-secondary op papier, gemeten in saas-kwaliteit.spec.js);
   text-muted op volle dekking haalt ruim 4,5:1 en blijft zachter dan een
   gewoon item. De oude regel in style.css (0,8) geldt nog voor beheer.html. */
:root body.app-shell .sidebar-item.locked { opacity: 1; color: var(--text-muted); }
:root body.app-shell .sidebar-item.locked .sidebar-icon { opacity: 0.6; }
:root body.app-shell .sidebar-item.locked.active,
:root body.app-shell .sidebar-item.locked[aria-current="page"] { color: var(--accent-text); }

/* Het slot staat er zolang de pagina vergrendeld is; met toegang verdwijnt
   het (fb-ui.js zet lock-icon-active). */
:root body.app-shell .sidebar-item .sidebar-lock { color: var(--text-muted); opacity: 1; }
:root body.app-shell .sidebar-item .sidebar-lock.lock-icon-active { display: none; }

.hpa-shell-prefs {
  display: grid;
  gap: var(--space-s);
  margin: var(--space-m) 0 var(--space-s);
}
.hpa-shell-prefs__rij { display: grid; gap: var(--space-xs); }
.hpa-shell-prefs__label {
  padding: 0 var(--space-xs);
  font-size: var(--type-caption2);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Smalle rail (ingeklapt of tablet): alleen iconen; groepnaam, tellers en
   voorkeuren staan in de brede zijbalk en in de lade op telefoon. */
:root body.app-shell.sidebar-collapsed .sidebar-group-label,
:root body.app-shell.sidebar-collapsed .sidebar-count,
:root body.app-shell.sidebar-collapsed .hpa-shell-prefs { display: none; }

.hpa-topbar,
.hpa-tabbar { display: none; }

@media (max-width: 1024px) {
  :root body.app-shell { padding-left: var(--sidebar-rail); }
  :root body.app-shell .sidebar { width: var(--sidebar-rail); }
  /* Inklappen bestaat alleen boven 1024 px: op de tablet is de rail vast, op de
     telefoon is de zijbalk een lade. Het knopje stak daar half uit de lade en
     zette met één tik de voorkeur voor desktop om. */
  :root body.app-shell .sidebar-toggle { display: none; }
  :root body.app-shell .sidebar-group-label,
  :root body.app-shell .sidebar-count,
  :root body.app-shell .hpa-shell-prefs { display: none; }
}

/* S-39 (productreview-trein E10): op de rail van 60 px (tablet staand en ingeklapt
   op desktop) bleven "Versienotities", de stip en het pijltje van de gebruikersregel
   ernaast staan. Die knoppen knippen nu af; het label en het pijltje verdwijnen en
   de stip zit op het icoon. Niet de hele zijbalk: de tooltips van de items staan erbuiten. */
:root body.app-shell.sidebar-collapsed .sidebar-changelog-btn,
:root body.app-shell.sidebar-collapsed .sidebar-user { overflow: hidden; }
:root body.app-shell.sidebar-collapsed .sidebar-changelog-btn .sidebar-label,
:root body.app-shell.sidebar-collapsed .sidebar-user-arrow { display: none; }
:root body.app-shell.sidebar-collapsed .changelog-badge { position: absolute; top: var(--space-xs); right: var(--space-s); margin: 0; }

@media (min-width: 769px) and (max-width: 1024px) {
  :root body.app-shell .sidebar-changelog-btn,
  :root body.app-shell .sidebar-user { overflow: hidden; }
  :root body.app-shell .sidebar-changelog-btn .sidebar-label,
  :root body.app-shell .sidebar-user-arrow { display: none; }
  :root body.app-shell .changelog-badge { position: absolute; top: var(--space-xs); right: var(--space-s); margin: 0; }
}

@media (max-width: 768px) {
  :root body.app-shell { padding-left: 0; }
  :root body.app-shell .sidebar { width: var(--sidebar-width); }
  :root body.app-shell .sidebar-group-label,
  :root body.app-shell .hpa-shell-prefs { display: block; }
  :root body.app-shell .hpa-shell-prefs { display: grid; }

  .hpa-topbar {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
    display: flex;
    align-items: center;
    gap: var(--space-m);
    min-height: var(--topbar-height);
    padding: max(var(--space-s), env(safe-area-inset-top, 0px)) var(--space-l) var(--space-s);
    border-bottom: var(--bw-hairline) solid var(--shell-border);
    background: var(--shell-bg);
  }

  /* De hamburger woont nu in de topbalk; style.css verbergt hem op telefoon
     met !important (uit de tijd van de bottom-nav). */
  :root body.app-shell .hpa-topbar .sidebar-hamburger {
    position: static;
    display: inline-flex !important;
    flex: none;
    flex-direction: column;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: var(--space-m);
  }

  .hpa-topbar__title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    color: var(--text-primary);
    font-size: var(--type-subheadline);
    font-weight: var(--weight-semibold);
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .hpa-topbar__crumbs:not([hidden]) {
    display: flex;
    gap: var(--space-xs);
    min-width: 0;
    font-size: var(--type-caption);
    color: var(--text-secondary);
  }

  .hpa-tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-sticky);
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    padding: var(--space-xs) var(--space-s) calc(var(--space-xs) + env(safe-area-inset-bottom, 0px));
    border-top: var(--bw-hairline) solid var(--shell-border);
    background: var(--shell-bg);
  }

  .hpa-tabbar__item {
    display: grid;
    justify-items: center;
    align-content: center;
    gap: 2px;
    min-width: 0;
    min-height: 48px;
    padding: var(--space-xs) 0;
    border: 0;
    border-radius: var(--radius-small);
    background: none;
    color: var(--text-secondary);
    font: inherit;
    font-size: var(--type-caption2);
    font-weight: var(--weight-semibold);
    text-decoration: none;
    cursor: pointer;
  }
  .hpa-tabbar__item .hpa-icon,
  .hpa-tabbar__item .hpa-ui { width: 22px; height: 22px; }
  .hpa-tabbar__item[aria-current="page"] { color: var(--accent-text); }

  /* Ruimte onder de inhoud voor de tabbalk (de oude .app-page-regel in
     style.css dekt alleen pagina's met .app-page). */
  :root body.app-shell { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
}

/* Offlinepagina: alleen topbalk (telefoon) en inhoud. Daar draait geen fb-ui.js en
   geen Firebase, dus lade, inklapknop, "Meer" en Uitloggen zouden dood zijn, en elke
   link komt offline toch weer hier uit. De shell zelf blijft byte-gelijk (R4). */
:root body.app-shell[data-saas-page="offline"] { padding-left: 0; padding-bottom: 0; }
:root body.app-shell[data-saas-page="offline"] .sidebar,
:root body.app-shell[data-saas-page="offline"] .sidebar-overlay,
:root body.app-shell[data-saas-page="offline"] .hpa-tabbar,
:root body.app-shell[data-saas-page="offline"] .hpa-topbar .sidebar-hamburger { display: none !important; }

/* ── Blurbeleid (OK-DP-3 a, prestatiebudget B5) ──────────────────────────
   Eén regel voor de hele SaaS: alleen hero, zijbalk, sheet en sectie-
   navigatie mogen blurren. style.css heeft nog 69 oudere backdrop-filters
   (kaarten, balken, overlays); zonder deze regel overschrijden die het
   budget stil zodra een pagina ze toont.
   ------------------------------------------------------------------- */
:root body.app-shell :not(.hpa-card--hero, .sidebar, .hpa-sheet, .hpa-secnav) {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* ============================================================================
   S11b-5 B0 — gedeelde laag trein B (06-10-2026)
   ============================================================================
   Wat dashboard, offertes, planning en straks team delen, zodat geen pagina
   een eigen kopie bouwt (regiebesluit R23): kengetal met bovenrij en
   aandachtsstand, avatar, activiteitenlijst, formuliervelden en schakelaar,
   bevestiging in de pagina, gevaarknop, filterchip met teller, toast-typen,
   tijdlijn met gevaarvariant en opslaanstand. Alles op de A0-tokens. Hier
   staat alleen de eindstand; wat beweegt (nieuw item, moduswissel, glans,
   schakelaar) staat opt-in in hpa-motion.css, blok B0.
   ========================================================================= */

/* ── Kengetaltegel: bovenrij en aandachtsstand ───────────────────────────
   Bovenrij: links de icoontegel (.hpa-tile-icon), rechts een chip. De
   aandachtsstand (.hpa-kpi--let-op, bijvoorbeeld Achterstallig > 0) zet rand
   en getal in de statuskleur rood. De kleur springt, ook terug naar neutraal
   (design-afspraken §6, moment 16): een kengetal dat ook kaart is
   (.hpa-card.hpa-kpi) verliest daarom de randovergang van .hpa-card; lift en
   schaduw bij aanwijzen blijven. Een tegel die in een rij hoger wordt dan zijn
   inhoud, houdt getal en label bij elkaar (align-content: start).
   ------------------------------------------------------------------- */
.hpa-kpi {
  align-content: start;
  transition-property: transform, box-shadow;
}

.hpa-kpi__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  min-width: 0;
}

.hpa-kpi--let-op,
:is(a, .hpa-card--interactive).hpa-kpi--let-op:hover {
  border-color: var(--color-danger-border);
}
.hpa-kpi--let-op .hpa-kpi__value { color: var(--danger-text); }

/* ── Avatar ──────────────────────────────────────────────────────────────
   Initialen op het recept van .sidebar-avatar: 30 px, kleine radius, vet.
   De persoonskleur is een zachte tint uit een naam-hash (avatar() in
   saas-ui.mjs zet data-kleur 0 tot en met 3); de letters blijven
   --text-primary, dus de tint is herkenning en geen stand. --sm (24 px) is
   voor rijen en lijsten.
   ------------------------------------------------------------------- */
.hpa-avatar {
  --avatar-tint: var(--text-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex: none;
  border: var(--bw-hairline) solid color-mix(in srgb, var(--avatar-tint) 28%, transparent);
  border-radius: var(--radius-small);
  background: color-mix(in srgb, var(--avatar-tint) 16%, transparent);
  color: var(--text-primary);
  font-size: var(--type-caption);
  font-weight: var(--weight-bold);
  line-height: 1;
  user-select: none;
}
.hpa-avatar--sm { width: 24px; height: 24px; font-size: var(--type-caption2); }
.hpa-avatar[data-kleur="1"] { --avatar-tint: var(--status-blue); }
.hpa-avatar[data-kleur="2"] { --avatar-tint: var(--accent-orange); }
.hpa-avatar[data-kleur="3"] { --avatar-tint: var(--success-color); }

/* ── Activiteitenlijst ───────────────────────────────────────────────────
   Een rij is avatar · zin · tijd; de tijd staat onder de zin. Een haarlijn
   tussen de rijen, niet onder de laatste. Een lange dossiernaam breekt af in
   plaats van de rij te verbreden (390 px).
   <ul class="hpa-activiteit"><li class="hpa-activiteit__rij">avatar()
   <p class="hpa-activiteit__zin">… <time class="hpa-activiteit__tijd">…</time></p></li></ul>
   ------------------------------------------------------------------- */
.hpa-activiteit {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hpa-activiteit__rij {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: var(--space-m);
  padding: var(--space-m) 0;
  border-bottom: var(--bw-hairline) solid var(--sub-border);
}
.hpa-activiteit__rij:last-child { border-bottom: 0; }

.hpa-activiteit__zin {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: var(--type-footnote);
  line-height: var(--lh-snug);
  color: var(--text-primary);
}

.hpa-activiteit__tijd {
  display: block;
  margin-top: 2px;
  font-size: var(--type-caption);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

/* ── Formuliervelden ─────────────────────────────────────────────────────
   Een veld is label, invoer, hint en bij een fout een veldfout. Vorm uit de
   mockups offertes.html en planning.html op de A0-tokens; het dossier (A1)
   houdt zijn eigen d-*-velden (A1b beslist). Een fout staat in de tekst én
   in aria-invalid op de invoer, en aria-describedby wijst naar hint en fout:
   <div class="hpa-veld"><label for="t">Titel</label>
     <input class="hpa-invoer" id="t" aria-invalid="true" aria-describedby="t-fout">
     <p class="hpa-veldfout" id="t-fout">(ui-alert) Vul een titel in.</p></div>
   ------------------------------------------------------------------- */
.hpa-veld {
  display: grid;
  gap: var(--space-xs);
  min-width: 0;
}

.hpa-veld > label,
.hpa-veld__label {
  font-size: var(--type-footnote);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}

.hpa-invoer {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  min-height: 44px;
  margin: 0;
  padding: var(--space-s) var(--space-m);
  border: var(--bw-hairline) solid var(--input-border);
  border-radius: var(--radius-input);
  background: var(--input-bg);
  color: var(--text-primary);
  font: inherit;
  font-size: var(--type-subheadline);
  line-height: var(--lh-snug);
}
textarea.hpa-invoer { min-height: 88px; resize: vertical; }
/* Voorbeeldtekst: 80 % van de tekstkleur. --text-muted haalt op de invoer
   in donker geen 4,5:1 (3,9:1 met de routine van de kwaliteitsspec,
   verificatie B0); zo is het 5,0:1 in donker en 10,3:1 in licht, en blijft de
   voorbeeldtekst lichter dan een ingevulde waarde. */
.hpa-invoer::placeholder { color: color-mix(in srgb, var(--text-primary) 80%, transparent); opacity: 1; }
.hpa-invoer option { color: var(--text-primary); background: var(--surface-raised); }
.hpa-invoer:focus-visible {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 1px;
}
.hpa-invoer[aria-invalid="true"] { border-color: var(--danger-text); }
.hpa-invoer:disabled { color: var(--text-secondary); cursor: not-allowed; }
/* Op een aanraakscherm 16 px: iOS Safari zoomt anders in zodra een invoer
   kleiner dan 16 px de focus krijgt (zie .app-input in style.css). De mockup
   heeft 15 px; de hoogte blijft 44 px, de layout verandert niet. */
@media (pointer: coarse) {
  .hpa-invoer { font-size: var(--fs-base); }
}

.hpa-hint {
  margin: 0;
  font-size: var(--type-caption);
  line-height: var(--lh-snug);
  color: var(--text-secondary);
}

/* De veldfout: het icoon en de rand van de invoer dragen de foutkleur, de
   tekst blijft in de tekstkleur. Rood als tekst op een glaskaart haalt in
   donker geen 4,5:1 (gemeten 3,4:1 met de routine van de kwaliteitsspec,
   B0-contrastprobe); de kleur is de stand, de zin is de melding. */
.hpa-veldfout {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  margin: 0;
  font-size: var(--type-caption);
  font-weight: var(--weight-semibold);
  line-height: var(--lh-snug);
  color: var(--text-primary);
}
.hpa-veldfout[hidden] { display: none; }
.hpa-veldfout .hpa-ui { width: 0.875rem; height: 0.875rem; margin-top: 1px; color: var(--danger-text); }

/* Datumchips: snelle keuze uit de komende werkdagen (sheet "Inplannen",
   planning), op het patroon van A1 (project-dossier.css, .d-datums).
   Knoppen met aria-pressed in een groep:
   <div class="hpa-datumchips" role="group" aria-labelledby="…">
     <button class="hpa-datumchips__dag" type="button" aria-pressed="true" aria-label="maandag 12 oktober">ma <b>12</b></button>… */
.hpa-datumchips {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-xs);
}

.hpa-datumchips__dag {
  display: grid;
  justify-items: center;
  gap: 2px;
  min-width: 0;
  min-height: 44px;
  padding: var(--space-s) 0;
  border: var(--bw-hairline) solid var(--sub-border);
  border-radius: var(--radius-small);
  background: var(--sub-bg);
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--type-caption);
  white-space: nowrap;
  cursor: pointer;
}
.hpa-datumchips__dag b {
  font-family: var(--font-numeric);
  font-size: var(--type-headline);
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
/* Gekozen: de rand (leesbare accenttint, >= 3:1) en de tint dragen de stand;
   de tekst blijft in de tekstkleur, want oranje op de oranje tint haalt op
   een glaskaart in donker geen 4,5:1 (gemeten, B0-contrastprobe). */
.hpa-datumchips__dag[aria-pressed="true"] {
  border-color: var(--accent-text);
  background: color-mix(in srgb, var(--accent-orange) 12%, transparent);
  color: var(--text-primary);
}
.hpa-datumchips__dag:focus-visible {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 1px;
}

/* Schakelaar (bijvoorbeeld het termijnschema): een echte checkbox met
   role="switch", visueel verborgen; de baan toont de stand. Uit = omlijnde
   baan met een grijze knop, aan = gevulde baan in de leesbare accenttint met
   een knop in de paginakleur. Beide standen halen 3:1 tegen de ondergrond
   (WCAG 1.4.11), ook in licht; een witte knop op een lichte baan (mockup)
   haalt dat niet. De overgang van de knop staat opt-in in hpa-motion.css.
   <label class="hpa-schakelaar"><input type="checkbox" role="switch">
     <span class="hpa-schakelaar__baan" aria-hidden="true"></span>Termijnschema gebruiken</label> */
.hpa-schakelaar {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-m);
  min-height: 44px;
  font-size: var(--type-subheadline);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  cursor: pointer;
}

/* De checkbox ligt onzichtbaar over het hele label, ook over de baan
   (z-index): VoiceOver op iPhone en iPad vindt hem dan onder de vinger en
   omlijnt de hele schakelaar in plaats van een stipje. De focusring blijft
   op de baan. */
.hpa-schakelaar > input {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: inherit;
}

.hpa-schakelaar__baan {
  position: relative;
  box-sizing: border-box;
  width: 44px;
  height: 26px;
  flex: none;
  border: var(--bw-strong) solid var(--text-muted);
  border-radius: var(--radius-pill);
  background: var(--sub-bg);
}
.hpa-schakelaar__baan::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--text-muted);
}
.hpa-schakelaar > input:checked + .hpa-schakelaar__baan {
  border-color: var(--accent-text);
  background: var(--accent-text);
}
.hpa-schakelaar > input:checked + .hpa-schakelaar__baan::after {
  background: var(--bg-primary);
  transform: translateX(18px);
}
.hpa-schakelaar > input:focus-visible + .hpa-schakelaar__baan {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}
.hpa-schakelaar:has(> input:disabled) {
  color: var(--text-secondary);
  cursor: not-allowed;
}
.hpa-schakelaar > input:disabled + .hpa-schakelaar__baan { opacity: 0.5; }

/* ── Bevestiging in de pagina ────────────────────────────────────────────
   Vervangt confirm(): een vraag, een korte uitleg en twee knoppen, op de
   plek van de actie (ontwerpsysteem.html, "Nieuw in ronde 2"). Neutraal in
   de merktint; --gevaar voor iets dat niet terug kan (intrekken, afwijzen,
   verwijderen), met .hpa-btn--gevaar als bevestigknop. De pagina zet de
   focus op de eerste knop en geeft hem na Annuleren terug aan de actie.
   <div class="hpa-bevestig hpa-bevestig--gevaar" role="group" aria-labelledby="v">
     <p class="hpa-bevestig__vraag" id="v">Afspraak verwijderen?</p>
     <p class="hpa-bevestig__tekst">…</p>
     <div class="hpa-bevestig__acties">(Annuleren) (Verwijderen)</div></div>
   ------------------------------------------------------------------- */
.hpa-bevestig {
  display: grid;
  gap: var(--space-s);
  padding: var(--space-l);
  border: var(--bw-hairline) solid color-mix(in srgb, var(--accent-orange) 40%, transparent);
  border-radius: var(--radius-sub);
  background: color-mix(in srgb, var(--accent-orange) 10%, transparent);
  color: var(--text-primary);
}
.hpa-bevestig[hidden] { display: none; }

.hpa-bevestig__vraag {
  margin: 0;
  font-size: var(--type-subheadline);
  font-weight: var(--weight-semibold);
  line-height: var(--lh-snug);
}

.hpa-bevestig__tekst {
  margin: 0;
  font-size: var(--type-footnote);
  line-height: var(--lh-base);
  color: var(--text-secondary);
}

.hpa-bevestig__acties {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-s);
  margin-top: var(--space-xs);
}

.hpa-bevestig--gevaar {
  border-color: var(--color-danger-border);
  background: var(--color-danger-bg);
}

/* ── Gevaarknop ──────────────────────────────────────────────────────────
   Bevestigt iets dat niet terug kan (intrekken, afwijzen, verwijderen);
   nooit de hoofdactie van een pagina. Zachte rode tint op een effen
   ondergrond (--surface-raised) met de tekst in de leesbare rode tint: zo
   haalt hij 4,5:1 ongeacht wat eronder ligt. Zonder die ondergrond zakt het
   op de glans van een glaskaart in donker naar 4,1:1 (B0-contrastprobe).
   ------------------------------------------------------------------- */
.hpa-btn--gevaar {
  background-color: var(--surface-raised);
  background-image: linear-gradient(var(--color-danger-bg), var(--color-danger-bg));
  border-color: var(--color-danger-border);
  color: var(--danger-text);
}
.hpa-btn--gevaar:hover:not(:disabled) { border-color: var(--status-dot-rood); }

/* ── Filterchip als knop met teller ──────────────────────────────────────
   Een .hpa-chip als <button> met aria-pressed: de gekozen chip kleurt als
   geheel in de merktint (actie), de rest is neutraal. De teller staat in
   ronde cijfers. A2 heeft dezelfde vorm lokaal (projecten.css, .projecten-
   filter) en mag die houden.
   <button class="hpa-chip hpa-chip--knop" type="button" aria-pressed="true">
     Concept <span class="hpa-chip__teller">3</span></button>
   ------------------------------------------------------------------- */
.hpa-chip--knop {
  min-height: 36px;
  padding: var(--space-s) var(--space-m);
  font: inherit;
  font-size: var(--type-footnote);
  font-weight: var(--weight-semibold);
  line-height: 1.3;
  color: var(--text-secondary);
  cursor: pointer;
}
.hpa-chip--knop:hover { color: var(--text-primary); }
.hpa-chip--knop:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.hpa-chip--knop[aria-pressed="true"] {
  background: color-mix(in srgb, var(--accent-orange) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent-orange) 40%, transparent);
  color: var(--accent-text);
}

.hpa-chip__teller {
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-bold);
}

/* ── Toast-typen ─────────────────────────────────────────────────────────
   toast(tekst, { type }) in saas-ui.mjs: 'ok' (standaard) houdt het
   getekende vinkje; 'info' en 'fout' krijgen een icoon in dezelfde bol,
   zonder vinkje. Een fout staat in de foutkleur: rand, bol en tekst.
   ------------------------------------------------------------------- */
.hpa-toast__teken {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  flex: none;
  border-radius: 50%;
  background: var(--chip-bg);
  color: var(--text-secondary);
}
.hpa-toast__teken .hpa-ui { width: 16px; height: 16px; }

.hpa-toast--fout { border-color: var(--color-danger-border); }
.hpa-toast--fout .hpa-toast__teken {
  background: var(--color-danger-bg);
  color: var(--danger-text);
}
.hpa-toast--fout .hpa-toast__tekst { color: var(--danger-text); }

/* ── Tijdlijn: gevaarvariant en datum per stap ───────────────────────────
   .hpa-steps--gevaar is de rode eindstand (afgewezen, ingetrokken, verlopen):
   de afgelegde streep kleurt rood in plaats van merk-oranje, zoals
   .hpa-steps--complete hem groen kleurt. Rood op papier is de leesbare tint
   van de statusstip (>= 3:1). Een datum per stap staat onder de naam:
   <li class="hpa-steps__step hpa-steps__step--done">Verstuurd
     <span class="hpa-steps__datum">5 okt</span></li>
   ------------------------------------------------------------------- */
.hpa-steps--gevaar .hpa-steps__step--done::before,
.hpa-steps--gevaar .hpa-steps__step--current::before {
  background: var(--status-dot-rood);
}

.hpa-steps__datum {
  margin-top: calc(var(--space-xs) - var(--space-s));
  font-size: var(--type-caption2);
  font-weight: var(--weight-regular);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

/* ── Opslaanstand ────────────────────────────────────────────────────────
   Een stip en een korte tekst naast de opslaanknop ("Niet-opgeslagen
   wijzigingen", "Opgeslagen"). De stip draagt de stand, de tekst blijft
   neutraal; de pagina zet role="status" als de tekst wisselt.
   ------------------------------------------------------------------- */
.hpa-opslaanstand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-s);
  margin: 0;
  font-size: var(--type-footnote);
  line-height: var(--lh-snug);
  color: var(--text-secondary);
}
.hpa-opslaanstand[hidden] { display: none; }
.hpa-opslaanstand::before {
  content: "";
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--status-dot-grijs);
}
.hpa-opslaanstand--gewijzigd::before { background: var(--status-dot-amber); }
.hpa-opslaanstand--opgeslagen::before { background: var(--status-dot-groen); }

/* ── Verborgen houden ────────────────────────────────────────────────────
   display: grid of inline-flex hierboven wint van het hidden-attribuut,
   zoals bij de actiebalk. Een pagina die een veld, de datumchips, een
   schakelaar, een activiteitenlijst of een kengetal met hidden verbergt
   (bijvoorbeeld de termijnvelden als het termijnschema uit staat), houdt
   het met deze regel echt weg. */
.hpa-veld[hidden],
.hpa-datumchips[hidden],
.hpa-schakelaar[hidden],
.hpa-activiteit[hidden],
.hpa-kpi[hidden] { display: none; }

/* ============================================================================
   S11b-5 C0 — gedeelde laag trein C (07-10-2026)
   ============================================================================
   Wat team, branding, account, licentie en de toegangspagina's delen (meting
   C1 §4, C2 §4, L1 §4; regiebesluiten R48, R59): vergrendeld met reden, de
   segmentknop in de uit-stand, de gevaarkaart, feedfilters boven de
   activiteitenlijst, sleutel en waarde, de kenmerkenlijst en de grote avatar.
   Alleen eindstanden op de A0-tokens: niets hiervan beweegt, dus dit blok
   staat vóór de sectie Beweging en telt niet in B9.
   ========================================================================= */

/* ── Vergrendeld met reden (R48, OK-DP-5 a) ──────────────────────────────
   Wat vergrendel(el, reden) in saas-ui.mjs zet: aria-disabled en
   .is-vergrendeld. Gedempt in de rustige tekstkleur, op volle dekking: de
   oude regels (button[aria-disabled] in style.css: 0,55 en geen klik;
   .hpa-btn[aria-disabled]: 0,5) drukten de tekst onder 4,5:1 en lieten de
   klik met de reden nooit aankomen. Op een knop of link dragen het slot
   vooraan en de cursor de stand, niet alleen de kleur; een rij krijgt geen
   slot (saas-ui.mjs: geef hem { zichtbaar: true } of een eigen slot). De
   focusring blijft: het element blijft
   focusbaar. Een merk- of gevaarknop wordt op slot een rustige knop; oranje of
   rood met gedempte tekst haalt geen 4,5:1. De knop op slot heeft een dichte
   ondergrond onder de chiptint (zoals de gevaarknop): op glas in donker zakte
   hij op de echte pixels anders tot 4,34:1 waar het achtergrondlicht doorschijnt.
   ------------------------------------------------------------------- */
.is-vergrendeld[aria-disabled="true"] {
  opacity: 1;
  pointer-events: auto;
  cursor: not-allowed;
  color: var(--text-secondary);
}

.hpa-btn.is-vergrendeld[aria-disabled="true"],
.hpa-btn.is-vergrendeld[aria-disabled="true"]:hover {
  background: var(--surface-raised);
  background-image: linear-gradient(var(--chip-bg), var(--chip-bg));
  border-color: var(--chip-border);
  box-shadow: none;
  color: var(--text-secondary);
  text-decoration: none;
  transform: none;
}
.hpa-btn--tertiary.is-vergrendeld[aria-disabled="true"],
.hpa-btn--tertiary.is-vergrendeld[aria-disabled="true"]:hover {
  background: transparent;
  border-color: transparent;
}
.hpa-btn.is-vergrendeld[aria-disabled="true"]:focus-visible { box-shadow: var(--focus-ring); }

/* Het slot staat vooraan; een eigen icoon van de knop wijkt zolang. */
.hpa-btn.is-vergrendeld > svg:not(.hpa-vergrendeld__slot),
.hpa-seg__btn.is-vergrendeld > svg:not(.hpa-vergrendeld__slot) { display: none; }
.hpa-vergrendeld__slot { color: var(--text-muted); }
.hpa-btn .hpa-vergrendeld__slot { width: 1rem; height: 1rem; }

/* ── Segmentknop in de uit-stand ─────────────────────────────────────────
   Een keuze die je niet mag maken, bijvoorbeeld "Beheerder" voor wie geen
   eigenaar is (meting C1 §4): vergrendel(knop, reden) zet aria-disabled, het
   slot en de reden; de knop blijft in de rij staan, op volle dekking in de
   rustige tekstkleur van een niet-gekozen keuze (de gedempte kleur haalt op
   een glaskaart in donker 4,29:1). Het slot vooraan en de cursor dragen de
   stand, en hover maakt de tekst niet feller. Een knop met disabled krijgt
   dezelfde vorm; die is echt uit en geeft geen reden.
   ------------------------------------------------------------------- */
.hpa-seg__btn[aria-disabled="true"],
.hpa-seg__btn[aria-disabled="true"]:hover,
.hpa-seg__btn:disabled {
  opacity: 1;
  color: var(--text-secondary);
  cursor: not-allowed;
}
.hpa-seg__btn[aria-disabled="true"] { pointer-events: auto; }
.hpa-seg__btn .hpa-vergrendeld__slot { width: 0.875rem; height: 0.875rem; }

/* ── Gevaarkaart ─────────────────────────────────────────────────────────
   Een kaart voor wat niet terug kan: eigenaarschap overdragen, de werkruimte
   of het account verwijderen (meting C1 §4, C2 §4). Rode rand en een rode
   icoontegel in de kop; titel en tekst blijven in de tekstkleur (rood als
   tekst haalt op een glaskaart in donker geen 4,5:1, zie de gevaarknop). De
   acties erin zijn .hpa-btn--gevaar, de bevestiging .hpa-bevestig--gevaar;
   wie het niet mag, ziet de actie vergrendeld met de reden.
   <section class="hpa-card hpa-card--gevaar" aria-labelledby="t">
     <div class="hpa-card__head"><span class="hpa-tile-icon"><svg class="hpa-ui">
     ui-trash</svg></span><h2 class="hpa-card__title" id="t">…</h2></div> …</section>
   ------------------------------------------------------------------- */
.hpa-card--gevaar { border-color: var(--color-danger-border); }
.hpa-card--gevaar .hpa-card__head .hpa-tile-icon {
  background: var(--color-danger-bg);
  color: var(--danger-text);
}

/* ── Feedfilters boven de activiteitenlijst ──────────────────────────────
   Filterchips zonder teller (meting C1 §2: een teller over de laatste
   twintig gebeurtenissen misleidt): .hpa-chip--knop met aria-pressed en
   data-filter, in een groep boven de .hpa-activiteit. Een rij draagt
   data-filter met haar soort(en); feedFilter() in saas-ui.mjs kiest één
   chip en zet hidden op de rijen die er niet bij horen.
   <div class="hpa-activiteit__filters" role="group" aria-label="Activiteit filteren">
     <button class="hpa-chip hpa-chip--knop" type="button" data-filter="alles"
       aria-pressed="true">Alles</button> …</div>
   ------------------------------------------------------------------- */
.hpa-activiteit__filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  margin: 0 0 var(--space-s);
}
/* De filters staan bovenin een glaskaart, waar de lichte glans van de kaart
   in donker de gekozen chip (merktint op glas) op 3,81:1 zette. Een dichte
   ondergrond onder de tint, zoals bij de gevaarknop, houdt beide standen
   boven 4,5:1, licht en donker. */
.hpa-activiteit__filters .hpa-chip--knop {
  background-color: var(--surface-raised);
  background-image: linear-gradient(var(--chip-bg), var(--chip-bg));
}
.hpa-activiteit__filters .hpa-chip--knop[aria-pressed="true"] {
  background-image: linear-gradient(
    color-mix(in srgb, var(--accent-orange) 14%, transparent),
    color-mix(in srgb, var(--accent-orange) 14%, transparent)
  );
}
.hpa-activiteit__filters[hidden],
.hpa-activiteit__rij[hidden] { display: none; }
/* Na filteren is de laatste zichtbare rij niet altijd het laatste kind; de regel van B0
   (:last-child) liet er dan een haarlijn onder staan. */
.hpa-activiteit__rij:not([hidden]):nth-last-child(1 of :not([hidden])) { border-bottom: 0; }

/* ── Sleutel en waarde ───────────────────────────────────────────────────
   Rijen "sleutel · waarde · acties" voor account en licentie (meting C2 §4):
   de sleutel rustig, de waarde vet, acties rechts, een haarlijn tussen de
   rijen. Onder 768 px staat de sleutel boven de waarde. Een persoonsgegeven
   dat bewust ontbreekt, is een lege chip in de waarde.
   <dl class="hpa-kv"><div class="hpa-kv__rij"><dt class="hpa-kv__sleutel">Rol</dt>
     <dd class="hpa-kv__waarde">Lid</dd><dd class="hpa-kv__acties">…</dd></div></dl>
   ------------------------------------------------------------------- */
.hpa-kv {
  display: grid;
  margin: 0;
}

.hpa-kv__rij {
  display: grid;
  grid-template-columns: minmax(7.5rem, 32%) minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-m);
  padding: var(--space-m) 0;
  border-bottom: var(--bw-hairline) solid var(--sub-border);
  font-size: var(--type-footnote);
  line-height: var(--lh-snug);
}
.hpa-kv__rij:last-child { border-bottom: 0; }

.hpa-kv__sleutel {
  margin: 0;
  color: var(--text-muted);
}

.hpa-kv__waarde {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.hpa-kv__acties {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-xs);
  margin: 0;
}

@media (max-width: 768px) {
  .hpa-kv__rij {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: var(--space-xs);
  }
  .hpa-kv__sleutel { grid-column: 1 / -1; }
}
.hpa-kv[hidden],
.hpa-kv__rij[hidden] { display: none; }

/* ── Kenmerkenlijst ──────────────────────────────────────────────────────
   Wat bij een licentie hoort (meting C2 §4): per regel een vinkje (zit
   erin, data-mag="ja") of een slot (zit er niet in). Zelfde vorm als de
   rolpoortregel, kleiner. Het icoon is aria-hidden, dus de stand staat ook
   in de tekst ("nog niet beschikbaar") of in een .hpa-sr-only ervoor.
   <ul class="hpa-kenmerken"><li class="hpa-kenmerken__regel" data-mag="ja">
     <span class="hpa-kenmerken__icoon"><svg class="hpa-ui">ui-check</svg></span>
     <span>Teamwerkruimte en rollen</span></li></ul>
   ------------------------------------------------------------------- */
.hpa-kenmerken {
  display: grid;
  gap: var(--space-s);
  margin: 0;
  padding: 0;
  list-style: none;
}

.hpa-kenmerken__regel {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: var(--space-m);
  font-size: var(--type-footnote);
  line-height: var(--lh-snug);
  color: var(--text-secondary);
}

.hpa-kenmerken__icoon {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: var(--bw-hairline) solid var(--chip-border);
  border-radius: var(--radius-sm);
  background: var(--chip-bg);
  color: var(--text-muted);
}
.hpa-kenmerken__icoon .hpa-ui { width: 14px; height: 14px; }
.hpa-kenmerken__regel[data-mag="ja"] .hpa-kenmerken__icoon {
  border-color: transparent;
  background: var(--color-success-bg);
  color: var(--success-text);
}
.hpa-kenmerken[hidden],
.hpa-kenmerken__regel[hidden] { display: none; }

/* ── Grote avatar ────────────────────────────────────────────────────────
   56 px voor de profielkop van Account (meting C2 §4). avatar(naam) geeft
   initialen en tint; de pagina zet er hpa-avatar--groot bij. Zelfde recept
   als de gewone avatar, met een radius en letter op schaal.
   ------------------------------------------------------------------- */
.hpa-avatar--groot {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-sub);
  font-size: var(--type-headline);
}

/* ============================================================================
   Beweging (S11b-5 A0b, motion-addendum §2 en §3)
   ============================================================================
   Opt-in: alles hieronder staat binnen prefers-reduced-motion: no-preference;
   "Rustig" zet het onderaan met één regel uit (animation: none). Wat
   beweegt, beweegt alleen transform en opacity (behalve de ringslag:
   eenmalig, 0,9 s, kleiner dan 200 px). Eindige
   animaties eindigen in de basisstijl (fill backwards), zodat ze na afloop
   uit document.getAnimations() verdwijnen (budget B3).
   ========================================================================= */
@keyframes hpa-fasen-groei  { from { transform: scaleX(0); } }
@keyframes hpa-fase-ring    { from { transform: scale(0.7); opacity: 0.7; } to { transform: scale(1.5); opacity: 0; } }
@keyframes hpa-vat-vul      { from { transform: scaleY(0); } }
@keyframes hpa-toast-in     { from { opacity: 0; transform: translateY(14px) scale(0.96); } }
@keyframes hpa-toast-uit    { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(8px) scale(0.98); } }
@keyframes hpa-toast-vink   { from { stroke-dashoffset: 20; } }
@keyframes hpa-menu-in      { from { opacity: 0; transform: scale(0.96) translateY(-4px); } }
@keyframes hpa-chip-pop     { from { transform: scale(0.92); } }

@media (prefers-reduced-motion: no-preference) {
  .hpa-steps__step--done::before,
  .hpa-steps__step--current::before {
    animation: hpa-bar-grow 0.6s var(--ease-out) backwards;
  }

  .hpa-fasen::after {
    animation: hpa-fasen-groei 0.7s var(--ease-out) 0.1s backwards;
    transition: transform 0.7s var(--ease-out);
  }
  .hpa-fasen:not([data-gestopt]) .hpa-fasen__stap.is-current .hpa-fasen__stip::after {
    animation: hpa-fase-ring 2.4s var(--ease-out) 3 backwards;
  }
  /* Kleur springt, vorm beweegt (design-afspraken §6): bij een statuswissel
     schaalt de stip, zijn kleur gaat niet over. */
  .hpa-fasen__stip {
    transition: transform 0.3s var(--ease-pop);
  }

  [data-hpa-reveal="in"] .hpa-meter__fill,
  [data-hpa-reveal="in"] .hpa-stack__deel {
    animation: hpa-bar-grow var(--duration-bar) var(--ease-out) 0.2s backwards;
  }
  [data-hpa-reveal="in"] .hpa-vat__water {
    animation: hpa-vat-vul 1.4s var(--ease-pop) 0.25s backwards;
  }

  .hpa-ring__bar {
    transition: stroke-dashoffset var(--duration-ring) var(--ease-pop) 0.3s;
  }

  .hpa-status.is-pop {
    animation: hpa-chip-pop 0.24s var(--ease-pop) backwards;
  }

  .hpa-table__toggle .hpa-ui {
    transition: transform var(--duration-quick) var(--ease-out);
  }

  .hpa-backdrop {
    transition: opacity 0.2s ease;
  }
  .hpa-sheet {
    transition: transform var(--duration-sheet) var(--ease-sheet);
  }

  .hpa-toast {
    animation: hpa-toast-in 0.28s var(--ease-out) backwards;
  }
  .hpa-toast.is-out {
    animation: hpa-toast-uit 0.22s ease backwards;
  }
  .hpa-toast__vink {
    animation: hpa-toast-vink 0.42s var(--ease-out) 0.12s backwards;
  }

  .hpa-menu {
    animation: hpa-menu-in 0.18s var(--ease-out) backwards;
  }

  .hpa-secnav__indicator {
    transition: transform 0.28s var(--ease-out), width 0.28s var(--ease-out);
  }

  .hpa-seg__btn {
    transition: background-color var(--duration-quick) ease, color var(--duration-quick) ease;
  }
}

/* ── Levend canvas (motion-addendum §2a, OK-DP-1 a, OK-MA-1 a) ────────────
   De statische laag (kern en anker, of het webgrijs in licht) ligt op de
   body; de twee bovenste gloeden zijn de body-pseudo's en drijven traag.
   Radiale gradient zonder filter, alleen transform: de compositor doet het
   werk (gemeten in de demo: ca. 1 ms hoofdthread per 5 s). Eindstand = stil
   in de middenstand. z-index -1: onder alle inhoud, ook onder de kaarten.
   ------------------------------------------------------------------- */
:root body.app-shell.dashboard-theme {
  background: var(--canvas-static);
  background-color: var(--bg-primary);
}

@media (min-width: 769px) {
  :root body.app-shell.dashboard-theme { background-attachment: fixed; }
}

:root body.app-shell::before,
:root body.app-shell::after {
  --aurora-x: var(--aurora-a-x);
  --aurora-y: var(--aurora-a-y);
  --aurora-kleur: var(--aurora-a);
  content: "";
  position: fixed;
  z-index: -1;
  top: calc(var(--aurora-y) - 55vmax);
  left: calc(var(--aurora-x) - 55vmax);
  width: 110vmax;
  height: 110vmax;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--aurora-kleur), transparent);
  pointer-events: none;
}

:root body.app-shell::after {
  --aurora-x: var(--aurora-b-x);
  --aurora-y: var(--aurora-b-y);
  --aurora-kleur: var(--aurora-b);
}

@keyframes hpa-aurora-a {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(5vw, 3vh, 0) scale(1.06); }
  100% { transform: translate3d(-4vw, 4vh, 0) scale(0.97); }
}

@keyframes hpa-aurora-b {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(-5vw, 2vh, 0) scale(1.05); }
  100% { transform: translate3d(3vw, -3vh, 0) scale(0.98); }
}

@media (prefers-reduced-motion: no-preference) {
  body.app-shell::before {
    animation: hpa-aurora-a var(--duration-aurora-a) ease-in-out infinite alternate;
  }
  body.app-shell::after {
    animation: hpa-aurora-b var(--duration-aurora-b) ease-in-out 1.8s infinite alternate;
  }
}

/* ── Overgang tussen pagina's (OK-MA-3 a) ────────────────────────────────
   Cross-document View Transition: zijbalk, topbalk en tabbalk blijven staan,
   het werkvlak crossfadet 0,2 s. Zonder ondersteuning: gewone navigatie. */
@view-transition { navigation: auto; }
:root body.app-shell .sidebar { view-transition-name: hpa-zijbalk; }
:root body.app-shell .hpa-topbar { view-transition-name: hpa-topbalk; }
:root body.app-shell .hpa-tabbar { view-transition-name: hpa-tabbalk; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 0.2s; }

/* ── Pauze (budget B6) ───────────────────────────────────────────────────
   Verborgen tabblad: hpa-motion.js zet data-hpa-verborgen op :root en dan
   staat alles in de shell stil, niet alleen het canvas. Buiten beeld: één
   IntersectionObserver zet data-hpa-in-beeld="nee" op elke laag met
   data-hpa-ambient (illustraties, adem). Geen polling, geen rAF-lus. */
:root[data-hpa-verborgen] body.app-shell,
:root[data-hpa-verborgen] body.app-shell::before,
:root[data-hpa-verborgen] body.app-shell::after,
:root[data-hpa-verborgen] body.app-shell *,
:root[data-hpa-verborgen] body.app-shell *::before,
:root[data-hpa-verborgen] body.app-shell *::after,
[data-hpa-ambient][data-hpa-in-beeld="nee"],
[data-hpa-ambient][data-hpa-in-beeld="nee"] *,
[data-hpa-ambient][data-hpa-in-beeld="nee"] *::before,
[data-hpa-ambient][data-hpa-in-beeld="nee"] *::after {
  animation-play-state: paused !important;
}

/* Rustvenster (A0d, R21): na 20 s zonder invoer zet hpa-motion.js
   data-hpa-rust op :root. Dan stoppen canvas en ambient-lagen echt: none, niet
   paused, want een gepauzeerde animatie telt in getAnimations() en het
   GPU-proces tekent door (B10). Overvloeien en hervatten doet het script. */
:root[data-hpa-rust] body.app-shell::before,
:root[data-hpa-rust] body.app-shell::after,
:root[data-hpa-rust] [data-hpa-ambient],
:root[data-hpa-rust] [data-hpa-ambient] *,
:root[data-hpa-rust] [data-hpa-ambient] *::before,
:root[data-hpa-rust] [data-hpa-ambient] *::after {
  animation: none !important;
}

/* ── Reduce Motion en "Rustig": 0 animaties (budget B7, regiebesluit R7) ──
   animation: none, geen korte duur: een afgelopen animatie met fill-mode
   forwards of both blijft anders in document.getAnimations() staan. Dit
   overschrijft ook de oudere blokken in style.css (0,01 ms) en de pagina-CSS.
   "Rustig" (data-beweging op :root, de knop in de zijbalk) doet hetzelfde
   als de systeeminstelling. */
@media (prefers-reduced-motion: reduce) {
  :root body.app-shell,
  :root body.app-shell::before,
  :root body.app-shell::after,
  :root body.app-shell *,
  :root body.app-shell *::before,
  :root body.app-shell *::after {
    animation: none !important;
    transition: none !important;
  }
  /* <html> zelf valt buiten body.app-shell. De *-regel in style.css gaf hem
     transition-duration 0,01 ms op "all", dus elke themawissel startte een
     kleurovergang op <html> die één frame in getAnimations() stond. Aparte
     regel: een browser zonder :has() verwerpt anders het hele blok hierboven. */
  :root:has(> body.app-shell) {
    animation: none !important;
    transition: none !important;
  }
  @view-transition { navigation: none; }
}

:root[data-beweging="rustig"] { scroll-behavior: auto; }
:root[data-beweging="rustig"] body.app-shell,
:root[data-beweging="rustig"] body.app-shell::before,
:root[data-beweging="rustig"] body.app-shell::after,
:root[data-beweging="rustig"] body.app-shell *,
:root[data-beweging="rustig"] body.app-shell *::before,
:root[data-beweging="rustig"] body.app-shell *::after,
:root[data-beweging="rustig"]::view-transition-group(*),
:root[data-beweging="rustig"]::view-transition-old(*),
:root[data-beweging="rustig"]::view-transition-new(*) {
  animation: none !important;
  transition: none !important;
}

/* Eindstanden die bij Reduce Motion in hpa-motion.css staan, ook voor Rustig:
   zonder animatie mag niets onzichtbaar of half getekend blijven. */
:root[data-beweging="rustig"] .hpa-fade-up[data-hpa-reveal] { opacity: 1; transform: none; }
:root[data-beweging="rustig"] .hpa-bar__fill { transform: scaleX(1); }
:root[data-beweging="rustig"] .hpa-success__circle,
:root[data-beweging="rustig"] .hpa-success__check { stroke-dashoffset: 0; }
:root[data-beweging="rustig"] .hpa-success__ring,
:root[data-beweging="rustig"] .hpa-flow-particle { display: none; }
:root[data-beweging="rustig"] .hpa-skeleton { background: var(--surface-2); }

/* -------------------------------------------------------------------
   Meer laden (productreview-trein E12, S-06)
   Lijsten laden een beperkt aantal dossiers per keer. Onder de lijst staat
   hoeveel er nu staan en een knop voor de volgende reeks:
   <div class="hpa-meerladen"><p class="hpa-meerladen__tekst" role="status">20 van 51 dossiers</p>
     <button class="hpa-btn hpa-btn--secondary hpa-btn--sm">Meer laden</button></div>
   ------------------------------------------------------------------- */
.hpa-meerladen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-s) var(--space-m);
  padding: var(--space-m) 0;
}
.hpa-meerladen[hidden] { display: none; }
.hpa-meerladen__tekst {
  margin: 0;
  font-size: var(--type-footnote);
  color: var(--text-secondary);
}
