/*
  AstroLink UI 0.1.0
  Gedeelde stijl voor de interne AstroLink-apps. Ontwerpbasis: shadcn/ui (tokens, vormen, states),
  zonder React en zonder bouwstap. Handleiding: README.md in astrolink-cc/ui.

  Alles staat in cascade-lagen. Stijl van de app zelf (zonder laag) wint dus altijd van deze bibliotheek.
*/
@layer astrolink.tokens, astrolink.base, astrolink.components, astrolink.utilities;

/* Onest (SIL Open Font License, zie fonts/OFL.txt), zelf gehost: geen verzoeken naar Google (AVG). */
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/onest-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF,
    U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/onest-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ------------------------------------------------------------------------------------------------
   Tokens (shadcn-themaformaat). Licht is de standaard; donker volgt het systeem, tenzij de pagina
   data-theme="light" of data-theme="dark" (of class="dark") op <html> zet.
   Grijs: koel neutraal (tint 286, dezelfde hoek als het merk-indigo). Accenten:
   blauw = algemeen (primair, links, focus), groen = goed, rood = slecht.
   ------------------------------------------------------------------------------------------------ */
@layer astrolink.tokens {
  :root {
    color-scheme: light;

    /* tokens:light */
    --background: oklch(0.985 0.002 286);
    --foreground: oklch(0.21 0.014 286);
    --card: oklch(1 0 0);
    --card-foreground: oklch(0.21 0.014 286);
    --popover: oklch(1 0 0);
    --popover-foreground: oklch(0.21 0.014 286);
    --primary: oklch(0.49 0.2 265);
    --primary-foreground: oklch(0.99 0.004 265);
    --primary-subtle: oklch(0.95 0.025 265);
    --primary-subtle-foreground: oklch(0.43 0.19 265);
    --secondary: oklch(0.955 0.004 286);
    --secondary-foreground: oklch(0.21 0.014 286);
    --muted: oklch(0.955 0.004 286);
    --muted-foreground: oklch(0.48 0.014 286);
    --accent: oklch(0.94 0.005 286);
    --accent-foreground: oklch(0.21 0.014 286);
    --success: oklch(0.49 0.12 152);
    --success-foreground: oklch(0.99 0.01 152);
    --success-subtle: oklch(0.95 0.04 152);
    --success-subtle-foreground: oklch(0.42 0.1 152);
    --destructive: oklch(0.52 0.19 27);
    --destructive-foreground: oklch(0.99 0.01 27);
    --destructive-subtle: oklch(0.95 0.025 27);
    --destructive-subtle-foreground: oklch(0.46 0.17 27);
    --border: oklch(0.91 0.005 286);
    --input: oklch(0.62 0.012 286);
    --ring: oklch(0.49 0.2 265);
    --overlay: oklch(0.21 0.014 286 / 0.5);
    /* end */

    --brand-gradient: linear-gradient(90deg, #b23a8b, #2e11a6);
    --shadow-sm: 0 1px 2px oklch(0.21 0.014 286 / 0.06);
    --shadow-md: 0 1px 3px oklch(0.21 0.014 286 / 0.08), 0 4px 12px oklch(0.21 0.014 286 / 0.06);
    --shadow-lg: 0 8px 30px oklch(0.21 0.014 286 / 0.16);

    --radius: 0.625rem;
    --radius-sm: calc(var(--radius) - 4px);
    --radius-md: calc(var(--radius) - 2px);
    --radius-lg: var(--radius);
    --radius-xl: calc(var(--radius) + 4px);

    --font-sans: 'Onest', ui-sans-serif, system-ui, sans-serif;
    --font-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
    --text-xs: 0.75rem;
    --text-sm: 0.875rem;
    --text-base: 1rem;
    --text-lg: 1.125rem;
    --text-xl: 1.375rem;
    --text-2xl: 1.75rem;
    --text-3xl: 2.25rem;

    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;

    --control-h: 2.5rem;
    --control-h-sm: 2rem;
    --control-h-lg: 2.75rem;
    --container: 70rem;
    --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
    --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%23858494' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 24 24'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  }

  /* Op aanraakschermen zijn bedieningselementen 44px hoog. */
  @media (pointer: coarse) {
    :root {
      --control-h: 2.75rem;
      --control-h-sm: 2.25rem;
      --control-h-lg: 3rem;
    }
  }

  @media (prefers-color-scheme: dark) {
    :root:not([data-theme='light']):not(.light) {
      color-scheme: dark;
      --background: oklch(0.17 0.006 286);
      --foreground: oklch(0.96 0.004 286);
      --card: oklch(0.205 0.007 286);
      --card-foreground: oklch(0.96 0.004 286);
      --popover: oklch(0.225 0.008 286);
      --popover-foreground: oklch(0.96 0.004 286);
      --primary: oklch(0.72 0.14 265);
      --primary-foreground: oklch(0.18 0.04 265);
      --primary-subtle: oklch(0.28 0.06 265);
      --primary-subtle-foreground: oklch(0.82 0.09 265);
      --secondary: oklch(0.27 0.008 286);
      --secondary-foreground: oklch(0.96 0.004 286);
      --muted: oklch(0.255 0.008 286);
      --muted-foreground: oklch(0.72 0.012 286);
      --accent: oklch(0.29 0.009 286);
      --accent-foreground: oklch(0.96 0.004 286);
      --success: oklch(0.75 0.14 152);
      --success-foreground: oklch(0.18 0.04 152);
      --success-subtle: oklch(0.27 0.05 152);
      --success-subtle-foreground: oklch(0.83 0.12 152);
      --destructive: oklch(0.71 0.16 25);
      --destructive-foreground: oklch(0.18 0.04 25);
      --destructive-subtle: oklch(0.28 0.06 25);
      --destructive-subtle-foreground: oklch(0.83 0.09 25);
      --border: oklch(0.3 0.008 286);
      --input: oklch(0.52 0.012 286);
      --ring: oklch(0.72 0.14 265);
      --overlay: oklch(0.08 0.005 286 / 0.7);
      --shadow-sm: none;
      --shadow-md: 0 0 0 1px oklch(1 0 0 / 0.04);
      --shadow-lg: 0 8px 30px oklch(0 0 0 / 0.5);
    }
  }

  :root[data-theme='dark'],
  :root.dark {
    color-scheme: dark;

    /* tokens:dark */
    --background: oklch(0.17 0.006 286);
    --foreground: oklch(0.96 0.004 286);
    --card: oklch(0.205 0.007 286);
    --card-foreground: oklch(0.96 0.004 286);
    --popover: oklch(0.225 0.008 286);
    --popover-foreground: oklch(0.96 0.004 286);
    --primary: oklch(0.72 0.14 265);
    --primary-foreground: oklch(0.18 0.04 265);
    --primary-subtle: oklch(0.28 0.06 265);
    --primary-subtle-foreground: oklch(0.82 0.09 265);
    --secondary: oklch(0.27 0.008 286);
    --secondary-foreground: oklch(0.96 0.004 286);
    --muted: oklch(0.255 0.008 286);
    --muted-foreground: oklch(0.72 0.012 286);
    --accent: oklch(0.29 0.009 286);
    --accent-foreground: oklch(0.96 0.004 286);
    --success: oklch(0.75 0.14 152);
    --success-foreground: oklch(0.18 0.04 152);
    --success-subtle: oklch(0.27 0.05 152);
    --success-subtle-foreground: oklch(0.83 0.12 152);
    --destructive: oklch(0.71 0.16 25);
    --destructive-foreground: oklch(0.18 0.04 25);
    --destructive-subtle: oklch(0.28 0.06 25);
    --destructive-subtle-foreground: oklch(0.83 0.09 25);
    --border: oklch(0.3 0.008 286);
    --input: oklch(0.52 0.012 286);
    --ring: oklch(0.72 0.14 265);
    --overlay: oklch(0.08 0.005 286 / 0.7);
    /* end */

    --shadow-sm: none;
    --shadow-md: 0 0 0 1px oklch(1 0 0 / 0.04);
    --shadow-lg: 0 8px 30px oklch(0 0 0 / 0.5);
  }
}

/* ------------------------------------------------------------------------------------------------
   Basis: kale HTML (server-rendered) ziet er zonder extra classes al goed uit.
   ------------------------------------------------------------------------------------------------ */
@layer astrolink.base {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }

  body {
    margin: 0;
    min-height: 100vh;
    background: var(--background);
    color: var(--foreground);
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: 1.5;
    font-variant-numeric: lining-nums;
    -webkit-font-smoothing: antialiased;
    padding-bottom: env(safe-area-inset-bottom);
  }

  h1,
  h2,
  h3,
  h4 {
    margin: 0 0 var(--space-2);
    line-height: 1.2;
    font-weight: 650;
    text-wrap: balance;
  }
  h1 {
    font-size: var(--text-2xl);
    letter-spacing: -0.02em;
    font-weight: 700;
  }
  h2 {
    font-size: var(--text-xl);
    letter-spacing: -0.015em;
  }
  h3 {
    font-size: var(--text-lg);
    letter-spacing: -0.01em;
  }
  h4 {
    font-size: var(--text-base);
  }

  p {
    margin: 0 0 var(--space-3);
    max-width: 68ch;
    text-wrap: pretty;
  }

  small {
    font-size: var(--text-sm);
  }

  a {
    color: var(--primary);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
  }
  a:hover {
    text-decoration-thickness: 2px;
  }

  :focus-visible {
    outline: 2px solid var(--ring);
    outline-offset: 2px;
  }

  ::selection {
    background: var(--primary-subtle);
    color: var(--foreground);
  }

  code,
  kbd,
  samp,
  pre {
    font-family: var(--font-mono);
    font-size: 0.875em;
  }
  code {
    background: var(--muted);
    border-radius: var(--radius-sm);
    padding: 0.1em 0.35em;
  }
  pre {
    margin: 0;
    overflow-x: auto;
    background: var(--muted);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    line-height: 1.55;
  }
  pre code {
    background: none;
    padding: 0;
    font-size: inherit;
  }
  kbd {
    display: inline-block;
    min-width: 1.6em;
    padding: 0.05em 0.4em;
    border: 1px solid var(--border);
    border-bottom-width: 2px;
    border-radius: var(--radius-sm);
    background: var(--card);
    text-align: center;
    font-size: var(--text-xs);
  }

  hr {
    border: 0;
    border-top: 1px solid var(--border);
    margin: var(--space-5) 0;
  }

  img,
  svg,
  video {
    max-width: 100%;
  }

  /* Formulierelementen */
  label {
    display: block;
    font-size: var(--text-sm);
    font-weight: 600;
    line-height: 1.3;
  }

  input:not([type='checkbox'], [type='radio'], [type='range'], [type='file'], [type='color'], [type='hidden']),
  select,
  textarea {
    display: block;
    width: 100%;
    min-height: var(--control-h);
    margin: 0;
    padding: 0.5rem 0.75rem;
    font: inherit;
    font-size: var(--text-base); /* 16px: iOS zoomt dan niet in */
    color: var(--foreground);
    background: var(--card);
    border: 1px solid var(--input);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    transition: border-color 0.15s, box-shadow 0.15s;
  }
  input::placeholder,
  textarea::placeholder {
    color: var(--muted-foreground);
    opacity: 1;
  }
  input:not([type='checkbox'], [type='radio'], [type='range'], [type='file'], [type='color']):focus-visible,
  select:focus-visible,
  textarea:focus-visible {
    outline: none;
    border-color: var(--ring);
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 35%, transparent);
  }
  textarea {
    min-height: 6.5rem;
    resize: vertical;
  }
  select {
    appearance: none;
    padding-right: 2.25rem;
    background-image: var(--select-chevron);
    background-repeat: no-repeat;
    background-position: right 0.65rem center;
    background-size: 1rem;
  }
  select[multiple] {
    background-image: none;
    padding-right: 0.75rem;
  }
  input[type='file'] {
    font: inherit;
    font-size: var(--text-sm);
    color: var(--muted-foreground);
  }
  input[type='file']::file-selector-button {
    font: inherit;
    font-weight: 600;
    margin-right: var(--space-3);
    min-height: var(--control-h-sm);
    padding: 0 0.75rem;
    border: 1px solid var(--input);
    border-radius: var(--radius-md);
    background: var(--card);
    color: var(--foreground);
    cursor: pointer;
  }
  input[type='checkbox'],
  input[type='radio'] {
    width: 1.125rem;
    height: 1.125rem;
    margin: 0;
    accent-color: var(--primary);
    flex: none;
    cursor: pointer;
  }
  input[type='range'] {
    width: 100%;
    accent-color: var(--primary);
  }

  [aria-invalid='true'],
  input:user-invalid,
  select:user-invalid,
  textarea:user-invalid {
    border-color: var(--destructive) !important;
  }
  [aria-invalid='true']:focus-visible {
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--destructive) 30%, transparent) !important;
  }

  :disabled,
  [aria-disabled='true'] {
    cursor: not-allowed;
  }
  input:disabled,
  select:disabled,
  textarea:disabled {
    opacity: 0.6;
    background: var(--muted);
  }

  fieldset {
    margin: 0;
    padding: 0;
    border: 0;
    min-width: 0;
  }
  legend {
    padding: 0;
    font-weight: 600;
    font-size: var(--text-sm);
    margin-bottom: var(--space-2);
  }

  /* Tabellen */
  table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
    font-variant-numeric: tabular-nums;
  }
  caption {
    caption-side: bottom;
    padding-top: var(--space-3);
    color: var(--muted-foreground);
    text-align: left;
  }
  th,
  td {
    padding: 0.625rem 0.75rem;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--border);
  }
  th {
    font-weight: 600;
    color: var(--muted-foreground);
    white-space: nowrap;
    vertical-align: bottom;
  }
  tfoot td,
  tfoot th {
    font-weight: 650;
    color: var(--foreground);
    border-bottom: 0;
    border-top: 1px solid var(--input);
  }

  dialog {
    color: var(--popover-foreground);
  }

  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }
}

/* ------------------------------------------------------------------------------------------------
   Componenten
   ------------------------------------------------------------------------------------------------ */
@layer astrolink.components {
  /* ---- Knop ---------------------------------------------------------------------------------- */
  .btn {
    --btn-bg: var(--primary);
    --btn-fg: var(--primary-foreground);
    --btn-border: transparent;
    --btn-hover: color-mix(in oklch, var(--primary) 88%, var(--foreground));
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--control-h);
    padding: 0 1rem;
    border: 1px solid var(--btn-border);
    border-radius: var(--radius-md);
    background: var(--btn-bg);
    color: var(--btn-fg);
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    transition: background-color 0.15s, border-color 0.15s, color 0.15s, transform 0.08s;
  }
  .btn:hover {
    background: var(--btn-hover);
    text-decoration: none;
  }
  .btn:active {
    transform: translateY(1px);
  }
  .btn:disabled,
  .btn[aria-disabled='true'] {
    opacity: 0.5;
    pointer-events: none;
  }
  .btn svg {
    width: 1rem;
    height: 1rem;
    flex: none;
  }
  .btn-secondary {
    --btn-bg: var(--secondary);
    --btn-fg: var(--secondary-foreground);
    --btn-hover: var(--accent);
  }
  .btn-outline {
    --btn-bg: var(--card);
    --btn-fg: var(--foreground);
    --btn-border: var(--input);
    --btn-hover: var(--accent);
    box-shadow: var(--shadow-sm);
  }
  .btn-ghost {
    --btn-bg: transparent;
    --btn-fg: var(--foreground);
    --btn-hover: var(--accent);
  }
  .btn-destructive {
    --btn-bg: var(--destructive);
    --btn-fg: var(--destructive-foreground);
    --btn-hover: color-mix(in oklch, var(--destructive) 88%, var(--foreground));
  }
  .btn-success {
    --btn-bg: var(--success);
    --btn-fg: var(--success-foreground);
    --btn-hover: color-mix(in oklch, var(--success) 88%, var(--foreground));
  }
  .btn-link {
    --btn-bg: transparent;
    --btn-fg: var(--primary);
    --btn-hover: transparent;
    padding: 0 0.25rem;
    text-decoration: underline;
    text-underline-offset: 0.2em;
    font-weight: 500;
  }
  .btn-sm {
    min-height: var(--control-h-sm);
    padding: 0 0.75rem;
    border-radius: var(--radius-sm);
  }
  .btn-lg {
    min-height: var(--control-h-lg);
    padding: 0 1.5rem;
    font-size: var(--text-base);
  }
  .btn-icon {
    padding: 0;
    width: var(--control-h);
  }
  .btn-icon.btn-sm {
    width: var(--control-h-sm);
  }
  .btn-block {
    display: flex;
    width: 100%;
  }
  .btn[aria-busy='true'] {
    pointer-events: none;
    opacity: 0.8;
  }
  .btn[aria-busy='true']::before,
  .spinner {
    content: '';
    display: inline-block;
    width: 1em;
    height: 1em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: astrolink-spin 0.7s linear infinite;
    flex: none;
  }
  @keyframes astrolink-spin {
    to {
      transform: rotate(360deg);
    }
  }

  .btn-group {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
  }

  /* ---- Formulier ----------------------------------------------------------------------------- */
  .field {
    display: grid;
    align-content: start;
    gap: 0.375rem;
    margin-bottom: var(--space-4);
  }
  .field-row {
    display: grid;
    gap: var(--space-4);
    grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
  }
  .field-row > .field {
    margin-bottom: 0;
  }
  .field-row + .field,
  .field-row + .field-row {
    margin-top: var(--space-4);
  }
  .field-hint {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--muted-foreground);
  }
  .field-error {
    display: flex;
    gap: 0.375rem;
    align-items: baseline;
    margin: 0;
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--destructive);
  }
  .field-error::before {
    content: '!';
    flex: none;
    display: inline-grid;
    place-items: center;
    width: 1rem;
    height: 1rem;
    transform: translateY(0.125rem);
    border-radius: 50%;
    background: var(--destructive);
    color: var(--destructive-foreground);
    font-size: 0.6875rem;
    font-weight: 700;
    line-height: 1;
  }
  .field-error:empty {
    display: none;
  }
  label .optional,
  label .required {
    font-weight: 400;
    color: var(--muted-foreground);
  }

  .check {
    display: flex;
    gap: 0.625rem;
    align-items: flex-start;
    font-weight: 500;
    font-size: var(--text-base);
    cursor: pointer;
  }
  .check input {
    margin-top: 0.19rem;
  }
  .check .field-hint {
    font-weight: 400;
  }

  /* Schakelaar: <input type="checkbox" role="switch" class="switch"> */
  input[type='checkbox'].switch {
    appearance: none;
    position: relative;
    width: 2.25rem;
    height: 1.25rem;
    border-radius: 999px;
    background: var(--input);
    transition: background-color 0.15s;
  }
  input[type='checkbox'].switch::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: calc(1.25rem - 4px);
    height: calc(1.25rem - 4px);
    border-radius: 50%;
    background: var(--card);
    box-shadow: var(--shadow-sm);
    transition: transform 0.15s var(--ease);
  }
  input[type='checkbox'].switch:checked {
    background: var(--primary);
  }
  input[type='checkbox'].switch:checked::after {
    transform: translateX(1rem);
  }
  input[type='checkbox'].switch:disabled {
    opacity: 0.5;
  }

  /* Invoer met vast voor- of achtervoegsel, bijvoorbeeld € of .nl */
  .input-group {
    display: flex;
    align-items: stretch;
  }
  .input-group > input {
    flex: 1;
    min-width: 0;
  }
  .input-group > .input-addon {
    display: flex;
    align-items: center;
    padding: 0 0.75rem;
    border: 1px solid var(--input);
    background: var(--muted);
    color: var(--muted-foreground);
    font-size: var(--text-sm);
    white-space: nowrap;
  }
  .input-group > .input-addon:first-child {
    border-right: 0;
    border-radius: var(--radius-md) 0 0 var(--radius-md);
  }
  .input-group > .input-addon:last-child {
    border-left: 0;
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
  }
  .input-group > .input-addon:first-child + input {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
  }
  .input-group > input:has(+ .input-addon) {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
  }

  /* ---- Kaart --------------------------------------------------------------------------------- */
  .card {
    background: var(--card);
    color: var(--card-foreground);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-sm);
    padding: var(--space-5);
  }
  .card > :last-child:not(.card-footer) {
    margin-bottom: 0;
  }
  .card-header {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: var(--space-4);
  }
  .card-header > div > :last-child {
    margin-bottom: 0;
  }
  .card-title {
    margin: 0 0 0.25rem;
    font-size: var(--text-lg);
    font-weight: 650;
    line-height: 1.25;
  }
  .card-description {
    margin: 0;
    color: var(--muted-foreground);
    font-size: var(--text-sm);
  }
  .card-footer {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
    justify-content: flex-end;
    margin: var(--space-5) calc(-1 * var(--space-5)) calc(-1 * var(--space-5));
    padding: var(--space-4) var(--space-5);
    border-top: 1px solid var(--border);
  }
  .card-flush {
    padding: 0;
    overflow: hidden;
  }
  .card-flush > .card-header {
    padding: var(--space-5) var(--space-5) 0;
  }
  .card-flush table tr:last-child td {
    border-bottom: 0;
  }

  /* ---- Kengetal ------------------------------------------------------------------------------ */
  .stat {
    display: grid;
    gap: 0.125rem;
    align-content: start;
  }
  .stat-label {
    font-size: var(--text-sm);
    color: var(--muted-foreground);
  }
  .stat-value {
    font-size: var(--text-2xl);
    font-weight: 650;
    letter-spacing: -0.02em;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
  }
  .stat-delta {
    font-size: var(--text-sm);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--muted-foreground);
  }
  .stat-delta.is-good {
    color: var(--success);
  }
  .stat-delta.is-bad {
    color: var(--destructive);
  }

  /* ---- Badge --------------------------------------------------------------------------------- */
  .badge {
    --badge-bg: var(--secondary);
    --badge-fg: var(--secondary-foreground);
    --badge-border: transparent;
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.125rem 0.5rem;
    border: 1px solid var(--badge-border);
    border-radius: 999px;
    background: var(--badge-bg);
    color: var(--badge-fg);
    font-size: var(--text-xs);
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
    vertical-align: middle;
  }
  .badge-primary {
    --badge-bg: var(--primary-subtle);
    --badge-fg: var(--primary-subtle-foreground);
  }
  .badge-success {
    --badge-bg: var(--success-subtle);
    --badge-fg: var(--success-subtle-foreground);
  }
  .badge-destructive {
    --badge-bg: var(--destructive-subtle);
    --badge-fg: var(--destructive-subtle-foreground);
  }
  .badge-outline {
    --badge-bg: transparent;
    --badge-fg: var(--foreground);
    --badge-border: var(--border);
  }
  .badge-solid {
    --badge-bg: var(--foreground);
    --badge-fg: var(--background);
  }
  /* Stip voor status: kleur is nooit de enige drager, de tekst zegt het ook. */
  .badge-dot::before {
    content: '';
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 50%;
    background: currentColor;
  }

  /* ---- Melding (alert) ----------------------------------------------------------------------- */
  .alert {
    --alert-accent: var(--foreground);
    display: grid;
    gap: 0.25rem;
    position: relative;
    padding: var(--space-3) var(--space-4) var(--space-3) calc(var(--space-4) + 3px);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--card);
    color: var(--card-foreground);
    font-size: var(--text-sm);
    overflow: hidden;
  }
  .alert::before {
    content: '';
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background: var(--alert-accent);
  }
  .alert-title {
    margin: 0;
    font-weight: 650;
    font-size: var(--text-sm);
    line-height: 1.4;
  }
  .alert > p,
  .alert-description {
    margin: 0;
    color: var(--muted-foreground);
  }
  .alert ul {
    margin: 0.25rem 0 0;
    padding-left: 1.1rem;
  }
  .alert-primary {
    --alert-accent: var(--primary);
    background: var(--primary-subtle);
    border-color: color-mix(in oklch, var(--primary) 25%, transparent);
  }
  .alert-primary .alert-title {
    color: var(--primary-subtle-foreground);
  }
  .alert-success {
    --alert-accent: var(--success);
    background: var(--success-subtle);
    border-color: color-mix(in oklch, var(--success) 25%, transparent);
  }
  .alert-success .alert-title {
    color: var(--success-subtle-foreground);
  }
  .alert-destructive {
    --alert-accent: var(--destructive);
    background: var(--destructive-subtle);
    border-color: color-mix(in oklch, var(--destructive) 25%, transparent);
  }
  .alert-destructive .alert-title {
    color: var(--destructive-subtle-foreground);
  }
  .alert-primary > p,
  .alert-success > p,
  .alert-destructive > p,
  .alert-primary .alert-description,
  .alert-success .alert-description,
  .alert-destructive .alert-description {
    color: var(--foreground);
  }
  .alert a {
    color: inherit;
    font-weight: 600;
  }

  /* ---- Tabel --------------------------------------------------------------------------------- */
  .table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .table td {
    vertical-align: middle;
  }
  .table tbody tr {
    transition: background-color 0.1s;
  }
  .table tbody tr:hover {
    background: color-mix(in oklch, var(--muted) 60%, transparent);
  }
  .table tbody tr[aria-selected='true'] {
    background: var(--primary-subtle);
  }
  .table th:first-child,
  .table td:first-child {
    padding-left: var(--space-5);
  }
  .table th:last-child,
  .table td:last-child {
    padding-right: var(--space-5);
  }
  .table .num,
  .table th.num {
    text-align: right;
    white-space: nowrap;
  }
  .table .actions {
    text-align: right;
    white-space: nowrap;
    width: 1%;
  }
  .table .is-negative {
    color: var(--destructive);
  }
  .table .is-positive {
    color: var(--success);
  }
  .table-compact th,
  .table-compact td {
    padding-top: 0.375rem;
    padding-bottom: 0.375rem;
  }

  /* Op telefoonbreedte worden rijen kaartjes. Geef elke <td> een data-label. */
  @media (max-width: 40rem) {
    .table-stack thead {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip-path: inset(50%);
    }
    .table-stack,
    .table-stack tbody,
    .table-stack tr,
    .table-stack td {
      display: block;
      width: 100%;
    }
    .table-stack tr {
      padding: var(--space-3) var(--space-4);
      border-bottom: 1px solid var(--border);
    }
    .table-stack tbody tr:last-child {
      border-bottom: 0;
    }
    .table-stack td,
    .table.table-stack td:first-child,
    .table.table-stack td:last-child {
      display: flex;
      justify-content: space-between;
      gap: var(--space-4);
      padding: 0.2rem 0;
      border: 0;
      text-align: right;
    }
    .table-stack td[data-label]::before {
      content: attr(data-label);
      font-family: var(--font-sans);
      font-size: var(--text-sm);
      color: var(--muted-foreground);
      text-align: left;
      font-weight: 500;
    }
    .table-stack td.table-stack-title {
      font-weight: 650;
      text-align: left;
      padding-bottom: 0.35rem;
    }
    .table-stack td.table-stack-title::before {
      content: none;
    }
    .table-stack td.actions {
      justify-content: flex-start;
      padding-top: var(--space-2);
      width: 100%;
    }
    .table-stack tfoot {
      display: block;
    }
    .table-stack tfoot tr {
      display: flex;
      justify-content: space-between;
      gap: var(--space-4);
      border-top: 1px solid var(--input);
      border-bottom: 0;
    }
    .table-stack tfoot td {
      padding: 0;
      border: 0;
    }
    .table-stack tfoot td:empty {
      display: none;
    }
  }

  /* ---- Feitenlijst --------------------------------------------------------------------------- */
  .facts {
    display: grid;
    grid-template-columns: minmax(8rem, max-content) 1fr;
    gap: var(--space-2) var(--space-5);
    margin: 0;
    font-size: var(--text-sm);
  }
  .facts dt {
    color: var(--muted-foreground);
  }
  .facts dd {
    margin: 0;
    overflow-wrap: anywhere;
  }
  @media (max-width: 30rem) {
    .facts {
      grid-template-columns: 1fr;
      gap: 0;
    }
    .facts dd + dt {
      margin-top: var(--space-3);
    }
  }

  /* ---- Dialoog: native <dialog class="dialog"> ----------------------------------------------- */
  .dialog {
    width: min(32rem, calc(100vw - 2rem));
    max-height: calc(100dvh - 2rem);
    padding: var(--space-5);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    background: var(--popover);
    color: var(--popover-foreground);
    box-shadow: var(--shadow-lg);
    overflow: auto;
  }
  .dialog::backdrop {
    background: var(--overlay);
  }
  .dialog[open] {
    animation: astrolink-pop 0.18s var(--ease);
  }
  .dialog[open]::backdrop {
    animation: astrolink-fade 0.18s ease-out;
  }
  .dialog-header {
    margin-bottom: var(--space-4);
    padding-right: var(--space-6);
  }
  .dialog-title {
    margin: 0 0 0.25rem;
    font-size: var(--text-lg);
    font-weight: 650;
  }
  .dialog-description {
    margin: 0;
    color: var(--muted-foreground);
    font-size: var(--text-sm);
  }
  .dialog-footer {
    display: flex;
    flex-wrap: wrap-reverse;
    gap: var(--space-2);
    justify-content: flex-end;
    margin-top: var(--space-5);
  }
  .dialog-close {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
  }
  .dialog-lg {
    width: min(48rem, calc(100vw - 2rem));
  }
  /* Op telefoonbreedte schuift de dialoog onderin het scherm (bottom sheet), knoppen onder elkaar. */
  @media (max-width: 30rem) {
    .dialog {
      width: 100vw;
      max-width: 100vw;
      margin: auto 0 0;
      border-radius: var(--radius-xl) var(--radius-xl) 0 0;
      border-bottom: 0;
      padding-bottom: calc(var(--space-5) + env(safe-area-inset-bottom));
    }
    .dialog[open] {
      animation: astrolink-sheet 0.22s var(--ease);
    }
    .dialog-footer {
      flex-direction: column-reverse;
    }
    .dialog-footer .btn {
      width: 100%;
    }
  }
  @keyframes astrolink-pop {
    from {
      opacity: 0;
      transform: translateY(6px) scale(0.98);
    }
  }
  @keyframes astrolink-sheet {
    from {
      transform: translateY(100%);
    }
  }
  @keyframes astrolink-fade {
    from {
      opacity: 0;
    }
  }

  /* ---- Toast --------------------------------------------------------------------------------- */
  .toaster {
    position: fixed;
    z-index: 100;
    right: var(--space-4);
    bottom: calc(var(--space-4) + env(safe-area-inset-bottom));
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    width: min(24rem, calc(100vw - 2rem));
    pointer-events: none;
  }
  .toast {
    --toast-accent: transparent;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.125rem var(--space-3);
    align-items: start;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border);
    border-left: 3px solid var(--toast-accent);
    border-radius: var(--radius-lg);
    background: var(--popover);
    color: var(--popover-foreground);
    box-shadow: var(--shadow-lg);
    font-size: var(--text-sm);
    pointer-events: auto;
    animation: astrolink-toast-in 0.22s var(--ease);
  }
  .toast[data-leaving] {
    animation: astrolink-toast-out 0.16s ease-in forwards;
  }
  .toast-title {
    font-weight: 650;
  }
  .toast-description {
    grid-column: 1;
    color: var(--muted-foreground);
  }
  .toast-close {
    grid-column: 2;
    grid-row: 1 / span 2;
    margin: -0.25rem -0.5rem 0 0;
  }
  .toast-success {
    --toast-accent: var(--success);
  }
  .toast-destructive {
    --toast-accent: var(--destructive);
  }
  .toast-primary {
    --toast-accent: var(--primary);
  }
  @media (max-width: 30rem) {
    .toaster {
      left: var(--space-4);
      right: var(--space-4);
      width: auto;
    }
  }
  @keyframes astrolink-toast-in {
    from {
      opacity: 0;
      transform: translateY(8px);
    }
  }
  @keyframes astrolink-toast-out {
    to {
      opacity: 0;
      transform: translateY(4px);
    }
  }

  /* ---- App-kop en navigatie ------------------------------------------------------------------ */
  /* De merkstreep (magenta naar indigo, uit brand/) is het enige niet-functionele kleuraccent. */
  .app-header {
    position: relative;
    background: var(--card);
    border-bottom: 1px solid var(--border);
  }
  .app-header::before {
    content: '';
    display: block;
    height: 3px;
    background: var(--brand-gradient);
  }
  .app-header-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-5);
    max-width: var(--container);
    margin: 0 auto;
    padding: var(--space-3) var(--space-4);
  }
  .app-brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--foreground);
    font-weight: 700;
    letter-spacing: -0.01em;
    text-decoration: none;
  }
  .app-brand img,
  .app-brand svg {
    width: 1.5rem;
    height: 1.5rem;
    border-radius: var(--radius-sm);
  }
  .app-brand-app {
    color: var(--muted-foreground);
    font-weight: 500;
  }
  .app-header-end {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-left: auto;
  }

  .nav {
    display: flex;
    gap: var(--space-1);
    overflow-x: auto;
    scrollbar-width: none;
    max-width: var(--container);
    margin: 0 auto;
    padding: 0 var(--space-4);
  }
  .nav::-webkit-scrollbar {
    display: none;
  }
  .nav a {
    position: relative;
    display: inline-flex;
    align-items: center;
    min-height: var(--control-h);
    padding: 0 0.75rem;
    color: var(--muted-foreground);
    font-size: var(--text-sm);
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
  }
  .nav a:hover {
    color: var(--foreground);
  }
  .nav a[aria-current='page'] {
    color: var(--foreground);
    font-weight: 600;
  }
  .nav a[aria-current='page']::after {
    content: '';
    position: absolute;
    left: 0.75rem;
    right: 0.75rem;
    bottom: -1px;
    height: 2px;
    border-radius: 2px;
    background: var(--foreground);
  }
  .nav a:focus-visible {
    outline-offset: -2px;
  }

  /* Gesegmenteerde keuze (shadcn Tabs-vorm): knoppen met aria-pressed of aria-selected. */
  .segmented {
    display: inline-flex;
    align-self: flex-start;
    gap: 2px;
    padding: 3px;
    border-radius: var(--radius-lg);
    background: var(--muted);
    max-width: 100%;
    overflow-x: auto;
  }
  .segmented > button,
  .segmented > a {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: calc(var(--control-h) - 6px);
    padding: 0 0.75rem;
    border: 0;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--muted-foreground);
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
  }
  .segmented > :hover {
    color: var(--foreground);
  }
  .segmented > [aria-pressed='true'],
  .segmented > [aria-selected='true'],
  .segmented > [aria-current='page'] {
    background: var(--card);
    color: var(--foreground);
    font-weight: 600;
    box-shadow: var(--shadow-md);
  }

  .breadcrumb {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: 0 0 var(--space-3);
    padding: 0;
    list-style: none;
    font-size: var(--text-sm);
    color: var(--muted-foreground);
  }
  .breadcrumb li + li::before {
    content: '/';
    margin-right: var(--space-2);
    color: var(--input);
  }
  .breadcrumb a {
    color: inherit;
    text-decoration: none;
  }
  .breadcrumb a:hover {
    color: var(--foreground);
    text-decoration: underline;
  }
  .breadcrumb [aria-current='page'] {
    color: var(--foreground);
  }

  /* ---- Lege staat ---------------------------------------------------------------------------- */
  .empty {
    display: grid;
    justify-items: center;
    gap: var(--space-2);
    padding: var(--space-7) var(--space-4);
    border: 1px dashed var(--input);
    border-radius: var(--radius-xl);
    text-align: center;
  }
  .empty-icon {
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-bottom: var(--space-1);
    border-radius: var(--radius-lg);
    background: var(--muted);
    color: var(--muted-foreground);
  }
  .empty-icon svg {
    width: 1.25rem;
    height: 1.25rem;
  }
  .empty-title {
    margin: 0;
    font-size: var(--text-base);
    font-weight: 650;
  }
  .empty-description {
    margin: 0 0 var(--space-2);
    max-width: 42ch;
    color: var(--muted-foreground);
    font-size: var(--text-sm);
  }

  /* ---- Laden --------------------------------------------------------------------------------- */
  .skeleton {
    display: block;
    min-height: 1em;
    border-radius: var(--radius-sm);
    background: linear-gradient(90deg, var(--muted) 0 40%, var(--accent) 50%, var(--muted) 60% 100%) 0 0 / 300% 100%;
    animation: astrolink-shimmer 1.4s linear infinite;
  }
  @keyframes astrolink-shimmer {
    to {
      background-position: -150% 0;
    }
  }

  /* ---- Overig -------------------------------------------------------------------------------- */
  .separator {
    border: 0;
    border-top: 1px solid var(--border);
    margin: var(--space-4) 0;
  }
  .skip-link {
    position: absolute;
    z-index: 200;
    left: var(--space-2);
    top: -10rem;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-md);
    background: var(--foreground);
    color: var(--background);
    font-weight: 600;
  }
  .skip-link:focus {
    top: var(--space-2);
  }
}

/* ------------------------------------------------------------------------------------------------
   Opmaak en hulpclasses
   ------------------------------------------------------------------------------------------------ */
@layer astrolink.utilities {
  .container {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--space-4);
  }
  .container-narrow {
    max-width: 44rem;
  }
  .page {
    padding-block: var(--space-5) var(--space-7);
  }
  .page-header {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3) var(--space-4);
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: var(--space-5);
  }
  .page-header > div > :last-child {
    margin-bottom: 0;
  }
  .stack {
    display: flex;
    flex-direction: column;
    gap: var(--stack-gap, var(--space-4));
  }
  .stack > * {
    margin-block: 0;
  }
  .cluster {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cluster-gap, var(--space-2));
    align-items: center;
  }
  .between {
    justify-content: space-between;
  }
  .grid {
    display: grid;
    gap: var(--grid-gap, var(--space-4));
    grid-template-columns: repeat(auto-fit, minmax(min(var(--grid-min, 15rem), 100%), 1fr));
  }

  .muted {
    color: var(--muted-foreground);
  }
  .text-sm {
    font-size: var(--text-sm);
  }
  .text-xs {
    font-size: var(--text-xs);
  }
  .text-primary {
    color: var(--primary);
  }
  .text-success {
    color: var(--success);
  }
  .text-destructive {
    color: var(--destructive);
  }
  .num {
    font-variant-numeric: tabular-nums;
    text-align: right;
  }
  .mono {
    font-family: var(--font-mono);
    font-size: 0.9em;
  }
  .nowrap {
    white-space: nowrap;
  }
  .break {
    overflow-wrap: anywhere;
  }
  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
  @media (max-width: 40rem) {
    .hide-sm {
      display: none !important;
    }
  }
  [hidden] {
    display: none !important;
  }
}
