/* Self-hosted fonts (Fase 1) — Inter, Outfit, JetBrains Mono.
   Latin + Latin-ext (dekt NL/EN/TR incl. ş/ğ/ı). Geen externe
   Google-call meer: sneller (geen render-block) en AVG-vriendelijk. */
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('/static/fonts/Inter-400-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-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('/static/fonts/Inter-400-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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('/static/fonts/Inter-500-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-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('/static/fonts/Inter-500-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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('/static/fonts/Inter-600-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-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('/static/fonts/Inter-600-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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url('/static/fonts/Inter-700-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-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url('/static/fonts/Inter-700-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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/static/fonts/JetBrainsMono-400-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-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/static/fonts/JetBrainsMono-400-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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;src:url('/static/fonts/JetBrainsMono-500-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-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;src:url('/static/fonts/JetBrainsMono-500-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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:700;font-display:swap;src:url('/static/fonts/JetBrainsMono-700-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-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:700;font-display:swap;src:url('/static/fonts/JetBrainsMono-700-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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Outfit';font-style:normal;font-weight:500;font-display:swap;src:url('/static/fonts/Outfit-500-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-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Outfit';font-style:normal;font-weight:500;font-display:swap;src:url('/static/fonts/Outfit-500-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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Outfit';font-style:normal;font-weight:600;font-display:swap;src:url('/static/fonts/Outfit-600-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-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Outfit';font-style:normal;font-weight:600;font-display:swap;src:url('/static/fonts/Outfit-600-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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Outfit';font-style:normal;font-weight:700;font-display:swap;src:url('/static/fonts/Outfit-700-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-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Outfit';font-style:normal;font-weight:700;font-display:swap;src:url('/static/fonts/Outfit-700-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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Outfit';font-style:normal;font-weight:800;font-display:swap;src:url('/static/fonts/Outfit-800-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-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Outfit';font-style:normal;font-weight:800;font-display:swap;src:url('/static/fonts/Outfit-800-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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}

/* ═══ De tokenbron van het PANEEL — één blok ════════════════════════════════
   Tot 29 juli 2026 stonden deze 33 tokens verspreid over VIER :root-blokken in dit
   bestand (regel 27, 2984, 3629 en 4112). Dat is geen stijlkwestie: wie een waarde
   zocht vond blok 1, zag daar geen --card, en verzon er een. Zo ontstond de drift
   die `tools/drift.py` meet. Ze zijn hier samengevoegd zonder één waarde te wijzigen
   — gemeten vóór de ingreep: alle 33 namen zijn disjunct verdeeld, geen enkele naam
   stond twee keer, dus de cascade kan geen andere uitkomst geven dan hiervoor.

   Dit blok is NIET de merkbron. Die staat in merk.css, en de paneelschermen
   (home.html, index.html, login…) laden merk.css bewust niet — zie de slotalinea
   van merk.css voor de meting die daaraan ten grondslag ligt. ═══════════════ */
:root {
  color-scheme: dark;

  /* ── Merk en status ─────────────────────────────────────────────────────── */
  --accent: var(--ch-paars, #5b8cff);
  --accent-rgb: 91, 140, 255;
  --accent2: #7aa2ff;
  --green: #10b981;
  --green-rgb: 16, 185, 129;
  --red: #f0594f;
  /* Toegankelijke varianten: alleen als ACHTERGROND onder witte tekst.
     De merkkleuren hierboven halen met wit geen 4,5:1 (WCAG AA). Als tekst-
     of randkleur op donker blijven de originelen gewoon in gebruik. */
  --accent-diep: #3D6BD6;   /* 4,92:1 met wit */
  --rood-diep:   #CC3328;   /* 5,16:1 */
  --groen-diep:  #1A7F50;   /* 5,01:1 */
  --red-rgb: 240, 89, 79;
  --yellow: #f59e0b;
  --yellow-rgb: 245, 158, 11;
  --amber: #e0a83f;

  /* ── Randen van bedieningselementen (stond op regel 2984) ───────────────────
     WCAG 1.4.11 eist 3:1 voor de RAND van een bedieningselement. Onze invoervelden
     hadden rgba(255,255,255,.05) — dat is ~1,3:1: je ziet niet waar het veld begint.
     WCAG 1.4.3 eist 4,5:1 voor tekst. Wit op #f87171 haalt 3,8:1 — dus de massieve
     rode knop wordt #DC2626 (4,8:1). */
  --border-interactive: #5d6779;   /* 3,2:1 op de kaartachtergrond */
  --danger-solid: #dc2626;         /* wit hierop: 4,8:1 */
  /* Fout-rood als TEKST/accent op donker. Zelfde naam en waarde als in merk.css, en
     dat is bewust: componenten.css (`.statuschip-fout`, `.veld-fout`) draait zowel op
     klantschermen die merk.css laden als in het adminpaneel en de statuspagina, die
     alleen dit bestand laden. Eén naam, twee bronnen — een tweede NAAM voor hetzelfde
     begrip is juist de drift die we opruimen. */
  --rood-l: #F0776B;
  /* Wit als TEKST of ICOON op een gekleurd vlak. Om precies dezelfde reden als
     --rood-l hierboven onder DEZELFDE naam en waarde als in merk.css: dit bestand
     draait op home.html, index.html en login.html, en die laden merk.css niet — een
     token dat daar niet bestaat is geen kleur maar een kapotte declaratie.
     Gemeten 29 juli 2026: `#fff` stond 70 keer los in dit bestand (64x als `color`,
     5x als achtergrond, 1x als randkleur). Dat is ruim boven de vuistregel "drie keer
     of vaker wordt een token", en het is de grootste enkele kleur in het bestand. */
  --wit: #fff;

  /* ── Oppervlakken (stond op regel 3629) ─────────────────────────────────────
     Solide, en de kaart precies +9..+12 lichter dan het canvas (de band die
     Vercel/Linear/Railway/Supabase/Coolify allemaal aanhouden). */
  --bg: #0B0D13;
  --surface: #14161F;
  --surface-solid: #14161F;
  --surface2: #191C26;
  --surface2-solid: #191C26;
  --card: #14161F;
  --card-solid: #14161F;

  /* De rand doet het werk: 1,26 contrast op de kaart (was 1,12). */
  --border: #262A36;
  --border-strong: #333847;
  --border-hover: #3f465a;

  --text: #E6E8EF;
  --muted: #99A1B3;

  /* Geen kaartschaduw meer — alleen zwevende dingen (menu, modal) krijgen diepte. */
  --shadow-card: none;
  --shadow-btn: none;
  --shadow-btn-hover: none;

  /* ── De oppervlakteladder (stond op regel 4112) ─────────────────────────── */
  --lift-1: inset 0 1px 0 0 rgba(255,255,255,.06);   /* lichtrand bovenop */
  --hair:   0 0 0 1px rgba(255,255,255,.07);         /* haarlijn rondom */
  --hair-h: 0 0 0 1px rgba(255,255,255,.12);         /* haarlijn bij hover */
}

* {
  box-sizing: border-box;
}

/* Het hidden-attribuut moet ALTIJD verbergen. De UA-regel [hidden]{display:none}
   heeft specificiteit 0-0-0 en wordt verslagen door élke class die display zet
   (bv. .ik-waarschuwing{display:flex} of .help-drawer). Zonder deze bron-regel
   toont zo'n element toch — dat lekte de "2FA verplicht"-banner naar iedereen op
   de profielpagina. Dit dekt de hele klasse in één keer; het juiste manier om te
   tonen is het attribuut wegnemen (JS/Jinja), niet display in CSS overschrijven. */
[hidden] { display: none !important; }

/* Bestel-voortgangschips (portal_order): sticky stap-oriëntatie boven het formulier
   — de klant ziet waar hij is (Spel → Pakket → Software → Naam → Gegevens) en kan
   naar een stap springen. Kleuren: tekst op de donkere pagina (veilig contrast),
   het cijfer-badge gebruikt de diepe tokens voor witte tekst. */
.order-chips {
  position: sticky; top: 0; z-index: 30;
  display: flex; gap: 6px; flex-wrap: wrap;
  padding: 10px 0 8px; margin: 0 0 8px;
  background: #0c0d14; border-bottom: 1px solid rgba(255, 255, 255, .06);
}
.order-chip {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 44px; padding: 8px 14px; border-radius: 999px;   /* 44px = WCAG 2.5.5 aanraakvlak */
  border: 1px solid rgba(255, 255, 255, .12); background: rgba(255, 255, 255, .03);
  color: #b8bccc; font-size: 12px; font-weight: 600; cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.order-chip .oc-n {
  display: inline-flex; width: 18px; height: 18px; border-radius: 50%;
  align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .14); color: #eef0f6; font-size: 10.5px; font-weight: 700;
}
.order-chip.done { color: #4ad991; border-color: rgba(63, 201, 122, .45); }
.order-chip.done .oc-n { background: var(--groen-diep, #15794a); color: var(--wit); }
.order-chip.active { color: #eef0f6; border-color: var(--ch-knop, #3a63c9); }
.order-chip.active .oc-n { background: var(--ch-knop, #3a63c9); color: var(--wit); }
@media (max-width: 520px) { .order-chip { font-size: 11px; padding: 5px 10px; gap: 6px; } }

/* Globale skeleton-shimmer — herbruikbaar BUITEN .server-page (bv. home.html /
   klantportaal, die .dashboard-page zijn). De bestaande .skel zat gescoped op
   .server-page met een ongeldig genest @keyframes; dit is de valide, globale
   versie zodat admin-/klantlijsten een nette laadstaat tonen i.p.v. "Laden…". */
@keyframes skelShimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
.skel {
  display: inline-block; border-radius: 6px; color: transparent !important;
  background: linear-gradient(90deg, rgba(255,255,255,.05) 25%, rgba(255,255,255,.11) 37%, rgba(255,255,255,.05) 63%);
  background-size: 400% 100%; animation: skelShimmer 1.3s ease infinite;
}
.skel-card { display: block; height: 74px; border-radius: 12px; border: 1px solid var(--border, rgba(255,255,255,.08)); }
@media (prefers-reduced-motion: reduce) { .skel { animation: none; } }

/* Margin and padding reset only for pages that originally used it (zero specificity wrapper) */
:where(body.dashboard-page, body.portal-order-page, body.portal-return-page, body.profile-page) :where(*) {
  margin: 0;
  padding: 0;
}
:where(body.dashboard-page, body.portal-order-page, body.portal-return-page, body.profile-page) {
  margin: 0;
  padding: 0;
}

html {
  width: 100%;
  /* Terugval: browsers zonder `clip` (Safari < 16) houden het oude gedrag —
     daar blijft de sticky-bug bestaan, maar niets breekt. */
  overflow-x: hidden;
  /* clip i.p.v. hidden: allebei blokkeren zijwaarts schuiven, maar `hidden` maakt
     hiervan een scroll-container en dan werkt `position: sticky` op alles
     eronder NIET meer. Daardoor scrolde de mobiele kopbalk met de menuknop (☰)
     uit beeld en leek het serverpaneel op een telefoon geen navigatie te hebben
     (runtime gemeten, review 25 juli 2026). */
  overflow-x: clip;
  scroll-behavior: smooth;
}

body {
  background:
    radial-gradient(1000px 600px at 10% -10%, rgba(var(--accent-rgb), 0.08), transparent 60%),
    radial-gradient(800px 500px at 95% 10%, rgba(var(--green-rgb), 0.04), transparent 50%),
    radial-gradient(700px 600px at 50% 90%, rgba(91, 140, 255, 0.03), transparent 60%),
    var(--bg);
  color: var(--text);
  font-family: 'Inter', -apple-system, sans-serif;
  min-height: 100vh;
  overflow-x: hidden;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

body.server-page {
  padding: 24px;
}
@media (max-width: 768px) {
  body.server-page {
    padding: 12px;
  }
}
@media (max-width: 360px) {
  body.server-page {
    padding: 9px;
  }
}

body.auth-page {
  padding: 16px;
}

/* ── Typography updates ── */
h1, h2, h3, h4, .logo, .brand-cave {
  font-family: 'Outfit', sans-serif;
  letter-spacing: -0.01em;
}

h1 {
  font-size: 24px;
  font-weight: 700;
  color: var(--wit);
  display: flex;
  align-items: center;
  gap: 10px;
}

/* ── Custom Scrollbar ── */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.15);
}
::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.08);
  border-radius: 99px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.16);
  border-radius: 99px;
  border: 2px solid transparent;
  background-clip: padding-box;
}

/* ── Glassmorphism Common ── */
.glass {
  background: var(--card);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--border);
}

/* ── Modals & Toasts (SaaS Kit) ── */
@keyframes caveToastOut {
  to { opacity: 0; transform: translateX(35px) scale(0.95); }
}

.cave-modal-ov {
  position: fixed;
  inset: 0;
  z-index: 14000;
  background: rgba(4, 5, 9, 0.68);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  animation: caveFade .2s ease;
}
@keyframes caveFade {
  from { opacity: 0; }
  to { opacity: 1; }
}
.cave-modal {
  background: linear-gradient(165deg, rgba(26, 28, 40, 0.75), rgba(20, 22, 32, 0.5));
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border: 1px solid var(--border-strong);
  border-radius: 18px;
  width: 100%;
  max-width: 440px;
  padding: 26px;
  box-shadow: 0 32px 70px rgba(0, 0, 0, 0.6), 0 1px 0 rgba(255, 255, 255, 0.05) inset;
  animation: caveModalIn .26s cubic-bezier(.2, .8, .2, 1);
  position: relative;
}
@keyframes caveModalIn {
  from { opacity: 0; transform: translateY(16px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
/* Bevestiging MET opmaak (opts.html): radio's, invoervelden, <strong>. Bewust een eigen
   blok i.p.v. de <p>: HTML met <p>/<label> erin mag niet in een alinea staan (de browser
   sluit die dan vroegtijdig) en pre-wrap zou de bronopmaak van de HTML-string tonen. */
.cave-modal-body {
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--muted, #9a9db0);
  margin: 0 0 16px;
}
.cave-modal-body p { margin: 0 0 8px; }
.cave-modal-body input[type="text"],
.cave-modal-body input:not([type]) { margin-bottom: 0; }
.cave-modal h3 {
  font-size: 18px;
  font-weight: 700;
  margin-bottom: 14px;
  color: var(--wit);
  display: flex;
  align-items: center;
  gap: 8px;
}
.cave-modal-btns {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 24px;
}


/* ── Interactive Layout Shell (Sidebar) ── */
.shell-container {
  display: flex;
  min-height: 100vh;
}

.shell-sidebar {
  width: 260px;
  background: rgba(12, 13, 20, 0.85);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-right: 1px solid var(--border);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: sticky;
  top: 0;
  height: 100vh;
  flex-shrink: 0;
  z-index: 100;
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
  /* Melding Cihan 24 jul: op 100% viel de ONDERKANT (Profiel/taal/gebruiker) buiten
     beeld — de HELE zijbalk scrollde, dus de footer zakte onder de vouw. Nu scrollt
     alleen het nav-menu (.sidebar-menu, flex:1 + overflow), en blijven logo (boven)
     en footer (onder) altijd zichtbaar. De zijbalk zelf scrollt niet meer.
     LET OP de eerdere les (390x844): het MENU moet blijven scrollen zodat de onderste
     items (Marktmonitor/Kennisbank) bereikbaar blijven — dat doet .sidebar-menu nu.
     Geldt voor hoofdpaneel én serverpaneel — beide gebruiken .shell-sidebar. */
  overflow: hidden;
  overscroll-behavior: contain;
}

.shell-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* Sidebar Navigation Items */
.sidebar-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  font-size: 19px;
  font-weight: 800;
  color: var(--wit);
  padding: 4px 6px;
  border-radius: 8px;
}
.sidebar-logo img {
  border-radius: 7px;
  box-shadow: 0 4px 12px rgba(var(--accent-rgb), 0.25);
}

.sidebar-menu {
  display: flex;
  flex-direction: column;
  gap: 5px;
  list-style: none;
  margin: 0;
  padding: 0;
  /* Alleen het nav-menu scrollt; logo (boven) + footer (onder) blijven vast in beeld.
     min-height:0 is essentieel — zonder dat weigert een flex-kind te krimpen onder z'n
     inhoud en scrolt het niet (dan zou de footer alsnog wegvallen). */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Ruimte voor de scrollbalk zodat die de tekst niet overlapt. */
  margin-right: -6px;
  padding-right: 6px;
}
.sidebar-menu::-webkit-scrollbar { width: 7px; }
.sidebar-menu::-webkit-scrollbar-thumb { background: rgba(255,255,255,.10); border-radius: 4px; }
.sidebar-menu::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.18); }
/* Groepskopje: tien losse tabs werden vier groepen (Klanten / Diensten / Onze
   etalage / Systeem). Rustig en klein — het is een wegwijzer, geen knop. */
.sidebar-groep {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 14px 12px 4px;
}
.sidebar-groep:first-child {
  padding-top: 2px;
}
.sidebar-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  color: var(--muted);
  text-decoration: none;
  border-radius: 9px;
  font-size: 13.5px;
  font-weight: 500;
  transition: all 0.2s;
}
.sidebar-link:hover, .sidebar-link.active {
  color: var(--wit);
  background: rgba(255, 255, 255, 0.04);
}
.sidebar-link.active {
  background: rgba(var(--accent-rgb), 0.08);
  border: 1px solid rgba(var(--accent-rgb), 0.15);
  color: var(--accent2);
}
.sidebar-link .icon {
  font-size: 17px;
  width: 22px;
  flex-shrink: 0;
  text-align: center;
  line-height: 1;
}

/* "Terug naar servers" — subtiele pill-knop i.p.v. kale tekstlink */
.servers-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 9px;
  padding: 6px 11px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: color .18s, background .18s, border-color .18s, transform .18s;
}
.servers-link:hover {
  color: var(--wit);
  background: rgba(var(--accent-rgb), 0.1);
  border-color: rgba(var(--accent-rgb), 0.3);
  transform: translateX(-2px);
}

/* Mobiele sidebar: backdrop om te sluiten + eigen sluitknop */
.sidebar-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  z-index: 98;
  opacity: 0;
  transition: opacity 0.25s;
}
.sidebar-close {
  display: none;
}

/* ── Topbar (Fallback/Secondary) ── */
.topbar {
  background: rgba(12, 13, 20, 0.7);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
  padding: 0 24px;
  height: 60px;
  display: none;
  align-items: center;
  gap: 16px;
  position: sticky;
  top: 0;
  z-index: 99;
}
/* Menuknop (☰): op een telefoon de ENIGE weg naar Wereld/Spelers/Bestanden, dus ruim
   aanraakbaar (WCAG 2.5.5). Was 34px — review 25 juli 2026. */
/* body.server-page vóór de selector: `body.server-page .btn-sm { min-height: 34px }`
   verderop is specifieker dan `.topbar .menu-knop` en won anders (runtime gemeten:
   computed min-height bleef 34px terwijl min-width wél 44 werd). */
body.server-page .topbar .menu-knop,
.topbar .menu-knop {
  min-width: 44px;
  min-height: 44px;
  padding: 0 12px;
  background: transparent;
  border-color: transparent;
  font-size: 18px;
  line-height: 1;
}
.topbar .logo {
  font-size: 17px;
  font-weight: 800;
  color: var(--wit);
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
}
.topbar .logo img {
  border-radius: 6px;
}

.user-badge {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--muted);
}
.user-badge strong {
  color: var(--text);
}

.lang-switch {
  background: var(--surface2-solid);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 12px;
  cursor: pointer;
  outline: none;
  transition: border-color 0.15s;
}
.lang-switch:focus {
  border-color: var(--accent);
}

/* ── Page Layout & Grid ── */
.main {
  max-width: 1240px;
  width: 100%;
  margin: 0 auto;
  padding: 32px 24px;
}

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 28px;
  flex-wrap: wrap;
  gap: 14px;
}
.page-header h1 {
  font-size: 24px;
  font-weight: 700;
}
.page-header p {
  color: var(--muted);
  font-size: 13px;
  margin-top: 2px;
}

/* ── Premium Buttons ── */
button, .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 9px;
  border: none;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--shadow-btn);
  transition: transform 0.15s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.15s, filter 0.15s;
  color: var(--wit);
}
button:hover:not(:disabled), .btn:hover:not(:disabled) {
  filter: brightness(1.08);
  box-shadow: var(--shadow-btn-hover);
  transform: translateY(-1.5px);
}
button:active:not(:disabled), .btn:active:not(:disabled) {
  transform: translateY(0);
  filter: brightness(0.95);
  box-shadow: 0 1px 2px rgba(0,0,0,0.4) inset;
}
button:disabled, .btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  transform: none !important;
  box-shadow: none !important;
  filter: none !important;
}

/* De KNOPVARIANTEN stonden hier (en nog drie keer verderop in dit bestand, met
   onderling verschillende waarden). Ze zijn op 30 juli 2026 verhuisd naar
   `componenten.css`, sectie "KNOPPEN — één familie, vier betekenissen" (§7b).
   Niet doorgehaald maar VERWIJDERD: `componenten.css` laadt in élk paneelscherm ná dit
   bestand en weegt even zwaar (0,1,0), dus deze regels konden per definitie niets meer
   doen. Ze laten staan zou de volgende sessie laten zoeken naar een regel die niet
   meer werkt — precies de drift die deze commit opruimt.
   De MATEN (`.btn-sm`/`.btn-xs`/`.btn-lg`) blijven hier: die zijn paneel-specifiek. */
.btn-sm {
  padding: 6px 12px;
  font-size: 11.5px;
  border-radius: 7px;
}

/* ── Premium Cards ── */
.server-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  gap: 20px;
}

.server-card, .card {
  background: linear-gradient(160deg, var(--card), rgba(20, 22, 33, 0.3));
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--border);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.2s, box-shadow 0.2s;
  margin-bottom: 16px;
}
.server-card:hover, .card:hover {
  transform: translateY(-3px);
  border-color: var(--border-hover);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45), 0 0 15px rgba(var(--accent-rgb), 0.05);
}

.card-header, .card h2 {
  padding: 16px 20px;
  display: flex;
  align-items: center;
  gap: 12px;
  border-bottom: 1px solid var(--border);
  background: linear-gradient(135deg, rgba(255,255,255,.02), transparent);
}
.card h2 {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted);
  font-weight: 700;
  margin: 0;
  justify-content: space-between;
}
.card h2 button:not(.btn-primary):not(.btn-green):not(.btn-red) {
  background: none;
  border: none;
  color: var(--accent2);
  cursor: pointer;
  font-size: 11.5px;
  font-weight: 600;
  padding: 4px 8px;
  border-radius: 6px;
  box-shadow: none;
  transform: none !important;
}
.card h2 button:hover {
  background: rgba(91,140,255,.12);
  filter: none;
}

.card-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  flex-shrink: 0;
  box-shadow: 0 4px 10px rgba(0,0,0,0.15);
}

.card-title {
  flex: 1;
  min-width: 0;
}
.card-title h3 {
  font-size: 14.5px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--wit);
}
.card-title p {
  font-size: 11.5px;
  color: var(--muted);
  margin-top: 1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Status Indicator Glows ── */
.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
  position: relative;
}
.status-dot.online, .status-dot.on {
  background: var(--green);
  box-shadow: 0 0 10px rgba(var(--green-rgb), 0.7);
  animation: status-pulse 2s infinite;
}
.status-dot.offline, .status-dot.off {
  background: #3c3d47;
  box-shadow: none;
}
.status-dot.loading {
  background: var(--yellow);
  box-shadow: 0 0 10px rgba(var(--yellow-rgb), 0.7);
  animation: status-pulse 1s infinite;
}
@keyframes status-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.55; transform: scale(0.92); }
}

.card-body {
  padding: 18px 20px;
}

/* ═══ Kaarten zonder kop of body kregen NUL padding ════════════════════════════
   `.card` heeft in het adminpaneel zelf geen padding: die komt uit `.card-header` /
   `.card h2` (16/20px) en `.card-body` (18/20px). Een kaart die zijn inhoud er
   RECHTSTREEKS in zet, kreeg dus niets — en omdat `.card` ook `border-radius:16px`
   plus `overflow:hidden` heeft, snijdt de afgeronde hoek de eerste regel aan. Zo
   hingen de koppen "Servers" / "Nodes" / "Incidenten" half over de kaartrand
   (melding Cihan, 31 juli 2026); op de Algemeen-tab deden vijf kaarten hetzelfde.

   Dit is bewust een `:has()`-regel en geen lijstje klassen: een lijst dekt de
   kaarten van vandaag en niet die van morgen, en dit is precies het soort
   opmaakfout dat niemand meldt tot hij lelijk wordt. Kaarten die hun padding al
   uit een kop of body halen worden overgeslagen, dus er ontstaat nergens dubbele
   lucht. Kent een browser `:has()` niet, dan valt de regel weg en is het beeld
   hooguit zoals het vóór deze fix al was — nooit slechter.
   Het serverpaneel en /profile zetten hun eigen `.card`-padding en blijven buiten
   schot. ═══════════════════════════════════════════════════════════════════════ */
body:not(.server-page):not(.profile-page) .card:not(:has(> .card-header)):not(:has(> h2)):not(:has(> .card-body)) {
  padding: 18px 20px;
}

.stat-row, .row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  font-size: 12.5px;
  color: var(--muted);
}
.stat-row .value, .row span:last-child {
  font-weight: 600;
  color: var(--text);
  text-align: right;
  overflow-wrap: anywhere;
}
.stat-row .value.online {
  color: var(--green);
}
.stat-row .value.offline {
  color: var(--muted);
}

/* ── Resource Meters ── */
.resource-bar {
  margin-bottom: 12px;
}
.resource-bar .bar-label {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--muted);
  margin-bottom: 4px;
}
.bar-track {
  height: 6px;
  background: rgba(0, 0, 0, 0.25);
  border-radius: 4px;
  overflow: hidden;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.3);
}
.bar-fill {
  height: 100%;
  border-radius: 4px;
  transition: width 0.5s cubic-bezier(0.1, 0.8, 0.2, 1);
}
.bar-fill.cpu, .hh-fill.cpu {
  background: linear-gradient(90deg, #60a5fa, var(--accent));
  box-shadow: 0 0 8px rgba(var(--accent-rgb), 0.45);
}
.bar-fill.ram, .hh-fill.ram {
  background: linear-gradient(90deg, #34d399, var(--green));
  box-shadow: 0 0 8px rgba(var(--green-rgb), 0.45);
}
.bar-fill.disk, .hh-fill.disk {
  background: linear-gradient(90deg, #fbbf24, var(--yellow));
  box-shadow: 0 0 8px rgba(var(--yellow-rgb), 0.45);
}
.bar-fill.warn {
  background: linear-gradient(90deg, #f87171, var(--red));
  box-shadow: 0 0 8px rgba(var(--red-rgb), 0.45);
}

.card-footer {
  padding: 12px 20px;
  border-top: 1px solid var(--border);
  display: flex;
  gap: 8px;
  align-items: center;
  /* Wrap als vangnet: liever de knoppen op een tweede regel dan 'Openen' van de
     kaart af geknipt. row-gap zorgt dat een tweede regel niet tegen de eerste plakt. */
  flex-wrap: wrap;
  row-gap: 8px;
  background: rgba(0,0,0,0.05);
}
/* De spacer duwt de knoppen naar rechts op de eerste regel. Bij wrap krijgt de
   knoppengroep zijn eigen regel; daarom houden de knoppen zelf hun natuurlijke maat. */
.card-footer .spacer {
  flex: 1 1 0;
  min-width: 0;
}
.card-footer .btn { flex: 0 0 auto; }
.port-badge {
  font-size: 11px;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  padding: 3px 8px;
  border-radius: 6px;
  font-family: ui-monospace, SFMono-Regular, monospace;
}

/* ── Modals & Popups ── */
.modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(4, 5, 10, 0.75);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  z-index: 1000;
  align-items: center;
  justify-content: center;
  padding: 16px;
  animation: modal-fadein 0.2s ease;
}
.modal-overlay.open {
  display: flex;
}

.modal-box, .modal {
  background: linear-gradient(165deg, var(--surface-solid), var(--bg));
  border: 1px solid var(--border-strong);
  border-radius: 18px;
  width: 100%;
  max-width: 520px;
  max-height: 85vh;
  overflow-y: auto;
  box-shadow: 0 24px 70px rgba(0,0,0,0.65), 0 1px 0 rgba(255,255,255,0.05) inset;
  position: relative;
  animation: modal-slideup 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.modal-box.wide {
  max-width: 760px;
}
@keyframes modal-fadein {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes modal-slideup {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.modal-head {
  padding: 18px 24px;
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: rgba(255,255,255,0.01);
}
.modal-head h2, .modal-box h3 {
  font-size: 16px;
  font-weight: 700;
  color: var(--wit);
}
.modal-close, .modal-close-x {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 20px;
  cursor: pointer;
  padding: 4px;
  line-height: 1;
  box-shadow: none !important;
  transform: none !important;
}
.modal-close:hover, .modal-close-x:hover {
  color: var(--wit);
}
.modal-body {
  padding: 24px;
}
.modal-footer {
  padding: 16px 24px;
  border-top: 1px solid var(--border);
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  background: rgba(0, 0, 0, 0.1);
}

/* ── Premium Forms & Inputs ── */
.field {
  margin-bottom: 16px;
}
.field label {
  display: block;
  font-size: 11.5px;
  color: var(--muted);
  margin-bottom: 6px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
/* "♾ oneindig"-badge: eigen element ONDER de invoerregel (niet in het uppercase-
   label, dat maakte het loud + brak over twee regels). nowrap → geen lelijke wrap;
   wordt-ie ooit te breed dan is dat overflow die de modal-check vangt. */
.oneindig-badge {
  margin-top: 8px;
  font-size: 12px;
  font-weight: 700;
  color: var(--green);
  text-transform: none;
  letter-spacing: 0;
  white-space: nowrap;
}
/* Versie-dropdown op de modpack-kaart (Modpacks-tab) — echte klasse i.p.v. inline
   stijl, zodat de opmaak niet stil terugvalt op de browser-default (ui_check). */
.mp-ver {
  font-size: 12px;
  padding: 6px 8px;
  border-radius: 8px;
  border: 1px solid var(--border-strong);
  background: rgba(0, 0, 0, 0.25);
  color: var(--wit);
  max-width: 200px;
}
/* "Bedrock-skins herstellen" bij het serveradres — voor servers van vóór de
   automatische installatie (nieuwe servers krijgen de skin-plugin bij provisioning). */
.bedrock-skins {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px 0 2px;
}
.bedrock-skins-hint {
  font-size: 11.5px;
  color: var(--muted);
  line-height: 1.4;
}
.field input, .field select, .field textarea, .setting-field input, .setting-field select, .cmdrow input {
  width: 100%;
  padding: 11px 14px;
  border-radius: 9px;
  border: 1px solid var(--border-strong);
  background: rgba(0, 0, 0, 0.25);
  color: var(--wit);
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.field input:focus, .field select:focus, .field textarea:focus,
.setting-field input:focus, .setting-field select:focus, .cmdrow input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.15);
}
.field input.invalid {
  border-color: var(--red) !important;
  box-shadow: 0 0 0 3px rgba(var(--red-rgb), 0.15) !important;
}
.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.field-hint, .setting-help {
  font-size: 11.5px;
  color: var(--muted);
  margin-top: 5px;
  line-height: 1.45;
}
.field-error {
  font-size: 11px;
  color: var(--red);
  margin-top: 5px;
}
.field-required {
  color: var(--red);
  margin-left: 2px;
}

/* ── Install Templates Grid ── */
.install-template-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 10px;
}
.install-template-card {
  min-height: 80px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: rgba(255,255,255,0.02);
  color: var(--text);
  cursor: pointer;
  padding: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  text-align: center;
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
.install-template-card:hover {
  border-color: var(--border-hover);
  background: rgba(255,255,255,0.04);
  transform: translateY(-1px);
}
.install-template-card.active {
  border-color: var(--accent);
  background: rgba(var(--accent-rgb), 0.12);
  box-shadow: 0 0 10px rgba(var(--accent-rgb), 0.05);
}
.install-template-icon {
  font-size: 22px;
}
.install-template-title {
  font-size: 11px;
  font-weight: 700;
}
.install-template-sub {
  font-size: 9.5px;
  color: var(--muted);
}

/* ── Interactive Tabs ── */
.tabs {
  display: flex;
  gap: 6px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 28px;
}
.tabs button {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 13.5px;
  font-weight: 600;
  padding: 10px 16px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  box-shadow: none;
  border-radius: 0;
  transform: none !important;
}
.tabs button:hover:not(.active) {
  color: var(--text);
}
.tabs button.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.tabview {
  display: none;
}
.tabview.active {
  display: block;
  animation: tab-fade 0.22s ease-out;
}
@keyframes tab-fade {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ── Tables & Lists ── */
.user-table, table.filetable {
  width: 100%;
  border-collapse: collapse;
}
.user-table th, table.filetable th {
  text-align: left;
  padding: 12px;
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid var(--border);
}
.user-table td, table.filetable td {
  padding: 12px;
  border-bottom: 1px solid rgba(255,255,255,0.03);
  vertical-align: middle;
}
.user-table tr:hover td, table.filetable tr:hover td {
  background: rgba(255,255,255,0.015);
}

/* ── Server Control Elements ── */
.state-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--surface2);
  border: 1px solid var(--border);
  padding: 6px 14px;
  border-radius: 20px;
  font-size: 12.5px;
  color: var(--muted);
  font-weight: 600;
}

.health-hero {
  background: linear-gradient(160deg, rgba(20, 22, 33, 0.65), rgba(15, 16, 26, 0.45));
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 20px 24px;
  margin-bottom: 20px;
  box-shadow: var(--shadow-card);
}
.hh-main {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}
.hh-status {
  display: flex;
  align-items: center;
  gap: 14px;
}
.hh-badge {
  font-size: 20px;
  font-weight: 800;
  color: var(--wit);
}
.hh-address {
  margin-left: 8px;
  cursor: pointer;
  padding: 8px 16px;
  border-radius: 10px;
  background: rgba(var(--accent-rgb), 0.08);
  border: 1px solid rgba(var(--accent-rgb), 0.15);
  transition: all 0.2s;
}
.hh-address:hover {
  background: rgba(var(--accent-rgb), 0.14);
}
.hh-addr-label {
  display: block;
  font-size: 9.5px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
}
.hh-addr-val {
  display: block;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--accent2);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.hh-actions {
  margin-left: auto;
  display: flex;
  gap: 8px;
}
.hh-meters {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-top: 20px;
}
.hh-m-top {
  display: flex;
  justify-content: space-between;
  font-size: 11.5px;
  color: var(--muted);
  margin-bottom: 5px;
}
.hh-m-top span:last-child {
  color: var(--wit);
  font-weight: 700;
}
.hh-bar {
  height: 6px;
  background: rgba(0, 0, 0, 0.25);
  border-radius: 4px;
  overflow: hidden;
}

/* ── Terminal Emulator (Console) ── */
#log {
  background: #06070a;
  border: 1px solid var(--border-strong);
  border-radius: 12px;
  padding: 16px;
  height: 380px;
  overflow-y: auto;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12.5px;
  white-space: pre-wrap;
  line-height: 1.6;
  box-shadow: inset 0 3px 12px rgba(0,0,0,0.6);
  color: #cdd2e0;
}
#log mark {
  background: rgba(245, 158, 11, 0.25);
  color: var(--wit);
  border-radius: 3px;
  padding: 0 2px;
}

/* Syntax coloring helpers for console lines */
.log-info { color: #8fa1c4; }
.log-warn { color: var(--yellow); font-weight: 500; }
.log-error { color: #f0594f; font-weight: 600; }

.cmdrow {
  display: flex;
  gap: 10px;
  margin-top: 12px;
}
.cmdrow input {
  flex: 1;
  font-family: 'JetBrains Mono', monospace;
  background: #0b0c14;
}

.console-tools {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
}
.console-tools input {
  background: #090a10;
  border: 1px solid var(--border);
  padding: 5px 10px;
  font-size: 11.5px;
  width: 140px;
}

/* ── Autocomplete Suggestions ── */
.cmd-suggest {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  right: 0;
  max-height: 220px;
  overflow-y: auto;
  display: none;
  z-index: 150;
  background: rgba(18, 20, 28, 0.95);
  backdrop-filter: blur(14px);
  border: 1px solid var(--border-strong);
  border-radius: 11px;
  padding: 6px;
  box-shadow: 0 -10px 30px rgba(0,0,0,0.55);
}
.cs-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 12.5px;
  font-family: 'JetBrains Mono', monospace;
  transition: background 0.15s;
}
.cs-item:hover, .cs-item.active {
  background: rgba(var(--accent-rgb), 0.15);
  color: var(--wit);
}
.cs-hint {
  color: var(--muted);
  font-size: 11px;
}

/* ── Support Ticket System ── */
.support-ticket-item {
  padding: 12px 14px;
  border-radius: 10px;
  cursor: pointer;
  transition: all 0.2s;
  border: 1px solid transparent;
  background: rgba(255, 255, 255, 0.01);
  margin-bottom: 6px;
}
.support-ticket-item:hover {
  background: rgba(255,255,255,0.04);
}
.support-ticket-item.active {
  background: rgba(var(--accent-rgb), 0.1);
  border-color: rgba(var(--accent-rgb), 0.2);
}
.support-ticket-item .ticket-subject {
  font-weight: 700;
  font-size: 13.5px;
  color: var(--wit);
}
.support-ticket-item .ticket-meta {
  font-size: 11px;
  color: var(--muted);
  margin-top: 3px;
}

.chat-bubble {
  max-width: 72%;
  padding: 12px 16px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.6;
  word-break: break-word;
  box-shadow: 0 4px 10px rgba(0,0,0,0.12);
}
.chat-bubble.admin {
  align-self: flex-end;
  background: linear-gradient(145deg, var(--accent2), var(--accent));
  color: var(--wit);
  border-bottom-right-radius: 4px;
}
.chat-bubble.customer {
  align-self: flex-start;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  border-bottom-left-radius: 4px;
  border: 1px solid var(--border);
}

/* ── Game Custom Player Inventories ── */
.mc-slot {
  width: 38px;
  height: 38px;
  background: linear-gradient(160deg, #8e8e90, #797979);
  box-shadow: inset 2px 2px 0 rgba(255,255,255,0.35), inset -2px -2px 0 rgba(0,0,0,0.45), 0 1px 2px rgba(0,0,0,0.3);
  border-radius: 5px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.12s ease;
}
.mc-slot:hover {
  transform: scale(1.1);
  z-index: 2;
}

/* ── Order/Checkout Styling ── */
.game-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(145px, 1fr));
  gap: 12px;
}
.game-card {
  border: 2px solid var(--border);
  border-radius: 12px;
  padding: 18px 14px;
  text-align: center;
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  background: rgba(255,255,255,0.02);
}
.game-card:hover {
  border-color: rgba(var(--accent-rgb), 0.35);
  background: rgba(255,255,255,0.04);
}
.game-card.active {
  border-color: var(--accent);
  background: rgba(var(--accent-rgb), 0.12);
  box-shadow: 0 0 15px rgba(var(--accent-rgb), 0.1);
}

.ram-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 10px;
}
.ram-card {
  border: 2px solid var(--border);
  border-radius: 10px;
  padding: 14px 10px;
  text-align: center;
  cursor: pointer;
  background: rgba(255,255,255,0.02);
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  font: inherit;
  color: var(--text);
}
.ram-card:hover:not(.disabled) {
  border-color: rgba(var(--accent-rgb), 0.45);
  background: rgba(255,255,255,0.04);
}
.ram-card.active {
  border-color: var(--accent);
  background: rgba(var(--accent-rgb), 0.12);
}
/* Pakket past niet meer op de node: eerlijk als 'tijdelijk vol' tonen i.p.v. de klant
   pas bij het afrekenen te weigeren. */
.ram-card.sold-out {
  opacity: 0.45;
  filter: grayscale(1);
  cursor: not-allowed;
}
.ram-card.sold-out:hover {
  border-color: rgba(255,255,255,0.08);
  background: transparent;
}
.ram-card.sold-out .ram-badge {
  background: rgba(255,255,255,0.12);
  color: #b9bcc9;
}
.ram-card .ram-gb {
  font-size: 17px;
  font-weight: 800;
  display: block;
}

.checkout-box {
  position: sticky;
  bottom: 0;
  background: linear-gradient(180deg, transparent 0%, rgba(9,10,16,0.98) 20%);
  padding: 24px 20px;
  margin: 0 -20px;
}
.checkout-inner {
  max-width: 820px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 24px;
  background: linear-gradient(165deg, rgba(26, 27, 40, 0.8), rgba(20, 21, 33, 0.6));
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 16px;
  padding: 20px 24px;
  box-shadow: 0 15px 45px rgba(0,0,0,0.55);
}

/* ── Switch / Toggle Toggles ── */
.switch {
  position: relative;
  width: 44px;
  height: 24px;
  flex-shrink: 0;
}
.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}
.switch .slider {
  position: absolute;
  inset: 0;
  background: #2e303d;
  border-radius: 24px;
  cursor: pointer;
  transition: background 0.18s;
}
.switch .slider::before {
  content: "";
  position: absolute;
  width: 18px;
  height: 18px;
  left: 3px;
  top: 3px;
  background: var(--wit);
  border-radius: 50%;
  transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
  box-shadow: 0 1px 3px rgba(0,0,0,0.4);
}
.switch input:checked + .slider {
  background: linear-gradient(150deg, var(--accent2), var(--accent));
}
.switch input:checked + .slider::before {
  transform: translateX(20px);
}

/* ── Responsive rules ── */
@media (max-width: 992px) {
  .shell-sidebar {
    transform: translateX(-100%);
    position: fixed;
    /* `dvh` en niet alleen `vh` — melding Cihan 27 juli 2026: "Testomgeving openen" bleef
       onderaan en je kon er niet naartoe scrollen. Op een telefoon is `100vh` GROTER dan
       wat je ziet: het rekent de ruimte onder de adresbalk mee. Bij `overflow: hidden` valt
       de onderkant van de zijbalk dus buiten beeld zonder enige manier om erbij te komen —
       en juist daar staat de voet (staging-knop, Bekijk als…, taal, uitloggen).
       `100vh` blijft als terugval staan voor browsers die `dvh` niet kennen. */
    height: 100vh;
    height: 100dvh;
    /* Vangnet: past de voet toch niet (korte telefoon, liggend scherm, extra menu-item),
       dan scrolt de zijbalk zelf. In het normale geval gebeurt dat niet, want
       `.sidebar-menu` vangt de lengte al op en de voet blijft onderaan staan — de les van
       24 juli dat de HELE zijbalk scrollen de voet onder de vouw duwde, blijft dus intact. */
    overflow-y: auto;
    max-width: 85vw;
    box-shadow: 0 0 40px rgba(0, 0, 0, 0.5);
  }
  .shell-sidebar.open {
    transform: translateX(0);
  }
  .topbar {
    display: flex;
  }
  /* De rol- en taalkiezer staan DUBBEL op dit scherm: in de topbalk én in de lade.
     Samen met de menuknop en het logo passen ze niet: gemeten 28 juli 2026 vroeg de
     topbalk 603px, dus het hele adminpaneel scrolde zijwaarts van 320px tot 601px --
     op ELKE tab, niet alleen de gebruikerstab. Mobile-first is een projectstandaard,
     dus dat is een echte fout.
     Hier verbergen en niet laten krimpen: een keuzelijst "Bekijk als…" van 40px is
     onbruikbaar, en er gaat niets verloren -- allebei de bedieningen staan in de lade
     die deze topbalk met de menuknop opent. Dat is meteen één bron in plaats van twee
     op hetzelfde scherm. */
  .topbar .rolkiezer-compact,
  .topbar .lang-switch,
  .topbar .user-badge {
    display: none;
  }
  .sidebar-backdrop.show {
    display: block;
    opacity: 1;
  }
  .sidebar-close {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 16px;
    right: 16px;
    width: 36px;
    height: 36px;
    border-radius: 9px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border);
    color: var(--muted);
    font-size: 15px;
    cursor: pointer;
    z-index: 2;
  }
  .sidebar-close:hover {
    color: var(--wit);
    background: rgba(255, 255, 255, 0.09);
  }
}

@media (max-width: 600px) {
  .main {
    padding: 20px 16px;
  }
  .server-grid {
    grid-template-columns: 1fr;
  }
  .field-row {
    grid-template-columns: 1fr;
  }
  .topbar {
    padding: 0 16px;
  }
  .checkout-inner {
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
  }
  .btn, button {
    min-height: 44px;
  }
}

/* ── Auth Pages (Login, Register, etc.) ── */
body.auth-page {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  min-height: 100vh;
}
.auth-page .page-brand {
  position: fixed;
  top: 24px;
  left: 26px;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  transition: opacity 0.15s;
}
.auth-page .page-brand:hover {
  opacity: 0.85;
}
.auth-page .page-brand img {
  border-radius: 7px;
}
.auth-page .page-brand-text {
  font-size: 16px;
  font-weight: 800;
  color: var(--wit);
  letter-spacing: -0.01em;
}
.auth-page .page-brand-text .brand-cave {
  color: var(--accent2);
}
.auth-page .lang-switch {
  position: fixed;
  top: 24px;
  right: 26px;
  z-index: 20;
}
.auth-page .box {
  position: relative;
  background: linear-gradient(165deg, var(--card), rgba(20, 22, 33, 0.4));
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--border-strong);
  padding: 44px 40px;
  border-radius: 20px;
  width: 420px;
  max-width: calc(100vw - 32px);
  box-shadow: var(--shadow-card);
}
/* Echt CaveHosting-logo i.p.v. de oude emoji-placeholder. De afbeelding heeft z'n
   eigen achtergrond, dus de blauwe gradient eronder moet weg — anders zie je een
   blauw blokje om het logo. */
.auth-page .icon.brand,
.logo-icon.brand {
  background: none;
  padding: 0;
  overflow: hidden;
}

/* Merk-kop gecentreerd boven het formulier (login/registratie/wachtwoord). De velden
   eronder blijven bewust links uitgelijnd — labels centreren leest slecht. */
.auth-page .icon {
  margin-left: auto;
  margin-right: auto;
}
.auth-page h1,
.auth-page .sub {
  text-align: center;
}
/* De globale h1 is `display: flex` (voor koppen met een icoon ernaast). In een flexbox
   doet text-align niets: de tekst is een flex-item en volgt justify-content. Zonder deze
   regel bleef "CaveHosting" links staan terwijl logo en subtitel wél centreerden. */
.auth-page h1 {
  justify-content: center;
}
.auth-page .icon.brand img,
.logo-icon.brand img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
  border-radius: inherit;
}

.auth-page .icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  background: linear-gradient(150deg, var(--accent2), var(--accent));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  margin-bottom: 18px;
  box-shadow: 0 6px 16px rgba(var(--accent-rgb), 0.35);
  text-decoration: none;
  transition: transform 0.15s, filter 0.15s;
}
.auth-page .icon:hover {
  filter: brightness(1.1);
  transform: translateY(-1.5px);
}
.auth-page h1 {
  font-size: 19px;
  margin-bottom: 6px;
  font-weight: 700;
  color: var(--wit);
}
.auth-page p.sub {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 24px;
}
.auth-page label {
  display: block;
  font-size: 11.5px;
  color: var(--muted);
  margin-bottom: 6px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.auth-page input {
  width: 100%;
  box-sizing: border-box;
  padding: 12px 14px;
  font-size: 14px;
  border-radius: 10px;
  margin-bottom: 16px;
  border: 1px solid var(--border-strong);
  background: rgba(0, 0, 0, 0.25);
  color: var(--wit);
}
.auth-page .btn-submit {
  width: 100%;
  padding: 12px;
  font-weight: 700;
  font-size: 14px;
}
.auth-page .error {
  color: var(--red);
  font-size: 13px;
  margin-bottom: 16px;
  background: rgba(var(--red-rgb), 0.1);
  border: 1px solid rgba(var(--red-rgb), 0.25);
  padding: 10px 12px;
  border-radius: 8px;
}
.auth-page .success {
  color: var(--green);
  font-size: 13.5px;
  background: rgba(var(--green-rgb), 0.1);
  border: 1px solid rgba(var(--green-rgb), 0.25);
  padding: 12px 14px;
  border-radius: 9px;
  line-height: 1.55;
  margin-bottom: 16px;
}
.auth-page .lock {
  text-align: center;
  font-size: 11px;
  color: var(--muted);
  margin-top: 18px;
}
.auth-page .switch {
  /* Reset de afmetingen van de globale toggle-.switch (naam-botsing): hier is
     .switch een tekst-alinea met een link, geen 42x24px schakelaar. */
  position: static;
  display: block;
  width: auto;
  height: auto;
  text-align: center;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
  margin: 18px 0 0;
}
.auth-page .switch a {
  color: var(--accent2);
  text-decoration: none;
  font-weight: 600;
}
.auth-page .switch a:hover {
  text-decoration: underline;
}
.auth-page .or-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 20px 0 16px;
  color: var(--muted);
  font-size: 12px;
}
.auth-page .or-divider::before,
.auth-page .or-divider::after {
  content: '';
  flex: 1;
  border-top: 1px solid var(--border);
}
.auth-page .btn-discord {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 12px;
  border-radius: 9px;
  border: none;
  background: #5865F2;
  color: var(--wit);
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  text-decoration: none;
  box-shadow: 0 4px 14px rgba(88, 101, 242, 0.35);
  transition: transform 0.15s, filter 0.15s;
}
.auth-page .btn-discord:hover {
  filter: brightness(1.1);
  transform: translateY(-1.5px);
}

@media (max-width: 420px) {
  .auth-page .page-brand {
    top: 14px;
    left: 16px;
  }
  .auth-page .page-brand-text {
    font-size: 15px;
  }
  .auth-page .lang-switch {
    top: 14px;
    right: 16px;
  }
}

/* ── Specific Dashboard Modal & Tab Elements ── */
#serverModal .srv-tabs {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
  margin-bottom: 16px;
}
#serverModal .srv-tab-btn {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  padding: 8px 12px;
  cursor: pointer;
  white-space: nowrap;
  margin-bottom: -1px;
}
#serverModal .srv-tab-btn:hover {
  color: var(--text);
}
#serverModal .srv-tab-btn.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
#serverModal .srv-tab-panel {
  display: none;
}
#serverModal .srv-tab-panel.active {
  display: block;
  animation: srvTabFade .15s ease;
}
@keyframes srvTabFade {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ── Market Monitor & Recommendations Styles ── */
.market-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
.market-stat-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  box-shadow: var(--shadow-card);
}
.market-stat-card h4 {
  font-size: 11.5px;
  color: var(--muted);
  text-transform: uppercase;
  margin: 0;
  letter-spacing: 0.05em;
  font-weight: 700;
}
.market-stat-card .value {
  font-size: 24px;
  font-weight: 800;
  color: var(--wit);
  font-family: 'Outfit', sans-serif;
}
.market-stat-card .footer-text {
  font-size: 11px;
  color: var(--muted);
}
.market-nav {
  display: flex;
  gap: 8px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px;
  overflow-x: auto;
  padding-bottom: 8px;
  scrollbar-width: none;
}
.market-nav::-webkit-scrollbar {
  display: none;
}
.market-nav button {
  background: none;
  border: none;
  padding: 8px 16px;
  border-radius: 7px;
  color: var(--muted);
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
  font-weight: 500;
  box-shadow: none;
  transform: none !important;
  transition: background .15s, color .15s;
}
.market-nav button:hover {
  background: rgba(255,255,255,.05);
  color: var(--text);
}
.market-nav button.active {
  background: rgba(91,140,255,.12);
  color: var(--accent);
  font-weight: 600;
}
.market-subview {
  display: none;
}
.market-subview.active {
  display: block;
  animation: tab-fade 0.2s ease-out;
}
.market-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
  font-size: 13px;
}
.market-table th, .market-table td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
}
.market-table th {
  color: var(--muted);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.05em;
}
.market-table tr:hover td {
  background: rgba(255,255,255,.02);
}
.badge-pill {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
}
.badge-pill.status-active { background: rgba(var(--green-rgb),.15); color: var(--green); }
.badge-pill.status-inactive { background: rgba(255,255,255,.08); color: var(--muted); }
.badge-pill.prio-high { background: rgba(var(--red-rgb),.15); color: var(--red); }
.badge-pill.prio-medium { background: rgba(var(--yellow-rgb),.15); color: var(--yellow); }
.badge-pill.prio-low { background: rgba(var(--accent-rgb),.15); color: var(--accent2); }
.prompt-box {
  background: rgba(0,0,0,.25);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  line-height: 1.55;
  white-space: pre-wrap;
  color: var(--text);
  max-height: 350px;
  overflow-y: auto;
}
.market-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(360px, 100%), 1fr));
  gap: 16px;
}
.market-card {
  background: linear-gradient(160deg, var(--card), rgba(20, 22, 33, 0.3));
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  box-shadow: var(--shadow-card);
}
.market-card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
}
.market-card-title {
  font-size: 14.5px;
  font-weight: 700;
  color: var(--wit);
}
.market-card-meta {
  font-size: 11px;
  color: var(--muted);
  display: flex;
  gap: 8px;
}
.market-card-content {
  font-size: 12.5px;
  color: var(--text);
  line-height: 1.5;
}
.market-card-actions {
  display: flex;
  gap: 8px;
  margin-top: auto;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}
.audit-evidence {
  background: rgba(0,0,0,.35);
  font-family: 'JetBrains Mono', monospace;
  padding: 8px;
  border-radius: 6px;
  font-size: 11px;
  margin-top: 4px;
  word-break: break-all;
  color: #fbbf24;
}


/* ── Single Server Page (index.html) Styles ── */body.server-page {
    color-scheme: dark;
    --bg: #0c0d14;
    --surface: #1a1c28;
    --surface2: #20222f;
    --border: rgba(255,255,255,.07);
    --border-strong: rgba(255,255,255,.12);
    --text: #e7e8ee;
    --muted: #94A0B8;
    --accent: var(--ch-paars, #5b8cff);
    --accent2: #7aa2ff;
    --green: #3fc97a;
    --red: #f0594f;
    --amber: #e0a83f;
    --shadow-card: 0 6px 20px rgba(0,0,0,.35), 0 1px 0 rgba(255,255,255,.03) inset;
    --shadow-btn: 0 2px 6px rgba(0,0,0,.35), 0 1px 0 rgba(255,255,255,.08) inset;
    --shadow-btn-hover: 0 4px 12px rgba(0,0,0,.4), 0 1px 0 rgba(255,255,255,.1) inset;
  }.server-page * { box-sizing: border-box; }html.server-page { width:100%; overflow-x:hidden; }body.server-page {
    background:
      radial-gradient(900px 500px at 15% -10%, rgba(91,140,255,.10), transparent 60%),
      radial-gradient(700px 500px at 100% 0%, rgba(63,201,122,.06), transparent 55%),
      var(--bg);
    color: var(--text);
    font-family: -apple-system, "Segoe UI", system-ui, sans-serif;
    margin:0; padding:24px; min-height:100vh; overflow-x:hidden;
  }.server-page h1 { font-size:19px; font-weight:700; color:var(--text); display:flex; align-items:center; gap:10px; margin:0; letter-spacing:.01em; }.server-page a.logout { color:var(--muted); font-size:13px; text-decoration:none; margin-left:auto; padding:7px 12px; border-radius:8px; transition: all .15s; }.server-page a.logout:hover { background: var(--surface2); color: var(--text); }.server-page .top { display:flex; align-items:center; gap:12px; padding-bottom:4px; min-width:0; }.server-page .brand-icon { width:34px; height:34px; border-radius:9px; background: linear-gradient(160deg, var(--accent2), var(--accent)); display:flex; align-items:center; justify-content:center; font-size:16px; box-shadow: 0 4px 12px rgba(91,140,255,.3); }.server-page .brand-logo-link { display:flex; align-items:center; gap:9px; text-decoration:none; min-width:0; }.server-page .brand-icon-img { display:block; border-radius:7px; }.server-page .brand-cave { color: var(--accent2); }.server-page .state-pill { display:flex; align-items:center; gap:7px; background: var(--surface2); border:1px solid var(--border); padding:6px 12px; border-radius:20px; font-size:12.5px; color:var(--muted); font-weight:600; }.server-page .lang-switch { background: var(--surface2); color:var(--text); border:1px solid var(--border-strong); border-radius:9px; padding:7px 10px; font-size:12.5px; cursor:pointer; }.server-page .lang-switch:focus { outline:none; border-color: var(--accent); }.server-page select, .server-page select option, .server-page select optgroup { background:#111320; color:#f4f6fb; }.server-page select option:disabled { color:#7b8194; }.server-page .user-badge { display:flex; flex-direction:column; align-items:flex-end; gap:1px; }.server-page .user-badge .user-name { font-size:12.5px; font-weight:700; color:var(--text); }.server-page .user-badge .user-role { font-size:10.5px; color:var(--muted); }.server-page .servers-link { color:var(--muted); font-size:12px; text-decoration:none; padding:4px 8px; border-radius:6px; border:1px solid var(--border); transition:background .15s,color .15s; }.server-page .servers-link:hover { background:rgba(255,255,255,.07); color:var(--text); }.server-page .server-breadcrumb { font-size:13px; font-weight:600; color:var(--text); max-width:160px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }.server-page .inline-select { background:rgba(255,255,255,.05); border:1px solid var(--border); color:var(--text); border-radius:6px; padding:4px 8px; font-size:12px; width:100%; cursor:pointer; }.server-page .inline-select:focus { outline:none; border-color:var(--accent); }.server-page .tabs { display:flex; gap:6px; margin:18px 0; background: var(--surface); padding:5px; border-radius:12px; width:fit-content; border:1px solid var(--border); box-shadow: var(--shadow-card); }.server-page .tabs button { background:transparent; color:var(--muted); border:none; padding:8px 16px; border-radius:8px; cursor:pointer; font-size:13.5px; font-weight:600; transition: all .15s; }.server-page .tabs button:hover { color: var(--text); }.server-page .tabs button.active { background: linear-gradient(160deg, var(--accent2), var(--accent)); color:#0a0d18; box-shadow: var(--shadow-btn); }.server-page .tabpanel { display:none; }.server-page .tabpanel.active { display:block; animation: fadein .18s ease; }.server-page @keyframes fadein { from { opacity:0; transform: translateY(3px); } to { opacity:1; transform: translateY(0); } }.server-page .grid { display:grid; grid-template-columns: 1fr 1fr; gap:16px; }.server-page .card {
    background: linear-gradient(160deg, var(--surface2), var(--surface));
    border: 1px solid var(--border);
    border-radius:14px; padding:18px 20px; margin-bottom:16px;
    box-shadow: var(--shadow-card);
  }.server-page .card h2 { font-size:12.5px; text-transform:uppercase; letter-spacing:.07em; color:var(--muted); font-weight:700; margin:0 0 14px; display:flex; justify-content:space-between; align-items:center; }.server-page .card h2 button:not(.btn-primary):not(.btn-green):not(.btn-red) { background:none; border:none; color:var(--accent2); cursor:pointer; font-size:12.5px; font-weight:600; padding:4px 8px; border-radius:6px; transition: background .15s; }.server-page .card h2 button:hover { background: rgba(91,140,255,.12); }.server-page .status-dot { display:inline-block; width:9px; height:9px; border-radius:50%; margin-right:4px; position:relative; }.server-page .status-dot.on { background:var(--green); box-shadow:0 0 10px var(--green); animation: pulse 2s infinite; }.server-page .status-dot.off { background:var(--red); box-shadow:0 0 8px rgba(240,89,79,.6); }.server-page @keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:.55; } }.server-page .row { display:flex; justify-content:space-between; gap:14px; padding:5px 0; font-size:13.5px; color: var(--muted); min-width:0; }.server-page .row span:first-child { min-width:0; }.server-page .row span:last-child { color:var(--text); font-weight:600; text-align:right; min-width:0; overflow-wrap:anywhere; }.server-page .bar { height:7px; background: rgba(0,0,0,.35); border-radius:6px; overflow:hidden; margin-top:5px; box-shadow: inset 0 1px 2px rgba(0,0,0,.4); }.server-page .bar-fill { height:100%; background: linear-gradient(90deg, var(--accent), #7ee787); border-radius:6px; transition: width .4s ease; box-shadow: 0 0 8px rgba(91,140,255,.5); }.server-page .btns { display:flex; gap:10px; margin-top:14px; }.server-page button {
    /* `border:none` en `box-shadow: var(--shadow-btn)` stonden hier en zijn op 30 juli
       2026 weggehaald. Ze wogen (0,1,1) tegen het contract (0,1,0) en wonnen dus: de
       glans lekte als enige eigenschap door een vlakke vulling heen (live gemeten op de
       bestelpagina), en `border:none` maakte de rand van elke rustige én gevaar-knop
       onzichtbaar — precies de twee varianten waar de rand HET bedieningselement is
       (WCAG 1.4.11). Een kale <button> houdt zijn randloze vorm via `button, .btn`
       bovenaan dit bestand; die weegt (0,0,1) en laat het contract dus voorgaan. */
    padding:9px 16px; border-radius:9px; font-weight:600; cursor:pointer; font-size:13px;
    transition: transform .1s ease, box-shadow .15s ease, filter .15s ease, opacity .15s ease;
  }.server-page button:hover:not(:disabled) { filter: brightness(1.08); box-shadow: var(--shadow-btn-hover); transform: translateY(-1px); }.server-page button:active:not(:disabled) { transform: translateY(0); filter: brightness(.95); box-shadow: 0 1px 2px rgba(0,0,0,.4) inset; }/* .btn-start en .btn-stop stonden hier met een verloop; sinds 30 juli 2026 komt hun
   vulling uit het contract in componenten.css (§7b.2, vlak + de diepe tokens). *//* Preview-modus vergrendelde elementen */.server-page .perm-locked { opacity: .35; pointer-events: none !important; cursor: not-allowed !important; position: relative; }.server-page .perm-locked button, .server-page .perm-locked input, .server-page .perm-locked select { pointer-events: none !important; cursor: not-allowed !important; }.server-page .perm-lock-badge { position:absolute; inset:0; display:flex; align-items:center; justify-content:center; z-index:2; pointer-events:none; }.server-page .perm-lock-badge::after { content:'🔒'; font-size:18px; background:rgba(13,17,23,.7); border-radius:8px; padding:4px 8px; }.server-page button.perm-locked { opacity:.32; cursor:not-allowed !important; }.server-page button.perm-locked::before { content:'🔒 '; }.server-page .btn-small { padding:6px 11px; font-size:11.5px; font-weight:600; }/* vulling + rand + hover: contract (§7b, rustig) */.server-page button:disabled { opacity:.35; cursor:not-allowed; filter:none; transform:none; }/* ── Loading shimmer + empty states ── */.server-page .skel { display:inline-block; border-radius:6px; background:linear-gradient(90deg, rgba(255,255,255,.05) 25%, rgba(255,255,255,.11) 37%, rgba(255,255,255,.05) 63%); background-size:400% 100%; animation:skelShimmer 1.3s ease infinite; color:transparent!important; }.server-page @keyframes skelShimmer { 0%{background-position:100% 0;} 100%{background-position:-100% 0;} }.server-page .empty-state { text-align:center; padding:28px 16px; color:var(--muted); }.server-page .empty-state .es-ic { font-size:30px; display:block; margin-bottom:8px; opacity:.7; }.server-page .empty-state .es-title { font-size:13.5px; font-weight:700; color:var(--text); margin-bottom:3px; }.server-page .empty-state .es-sub { font-size:12px; }/* ── Server-health hero ── */.server-page .health-hero { background: linear-gradient(160deg, var(--surface2, #1a1c28), var(--surface, #141520)); border:1px solid var(--border); border-radius:16px; padding:18px 20px; margin-bottom:16px; box-shadow: var(--shadow-card, 0 8px 24px rgba(0,0,0,.3)); }.server-page .hh-main { display:flex; align-items:center; gap:22px; flex-wrap:wrap; }.server-page .hh-status { display:flex; align-items:center; gap:13px; }.server-page .hh-badge { font-size:19px; font-weight:800; color:var(--text); line-height:1.1; }.server-page .hh-sub { font-size:12px; color:var(--muted); margin-top:2px; }.server-page .hh-address { margin-left:8px; cursor:pointer; padding:8px 14px; border-radius:10px; background:rgba(91,140,255,.09); border:1px solid rgba(91,140,255,.22); transition:background .15s; }.server-page .hh-address:hover { background:rgba(91,140,255,.16); }.server-page .hh-addr-label { display:block; font-size:10.5px; color:var(--muted); text-transform:uppercase; letter-spacing:.05em; }.server-page .hh-addr-val { display:block; font-size:15px; font-weight:800; color:var(--accent); font-family:ui-monospace,monospace; }.server-page .hh-actions { margin-left:auto; display:flex; gap:8px; }.server-page .hh-meters { display:grid; grid-template-columns:repeat(3,1fr); gap:16px; margin-top:16px; }.server-page .hh-m-top { display:flex; justify-content:space-between; font-size:11.5px; color:var(--muted); margin-bottom:5px; }.server-page .hh-m-top span:last-child { color:var(--text); font-weight:700; }.server-page .hh-bar { height:7px; background:rgba(255,255,255,.06); border-radius:4px; overflow:hidden; }.server-page .hh-fill { height:100%; border-radius:4px; width:0%; transition:width .5s ease; }.server-page .hh-fill.ram { background:linear-gradient(90deg,var(--accent),var(--accent2)); }.server-page .hh-fill.cpu { background:linear-gradient(90deg,#3fc97a,#5fe89a); }.server-page .hh-fill.disk { background:linear-gradient(90deg,#eab308,#f5c542); }@media (max-width:768px) {.server-page .hh-actions {margin-left:0;width:100%;}.server-page .hh-meters {grid-template-columns:1fr;}.server-page .hh-address {margin-left:0;}}.server-page .console { grid-column: 1 / -1; }.server-page .console-tools { margin-left:auto; display:flex; align-items:center; gap:5px; text-transform:none; letter-spacing:0; }.server-page .console-tools input { background:#11121a; border:1px solid var(--border); color:var(--text); border-radius:7px; padding:4px 9px; font-size:12px; width:130px; font-weight:400; }.server-page .console-tools input:focus { outline:none; border-color:var(--accent); }.server-page .ct-btn { background:var(--surface2); color:var(--muted); border:1px solid var(--border); border-radius:7px; padding:4px 8px; font-size:12px; cursor:pointer; line-height:1; font-weight:600; }.server-page .ct-btn:hover { background:#2a2d3d; color:var(--text); }.server-page .ct-btn.active { background:linear-gradient(160deg,var(--accent2),var(--accent)); color:#0a0d18; border-color:transparent; }.server-page #log {
    background:#080910; border:1px solid var(--border); border-radius:10px; padding:12px; height:340px; overflow-y:auto;
    font-family: ui-monospace, Consolas, monospace; font-size:12.5px; white-space:pre-wrap; line-height:1.5;
    box-shadow: inset 0 2px 8px rgba(0,0,0,.5);
  }.server-page #log mark { background:rgba(234,179,8,.35); color:var(--wit); border-radius:2px; }.server-page .cmdrow { display:flex; gap:8px; margin-top:10px; }.server-page .cmdrow input { flex:1; padding:10px 12px; border-radius:9px; border:1px solid var(--border-strong); background:#11121a; color:var(--wit); font-family: ui-monospace, monospace; transition: border-color .15s, box-shadow .15s; }.server-page .cmdrow input:focus { outline:none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(91,140,255,.18); }.server-page .cmdrow button { background: linear-gradient(160deg, var(--accent2), var(--accent)); color:#0a0d18; }.server-page .plist { display:flex; flex-direction:column; gap:7px; }.server-page .pitem {
    display:flex; align-items:center; justify-content:space-between; background: var(--surface2);
    border:1px solid var(--border); padding:10px 12px; border-radius:10px; font-size:13.5px; transition: border-color .15s;
  }.server-page .pitem:hover { border-color: var(--border-strong); }.server-page .pitem .name { font-weight:600; }.server-page .pitem .actions { display:flex; gap:6px; }/* .btn-kick was amber; §7b.4 houdt amber exclusief als statusdrager, dus hij is rustig
   geworden (contract) mét bevestigingsvenster (§7b.3). */.server-page .btn-ban { background: linear-gradient(160deg, #f57168, var(--red)); color:#1a0605; }.server-page .btn-pardon { background: linear-gradient(160deg, #4ee08a, #29a85e); color:#06150c; }.server-page .btn-inv { background: linear-gradient(160deg, var(--accent2), var(--accent)); color:#0a0d18; }.server-page .btn-rm { background: var(--surface2); color:#ddd; border:1px solid var(--border-strong); box-shadow:none; }.server-page .btn-rm:hover:not(:disabled) { background:#2c2f40; box-shadow:none; transform:none; }.server-page .empty { color: var(--muted); font-size:13px; padding:8px 0; }.server-page table.filetable { width:100%; border-collapse:collapse; font-size:13.5px; margin-top:12px; }.server-page table.filetable th { text-align:left; color:var(--muted); font-size:11.5px; text-transform:uppercase; letter-spacing:.04em; padding:8px 10px; border-bottom:1px solid var(--border); }.server-page table.filetable td { padding:9px 10px; border-bottom:1px solid var(--border); }.server-page table.filetable tr:hover td { background: rgba(255,255,255,.025); }.server-page .fname { cursor:pointer; border-radius:5px; }.server-page .fname:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }.server-page .fname.dir { color: var(--accent2); font-weight:600; }.server-page .fname.dir::before { content:"\1F4C1 "; }.server-page .fname.file::before { content:"\1F4C4 "; }.server-page .ftools { display:flex; gap:8px; align-items:center; }.server-page #fbBreadcrumb { color:var(--muted); font-size:13px; margin-bottom:8px; }.server-page #fbBreadcrumb span { cursor:pointer; color: var(--accent2); }.server-page #fbBreadcrumb span:hover { text-decoration:underline; }.server-page .filetoolbar { display:flex; gap:8px; }.server-page .modal-overlay { position:fixed; inset:0; background:rgba(4,5,10,.65); backdrop-filter: blur(3px); display:flex; align-items:center; justify-content:center; z-index:50; animation: fadein .15s ease; }.server-page .modal-overlay.hidden { display:none; }.server-page .modal-box {
    background: linear-gradient(165deg, var(--surface2), var(--surface));
    border:1px solid var(--border-strong); border-radius:16px; padding:22px;
    width:480px; max-width:90vw; max-height:85vh; overflow:auto;
    box-shadow: 0 20px 60px rgba(0,0,0,.55), 0 1px 0 rgba(255,255,255,.05) inset;
    position: relative;
  }.server-page .modal-box.wide { width:740px; }.server-page .modal-close-x { position:absolute; top:12px; right:12px; background:none; border:none; color:var(--muted); font-size:18px; line-height:1; cursor:pointer; padding:4px 8px; border-radius:6px; box-shadow:none; z-index:1; }.server-page .modal-close-x:hover { background:rgba(255,255,255,.08); color:var(--text); box-shadow:none; transform:none; }/* .btn-danger en .btn-warn kwamen hier drie keer voor, met een eigen rood en een eigen
   amber, en twee ervan met !important — dat laatste had het contract per definitie
   overruled. Vulling, tekst en rand komen sinds 30 juli 2026 uit componenten.css
   (§7b: danger = gevaar, warn = rustig want amber blijft statusdrager). */.server-page .btn-danger:disabled { opacity:.5; cursor:not-allowed; }.server-page .mod-section-label { font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:.06em; font-weight:700; margin:10px 0 6px; }.server-page .modal-box h3 { margin:0 0 12px; color:var(--text); font-size:16px; }.server-page .modal-box::-webkit-scrollbar, .server-page #log::-webkit-scrollbar { width:9px; }.server-page .modal-box::-webkit-scrollbar-thumb, .server-page #log::-webkit-scrollbar-thumb { background:#383b4d; border-radius:6px; }.server-page .modal-box::-webkit-scrollbar-track, .server-page #log::-webkit-scrollbar-track { background:transparent; }.server-page .editor-wrap { position:relative; height:420px; }.server-page .editor-wrap #editArea, .server-page .editor-wrap .editor-highlight {
    position:absolute; top:0; left:0; width:100%; height:100%; margin:0;
    font-family: ui-monospace, monospace; font-size:13px; line-height:1.5;
    padding:12px; box-sizing:border-box; border-radius:10px;
    white-space:pre-wrap; word-wrap:break-word; overflow-wrap:break-word;
    tab-size:2;
  }.server-page #editArea {
    background:transparent; color:transparent; caret-color: var(--text);
    border:1px solid var(--border-strong); overflow:auto; resize:none; z-index:1;
  }.server-page #editArea:focus { outline:none; border-color: var(--accent); }.server-page .editor-highlight {
    background:#0a0b12; color:var(--text); border:1px solid transparent;
    overflow:hidden; pointer-events:none; z-index:0;
  }.server-page .editor-highlight code { font: inherit; color: inherit; }.server-page .tok-comment { color: var(--muted); font-style: italic; }.server-page .tok-key { color: var(--accent2); }.server-page .tok-str { color: var(--green); }.server-page .tok-num { color: #e8b339; }.server-page .tok-kw { color: #c586c0; }.server-page .mc-inv { display:flex; flex-direction:column; gap:10px; align-items:center; margin-bottom:16px; }.server-page .mc-armor-row { display:flex; justify-content:center; gap:4px; }.server-page .mc-grid { display:grid; grid-template-columns: repeat(9, 38px); gap:4px; }.server-page .mc-grid.hotbar { margin-top:8px; padding-top:12px; border-top:2px solid var(--border-strong); }.server-page .mc-slot {
    width:38px; height:38px; background: linear-gradient(160deg, #8e8e90, #797979);
    box-shadow: inset 2px 2px 0 rgba(255,255,255,.4), inset -2px -2px 0 rgba(0,0,0,.4), 0 1px 2px rgba(0,0,0,.3);
    border-radius:4px; position:relative; display:flex; align-items:center; justify-content:center; transition: transform .1s;
  }.server-page .mc-slot:hover { transform: scale(1.08); z-index:2; }.server-page .mc-slot img { width:28px; height:28px; image-rendering: pixelated; }.server-page .mc-fallback { font-size:10px; font-weight:700; color:#2a2a2a; letter-spacing:.02em; }.server-page .mc-count { position:absolute; bottom:0px; right:2px; font-size:11px; font-weight:700; color:var(--wit); text-shadow: 1px 1px 0 #000, -1px -1px 0 #000; }.server-page .ptabs { display:flex; gap:6px; flex-wrap:wrap; }.server-page .ptabs button.active { background: linear-gradient(160deg, var(--accent2), var(--accent)); color:#0a0d18; border-color:transparent; }.server-page #playerSearch {
    width:100%; padding:10px 12px; margin:14px 0; border-radius:9px; border:1px solid var(--border-strong);
    background:#11121a; color:var(--wit); transition: border-color .15s, box-shadow .15s;
  }.server-page #playerSearch:focus { outline:none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(91,140,255,.18); }.server-page .player-grid { display:grid; grid-template-columns: repeat(auto-fill, minmax(195px, 1fr)); gap:10px; }.server-page .player-card {
    background: var(--surface2); border:1px solid var(--border); border-radius:11px; padding:11px;
    display:flex; align-items:center; gap:10px; cursor:pointer; transition: all .15s;
  }.server-page .player-card:hover { background:#262838; border-color: var(--border-strong); transform: translateY(-1px); box-shadow: var(--shadow-card); }.server-page .player-card img { width:36px; height:36px; border-radius:7px; image-rendering: pixelated; flex-shrink:0; box-shadow: 0 0 0 1px var(--border-strong); }.server-page .player-card .pname { font-weight:600; font-size:13.5px; }.server-page .player-card .pstatus { font-size:11px; margin-top:2px; }.server-page .pstatus.online { color:var(--green); }.server-page .pstatus.offline { color:var(--muted); }.server-page .detail-head { display:flex; gap:16px; align-items:center; margin-bottom:16px; }.server-page .detail-head img { width:60px; height:60px; border-radius:10px; image-rendering: pixelated; box-shadow: 0 0 0 1px var(--border-strong), var(--shadow-card); object-fit: cover; }.server-page .detail-head h3 { margin:0; }.server-page .uuid-row { display:flex; align-items:center; gap:8px; margin-top:4px; }.server-page .uuid-row span { font-family: ui-monospace, monospace; font-size:11.5px; color:var(--muted); }.server-page .uuid-row .btn-small { padding:3px 8px; font-size:11px; }.server-page .character-render { display:flex; justify-content:center; margin:6px 0 16px; min-height:170px; align-items:flex-end; }.server-page .character-render img { height:170px; width:auto; image-rendering: pixelated; filter: drop-shadow(0 10px 16px rgba(0,0,0,.45)); }.server-page .stat-bars { display:flex; flex-direction:column; gap:9px; margin-bottom:4px; }.server-page .stat-row { display:flex; align-items:center; gap:10px; }.server-page .stat-label { width:90px; flex-shrink:0; font-size:12.5px; color:var(--muted); }.server-page .stat-bar { flex:1; height:9px; }.server-page .stat-val { width:60px; flex-shrink:0; text-align:right; font-size:12.5px; font-weight:600; }.server-page .bar-fill.bar-health { background: linear-gradient(90deg, #c23b3b, #f0594f); box-shadow: 0 0 8px rgba(240,89,79,.5); }.server-page .bar-fill.bar-food { background: linear-gradient(90deg, #b5651d, #e0a83f); box-shadow: 0 0 8px rgba(224,168,63,.5); }.server-page .bar-fill.bar-armor { background: linear-gradient(90deg, #6c7689, #9aa6bc); box-shadow: 0 0 8px rgba(154,166,188,.5); }.server-page .bar-fill.bar-xp { background: linear-gradient(90deg, #3fc97a, #7ee787); box-shadow: 0 0 8px rgba(63,201,122,.5); }.server-page .actioncard { background: rgba(0,0,0,.18); border:1px solid var(--border); border-radius:12px; padding:16px; margin:16px 0; }.server-page .actioncard h4 { margin:0 0 12px; font-size:11.5px; color:var(--muted); text-transform:uppercase; letter-spacing:.07em; font-weight:700; }.server-page .gm-btns { display:flex; gap:6px; flex-wrap:wrap; margin-bottom:12px; }.server-page .gm-btns button { background: var(--surface2); color:var(--text); border:1px solid var(--border-strong); box-shadow:none; text-transform:capitalize; }.server-page .gm-btns button:hover:not(:disabled) { background:#2c2f40; box-shadow:none; transform:none; }.server-page .gm-btns button.gm-active { background: linear-gradient(160deg, var(--accent2), var(--accent)); color:#0a0d18; border-color:transparent; }/* Player toggle rows (fly / god) */.server-page .ptog-list { margin-bottom:12px; }.server-page .ptog-row { display:flex; align-items:center; justify-content:space-between; padding:9px 0; border-bottom:1px solid var(--border); }.server-page .ptog-row:last-child { border-bottom:none; }.server-page .ptog-label { font-size:13.5px; display:flex; align-items:center; gap:7px; }.server-page .ptog-state { font-size:11px; font-weight:700; padding:2px 7px; border-radius:10px; }.server-page .ptog-state.on { background:rgba(63,201,122,.15); color:var(--green); }.server-page .ptog-state.off { background:rgba(255,255,255,.07); color:var(--muted); }.server-page .coordrow input {
    width:68px; padding:10px; border-radius:9px; border:1px solid var(--border-strong); background:#11121a; color:var(--wit);
    transition: border-color .15s;
  }.server-page .coordrow input:focus { outline:none; border-color: var(--accent); }.server-page .restart-banner { background: rgba(224,168,63,.12); border:1px solid rgba(224,168,63,.35); color:#e0a83f; padding:10px 14px; border-radius:9px; font-size:13px; margin-bottom:12px; }.server-page .restart-banner.hidden { display:none; }.server-page .global-restart { display:flex; align-items:center; justify-content:space-between; gap:14px; margin:14px 0 0; }.server-page .billing-banner.expired { background: rgba(240,89,79,.13); border-color: rgba(240,89,79,.4); color:#f0847d; }.server-page .billing-banner .btn-update { flex-shrink:0; }.server-page .grb-text { font-weight:600; }.server-page .grb-text span { font-weight:400; opacity:.85; }.server-page .btn-update { background: linear-gradient(160deg, var(--accent2), var(--accent)); color:#0a0d18; }.server-page .btn-update, .server-page .btn-downgrade {
    display:inline-flex; align-items:center; justify-content:center; gap:6px;
    min-height: 44px; padding:9px 14px; border-radius:9px; font-weight:700;
    text-decoration:none; font-size:13px; line-height:1.2;
  }/* .btn-downgrade: vulling + rand + hover uit het contract (§7b, rustig). */.server-page .settings-grid { display:grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap:14px; margin-top:10px; }.server-page .setting-field { display:flex; flex-direction:column; gap:6px; }.server-page .setting-field label { font-size:12.5px; color:var(--muted); }.server-page .setting-help { font-size:11.5px; color:#94A0B8; line-height:1.4; }/* Oranje cursief betekent 'let op'. Maar 'staat op de standaardwaarde' is geen
   waarschuwing — het is de normale toestand van bijna elk veld. Zeven oranje
   zinnen op één scherm leren je alleen om oranje te negeren. Nu: een rustig
   etiket. */
.server-page .default-tag { display:inline-block; font-style:normal; font-size:10.5px; font-weight:700;
  padding:1px 7px; border-radius:20px; margin-left:4px; vertical-align:1px;
  background:rgba(255,255,255,.06); color:var(--muted); border:1px solid var(--border); }.server-page .setting-field input[type="text"], .server-page .setting-field input[type="number"], .server-page .setting-field input[type="time"], .server-page .setting-field select {
    padding:9px 11px; border-radius:9px; border:1px solid var(--border-strong); background:#11121a; color:var(--wit); font-size:13.5px;
    color-scheme: dark;
  }.server-page .setting-field input:focus, .server-page .setting-field select:focus { outline:none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(91,140,255,.18); }.server-page .setting-toggle { display:flex; align-items:flex-start; justify-content:space-between; gap:14px; padding:9px 0; border-bottom:1px solid var(--border); }.server-page .setting-toggle:last-child { border-bottom:none; }.server-page .setting-toggle label { font-size:13.5px; color:var(--text); }.server-page .setting-toggle .switch { margin-top:2px; }.server-page .switch { position:relative; width:42px; height:24px; flex-shrink:0; }.server-page .switch input { opacity:0; width:0; height:0; }.server-page .switch .slider { position:absolute; inset:0; background:#3a3d4d; border-radius:24px; cursor:pointer; transition:.15s; }.server-page .switch .slider::before { content:""; position:absolute; width:18px; height:18px; left:3px; top:3px; background:var(--wit); border-radius:50%; transition:.15s; }.server-page .switch input:checked + .slider { background: linear-gradient(160deg, var(--accent2), var(--accent)); }.server-page .switch input:checked + .slider::before { transform: translateX(18px); }.server-page .settings-savebar { margin-top:14px; }.server-page .btn-menu { background: var(--surface2); color:var(--muted); border:1px solid var(--border); box-shadow:none; padding:6px 10px; font-size:14px; line-height:1; }.server-page .btn-menu:hover:not(:disabled) { background:#2a2d3d; color:var(--text); box-shadow:none; transform:none; }.server-page .context-menu {
    position:absolute; background: linear-gradient(165deg, var(--surface2), var(--surface));
    border:1px solid var(--border-strong); border-radius:10px; padding:6px; min-width:180px; z-index:200;
    box-shadow: 0 12px 30px rgba(0,0,0,.5), 0 1px 0 rgba(255,255,255,.05) inset;
  }.server-page .context-menu.hidden { display:none; }.server-page .ctx-item { padding:8px 12px; border-radius:7px; font-size:13px; cursor:pointer; color:var(--text); transition: background .1s; }.server-page .ctx-item:hover { background: rgba(91,140,255,.16); }.server-page .ctx-item.danger { color: var(--red); }.server-page .ctx-item.danger:hover { background: rgba(240,89,79,.14); }/* ---------- Console autocomplete ---------- */.server-page .cmd-suggest {
    position:absolute; bottom:calc(100% + 6px); left:0; right:0;
    max-height:230px; overflow-y:auto; display:none; z-index:150;
    background:linear-gradient(165deg, var(--surface2), var(--surface));
    border:1px solid var(--border-strong); border-radius:10px; padding:5px;
    box-shadow:0 -10px 28px rgba(0,0,0,.5);
  }.server-page .cmd-suggest.open { display:block; }.server-page .cs-item {
    display:flex; justify-content:space-between; align-items:center; gap:12px;
    padding:6px 10px; border-radius:7px; cursor:pointer; font-size:13px;
    font-family:ui-monospace, 'Cascadia Mono', Consolas, monospace;
  }.server-page .cs-item:hover, .server-page .cs-item.active { background:rgba(91,140,255,.16); }.server-page .cs-hint { color:var(--muted); font-size:11px; font-family:inherit; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }/* ---------- Give item picker ---------- */.server-page .give-grid {
    display:grid; grid-template-columns:repeat(auto-fill, minmax(40px, 1fr)); gap:5px;
    margin-top:8px; max-height:160px; overflow-y:auto;
  }.server-page .give-slot {
    aspect-ratio:1; background:rgba(255,255,255,.05); border:1px solid var(--border);
    border-radius:7px; display:flex; align-items:center; justify-content:center;
    cursor:pointer; padding:5px; transition:all .12s;
  }.server-page .give-slot img { max-width:100%; max-height:100%; image-rendering:pixelated; }.server-page .give-slot:hover { border-color:var(--accent); background:rgba(91,140,255,.12); }.server-page .give-slot.sel { border-color:var(--accent); background:rgba(91,140,255,.22); box-shadow:0 0 0 1px var(--accent); }.server-page .give-selected-name { font-size:11.5px; color:var(--muted); margin-top:5px; min-height:15px; }/* ---------- Wereld tab ---------- */.server-page .world-time-display { text-align:center; padding:14px 0 10px; }.server-page .world-time-emoji { font-size:44px; line-height:1; margin-bottom:6px; }.server-page .world-time-clock { font-size:30px; font-weight:800; letter-spacing:2px; font-variant-numeric:tabular-nums; }.server-page .world-time-lbl { font-size:12.5px; color:var(--muted); margin-top:4px; }.server-page .world-bar-wrap { margin:10px 0 6px; }.server-page .world-bar { position:relative; height:10px; border-radius:5px;
                        background:linear-gradient(to right, #ffdc72 0%, #e88a00 50%, #232541 50%, #111320 100%);
                        overflow:visible; }.server-page .world-bar-cursor { position:absolute; top:-5px; width:20px; height:20px; border-radius:50%;
                        background:var(--wit); margin-left:-10px; box-shadow:0 0 0 2px rgba(0,0,0,.3),0 2px 6px rgba(0,0,0,.45);
                        transition:left .6s ease; pointer-events:none; }.server-page .world-bar-labels { display:flex; justify-content:space-between; font-size:10.5px; color:var(--muted); margin-top:4px; }.server-page .world-btns { display:flex; flex-wrap:wrap; gap:6px; margin:12px 0 4px; }.server-page .world-btn { flex:1; min-width:70px; padding:7px 8px; font-size:12px; white-space:nowrap;
                        background:rgba(255,255,255,.06); border:1px solid var(--border); color:var(--text);
                        border-radius:8px; cursor:pointer; transition:all .15s; }.server-page .world-btn:hover:not(:disabled) { background:rgba(91,140,255,.15); border-color:var(--accent); }.server-page .world-btn.w-active { background:linear-gradient(160deg,var(--accent2),var(--accent)); color:#0a0d18; border-color:transparent; }.server-page .world-btn:disabled { opacity:.4; cursor:default; }.server-page .world-cycle-note { font-size:11.5px; color:var(--muted); margin-top:10px; padding-top:10px; border-top:1px solid var(--border); }/* ---------- Support ticket bubble ---------- */.server-page .support-fab {
    position: fixed; right: 20px; bottom: 20px; z-index: 1200;
    display: inline-flex; align-items: center; gap: 10px;
    min-height: 52px; padding: 0 18px; border: 1px solid rgba(91,140,255,.45);
    border-radius: 999px; background: linear-gradient(145deg, var(--accent), #38BDF8);
    color: var(--wit); font-weight: 900; font-size: 13px; letter-spacing: .01em;
    box-shadow: 0 18px 44px rgba(0,0,0,.42), 0 10px 28px rgba(91,140,255,.26);
    cursor: pointer; transition: transform .16s ease, filter .16s ease;
  }.server-page .support-fab:hover { transform: translateY(-2px); filter: brightness(1.06); }.server-page .support-fab:focus-visible { outline: 3px solid rgba(122,162,255,.55); outline-offset: 3px; }.server-page .support-fab .cloud { width: 26px; height: 26px; display: inline-grid; place-items: center; border-radius: 999px; background: rgba(255,255,255,.18); }.server-page .support-modal {
    position: fixed; inset: 0; z-index: 1300; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(5,7,13,.72); backdrop-filter: blur(6px);
  }.server-page .support-modal.open { display: flex; }.server-page .support-card {
    width: min(560px, 100%); max-height: min(760px, calc(100vh - 36px)); overflow-y: auto;
    background: linear-gradient(165deg,#191b28,#11131e); border: 1px solid var(--border-strong);
    border-radius: 18px; box-shadow: 0 28px 80px rgba(0,0,0,.58);
  }.server-page .support-head { display:flex; justify-content:space-between; gap:14px; padding:20px 22px 14px; border-bottom:1px solid rgba(255,255,255,.07); }.server-page .support-head h2 { margin:0; font-size:18px; }.server-page .support-head p { margin:5px 0 0; color:var(--muted); font-size:13px; line-height:1.45; }.server-page .support-close { width:40px; height:40px; border:1px solid var(--border); border-radius:10px; background:rgba(255,255,255,.06); color:var(--text); cursor:pointer; font-size:22px; }.server-page .support-body { padding:18px 22px 22px; display:grid; gap:13px; }.server-page .support-grid { display:grid; grid-template-columns: 1fr 1fr; gap:12px; }.server-page .support-field label { display:block; color:var(--muted); font-size:12px; font-weight:800; margin-bottom:6px; }.server-page .support-field input, .server-page .support-field select, .server-page .support-field textarea {
    width:100%; box-sizing:border-box; border:1px solid var(--border); border-radius:11px;
    background:rgba(255,255,255,.055); color:var(--text); padding:12px 13px; font-size:14px;
  }.server-page .support-field textarea { min-height:150px; resize:vertical; line-height:1.55; }.server-page .support-field input:focus, .server-page .support-field select:focus, .server-page .support-field textarea:focus { outline:none; border-color:var(--accent); box-shadow:0 0 0 3px rgba(91,140,255,.14); }.server-page .support-context { border:1px solid rgba(91,140,255,.22); background:rgba(91,140,255,.075); color:#aebcff; border-radius:12px; padding:10px 12px; font-size:12px; line-height:1.5; }.server-page .support-option { display:flex; align-items:flex-start; gap:10px; border:1px solid rgba(255,255,255,.08); background:rgba(255,255,255,.035); border-radius:12px; padding:11px 12px; color:var(--muted); font-size:12px; line-height:1.45; }.server-page .support-option input { margin-top:2px; width:18px; height:18px; accent-color:var(--accent); flex-shrink:0; }.server-page .support-option strong { display:block; color:var(--text); font-size:12.5px; margin-bottom:2px; }.server-page .support-actions { display:flex; justify-content:flex-end; gap:10px; margin-top:4px; }.server-page .support-history { border-top:1px solid rgba(255,255,255,.08); padding-top:16px; margin-top:4px; }.server-page .support-history-head { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:10px; }.server-page .support-history-head h3 { margin:0; font-size:14px; color:var(--text); }.server-page .support-history-list { display:grid; gap:8px; }.server-page .support-ticket-row { border:1px solid var(--border); border-radius:12px; background:rgba(255,255,255,.035); padding:11px 12px; }.server-page .support-ticket-top { display:flex; align-items:flex-start; justify-content:space-between; gap:10px; }.server-page .support-ticket-title { color:var(--text); font-weight:850; font-size:13px; line-height:1.35; }.server-page .support-ticket-meta { color:var(--muted); font-size:11px; margin-top:3px; }.server-page .support-ticket-status { white-space:nowrap; font-size:11px; font-weight:850; color:#aebcff; }.server-page .support-ticket-msg { color:var(--muted); font-size:12px; line-height:1.5; margin-top:8px; white-space:pre-wrap; }.server-page .support-ticket-reply { border-left:3px solid var(--accent2); padding:8px 10px; margin-top:9px; border-radius:8px; background:rgba(6,182,212,.08); color:#bdefff; font-size:12px; line-height:1.5; white-space:pre-wrap; }.server-page .plugin-support-cta { display:flex; align-items:center; justify-content:space-between; gap:12px; margin:0 0 14px; padding:12px 14px; border:1px solid rgba(6,182,212,.25); background:rgba(6,182,212,.07); border-radius:12px; color:var(--muted); font-size:12.5px; }/* ---------- Support chat ---------- */.server-page .support-ticket-row { cursor:pointer; transition:background .15s,border-color .15s; }.server-page .support-ticket-row:hover { background:rgba(91,140,255,.08); border-color:rgba(91,140,255,.25); }.server-page .support-chat-view { display:none; }.server-page .support-chat-view.open { display:flex; flex-direction:column; }.server-page .support-chat-back { display:inline-flex; align-items:center; gap:6px; background:none; border:none; color:var(--accent); font-size:13px; font-weight:700; cursor:pointer; padding:0; margin-bottom:12px; }.server-page .support-chat-back:hover { text-decoration:underline; }.server-page .support-chat-messages { flex:1; overflow-y:auto; display:flex; flex-direction:column; gap:8px; padding:4px 0 12px; max-height:320px; }.server-page .support-chat-bubble { max-width:80%; padding:10px 14px; border-radius:14px; font-size:12.5px; line-height:1.55; word-break:break-word; white-space:pre-wrap; }.server-page .support-chat-bubble.mine { align-self:flex-end; background:linear-gradient(145deg,var(--accent),#3d6fe8); color:var(--wit); border-bottom-right-radius:4px; }.server-page .support-chat-bubble.theirs { align-self:flex-start; background:rgba(6,182,212,.12); color:#bdefff; border-bottom-left-radius:4px; }.server-page .support-chat-bubble .chat-sender { font-size:10px; font-weight:800; text-transform:uppercase; letter-spacing:.04em; margin-bottom:3px; opacity:.7; }.server-page .support-chat-bubble .chat-time { font-size:10px; margin-top:4px; opacity:.5; text-align:right; }.server-page .support-chat-input-row { display:flex; gap:8px; margin-top:8px; padding-top:10px; border-top:1px solid rgba(255,255,255,.08); }.server-page .support-chat-input-row textarea { flex:1; background:rgba(255,255,255,.055); border:1px solid var(--border); border-radius:11px; color:var(--text); padding:10px 12px; font-size:13px; resize:none; min-height:44px; max-height:120px; line-height:1.5; }.server-page .support-chat-input-row textarea:focus { outline:none; border-color:var(--accent); box-shadow:0 0 0 3px rgba(91,140,255,.14); }.server-page .support-chat-status-row { display:flex; align-items:center; gap:10px; margin-bottom:10px; padding-bottom:10px; border-bottom:1px solid rgba(255,255,255,.08); flex-wrap:wrap; }/* ---------- mobile (iPhone / Samsung / Android) ---------- */@media (max-width: 768px) {body.server-page { padding: 12px; }.server-page h1 { font-size: 16px; }.server-page .top { flex-wrap: wrap; row-gap: 8px; align-items:center; }.server-page .brand-logo-link { flex:1 1 auto; max-width:calc(100% - 96px); }.server-page .brand-logo-link h1 { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }.server-page .state-pill { font-size: 11.5px; padding: 5px 10px; }.server-page .lang-switch { padding: 6px 8px; font-size: 11px; }.server-page a.logout { margin-left: auto; padding: 6px 10px; font-size: 12px; }.server-page .user-badge { display:none; }.server-page .server-breadcrumb {
      order: 10; flex: 1 1 100%; max-width:100%; min-height:34px;
      display:flex; align-items:center; padding:7px 10px; border-radius:9px;
      background:rgba(255,255,255,.04); border:1px solid var(--border);
      white-space:normal; overflow-wrap:anywhere;
    }.server-page .servers-link, .server-page a.logout { min-height:44px; display:inline-flex; align-items:center; }.server-page .tabs {
      width: 100%; max-width: 100%; overflow-x: auto; flex-wrap: nowrap; position:sticky; top:0; z-index:40;
      -webkit-overflow-scrolling: touch; scrollbar-width: none;
    }.server-page .tabs::-webkit-scrollbar { display: none; }.server-page .tabs button { white-space: nowrap; flex-shrink: 0; padding: 8px 13px; font-size: 12.5px; }.server-page .grid { grid-template-columns: 1fr; gap: 12px; }.server-page .card { padding: 14px 15px; border-radius:12px; }.server-page .card h2 { font-size: 11.5px; flex-wrap: wrap; row-gap: 6px; }.server-page .row { align-items:flex-start; gap:10px; }.server-page .row span:last-child { max-width:62%; }.server-page .btns { flex-wrap: wrap; }.server-page .btns button, .server-page .btns a { flex: 1 1 auto; min-width: 120px; min-height:44px; }.server-page .table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }.server-page table.filetable { font-size: 12.5px; white-space: nowrap; }.server-page .modal-overlay { padding: 10px; align-items: flex-end; }.server-page .modal-box, .server-page .modal-box.wide {
      width: 100%; max-width: 100%; max-height: 88vh; padding: 16px;
      border-radius: 16px 16px 0 0;
    }.server-page .modal-close-x { width:42px; height:42px; top:8px; right:8px; }.server-page .editor-wrap { height:min(58vh, 440px); }.server-page .editor-wrap #editArea, .server-page .editor-wrap .editor-highlight { font-size:12.5px; }.server-page .detail-head { gap: 10px; }.server-page .detail-head img { width: 46px; height: 46px; }.server-page .detail-head h3 { font-size: 14.5px; }.server-page .character-render { min-height: 120px; margin: 4px 0 10px; }.server-page .character-render img { height: 120px; }.server-page .mc-grid { grid-template-columns: repeat(9, 1fr); width: 100%; gap: 3px; }.server-page .mc-armor-row { display: flex; justify-content: center; gap: 3px; }.server-page .mc-slot { width: auto; height: auto; aspect-ratio: 1 / 1; }.server-page .mc-slot img { width: 75%; height: 75%; }.server-page .mc-count { font-size: 9.5px; }.server-page .mc-fallback { font-size: 8.5px; }.server-page .stat-label { width: 64px; font-size: 11px; }.server-page .stat-val { width: 48px; font-size: 11px; }.server-page .coordrow { flex-wrap: wrap; }.server-page .coordrow input { flex: 1 1 60px; width: auto; min-width: 0; }.server-page .coordrow button { flex: 1 1 100%; }.server-page .gm-btns button { flex: 1 1 calc(50% - 6px); }.server-page .ptog-row { padding: 11px 0; }.server-page .global-restart { flex-direction: column; align-items: stretch; gap: 10px; }.server-page .global-restart button { width: 100%; }.server-page .player-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }.server-page .pitem { gap:10px; align-items:flex-start; }.server-page .pitem .actions { flex-wrap:wrap; justify-content:flex-end; }.server-page .pitem .actions button { min-height: 44px; }.server-page .settings-grid { grid-template-columns: 1fr; }.server-page .ptabs { overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }.server-page .ptabs button { white-space: nowrap; flex-shrink: 0; }.server-page .uuid-row { flex-wrap: wrap; }.server-page .uuid-row span { word-break: break-all; }.server-page input, .server-page select, .server-page textarea { font-size: 16px; }/* voorkomt iOS-zoom */.server-page .btn-small, .server-page .ptabs button { font-size: 12px; }.server-page .filetoolbar, .server-page .ftools { width:100%; flex-wrap:wrap; margin-left:0 !important; }.server-page #fileSearch { width:100% !important; flex:1 1 100%; min-height:40px; }.server-page .ftools button { flex:1 1 auto; min-height: 44px; }.server-page .context-menu { min-width: 160px; max-width: calc(100vw - 20px); }.server-page .support-fab { right: 12px; bottom: 12px; min-height: 50px; padding: 0 14px; }.server-page .support-fab .label { display:none; }.server-page .support-modal { align-items:flex-end; padding:10px; }.server-page .support-card { max-height:88vh; border-radius:16px 16px 0 0; }.server-page .support-actions { flex-direction:column-reverse; }.server-page .support-actions button { width:100%; min-height:44px; }.server-page .support-grid { grid-template-columns: 1fr; }.server-page .plugin-support-cta, .server-page .support-ticket-top { flex-direction:column; align-items:flex-start; }.server-page .support-head, .server-page .support-body { padding-left:16px; padding-right:16px; }/* Touch-targets ≥44px (WCAG 2.5.5 / master-prompt) */.server-page .btns button, .server-page .btns a, .server-page .gm-btns button, .server-page .cmdrow button, .server-page .cmdrow input, .server-page .ptabs button, .server-page .tabs button, .server-page .lang-switch, .server-page select.inline-select, .server-page .switch { min-height: 44px; }.server-page .ct-btn { min-height: 44px; min-width: 44px; }.server-page .cmdrow { flex-wrap:wrap; }.server-page .cmdrow input, .server-page .cmdrow select { min-width:0; }.server-page .cmdrow button { flex:0 0 auto; }/* Console-tools: zoekveld vol, knoppen op een rij eronder */.server-page .console-tools { width: 100%; margin-left: 0; flex-wrap: wrap; margin-top: 6px; }.server-page .console-tools input { flex: 1 1 100%; width: auto; }.server-page #log { height:260px; font-size:12px; }/* Nieuwe kaarten: meters/adres netjes stapelen */.server-page .hh-address { width: 100%; box-sizing: border-box; }.server-page .hh-actions { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px; }.server-page .hh-actions button { width:100%; min-width:0; padding-left:8px; padding-right:8px; }.server-page #perfChart { height: 80px; }}@media (max-width: 420px) {.server-page .brand-icon { width: 28px; height: 28px; font-size: 13px; }.server-page h1 { font-size: 14.5px; }.server-page .state-pill span:not(.status-dot) { display: none; }.server-page .gm-btns button { flex: 1 1 100%; }.server-page .hh-actions { grid-template-columns:1fr; }.server-page .row { flex-direction:column; gap:3px; padding:7px 0; }.server-page .row span:last-child { max-width:100%; text-align:left; }.server-page .cmdrow button { width:100%; }.server-page .pitem { flex-direction:column; align-items:stretch; }.server-page .pitem .actions { width:100%; }.server-page .pitem .actions button { flex:1 1 auto; }.server-page .support-ticket-status { white-space:normal; }}/* Extra-smal (320-360px): niets mag horizontaal overlopen */@media (max-width: 360px) {body.server-page { padding: 9px; }.server-page .card { padding: 12px; }.server-page .hh-badge { font-size: 17px; }.server-page .hh-addr-val { font-size: 13px; word-break: break-all; }.server-page .player-grid { grid-template-columns: 1fr; }.server-page .console-tools input { font-size: 12px; }}/* ── Portal Order Page (portal_order.html) Styles ── */
.portal-order-page * { box-sizing: border-box; }
body.portal-order-page {
  background:
    radial-gradient(900px 700px at 15% -10%, rgba(91,140,255,.10), transparent 55%),
    radial-gradient(600px 500px at 95% 95%, rgba(63,201,122,.07), transparent 55%),
    #0c0d14;
  color: #e7e8ee;
  font-family: -apple-system, "Segoe UI", system-ui, sans-serif;
  min-height: 100vh;
}

/* ── Header ── */
.portal-order-page header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 28px; border-bottom: 1px solid rgba(255,255,255,.07);
  background: rgba(12,13,20,.8); backdrop-filter: blur(10px);
  position: sticky; top: 0; z-index: 10;
}
.portal-order-page .logo { font-size: 17px; font-weight: 800; color: #e7e8ee; display: flex; align-items: center; gap: 8px; }
.portal-order-page .logo-icon { width: 32px; height: 32px; background: linear-gradient(145deg,#7aa2ff,var(--accent)); border-radius: 8px; display:flex; align-items:center; justify-content:center; font-size:16px; }
.portal-order-page .header-user { display: flex; align-items: center; gap: 14px; font-size: 13px; color: #8a8d9c; }
.portal-order-page .header-user a { color: var(--accent); text-decoration: none; }
.portal-order-page .header-user a:hover { text-decoration: underline; }
.portal-order-page .lang-switch { background: #181921; color: #e7e8ee; border: 1px solid rgba(255,255,255,.12); border-radius: 9px; padding: 6px 9px; font-size: 12.5px; cursor: pointer; }
.portal-order-page .lang-switch:focus { outline: none; border-color: var(--accent); }
.portal-order-page select, .portal-order-page select option, .portal-order-page select optgroup { background: #111320; color: #f4f6fb; }
.portal-order-page select option:disabled { color: #7b8194; }

/* ── Main layout ── */
.portal-order-page main { max-width: 820px; margin: 0 auto; padding: 36px 20px 80px; }
.portal-order-page h1 { font-size: 26px; font-weight: 800; margin-bottom: 6px; }
.portal-order-page .sub { font-size: 14px; color: #6b7080; margin-bottom: 32px; }

/* ── Section card ── */
.portal-order-page .section {
  background: linear-gradient(165deg, #181921, #141520);
  border: 1px solid rgba(255,255,255,.08); border-radius: 14px;
  padding: 22px 24px; margin-bottom: 18px;
}
.portal-order-page .section-title {
  font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 16px;
}

/* ── Game cards ── */
.portal-order-page .game-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
.portal-order-page .game-card {
  border: 2px solid rgba(255,255,255,.08); border-radius: 11px; padding: 16px 12px;
  text-align: center; cursor: pointer; transition: border-color .15s, background .15s;
  background: rgba(255,255,255,.03); user-select: none;
}
.portal-order-page .game-card.active { border-color: var(--accent); background: rgba(91,140,255,.12); }
.portal-order-page .game-card.disabled { opacity: .38; cursor: not-allowed; }
.portal-order-page .game-card .game-icon { font-size: 28px; display: block; margin-bottom: 6px; }
.portal-order-page .game-card .game-name { font-size: 13px; font-weight: 600; }
.portal-order-page .game-card .tpl-desc { font-size: 10.5px; color: #6b7080; display: block; margin-top: 2px; }
.portal-order-page .game-card .game-badge {
  display: inline-block; font-size: 10px; margin-top: 5px; padding: 2px 7px;
  border-radius: 20px; background: rgba(91,140,255,.2); color: #7aa2ff; font-weight: 600;
}
.portal-order-page .game-card.disabled .game-badge { background: rgba(255,255,255,.08); color: #5a5e70; }

/* ── Field ── */
.portal-order-page .field { margin-bottom: 18px; }
.portal-order-page .field:last-child { margin-bottom: 0; }
.portal-order-page label { display: block; font-size: 12px; font-weight: 600; color: #8a8d9c; margin-bottom: 7px; letter-spacing: .03em; }
.portal-order-page input[type="text"], .portal-order-page select {
  width: 100%; padding: 11px 13px; border-radius: 9px;
  border: 1px solid rgba(255,255,255,.12); background: #0e0f1a; color: #e7e8ee;
  font-size: 15px; transition: border-color .15s, box-shadow .15s;
}
.portal-order-page input[type="text"]:focus, .portal-order-page select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(91,140,255,.18); }
.portal-order-page .hint { font-size: 12px; color: #5a5e70; margin-top: 5px; }
.portal-order-page .hint strong { color: #a0a4b8; }

/* ── Field row (two columns) ── */
.portal-order-page .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 480px) { .portal-order-page .field-row { grid-template-columns: 1fr; } }

/* ── RAM cards ── */
.portal-order-page .ram-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 10px; }
.portal-order-page .ram-card {
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 4px;
  min-height: 120px;
  border: 2px solid rgba(255,255,255,.08); border-radius: 12px; padding: 16px 10px;
  text-align: center; cursor: pointer; background: rgba(255,255,255,.03);
  transition: border-color .15s, background .15s, transform .12s; font: inherit; color: #e7e8ee;
}
.portal-order-page .ram-card:hover { border-color: rgba(91,140,255,.4); transform: translateY(-2px); }
.portal-order-page .ram-card.active { border-color: var(--accent); background: rgba(91,140,255,.12); }
.portal-order-page .ram-card.disabled, .portal-order-page .ram-card:disabled { opacity: .45; cursor: not-allowed; filter: grayscale(.25); transform: none; }
.portal-order-page .ram-card.disabled:hover, .portal-order-page .ram-card:disabled:hover { border-color: rgba(255,255,255,.08); transform: none; }
.portal-order-page .ram-card .ram-gb { font-size: 20px; font-weight: 800; line-height: 1.1; }
.portal-order-page .ram-card .ram-badge { font-size: 9px; font-weight: 800; color: #3fc97a; text-transform: uppercase; letter-spacing: .05em; line-height: 1.2; }
.portal-order-page .ram-card .ram-price { font-size: 13px; font-weight: 700; color: var(--accent2); margin-top: 1px; }
.portal-order-page .ram-card .ram-hint { font-size: 10.5px; color: var(--muted); line-height: 1.3; margin-top: auto; }
.portal-order-page .ram-card.active .ram-price { color: #9db8ff; }

/* ── Toggle ── */
.portal-order-page .toggle-row {
  display: flex; align-items: center; gap: 12px; padding: 14px 16px;
  border: 1px solid rgba(255,255,255,.08); border-radius: 10px; cursor: pointer;
  background: rgba(255,255,255,.03); transition: background .15s;
}
.portal-order-page .toggle-row:hover { background: rgba(255,255,255,.05); }
.portal-order-page .toggle-row input[type="checkbox"] { display: none; }
.portal-order-page .toggle-track {
  width: 38px; height: 22px; border-radius: 11px; background: #2a2c3a;
  position: relative; flex-shrink: 0; transition: background .2s;
}
.portal-order-page .toggle-track::after {
  content: ''; position: absolute; top: 3px; left: 3px;
  width: 16px; height: 16px; border-radius: 50%; background: var(--wit); transition: left .2s;
}
.portal-order-page .toggle-row.on .toggle-track { background: var(--accent); }
.portal-order-page .toggle-row.on .toggle-track::after { left: 19px; }
.portal-order-page .toggle-info { flex: 1; }
.portal-order-page .toggle-label-text { font-size: 14px; font-weight: 600; }
.portal-order-page .toggle-desc { font-size: 12px; color: #6b7080; margin-top: 2px; }
.portal-order-page .toggle-price { display: flex; align-items: center; justify-content: flex-end; }
.portal-order-page .badge { display: inline-flex; align-items: center; justify-content: center; padding: 5px 11px; border-radius: 999px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.portal-order-page .badge-success { background: rgba(63,201,122,.18); color: #3fc97a; }

/* ── Checkout box ── */
.portal-order-page .checkout-box {
  position: sticky; bottom: 0;
  background: linear-gradient(180deg, transparent 0%, rgba(12,13,20,.98) 20%);
  padding: 20px 20px 24px; margin: 0 -20px;
}
.portal-order-page .checkout-inner {
  max-width: 820px; margin: 0 auto;
  display: flex; align-items: center; gap: 20px;
  background: linear-gradient(165deg, #1a1b28, #151621);
  border: 1px solid rgba(255,255,255,.1); border-radius: 14px;
  padding: 18px 22px;
  box-shadow: 0 8px 32px rgba(0,0,0,.5);
}
@media (max-width: 560px) { .portal-order-page .checkout-inner { flex-direction: column; align-items: stretch; } }

/* ═══════════════════════════════════════════════════════════════════════════
   BESTELPAGINA OP TELEFOON — melding Cihan 27 juli 2026: "chaotisch".
   Gemeten op staging bij 390x780, en het waren twee KLEVENDE blokken tegelijk:

     .order-chips   sticky top,    hoogte 113px  (de 5 stappen breken naar 3 rijen)
     .checkout-box  sticky bottom, hoogte 494px  (63% van het scherm)

   Samen 78% van de hoogte permanent bezet, met een overlap-band waarin de chips
   over de trial-tekst heen vielen. Op desktop klopt het ontwerp: daar is de
   stappenbalk één rij en past de checkout-box onderin.

   Twee ingrepen, allebei alleen onder 720px:
     1. De stappenbalk blijft ÉÉN rij en schuift horizontaal. `flex-wrap: wrap`
        was hier de fout: een klevende balk die meegroeit met de inhoud kan het
        halve scherm opeten. 44px-aanraakvlak blijft (WCAG 2.5.5).
     2. De checkout-box kleeft niet meer. Een blok van 494px vastzetten op een
        scherm van 780px laat geen ruimte over om het formulier te lezen dat je
        juist moet invullen; hij hoort daar gewoon onderaan de pagina.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
  .order-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    /* Twee schrijfwijzen omdat geen van beide overal werkt: `scrollbar-width` kent
       Safari niet, `::-webkit-scrollbar` kent Firefox niet. Samen dekken ze alles.
       (`-webkit-overflow-scrolling: touch` stond hier eerst en is verwijderd: dat doet
       sinds iOS 13 in geen enkele browser nog iets.) */
    scrollbar-width: none;
  }
  .order-chips::-webkit-scrollbar { display: none; }
  .order-chip { flex-shrink: 0; }       /* anders persen 5 chips zichzelf plat */
  .portal-order-page .checkout-box,
  .checkout-box {
    position: static;
    background: none;                   /* de verloop-fade hoort bij het kleven */
  }
}
.portal-order-page .price-block { flex: 1; }
.portal-order-page .price-label { font-size: 11px; color: #6b7080; text-transform: uppercase; letter-spacing: .06em; display: block; }
.portal-order-page .price-value { font-size: 28px; font-weight: 900; color: #e7e8ee; line-height: 1.1; }
.portal-order-page .price-sub { font-size: 11px; color: #4a4d5e; display: block; margin-top: 2px; }
.portal-order-page .btn-checkout {
  flex-shrink: 0; padding: 14px 28px; border-radius: 10px; border: none;
  background: linear-gradient(145deg, var(--accent), #3d6fe8);
  color: var(--wit); font-weight: 800; font-size: 15px; cursor: pointer;
  box-shadow: 0 4px 16px rgba(91,140,255,.35);
  transition: transform .1s, filter .15s;
  display: flex; align-items: center; gap: 8px;
}
.portal-order-page .btn-checkout:hover { filter: brightness(1.1); transform: translateY(-1px); }
.portal-order-page .btn-checkout:active { transform: translateY(0); }
.portal-order-page .btn-checkout:disabled { opacity: .5; cursor: not-allowed; transform: none; filter: none; }
.portal-order-page .checkout-error { color: var(--red); font-size: 13px; background: rgba(240,89,79,.1); border: 1px solid rgba(240,89,79,.25); padding: 9px 13px; border-radius: 8px; margin-bottom: 12px; display: none; }

/* ── Spinner ── */
.portal-order-page .spinner { width: 18px; height: 18px; border: 2.5px solid rgba(255,255,255,.3); border-top-color: var(--wit); border-radius: 50%; animation: spin .7s linear infinite; display: none; }
@keyframes spin { to { transform: rotate(360deg); } }


/* ── Portal Return Page (portal_return.html) Styles ── */
.portal-return-page * { box-sizing: border-box; }
body.portal-return-page {
  background:
    radial-gradient(900px 700px at 15% -10%, rgba(91,140,255,.10), transparent 55%),
    #0c0d14;
  color: #e7e8ee; font-family: -apple-system, "Segoe UI", system-ui, sans-serif;
  min-height: 100vh; display: flex; flex-direction: column;
}
.portal-return-page header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 28px; border-bottom: 1px solid rgba(255,255,255,.07);
}
.portal-return-page .logo { font-size: 17px; font-weight: 800; display: flex; align-items: center; gap: 8px; }
.portal-return-page .logo-icon { width: 32px; height: 32px; background: linear-gradient(145deg,#7aa2ff,var(--accent)); border-radius: 8px; display:flex; align-items:center; justify-content:center; font-size:16px; }
.portal-return-page .header-user { font-size: 13px; color: #8a8d9c; }
.portal-return-page .header-user a { color: var(--accent); text-decoration: none; }

.portal-return-page main {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 32px 20px;
}
.portal-return-page .box {
  background: linear-gradient(165deg, #181921, #141520);
  border: 1px solid rgba(255,255,255,.09); border-radius: 18px;
  padding: 40px 36px; max-width: 460px; width: 100%; text-align: center;
  box-shadow: 0 20px 60px rgba(0,0,0,.5);
}

/* ── Status icon ── */
.portal-return-page .status-icon {
  width: 72px; height: 72px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 32px;
  margin: 0 auto 22px;
  background: rgba(91,140,255,.15); border: 2px solid rgba(91,140,255,.3);
}
.portal-return-page .status-icon.done  { background: rgba(63,201,122,.15); border-color: rgba(63,201,122,.4); }
.portal-return-page .status-icon.error { background: rgba(240,89,79,.15);  border-color: rgba(240,89,79,.4); }

/* ── Steps ── */
.portal-return-page .steps { margin: 24px 0 28px; text-align: left; display: flex; flex-direction: column; gap: 10px; }
.portal-return-page .step {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  border-radius: 10px; font-size: 14px; background: rgba(255,255,255,.03);
  border: 1px solid rgba(255,255,255,.06);
}
.portal-return-page .step .step-icon { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 13px; }
.portal-return-page .step.pending  .step-icon { background: rgba(255,255,255,.08); color: #5a5e70; }
.portal-return-page .step.active   .step-icon { background: rgba(91,140,255,.2); }
.portal-return-page .step.complete .step-icon { background: rgba(63,201,122,.2); }
.portal-return-page .step.failed   .step-icon { background: rgba(240,89,79,.15); }
.portal-return-page .step-label { font-weight: 600; }
.portal-return-page .step-sub   { font-size: 12px; color: #6b7080; margin-top: 1px; }

/* ── Spinner ── */
.portal-return-page .spin { animation: spin .8s linear infinite; display: inline-block; }

/* ── Heading ── */
.portal-return-page h2 { font-size: 22px; font-weight: 800; margin-bottom: 6px; }
.portal-return-page .sub { font-size: 14px; color: #6b7080; }

/* ── CTA button ── */
.portal-return-page .btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 14px 28px; border-radius: 10px; border: none;
  background: linear-gradient(145deg, #4ee08a, #29a85e); color: #06150c;
  font-weight: 800; font-size: 15px; cursor: pointer; text-decoration: none;
  box-shadow: 0 4px 16px rgba(46,180,110,.3); transition: filter .15s, transform .1s;
  margin-top: 6px;
}
.portal-return-page .btn:hover { filter: brightness(1.08); transform: translateY(-1px); }
.portal-return-page .btn-retry {
  background: linear-gradient(145deg, var(--accent), #3d6fe8); color: var(--wit);
  box-shadow: 0 4px 16px rgba(91,140,255,.3);
}
.portal-return-page .btn-pay {
  background: linear-gradient(145deg, #4ee08a, #29a85e); color: #06150c;
  box-shadow: 0 4px 16px rgba(46,180,110,.3);
}
.portal-return-page .payment-box {
  margin-top: 18px; padding: 14px 16px; border-radius: 10px;
  background: rgba(91,140,255,.08); border: 1px solid rgba(91,140,255,.2);
  font-size: 13px; color: #b7bcc9; text-align: left;
}
.portal-return-page .payment-box strong { color: #e7e8ee; }
.portal-return-page .contact-row { margin-top: 14px; font-size: 12.5px; color: #6b7080; }
.portal-return-page .contact-row a { color: var(--accent); text-decoration: none; font-weight: 600; }


/* ── Profile Page (profile.html) Styles ── */
.profile-page * { box-sizing: border-box; }
body.profile-page {
  --bg: #0c0d14; --surface: #15161f; --card: #1a1b27;
  --border: rgba(255,255,255,.08); --text: #e7e8ee; --muted: #94A0B8;
  --accent: var(--ch-paars, #5b8cff); --green: #3fc37a; --red: #f0594f;
  background: var(--bg); color: var(--text); font-family: -apple-system, "Segoe UI", system-ui, sans-serif; min-height: 100vh;
}
.profile-page .topbar {
  background: var(--surface); border-bottom: 1px solid var(--border);
  padding: 0 24px; height: 56px; display: flex; align-items: center; gap: 12px;
}
.profile-page .topbar .logo { font-size: 18px; font-weight: 700; color: var(--wit); display: flex; align-items: center; gap: 8px; text-decoration: none; }
.profile-page .topbar .logo .brand-cave { color: var(--accent); }
.profile-page .topbar .spacer { flex: 1; }
.profile-page .topbar .user-badge { display: flex; align-items: center; gap: 12px; font-size: 13px; color: var(--muted); }
.profile-page .topbar .user-badge strong { color: var(--text); }
/* Alleen MAAT en vorm. De vullingen van `.btn-primary`, `.btn-muted` en `.btn-logout`
   stonden hier en zijn op 30 juli 2026 weggehaald: ze wogen (0,2,0) tegen het contract
   (0,1,0) en wonnen dus. Gemeten gevolg: na de unificatie was dit het ENIGE scherm met
   nog een verloop-primair, terwijl de glans er wél al af was — een halve knop. Ook
   `border: none` is weg; dat maakte de rand van de rustige én gevaar-knop onzichtbaar,
   en juist daar IS de rand het bedieningselement (WCAG 1.4.11). */
.profile-page .btn, .profile-page .btn-logout { padding: 8px 14px; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 600; text-decoration: none; display: inline-flex; align-items: center; gap: 6px; }
.profile-page .main { max-width: 980px; margin: 28px auto 40px; padding: 0 24px; }
.profile-page .page-header { margin-bottom: 24px; }
.profile-page .page-header h1 { font-size: 24px; margin-bottom: 8px; }
.profile-page .page-header p { color: var(--muted); font-size: 14px; line-height: 1.6; }
.profile-page .grid { display:grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap:18px; align-items:start; }
.profile-page .card { background: var(--surface); border: 1px solid var(--border); border-radius: 18px; padding: 24px; box-shadow: 0 18px 40px rgba(0,0,0,.25); }
.profile-page .card h2 { font-size:18px; margin:0 0 8px; }
.profile-page .card-sub { color:var(--muted); font-size:13px; line-height:1.55; margin-bottom:16px; }
.profile-page .field { margin-bottom: 18px; }
.profile-page .field label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
/* `min-height` erbij (28 juli 2026). Deze regel zette alleen padding, en dat kwam op
   42px uit -- twee pixels onder de 44px-vloer die op de KLANTkant op elke breedte
   geldt. Gemeten in de render, niet in de CSS: `check_knoppen_44px` leest gedeclareerde
   min-heights en een regel die er geen heeft valt daar per constructie buiten. Precies
   het gat waarvoor AGENTS.md zegt dat statisch en runtime allebei moeten draaien. */
.profile-page .field input { width: 100%; min-height: 44px; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--border); background: rgba(255,255,255,.04); color: var(--text); font-size: 14px; }
.profile-page .field input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(91,140,255,.12); }
.profile-page .field-hint { font-size: 12px; color: var(--muted); margin-top: -8px; margin-bottom: 14px; }
.profile-page
.profile-page
.profile-page
.profile-page .stack { display:grid; gap:12px; }
.profile-page .item { border:1px solid var(--border); background:rgba(255,255,255,.035); border-radius:14px; padding:14px; }
.profile-page .item-top { display:flex; align-items:flex-start; justify-content:space-between; gap:10px; margin-bottom:7px; }
.profile-page .item-title { font-weight:800; color:var(--text); }
.profile-page .item-meta { color:var(--muted); font-size:12px; line-height:1.55; }
.profile-page .pill { display:inline-flex; align-items:center; border:1px solid rgba(91,140,255,.28); background:rgba(91,140,255,.1); color:#aebcff; border-radius:999px; padding:4px 8px; font-size:11px; font-weight:800; white-space:nowrap; }
.profile-page .pill.warn { border-color:rgba(245,158,11,.35); background:rgba(245,158,11,.12); color:#fbbf24; }
.profile-page .pill.ok { border-color:rgba(63,195,122,.35); background:rgba(63,195,122,.12); color:#4ade80; }
.profile-page .item-actions { display:flex; gap:8px; flex-wrap:wrap; margin-top:10px; }
.profile-page .empty { border:1px dashed var(--border); border-radius:14px; padding:16px; color:var(--muted); font-size:13px; line-height:1.55; }
@media (max-width: 820px) { .profile-page .grid { grid-template-columns:1fr; } }
@media (max-width: 680px) { .profile-page .main { padding: 0 16px; } .profile-page .topbar { padding: 0 16px; } .profile-page .topbar .user-badge { display:none; } }

/* ══════════════════════════════════════════════════════════════════════════
   FASE 1 — Fundament (toegankelijkheid + bewegingsrespect)
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Consistente toetsenbord-focus ──────────────────────────────────────────
   Inputs/selects/textareas hebben al een zichtbare focus (border + shadow);
   deze sweep geeft knoppen, links, tabs en sidebar-links een duidelijke ring
   voor toetsenbordgebruikers. Muisklikken tonen geen ring (:focus-visible). */
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
.btn-small:focus-visible,
.sidebar-link:focus-visible,
.tabs button:focus-visible,
.tabs a:focus-visible,
[role="button"]:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
.lang-switch:focus-visible,
.switch input:focus-visible + .slider {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 8px;
}
/* Muisinteractie: geen zichtbare outline, alleen toetsenbord. */
:focus:not(:focus-visible) {
  outline: none;
}

/* ── Bewegingsreductie respecteren ──────────────────────────────────────────
   Gebruikers met "verminder beweging" (OS-instelling) krijgen vrijwel geen
   animaties/overgangen — voorkomt misselijkheid en voelt rustiger. */
@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;
  }
  html {
    scroll-behavior: auto;
  }
}

/* Speler-inventaris: op desktop mag het hoofd-/hotbar-rooster niet naar volle
   breedte rekken (dan plakken de slots links terwijl de armor-rij centreert →
   misaligned). Forceer content-breedte zodat armor + inventaris + hotbar allen
   even breed en gecentreerd uitlijnen. Mobiel (repeat(9,1fr)) blijft ongemoeid. */
@media (min-width: 769px) {
  .server-page .mc-inv .mc-grid { width: max-content; }
}

/* Speler-detail-modal: 2-koloms (acties links, skin + inventaris rechts) zodat
   je alles in één oogopslag ziet zonder scrollen. Stapelt op smalle schermen. */
.server-page #invModal .modal-box.wide { width: 960px; max-width: calc(100vw - 24px); }
.server-page #invModal .inv-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 22px;
  align-items: start;
}
.server-page #invModal .inv-col-left { min-width: 0; }
/* Gamemode-rij: alle 4 knoppen (Survival/Creative/Adventure/Spectator) op één
   rij i.p.v. de standaard 2-per-rij. Alleen deze rij; andere knopgroepen
   (Mute/Heal/Feed, moderatie) en de inventaris blijven ongemoeid. */
.server-page #invModal #gmBtns button { flex: 1 1 0; min-width: 0; }
.server-page #invModal .inv-col-right {
  display: flex;
  flex-direction: column;
  align-items: center;
}
@media (max-width: 820px) {
  .server-page #invModal .inv-cols { grid-template-columns: 1fr; gap: 12px; }
  .server-page #invModal .modal-box.wide { width: 100%; }
}

/* Serverpaneel gebruikt nu dezelfde sidebar-shell als het hoofdpaneel: de
   body mag geen eigen padding meer hebben (de .main levert de content-padding),
   anders zit er een rand rond de full-bleed shell. */
body.server-page { padding: 0; }
/* Staging is op iedere pagina onmiskenbaar en kan niet voor productie worden
   aangezien. Het attribuut wordt server-side op <html> gezet. */
html[data-panel-environment="staging"] body::after {
  content: "TESTOMGEVING · GEEN ECHTE KLANTACTIES";
  position: fixed;
  /* Onder de modal-overlays (.cave-modal-ov = 10000, panel-modals 14000, toasts 15000):
     de badge zit rechtsonder, precies waar modal-actieknoppen staan. Op z-index max
     dekte hij die knoppen af (Cihan kon de CurseForge-install niet bevestigen). Hij is
     pointer-events:none (blokkeerde nooit de klik), maar wél visueel — dus lager dan
     elke modal, en de modal-overlay dimt 'm netjes weg zodra er een venster open staat. */
  z-index: 9990;
  right: 12px;
  bottom: 12px;
  padding: 8px 12px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 999px;
  background: #b45309;
  color: var(--wit);
  font: 700 12px/1.2 Inter, sans-serif;
  letter-spacing: 0.05em;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.35);
  pointer-events: none;
}

@media (max-width: 480px) {
  html[data-panel-environment="staging"] body::after {
    right: 8px;
    bottom: 8px;
    max-width: calc(100vw - 16px);
    font-size: 10px;
  }
  html[data-panel-environment="staging"] .shell-sidebar {
    padding-bottom: 52px;
  }
}

/* ═══ Koppelingen op de gebruikerskaart: servers & websites ═══════════════════
   Eén visuele taal voor beide (chips met naam + rol/status en een subtiele
   verwijderknop), zodat de Gebruikers-tab niet uit elkaar valt. */
.link-groep {
  margin-top: 6px;
  padding-top: 8px;
  border-top: 1px dashed var(--border);
}
.link-groep + .link-groep { margin-top: 8px; }

.link-kop {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}
.link-kop button {
  background: none;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 99px;
  padding: 3px 10px;
  font-size: 10.5px;
  font-weight: 700;
  cursor: pointer;
  min-height: 44px;
  transition: color .15s, border-color .15s;
}
.link-kop button:hover { color: var(--accent-l, #9CC0FF); border-color: var(--accent, #5B8CFF); }

.link-chips { display: flex; flex-wrap: wrap; gap: 6px; }

.link-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--border);
  border-radius: 99px;
  padding: 4px 6px 4px 11px;
  font-size: 11.5px;
  max-width: 100%;
}
.link-chip .naam {
  color: var(--text);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 150px;
}
.link-chip .rol { color: var(--muted); font-size: 10.5px; }
.link-chip .x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.link-chip .x:hover { background: rgba(240, 89, 79, .18); color: #f0594f; }
.link-chip.web { border-color: rgba(91, 140, 255, .3); background: rgba(91, 140, 255, .07); }
.link-chip .stip {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: #e0a03a;
}
.link-chip .stip.live { background: var(--green, #34d399); }
.link-leeg { font-size: 11px; color: var(--muted); font-style: italic; }


/* Koppel-dropdown op de gebruikerskaart */
.link-koppel {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}
.link-koppel select {
  flex: 1;
  min-width: 0;
  background: #0c0d14;
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 8px;
  padding: 7px 9px;
  font-size: 11.5px;
  font-family: inherit;
  min-height:44px;
  cursor: pointer;
}
.link-koppel select:focus { outline: 2px solid var(--accent, #5B8CFF); outline-offset: 1px; }
.link-koppel button {
  background: rgba(91, 140, 255, .15);
  border: 1px solid rgba(91, 140, 255, .35);
  color: var(--accent-l, #9CC0FF);
  border-radius: 8px;
  padding: 7px 14px;
  font-size: 11.5px;
  font-weight: 700;
  cursor: pointer;
  min-height: 44px;
  white-space: nowrap;
}
.link-koppel button:hover { background: var(--accent, #5B8CFF); color: var(--wit); }

/* Statusmeldingen buiten de profielpagina (Gebruikers-/Website-aanvragen-tab):
   de .msg-ok/.msg-err-regels waren alleen binnen .profile-page gestyled. */


/* ═══ Merkconsistentie klantkant ═══════════════════════════════════════════
   De marketingsite (cavehosting.com) is de merkbron: paars accent + logo.
   De klantgerichte paneelpagina's (bestellen, betaalretour) draaiden nog op
   het blauwe beheerderspalet, waardoor een klant tijdens één reis van kleur
   wisselde. Alleen deze twee body-classes worden omgezet; het beheerpaneel
   houdt bewust zijn eigen (blauwe) identiteit. */
body.portal-order-page,
body.portal-return-page {
  --accent: var(--ch-paars, #5b8cff);
  --accent2: var(--ch-paars-l, #9CC0FF);
}
body.portal-order-page .brand-cave,
body.portal-return-page .brand-cave {
  color: var(--accent2);
}


/* ═══════════════════════════════════════════════════════════════════════════
   Knoppen, meldingen en raamwerk — één plek, één afspraak
   ═══════════════════════════════════════════════════════════════════════════
   Drie fouten die hier vandaan kwamen:
   1. .cave-btn* (de bevestigingsvensters) bestond alléén in index.html. In het
      beheerpaneel viel 'Definitief verwijderen' daardoor terug op een grijze
      standaardknop — visueel identiek aan 'Annuleren'. Precies bij de acties
      waar het verschil telt.
   2. Layoutklassen die nergens gedefinieerd waren (.user-form-grid,
      .products-layout-grid): formulieren zonder kolommen, een 'live preview'
      die onder de hele catalogus viel in plaats van ernaast.
   3. min-height:unset stond 21× inline en zette de 44px-touchregel uit — óók op
      de hamburgerknop, dé navigatieknop op mobiel.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Bevestigingsvensters (cave-modal) ── */
.cave-modal-btns { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; }
.cave-btn {
  padding: 10px 18px;
  border-radius: 10px;
  border: 1px solid transparent;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  min-height: 44px;                 /* WCAG 2.5.5 — geldt ook hier */
  transition: filter .12s, transform .08s, background .12s;
}
.cave-btn:active { transform: translateY(1px); }
.cave-btn:focus-visible { outline: 2px solid var(--accent2, #7aa2ff); outline-offset: 2px; }
.cave-btn-cancel {
  background: rgba(255, 255, 255, .06);
  color: var(--text, #e7e8ee);
  border-color: var(--border, #2c3040);
}
.cave-btn-cancel:hover { background: rgba(255, 255, 255, .1); }
.cave-btn-ok { background: linear-gradient(150deg, var(--accent2, #7aa2ff), var(--accent, #5B8CFF)); color: var(--wit); }
/* Onomkeerbaar = rood en onmiskenbaar anders dan annuleren. */
.cave-btn-danger { background: linear-gradient(150deg, #f87171, var(--danger-solid)); color: var(--wit); }
.cave-btn:hover { filter: brightness(1.08); }

/* ── Compacte knop die op mobiel alsnog aanraakbaar is ── */
.btn-xs { padding: 5px 10px; font-size: 11.5px; border-radius: 7px; min-height: 44px; }
@media (max-width: 992px) {
  /* De shell wordt hier al mobiel (zijbalk klapt dicht), dus vanaf hier gelden
     ook de touch-targets. Stond eerder op 600px: tussen 601 en 992px waren
     knoppen ~29px hoog. */
  .btn, button, .cave-btn, .btn-xs { min-height: 44px; }
  /* Review 25 juli 2026: de regel dekte alleen KNOPPEN. Uit de meting op 390px bleef
     een handvol bedieningselementen onder de 44px hangen — steeds dezelfde, op élk
     scherm: de twee zijbalk-dropdowns ('Bekijk als…', taal), het woordmerk, de
     terug-link en de sluitkruisjes van vensters. Een <select> en een navigatielink
     zijn net zo goed aanraakvlakken als een knop. */
  .modal-close-x { min-width: 44px; }
}

/* Deze bedieningselementen stonden BINNEN de media-query, dus op desktop gold de norm
   niet. De zichtbare kliktest van 27 juli 2026 mat op 1600px nog 38px op de
   dropdowns (Bekijk als..., taal) en de navigatielinks (Servers, Mijn overzicht).
   Een <select> en een navigatielink zijn net zo goed aanraakvlakken als een knop, en
   regel 7.4 maakt geen uitzondering voor beeldbreedte. Nu onvoorwaardelijk. */
select,
.sidebar-logo,
.server-breadcrumb a,
.modal-close-x,
.ct-btn {
  min-height: 44px;
}
.sidebar-logo, .server-breadcrumb a { display: flex; align-items: center; }

/* ── Gevarenzone: destructieve actie hoort niet naast een routineknop ── */
.gevaarzone {
  display: flex;
  align-items: center;
  gap: 16px;                        /* minimaal 16px scheiding van functionele knoppen */
  margin-left: 16px;
  padding-left: 16px;
  border-left: 1px solid var(--border);
}

/* ── Formulier- en layoutrasters die ontbraken ── */
.user-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px;
  align-items: end;
}
.products-layout-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(min(320px, 100%), 1fr);
  gap: 20px;
  align-items: start;
}
.products-config-col, .products-preview-col { min-width: 0; }
.products-preview-col { position: sticky; top: 16px; }
.products-preview-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px;
}
@media (max-width: 1100px) {
  .products-layout-grid { grid-template-columns: 1fr; }
  .products-preview-col { position: static; }
}

/* ── Hostbronnen en support-splitsing: waren inline, dus onoverschrijfbaar ── */
/* Deze twee stonden inline. Bij het verplaatsen naar een klasse ging de rest van
   de stijl verloren (achtergrond, rand, padding, marge) — daardoor plakten de
   hostgegevens tegen de serverkaarten aan. Hier staat hij nu compleet. */
.host-bronnen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 18px;
  margin-bottom: 20px;
}
/* Hostbronnen per node: één kaart per machine. Eén balk "host" was misleidend zodra
   klantservers op een uitbreidingsnode draaien (melding Cihan, 25 juli 2026). */
.host-nodes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: 14px;
  margin-bottom: 20px;
}
.host-node {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 18px;
}
.host-node-kop {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.host-node-naam { font-weight: 600; font-size: 13.5px; }
.host-node-plek { color: var(--muted); font-size: 11.5px; }
.host-node-meters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 14px;
}
.host-node-leeg { color: var(--muted); font-size: 12.5px; padding: 6px 0; }

/* "Nu geïnstalleerd"-kaart in de Modpacks-tab. Stond nergens in het paneel, terwijl je
   het nodig hebt om de juiste clientversie te kiezen (melding Cihan, 25 juli 2026). */
.modpack-nu {
  margin: 10px 0;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  background: #11121a;
  font-size: 13px;
  line-height: 1.6;
}
.mp-nu-kop { margin-bottom: 6px; }
.mp-nu-label { color: var(--muted); display: inline-block; min-width: 210px; }
.mp-nu-meta { color: var(--muted); font-size: 12px; }
.mp-nu-afwijking {
  margin: 8px 0 0;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  color: #e0a060;
  font-size: 12.5px;
}
@media (max-width: 620px) {
  .mp-nu-label { min-width: 0; display: block; }
}

/* Versiekeuze bij een CurseForge-pack (zoals bij Modrinth-packs): de klant kiest zelf
   welke packversie hij installeert i.p.v. stil 'de nieuwste'. */
.cf-versie {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;             /* WCAG 2.5.5: het hele label is het aanraakvlak */
  font-size: 12px;
  color: var(--muted);
}
.cf-versie-select {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 6px 10px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  font-size: 12.5px;
}
.support-split {
  display: grid;
  grid-template-columns: minmax(280px, 380px) minmax(0, 1fr);
  gap: 16px;
  min-height: 520px;
}
@media (max-width: 900px) {
  .support-split { grid-template-columns: 1fr; min-height: 0; }
}

/* De vier .msg-*-meldingscomponenten zijn op 26 juli 2026 vervangen door de
   gedeelde .alert in merk.css (16 gebruiken omgezet). */

/* ═══ Contrast: gemeten, niet geschat ══════════════════════════════════════
   WCAG 1.4.11 eist 3:1 voor de RAND van een bedieningselement. Onze invoervelden
   hadden rgba(255,255,255,.05) — dat is ~1,3:1: je ziet niet waar het veld begint.
   WCAG 1.4.3 eist 4,5:1 voor tekst. Wit op #f87171 haalt 3,8:1 — dus de massieve
   rode knop wordt #DC2626 (4,8:1).
   ═══════════════════════════════════════════════════════════════════════════ */
/* --border-interactive en --danger-solid staan in het :root-blok bovenaan. */
input:not([type="checkbox"]):not([type="radio"]),
select,
textarea {
  border: 1px solid var(--border-interactive);
}
/* Dropdown-opties leesbaar op elk donker paneel. Het admin-paneel (home.html)
   had — anders dan de server- en bestelpagina — geen option/optgroup-kleur, dus
   de opties werden grijs en nauwelijks leesbaar (bijv. de eigenaar-dropdown bij
   'Server toevoegen'). Solide donkere achtergrond + lichte tekst, zelfde waarden
   als de al bestaande scoped-regels — dus geen regressie elders. */
select option,
select optgroup {
  background: #111320;
  color: #f4f6fb;
}
select optgroup {
  font-weight: 700;
}
select option:disabled {
  color: #7b8194;
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
  border-color: var(--accent2);
  outline: 2px solid var(--accent2);
  outline-offset: 1px;
}
.cave-btn-danger { background: var(--danger-solid); color: var(--wit); }
.cave-btn-danger:hover { background: #b91c1c; filter: none; }

/* Getallen die onder elkaar staan (prijzen, bedragen, RAM) horen uit te lijnen. */
.tabular, td.bedrag, .bedrag, .prijs {
  font-variant-numeric: tabular-nums;
}

/* ═══ Kaarten die wél gebruikt maar nooit gedefinieerd waren ════════════════
   .user-card, .order-card en .package-catalog-card stonden in de HTML maar in
   geen enkele stylesheet: die kaarten hadden dus letterlijk geen opmaak en
   erfden alleen wat toevallig van hun ouder kwam. Nu één afspraak: rustige
   kaart, hairline rand, 16px binnenruimte, hover die je positie bevestigt.
   ═══════════════════════════════════════════════════════════════════════════ */
.user-card, .order-card, .package-catalog-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  transition: border-color .12s ease, transform .12s ease;
}
.user-card:hover, .order-card:hover, .package-catalog-card:hover {
  border-color: var(--border-strong);
  transform: translateY(-1px);
}
.chat-text { font-size: 13.5px; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; }
.ticket-status-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.versielijst { font-size: 12.5px; color: var(--muted); }

/* Serverpaneel: de context in de topbalk (welke server bedien ik?) */
.topbar-context { min-width: 0; }
.support-badge {
  background: var(--accent-diep); color: var(--wit); font-size: 10px; font-weight: 800;
  border-radius: 99px; padding: 1px 7px; margin-left: 6px;
}
/* .hh-meter is de OMHULLING (label + balk), niet de balk zelf — die is .hh-bar.
   Als 6px hoog met overflow:hidden knipte deze regel het label en de balk
   doormidden op elke telefoon. De omhulling heeft geen eigen hoogte nodig. */
.plsub { font-size: 11.5px; color: var(--muted); }

/* ═══ Serverkaarten: dezelfde klasse als de rest van het paneel ═════════════
   De kaarten oogden dof: matte iconen, grijze cijfers, geen duidelijke status.
   Ze zagen er ouder uit dan de rest van het paneel. Dit is geen herontwerp —
   dezelfde structuur, maar met de hiërarchie die de rest van het paneel ook heeft:
   accent op de naam, cijfers die uitlijnen, en een status die je van een meter
   afstand leest.
   ═══════════════════════════════════════════════════════════════════════════ */
.server-card {
  position: relative;
}
/* Accentlijn bovenaan bij hover: dezelfde taal als de keuzekaarten in het portaal. */
.server-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: linear-gradient(90deg, var(--accent2), var(--accent));
  opacity: 0;
  transition: opacity .15s ease;
}
.server-card:hover::before { opacity: 1; }

.server-card .card-icon {
  font-size: 19px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .04);
}
.server-card .card-title h3 {
  font-size: 15px;
  letter-spacing: -.01em;
}
/* Cijfers die onder elkaar staan, horen uit te lijnen. */
.server-card .stat-row .value,
.server-card .bar-label span:last-child {
  font-variant-numeric: tabular-nums;
  color: var(--text);
  font-weight: 600;
}
.server-card .stat-row .label,
.server-card .bar-label span:first-child {
  color: var(--muted);
}
.server-card .bar-track {
  height: 6px;
  border-radius: 99px;
  background: rgba(255, 255, 255, .06);
  overflow: hidden;
}
.server-card .bar-fill { border-radius: 99px; }

/* Status leest als een woord, niet alleen als een stipje (WCAG 1.4.1: kleur mag
   nooit de enige drager van betekenis zijn). */
.server-card .stat-row .value#status-,
.server-card .stat-row .value[id^="status-"] {
  font-weight: 700;
}

/* ═══ Serverpaneel: hetzelfde palet als de rest ═════════════════════════════
   Het serverpaneel oogde ouder dan het hoofdpaneel: melkige kaarten met blur,
   grijze tekst op te laag contrast, felgekleurde tabpillen met donkere tekst en
   zware slagschaduwen. Dat leest als 'goedkoop' (het is precies de lijst uit het
   UX-onderzoek). Structuur blijft; alleen kleur, contrast en diepte.

   Gemeten: --muted #74788c haalt ~4,0:1 en zakt daarmee voor tekst (4,5:1 nodig).
   ═══════════════════════════════════════════════════════════════════════════ */
body.server-page {
  --surface: #14171F;
  --surface-solid: #14171F;
  --surface2-solid: #1B1F29;
  --card-solid: #14171F;
  --border: #232936;
  --border-strong: #2E3545;
  --border-hover: rgba(122, 162, 255, .45);
  --text: #E8EAF0;                /* off-white, geen puur wit */
  --green: #4ADE80;
  --red: #F87171;
  --amber: #FBBF24;
  /* Eén rustige gloed in plaats van twee concurrerende. */
  background:
    radial-gradient(1100px 600px at 20% -10%, rgba(91, 140, 255, .07), transparent 60%),
    #0D0F14;
}

/* Kaarten: rustig vlak met een hairline, geen blur en geen zware schaduw. */
body.server-page .card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
body.server-page .card:hover { border-color: var(--border-strong); transform: none; }
body.server-page .card h2 {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0;
}

/* Tabs: de actieve is herkenbaar aan accentkleur en een lijn — niet aan een
   felle vulling met donkere tekst (dat is de 'goedkope' tell uit het onderzoek). */
body.server-page .tabs {
  background: transparent;
  border: 0;
  box-shadow: none;
  padding: 0;
  gap: 2px;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  width: 100%;
}
body.server-page .tabs button {
  border-radius: 8px 8px 0 0;
  border-bottom: 2px solid transparent;
  padding: 10px 16px;
  color: var(--muted);
}
body.server-page .tabs button:hover { color: var(--text); background: rgba(255, 255, 255, .03); }
body.server-page .tabs button.active {
  background: rgba(91, 140, 255, .10);
  color: #A9C4FF;                 /* accent als TEKST, met genoeg contrast */
  border-bottom-color: var(--accent);
  box-shadow: none;
}

/* Zijbalk van het serverpaneel: actieve keuze net zo rustig. */
body.server-page .sidebar-link.active {
  background: rgba(91, 140, 255, .12);
  color: var(--text);
  box-shadow: inset 2px 0 0 var(--accent);
}

/* Meters en cijfers. */
body.server-page .bar-track { background: rgba(255, 255, 255, .06); border-radius: 99px; height: 6px; }
body.server-page .bar-fill { border-radius: 99px; }
body.server-page .stat-val,
body.server-page .value,
body.server-page .bar-label span:last-child { font-variant-numeric: tabular-nums; }

/* Console: een echt donker vlak (inset), niet dezelfde kleur als de kaart. */
body.server-page #console, body.server-page .console-box, body.server-page pre {
  background: #0A0C10;
  border: 1px solid var(--border);
  border-radius: 10px;
}

/* ═══ Serverpaneel: kleur terug, contrast houden ════════════════════════════
   Ik had bij het opfrissen te veel kleur weggehaald: grijze hoofdletter-koppen,
   doffe waarden, geen accenten. Naast het hoofdpaneel (gekleurde meters, chips,
   groene/rode knoppen) zag het er dood uit. Dit brengt dezelfde taal terug:
   accent op de kop, kleur op de meters, status als gekleurde chip — met het
   contrast dat we gemeten hebben.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Kaartkop: leesbare titel met accentstreepje, geen grijze hoofdletters
   (uppercase + wijde tracking is precies de 'gedateerd'-tell uit het onderzoek). */
body.server-page .card h2 {
  font-size: 13.5px;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text);
  padding-bottom: 10px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
  gap: 8px;
}
body.server-page .card h2::before {
  content: "";
  width: 3px;
  height: 15px;
  border-radius: 99px;
  background: linear-gradient(180deg, var(--accent2), var(--accent));
  flex: none;
}
/* De knop in de kaartkop blijft rustig — de kop is geen actiebalk. */
body.server-page .card h2 button:not(.btn-primary):not(.btn-green):not(.btn-red) {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  font-weight: 600;
}
body.server-page .card h2 button:hover { color: var(--text); border-color: var(--border-strong); }

/* Waarden springen eruit, labels stappen terug. */
body.server-page .stat-row .label,
body.server-page .info-row .label,
body.server-page .bar-label span:first-child { color: var(--muted); font-weight: 500; }
body.server-page .stat-row .value,
body.server-page .info-row .value { color: var(--wit); font-weight: 600; }

/* Meters: dezelfde kleuren als in het hoofdpaneel (blauw/groen/amber met gloed). */
body.server-page .bar-fill.cpu  { background: linear-gradient(90deg, #60a5fa, var(--accent)); box-shadow: 0 0 8px rgba(91,140,255,.45); }
body.server-page .bar-fill.ram  { background: linear-gradient(90deg, #34d399, #10b981); box-shadow: 0 0 8px rgba(16,185,129,.45); }
body.server-page .bar-fill.disk { background: linear-gradient(90deg, var(--amber), var(--yellow)); box-shadow: 0 0 8px rgba(245,158,11,.45); }
body.server-page .bar-fill.warn { background: linear-gradient(90deg, var(--red), #ef4444); box-shadow: 0 0 8px rgba(239,68,68,.45); }

/* Status als gekleurde chip: kleur mag nooit de enige drager zijn, dus het woord
   blijft staan (WCAG 1.4.1). */
body.server-page .state-pill { color: var(--text); }
body.server-page .state-pill.online  { background: rgba(74,222,128,.12); border-color: rgba(74,222,128,.35); color: var(--green); }
body.server-page .state-pill.offline { background: rgba(248,113,113,.10); border-color: rgba(248,113,113,.30); color: var(--red); }

/* Serveradres: dit is het enige dat de klant echt nodig heeft — dus geen grijs. */
body.server-page .addr-box, body.server-page .server-address {
  background: rgba(91,140,255,.08);
  border: 1px solid rgba(91,140,255,.28);
}
body.server-page code, body.server-page .mono { color: #A9C4FF; }

/* Actieve tab en zijbalkkeuze duidelijk, maar rustig. */
body.server-page .tabs button.active { font-weight: 700; }

/* ═══ Serverpaneel, ronde 2: diepte, kleur en kaarten die passen ════════════
   Drie echte problemen (uit Cihans screenshot):
   1. Mijn accentstreepje stond in een kop die 'space-between' is — daardoor werd
      de kaarttitel naar RECHTS geduwd. Eigen fout, en meteen zichtbaar.
   2. De achtergrond en de kaarten hadden bijna dezelfde toon: niets 'popte'.
      In een donker thema doe je diepte met een LICHTER vlak (Material), niet met
      een schaduw — die zie je toch niet.
   3. Kaarten rekten mee met de langste kaart in de rij: een kaart met drie regels
      kreeg de hoogte van een kaart met tien. Vandaar de grote lege vlakken.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1. Accent terug naar links, titel blijft links staan. */
body.server-page .card h2::before { content: none; }
body.server-page .card h2 {
  justify-content: flex-start;
  gap: 10px;
}
/* Alleen een KNOP of link in de kop schuift naar rechts. (Deed ik het op 'het
   laatste kind', dan schoof bij een kop als '💾 Backups' de titel zelf naar rechts
   — precies de fout die net zichtbaar was.) */
body.server-page .card h2 > button:first-of-type,
body.server-page .card h2 > a:first-of-type,
body.server-page .card h2 > .kop-actie { margin-left: auto; }
/* Accent als linkerrand op de kaart zelf: kleur zonder de tekst te verstoren. */
body.server-page .card {
  border-left: 2px solid rgba(91, 140, 255, .35);
}

/* 2. Diepte: canvas donkerder, kaarten lichter, met een fijne lichtrand bovenin. */
body.server-page {
  background:
    radial-gradient(1200px 700px at 12% -12%, rgba(91, 140, 255, .10), transparent 62%),
    radial-gradient(900px 600px at 100% 0%, rgba(16, 185, 129, .05), transparent 55%),
    #0A0C11;
}
body.server-page .card {
  background: linear-gradient(180deg, #171B25, var(--surface));
  box-shadow: 0 1px 0 rgba(255, 255, 255, .04) inset, 0 8px 24px rgba(0, 0, 0, .35);
}
body.server-page .card:hover {
  border-color: var(--border-strong);
  border-left-color: rgba(91, 140, 255, .7);
}

/* 3. Kaarten krijgen de hoogte van hun inhoud, niet van hun buurman. */
body.server-page .grid,
body.server-page .grid-2,
body.server-page .cards,
body.server-page .card-grid {
  align-items: start;
}
body.server-page .card { height: auto; align-self: start; }

/* Rijen wat luchtiger, zodat lange lijsten leesbaar blijven. */
body.server-page .info-row,
body.server-page .stat-row {
  padding: 9px 0;
  border-bottom: 1px solid rgba(255, 255, 255, .04);
}
body.server-page .info-row:last-child,
body.server-page .stat-row:last-child { border-bottom: 0; }

/* Waarden die 'aan/uit' zeggen, mogen dat ook laten zien. */
body.server-page .value.aan, body.server-page .value.ja { color: var(--green); }
body.server-page .value.uit, body.server-page .value.nee { color: #8A93A6; }

/* ═══ Serverpaneel, ronde 3: kaarten die écht loskomen ══════════════════════
   Gemeten: kaart tegen achtergrond was 1,14:1 — bijna geen verschil, dus niets
   'popte'. In een donker thema maak je diepte met een LICHTER vlak, en dat vlak
   moet ook echt lichter zijn. Nu 1,38:1 plus een zichtbare rand en een schaduw.
   Labeltekst blijft op 4,7:1 (WCAG AA) op dat lichtere vlak.
   ═══════════════════════════════════════════════════════════════════════════ */
body.server-page {
  background:
    radial-gradient(1200px 700px at 12% -12%, rgba(91, 140, 255, .12), transparent 62%),
    radial-gradient(900px 600px at 100% 0%, rgba(16, 185, 129, .06), transparent 55%),
    #06080B;                                   /* echt donker canvas */
}
body.server-page .card {
  background: linear-gradient(180deg, #242A38, #1E2431);   /* lichter dan het canvas */
  border: 1px solid #333B4C;
  border-left: 2px solid rgba(91, 140, 255, .5);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .05) inset,
    0 10px 28px rgba(0, 0, 0, .45);
}
body.server-page .card:hover {
  border-color: #414B60;
  border-left-color: var(--accent);
}
/* Rijen krijgen een hairline die op dít vlak zichtbaar is. */
body.server-page .info-row,
body.server-page .stat-row { border-bottom-color: rgba(255, 255, 255, .07); }
/* Invoervelden op een lichtere kaart: nog steeds duidelijk begrensd. */
body.server-page input,
body.server-page select,
body.server-page textarea {
  background: #12151D;
  /* Op het lichtere kaartvlak haalde #5d6779 nog maar 2,5:1 — WCAG 1.4.11 eist
     3:1 voor de rand van een bedieningselement. #6b7689 haalt 3,13:1. */
  border: 1px solid #6b7689;
}
/* De console blijft het donkerste vlak: dat leest als 'hier draait iets'. */
body.server-page #console,
body.server-page .console-box,
body.server-page pre { background: #0A0C11; border-color: #333B4C; }

/* ═══ Serverpaneel: informatiedichtheid ════════════════════════════════════
   Gemeten in een echte render: de kaart 'Server informatie' was 502px hoog met
   350px inhoud — tien regels van 40px onder elkaar. Zijn buurman was 227px, dus
   ernaast viel een gat van 275px. Dát is de lege ruimte die opvalt.

   Oplossing is niet 'minder padding' maar een andere vorm: een lijst van tien
   label/waarde-paren hoort in twee kolommen, niet in tien regels. Zo wordt de
   kaart half zo hoog en past hij naast zijn buurman.
   ═══════════════════════════════════════════════════════════════════════════ */
body.server-page .card .row {
  padding: 7px 0;
  font-size: 13px;
}
/* Twee kolommen zodra er ruimte is; op een telefoon vanzelf één. */
body.server-page .card.info-kaart {
  container-type: inline-size;
}
body.server-page .info-tweekolom {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  column-gap: 22px;
}
body.server-page .info-tweekolom .row {
  border-bottom: 1px solid rgba(255, 255, 255, .06);
}
/* Abonnementsregel: staat bewust ONDER de twee kolommen met servergegevens, want
   het is een ander soort informatie — wat je betaalt en tot wanneer, niet hoe de
   server ingesteld staat. Een lijn erboven maakt dat verschil zichtbaar zonder
   een tweede kaart nodig te hebben. */
body.server-page .abo-regel {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, .12);
}
body.server-page .abo-regel span:last-child {
  font-weight: 600;
}
/* De laatste rij van elke kolom mag zijn lijn houden: dat leest rustiger dan een
   halve tabel zonder onderrand. */

/* Kaarten dichter op elkaar: 20px lucht tussen kaarten is genoeg, 14px binnenin
   was te krap voor de leesbaarheid. */
body.server-page .card { padding: 16px 18px; }
body.server-page .grid { gap: 18px; }

/* ═══ Knopmaten: één schaal, overal ════════════════════════════════════════
   Gemeten in de render: knoppen van 27-28px hoog. Dat is te klein om prettig te
   raken (WCAG AA vraagt 24px, Apple 44px) en het leest als 'onaf'. Eén schaal:
   groot 44 · normaal 40 · klein 34 · mini 30 — en op mobiel alles 44px.
   ═══════════════════════════════════════════════════════════════════════════ */
.btn, button, .cave-btn {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
/* AANRAAKVLAK: 44px is de VLOER, op elke breedte (ONTWERPSYSTEEM 7.4, GOEDGEKEURD).
   Gevonden door de zichtbare kliktest op staging, 27 juli 2026: de 'Markeer betaald'-knop
   in de Bestellingen-tab meet 131x30px. De 44px-regel stond alleen in
   `@media (max-width: 992px)`, dus op desktop was de norm uitgeschakeld. WCAG 2.5.5 gaat
   over het AANRAAKVLAK, niet over de vensterbreedte — een touchscreen-laptop of een
   trillende hand heeft er net zo veel aan. `visueel.py` meldde deze klasse al (34 groepen
   met 35/38/40px op desktop): gemeten en getolereerd, niet onbekend.
   De compacte padding en lettergrootte blijven; alleen de hoogte krijgt een vloer. */
.btn-sm { min-height: 44px; padding: 7px 13px; font-size: 12.5px; }
.btn-xs { min-height: 44px; padding: 5px 11px; font-size: 12px; }
.btn-lg { min-height: 46px; padding: 12px 22px; font-size: 14px; }

/* Icoonknoppen zijn vierkant en houden hun raakvlak. */
.btn-icon, .btn-menu, .link-chip .x {
  min-width: 34px;
  min-height: 44px;
  padding: 0 8px;
}

@media (max-width: 992px) {
  .btn, button, .cave-btn, .btn-sm, .btn-xs, .btn-lg { min-height: 44px; }
  .btn-icon, .btn-menu { min-width: 44px; min-height: 44px; }
}

/* Zelfde VLOER in het serverpaneel. Stond op 40px en 34px; de zichtbare kliktest
   van 27 juli 2026 legde bloot dat de 44px-norm alleen onder 992px gold. Regel 7.4
   is GOEDGEKEURD en maakt geen uitzondering voor beeldbreedte. */
body.server-page .btn,
body.server-page button { min-height: 44px; }
body.server-page .btn-small,
body.server-page .btn-sm { min-height: 44px; }
body.server-page .tabs button { min-height: 44px; }

/* ═══ Serverpaneel: de hoofdoorzaak van 'te veel lucht' ═════════════════════
   Elke kaartkop erfde 16px+20px padding uit het hoofdpaneel (.card-header, .card h2),
   waar .card zelf géén padding heeft. In het serverpaneel heeft .card die padding
   wél — dus dubbel. Netto ~57px 'chroom' per kaart, in alle acht de tabbladen, plus
   een titel die 20px verder inspringt dan de rijen eronder.
   ═══════════════════════════════════════════════════════════════════════════ */
body.server-page .card h2 {
  padding: 0 0 10px;
  background: none;
  margin-bottom: 12px;
}

/* Kaarten mogen hun rij niet ophouden: met '1fr 1fr' krijgt de korte kaart een
   gat van 200-300px onder zich, omdat de rijhoogte die van de langste kaart is. */
body.server-page .grid {
  grid-template-columns: repeat(auto-fit, minmax(min(330px, 100%), 1fr));
  grid-auto-flow: dense;
  gap: 18px;
}
/* MAAR: de modpack-lijst heeft groepskoppen (past/wissel/niet) ín het grid.
   Met 'dense' vult een kaart uit een LATERE groep een gat in een eerdere rij —
   een niet-compatibele kaart belandde zo optisch in de waarschuwingsgroep
   (bug 17 jul). Groepsvolgorde gaat hier boven gaatjes vullen. */
body.server-page #modpackList.grid { grid-auto-flow: row; }
/* Een grid-item hoort geen eigen marge te hebben — dat komt bovenop de gap. */
body.server-page .grid > .card,
body.server-page .card { margin-bottom: 0; }

/* De informatiekaarten in het gameserverpaneel (Server informatie, Backups,
   Netwerk) linken nergens heen. Een hover die ze optilt belooft een klik die niet
   bestaat — en de zware zwarte schaduw die erbij hoorde werd op een donkere
   achtergrond toch alleen een vuile vlek. Alleen klikbare kaarten tillen op. */

/* De politoer landde op klassen die in dit paneel niet bestaan (.stat-row,
   .info-row) terwijl de dashboardrijen gewoon .row heten. */
body.server-page .card .row {
  padding: 8px 0;
  border-bottom: 1px solid rgba(255, 255, 255, .07);
}
body.server-page .card .row:last-child { border-bottom: 0; }
body.server-page .card .row > span:last-child {
  color: var(--wit);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
body.server-page .card .row > span:first-child { color: var(--muted); }
/* .stat-row hoort bij de speler-modal (health/food/armor): geen hairlines. */
body.server-page #invModal .stat-row,
body.server-page .stat-bars .stat-row { padding: 0; border-bottom: 0; }

/* Tabellen mogen ook boven 768px zijwaarts scrollen in plaats van uit hun kaart
   te lopen (de regel bestond alleen in de mobiele mediaquery). */
body.server-page .table-scroll { overflow-x: auto; }

/* De console had een vaste hoogte van 340px — ook met drie regels log. */
body.server-page #log {
  height: auto;
  min-height: 180px;
  max-height: min(46vh, 400px);
  resize: vertical;
}

/* Formulieren die uitgesmeerd worden over de volle breedte lezen als 'leeg'. */
body.server-page .settings-grid { align-items: start; }
body.server-page .card > .settings-grid { max-width: 720px; }


/* ── Tegels: één getal, geen hele kaart ───────────────────────────────────── */
body.server-page .tegels {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}
body.server-page .tegel {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: linear-gradient(180deg, #242A38, #1E2431);
  border: 1px solid #333B4C;
  border-radius: 12px;
  padding: 14px 16px;
}
body.server-page .tegel-nr {
  font-size: 24px;
  font-weight: 700;
  color: var(--wit);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}
body.server-page .tegel-lbl { font-size: 12px; color: var(--muted); }

/* ═══ Dashboard: metselwerk in plaats van rijen met gaten ═══════════════════
   Met een gewone grid krijgt de korte kaart de rijhoogte van de langste buurman:
   onder 'Purpur' viel een gat van 300px. Kolommen (metselwerk) laten elke kaart
   direct onder zijn voorganger vallen — geen gaten meer, en de leesvolgorde is
   nog steeds logisch (per kolom van boven naar beneden).
   ═══════════════════════════════════════════════════════════════════════════ */
/* De console staat nu als eigen blok bóven dit raster (zie index.html): binnen
   metselwerk kan niets de volle breedte pakken. Het raster zelf blijft metselwerk,
   want in een gewone grid krijgt een korte kaart de rijhoogte van zijn langste
   buurman — dát veroorzaakte het gat van 250px onder 'Purpur'. */
body.server-page .dash-grid {
  display: block;
  columns: 340px auto;
  column-gap: 18px;
}
body.server-page .dash-grid > .card {
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  margin-bottom: 18px;
  display: block;
}

/* De console: het hart van dit scherm. Volle breedte, echt donker vlak, eigen scroll. */
body.server-page .console-vol { margin-bottom: 18px; }
body.server-page .console-vol #log {
  min-height: 320px;
  max-height: 48vh;
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

@media (max-width: 760px) {
  body.server-page .dash-grid { columns: 1; }
  body.server-page .console-vol #log { min-height: 220px; max-height: 40vh; }
}

/* De informatiekaart is de langste: die mag zijn paren in twee kolommen zetten
   zodra hij breed genoeg is. In een smalle kolom blijft het één kolom. */
body.server-page .info-tweekolom { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

/* Informatierijen compacter: tien paren van 46px maakten de kaart 500px hoog. */
body.server-page .card .row {
  padding: 6px 0;
  font-size: 12.75px;
  line-height: 1.45;
  gap: 12px;
}
body.server-page .info-tweekolom { column-gap: 26px; }

/* ═══════════════════════════════════════════════════════════════════════════
   PREMIUM-PAS — op basis van gemeten referenties
   ═══════════════════════════════════════════════════════════════════════════
   Onderzocht: Pterodactyl, Pelican, AMP, Nodecraft, PebbleHost, Falix + de
   kwaliteitslat (Vercel, Linear, Railway, Supabase, Coolify). Drie harde regels
   komen daar overal uit:

   1. De RAND doet het werk, niet de schaduw. Alle vijf de premium-panelen geven
      hun kaart een hairline met ~1,15-1,40 contrast en NUL schaduw. Onze rand was
      rgba(255,255,255,.05) = 1,12 contrast — onder de hele band. En onze schaduw
      (0 10px 30px zwart) maakt op een bijna zwart canvas geen diepte maar een
      modderige halo.
   2. Oppervlakken zijn SOLIDE. Half-transparante kaarten boven een canvas met
      kleurverlopen geven een wisselende, wazige rand.
   3. Kleur is voor STATUS, niet voor chroom. Wij gaven kleur uit aan tabs, knoppen
      en meters — daardoor valt de serverstatus (het enige wat je écht scant) weg
      in het geweld.
   ═══════════════════════════════════════════════════════════════════════════ */
/* De oppervlakte- en randtokens staan in het :root-blok bovenaan. */

/* Kaarten: vlak, met een zichtbare hairline. */
.card, .server-card {
  background: var(--card);
  border: 1px solid var(--border);
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.card:hover, .server-card:hover {
  border-color: var(--border-hover);
  box-shadow: none;
  transform: none;
}
/* Menu's en modals mogen wél zweven: die liggen echt boven de pagina. */
.modal, .cave-modal, .context-menu, .dropdown {
  box-shadow: 0 8px 24px rgba(0, 0, 0, .5);
}

/* Serverstatus krijgt de aandacht die hij verdient: gloeiende stip + zachte pil.
   (Falix doet dit, en ontkleurt de rest van zijn paneel juist daarvoor.) */
.status-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
}
.status-dot.online, .status-dot.running {
  background: #3FCF8E;
  box-shadow: 0 0 8px rgba(63, 207, 142, .6);
}
.status-dot.offline, .status-dot.stopped {
  background: #F0594F;
  box-shadow: 0 0 8px rgba(240, 89, 79, .6);
}
.status-dot.loading, .status-dot.starting {
  background: #F5A524;
  box-shadow: 0 0 8px rgba(245, 165, 36, .6);
  animation: statuspuls 1.5s infinite;
}
@keyframes statuspuls { 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .status-dot { animation: none !important; } }

/* Twee opeenvolgende blokken knopvullingen stonden hier — de tweede overschreef de
   eerste volledig, en beide zijn op 30 juli 2026 vervangen door de ÉNE familie in
   `componenten.css` (§7b). Wat de tweede aan kennis bevatte staat daar in de comments:
   wit op het lichte accent (#5b8cff) haalt 3,16:1 en wit op groen (#1f9d63) 3,46:1,
   allebei onder de 4,5:1 die WCAG eist — daarom is de VULLING een diepere tint
   (`--ch-knop`/`--groen-diep`/`--rood-diep`) en blijft het lichte accent voor tekst,
   links en focus, waar het 5,7:1 haalt.
   `.cave-btn-*` (het bevestigingsvenster uit cave-ui.js) is een eigen familie en blijft
   hier staan; die staat niet in de §7b-mapping. */
.cave-btn-ok { background: #3b6fe0; }
.cave-btn-danger { background: #c53f36; }

/* Accentkleur als tekst (links, actieve labels): het lichte blauw, niet de vulling. */
a.accent, .accent-text, .link-accent { color: #93b4ff; }

/* ═══ Aanraakvlakken: alles wat je met een duim moet raken ═══════════════════
   WCAG 2.5.5 vraagt 44x44px. Kopregel-links ("Profiel", "Uitloggen", het logo,
   "⬅ Servers", "← Terug naar je klantenpaneel") waren 16-28px hoog: op een
   telefoon mis je die. Selectievakjes waren 13x13px — kleiner dan een potlood-
   punt. Ze krijgen hier hun vlak terug zonder dat de tekst groter wordt.
   ═══════════════════════════════════════════════════════════════════════════ */
.topbar a, .top a, .topbar-links a,
.brand-logo-link, a.logo, .logo-link,
.servers-link, a.logout, .terug, a.terug {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding-inline: 6px;
  border-radius: 8px;
}
.servers-link { padding-inline: 10px; }
.topbar a:hover, .top a:hover, .servers-link:hover, a.logout:hover {
  background: rgba(255,255,255,.05);
}

/* Selectievakjes en keuzerondjes: raakbaar, en zichtbaar als ze aanstaan. */
input[type=checkbox], input[type=radio] {
  width: 18px;
  height: 18px;
  accent-color: var(--accent);
  cursor: pointer;
  flex-shrink: 0;
}
.lang-switch, select.lang-switch { min-height: 44px; }

/* Op een telefoon is 36px te krap: daar geldt de volle 44px. */
@media (max-width: 768px) {
  .topbar a, .top a, .brand-logo-link, a.logo,
  .servers-link, a.logout, .terug, a.terug,
  .lang-switch, select.lang-switch { min-height: 44px; }
  input[type=checkbox], input[type=radio] { width: 22px; height: 22px; }
}

/* De kopbalk van de bestelpagina is een <header> met .header-user, geen .topbar —
   die viel daarom buiten de regel hierboven. */
header .header-user a, header a.logo, .terug-link {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding-inline: 6px;
  border-radius: 8px;
}
header .header-user a:hover, .terug-link:hover { background: rgba(255,255,255,.05); }
.lang-switch, select.lang-switch { min-width: 74px; }   /* werd op een telefoon tot 20px geknepen */

/* Een selectievakje van 18px raak je niet met een duim. Het label eromheen geeft
   het een vlak van 44px, zonder dat het vakje zelf groter oogt. */
.vak-doel {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  cursor: pointer;
}
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 768px) {
  header .header-user a, header a.logo, .terug-link { min-height: 44px; }
}

/* 44px is hier de BASIS; de krappere 38px staat achter een min-width. Precies andersom
   dan het was, en dat verschil was geen detail.
   Gemeten op staging (28 juli 2026, `visueel.py --streng`): 76 van de 76 bevindingen
   zaten op 390px -- nul op desktop en breedbeeld -- en 48 daarvan kwamen van deze twee
   regels. De oorzaak was de cascade: `@media (max-width:768px) { .shell-sidebar select
   { min-height:44px } }` stond hierboven en `.shell-sidebar select { min-height:38px }`
   eronder. Een media-query voegt geen specificiteit toe, dus won de LATERE regel --
   ook op een telefoon. De mobiele regel was dode code, en dat zie je nergens aan: de
   CSS ziet er volledig verzorgd uit en de statische 44px-check gaf groen omdat er
   ergens wél een 44px-regel stond.
   Zelfde les als de onbereikbare adminschermen van 19 juli, die AGENTS.md al vastlegt:
   zet responsive eigenschappen op de BASISREGEL en maak de uitzondering expliciet. */
/* De "Bekijk als"-rolkiezer. Stond twee keer in home.html als een volledig INLINE
   gestylede <select> zonder klasse -- daardoor kon geen enkele CSS-regel hem bereiken
   en bleef de compacte variant op 32px steken (gemeten 28 juli 2026 op 390px, de
   laatste van 76 aanraakvlak-bevindingen). Inline stijl is bovendien wat de
   projectregel al verbiedt: gebruik een klasse. Alleen de VULLING en de letter
   verschillen tussen de twee plekken; de aanraakvloer is voor beide gelijk. */
.rolkiezer {
  width: 100%; min-height: 44px; padding: 8px 12px; border-radius: 8px;
  background: rgba(255,255,255,.05); border: 1px solid var(--border);
  color: var(--text); font-size: 12.5px; cursor: pointer; outline: none;
}
.rolkiezer-compact {
  width: auto; max-width: 160px; padding: 5px 10px; border-radius: 7px;
  background: rgba(255,255,255,.07); color: var(--muted); font-size: 12px;
}
.shell-sidebar select, .sidebar select, .topbar select { min-height: 44px; }
@media (min-width: 769px) {
  .shell-sidebar select, .sidebar select, .topbar select { min-height: 38px; }
}

/* Een knop is geen tekstlink. "Openen →" stond onderstreept omdat het een <a> is;
   daardoor las de belangrijkste actie van de serverkaart als bijzaak. */
a.btn, a.btn:hover, .btn { text-decoration: none; }

/* ═══ De zijbalk blijft staan tijdens het scrollen ═══════════════════════════
   Hij was een gewoon flex-kind: scrolde je naar beneden, dan schoof het menu mee
   naar boven en was je navigatie kwijt. Nu blijft hij op zijn plek, met een eigen
   schuifbalk als het menu langer is dan het scherm. Op een telefoon wordt hij een
   uitschuifmenu (position:fixed) — die regel wint daar, dus dit raakt hem niet.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 993px) {
  .shell-sidebar {
    position: sticky;
    top: 0;
    height: 100vh;
    /* NIET meer de hele zijbalk laten scrollen (anders zakt de footer onder de vouw —
       melding Cihan). De base-regel zet overflow:hidden; alleen .sidebar-menu scrollt.
       Deze media-query overschreef dat eerder met overflow-y:auto → daarom hier ook. */
    overflow: hidden;
    overscroll-behavior: contain;
    flex-shrink: 0;
  }
  /* Een dunne, ingetogen schuifbalk op het NAV-menu — dat is wat scrollt. */
  .sidebar-menu { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.12) transparent; }
}

/* ═══ Eén knoptaal in het hele paneel ════════════════════════════════════════
   Dit blok trok het serverpaneel gelijk met het hoofdpaneel: het had zeven eigen
   knopdialecten (.btn-start, .btn-stop, .btn-update, .btn-small, .ct-btn,
   .settings-pill en kale <button>), grotendeels met kleurverlopen.

   Dat doel is per 30 juli 2026 overgenomen door `componenten.css` (§7b), en dat is
   breder: dáár geldt het óók voor het klantportaal. De `body.server-page`-varianten
   die in de §7b-mapping staan zijn hier weggehaald in plaats van doorgehaald, want
   ze WONNEN: `body.server-page .btn-start` weegt (0,2,1) tegen het contract (0,1,0),
   dus zolang ze bleven staan werd het adminpaneel vlak en hield het serverpaneel zijn
   verloop — één divergentie geruild voor een andere, tussen twee schermen die naast
   elkaar leven. Precies dat maakte de eerste poging waardeloos.

   Wat hier BLIJFT staat niet in de mapping en heeft geen contract-tegenhanger:
   `.ct-btn` en `.settings-pill` (eigen families) en `.btn-update`/`.btn-menu`
   (serverpaneel-eigen, geen van de vier betekenissen toegewezen). Die houden dus hun
   huidige vulling; benoemd, niet vergeten.
   ═══════════════════════════════════════════════════════════════════════════ */
body.server-page .btn-update,
body.server-page .cmdrow button  { background: #3b6fe0; color: var(--wit); border: none; }   /* 4,63:1 */
body.server-page .btn-update:hover:not(:disabled),
body.server-page .cmdrow button:hover:not(:disabled) { background: #3364cf; filter: none; }

/* Secundair: rustig vlak met een rand die je wél ziet (3:1, WCAG 1.4.11). */
body.server-page .ct-btn,
body.server-page .btn-menu {
  background: var(--surface2);
  border: 1px solid var(--border-strong);
  color: var(--text);
  box-shadow: none;
}
body.server-page .ct-btn:hover:not(:disabled),
body.server-page .btn-menu:hover:not(:disabled) {
  background: #232735;
  border-color: var(--border-hover);
  color: var(--wit);
  filter: none;
}

/* Gekozen staat (Live/1u/24u, Alle spelers, Gameplay…): één tint, geen verloop. */
body.server-page .btn-small.active,
body.server-page .ct-btn.active,
body.server-page .settings-pill.active {
  background: rgba(91,140,255,.16);
  border: 1px solid rgba(91,140,255,.45);
  color: #a8c3ff;
  box-shadow: none;
}

/* ═══ Randen die je daadwerkelijk ziet ══════════════════════════════════════
   Een 'ghost'-knop of invoerveld heeft geen vulling: de rand IS het bedienings-
   element. Die rand had 1,24:1 tegen de kaart — praktisch onzichtbaar, en ver
   onder de 3:1 die WCAG 1.4.11 voor bedieningselementen eist. #6b7689 haalt
   3,93:1. Kaarten en scheidslijnen blijven subtiel: dat zijn geen knoppen.
   ═══════════════════════════════════════════════════════════════════════════ */
/* De rustige KNOPVARIANTEN (`btn-muted`/`btn-logout`/`btn-small`/`btn-downgrade`) zijn
   hier weggehaald: `componenten.css` zet hun rand nu op ditzelfde `--border-interactive`,
   dus de eis van dit blok blijft gehaald vanuit één bron. De `body.server-page`-varianten
   MOESTEN weg — die wogen (0,2,1) en hadden het contract overruled. Wat blijft zijn de
   families zonder contract-tegenhanger (`.ct-btn`, `.btn-menu`) en de kaartkop-knoppen. */
.btn-menu,
body.server-page .ct-btn,
body.server-page .btn-menu,
body.server-page .card h2 button:not(.btn-primary):not(.btn-green):not(.btn-red),
.card h2 button:not(.btn-primary):not(.btn-green):not(.btn-red) {
  border: 1px solid var(--border-interactive, #6b7689);
}
input[type=text], input[type=email], input[type=password], input[type=number],
input[type=search], input[type=url], select, textarea {
  border: 1px solid var(--border-interactive, #6b7689);
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent);
  outline: 2px solid rgba(91,140,255,.35);
  outline-offset: 1px;
}

/* ═══ Badges in de zijbalk staan in één kolom ═══════════════════════════════
   Elke badge had zijn eigen inline stijl met margin-left:4px: hij plakte tegen
   het einde van de tekst. Bij 'Website-aanvragen' brak het label af en schoof de
   badge mee, waardoor ze niet meer onder elkaar stonden. Nu duwt margin-left:auto
   ze allemaal naar dezelfde rechterkant, en breken de labels niet meer af.
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar-link { min-width: 0; }
.sidebar-link > span:not(.icon):not(.nav-badge) {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.nav-badge {
  margin-left: auto;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  /* Premium: subtiele glans (inset top-highlight) + zachte drop-shadow voor diepte +
     een dunne lichtring, zodat het geen platte pil is. De volle kleur blijft de basis
     (contrast-governance: wit-op-diep blijft ≥4,5:1); de highlight is te subtiel om
     dat te breken. */
  box-shadow: inset 0 1px 0 rgba(255,255,255,.22),
              inset 0 -1px 0 rgba(0,0,0,.18),
              0 1px 3px rgba(0,0,0,.28);
  border: 1px solid rgba(255,255,255,.10);
  letter-spacing: .01em;
}
.nav-badge.groen { background: linear-gradient(180deg, #1e9c5e, #157a49); color: var(--wit); }   /* basis #18844f, contrast ok */
.nav-badge.paars { background: linear-gradient(180deg, color-mix(in srgb, var(--accent-diep) 88%, var(--wit)), var(--accent-diep)); color: var(--wit); }
.nav-badge.rood  { background: linear-gradient(180deg, #e04b45, var(--rood-diep)); color: var(--wit);   /* basis blijft --rood-diep */
  box-shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 3px rgba(0,0,0,.3),
              0 0 0 3px rgba(204,51,40,.16); }
/* Rustige pulse voor de proactieve update-badge — trekt aandacht zonder te schreeuwen. */
.nav-badge.pulse { animation: navBadgePulse 2.4s ease-in-out infinite; }
@keyframes navBadgePulse {
  0%, 100% { box-shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 3px rgba(0,0,0,.3), 0 0 0 0 rgba(204,51,40,.42); }
  50%      { box-shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 3px rgba(0,0,0,.3), 0 0 0 5px rgba(204,51,40,0); }
}
@media (prefers-reduced-motion: reduce) { .nav-badge.pulse { animation: none; } }

/* Per-server upgrade-veiligheidsadvies (in de Purpur-kaart onder de MC-versie-melding). */
.upg-advies { margin-top: 8px; font-size: 12px; line-height: 1.5; padding: 7px 10px; border-radius: 8px; }
.upg-advies.upg-veilig   { background: rgba(var(--green-rgb,24,132,79),.12);  color: var(--text); border: 1px solid rgba(var(--green-rgb,24,132,79),.30); }
.upg-advies.upg-blokkeer { background: rgba(var(--yellow-rgb,224,160,58),.12); color: var(--text); border: 1px solid rgba(var(--yellow-rgb,224,160,58),.32); }
.upg-advies.upg-onbekend { background: rgba(255,255,255,.05); color: var(--muted); border: 1px solid var(--border); }

/* MC-compatibiliteitskolom in de plugins-tab: 'van–tot' MC-versie-range per plugin
   (tot waar je kunt upgraden). Rustig informatief, geen statuskleur. */
.compat-range { display: inline-block; padding: 1px 8px; border-radius: 999px;
  font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap;
  background: rgba(255,255,255,.06); color: var(--text); border: 1px solid var(--border); }
.compat-onbekend { color: var(--muted); }

/* ── Financiën-tab: KPI-tegels + actieblokken ─────────────────────────────
   Waarde-tekst blijft --text (hoog contrast); groen/rood alleen als rand-accent,
   zodat de contrast-governance niet op gekleurde tekst hoeft te vallen. */
.fin-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px;
  margin-bottom: 22px;
}
.fin-kpi {
  background: var(--card-solid);
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--border-strong);
  border-radius: 12px;
  padding: 15px 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.fin-kpi.groen { border-left-color: var(--green); }
.fin-kpi.rood  { border-left-color: var(--red); }
.fin-kpi-lbl { font-size: 12px; color: var(--muted); }
.fin-kpi-val { font-size: 24px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.fin-block {
  background: var(--card-solid);
  border: 1px solid var(--border-strong);
  border-radius: 12px;
  padding: 16px 18px;
  margin-bottom: 16px;
}
.fin-block h2 { font-size: 15px; margin: 0 0 4px; color: var(--text); }
.fin-block-hint { font-size: 12px; color: var(--muted); margin: 0 0 10px; }
.fin-block-actie { border-color: rgba(var(--red-rgb), .32); background: rgba(var(--red-rgb), .07); }
.fin-block-ok { border-color: rgba(var(--green-rgb), .3); background: rgba(var(--green-rgb), .06); }
.fin-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}
.fin-row:first-of-type { border-top: 0; }
.fin-age { font-size: 11px; color: var(--muted); margin-left: 6px; }
/* 'Website-aanvragen' paste net niet en werd afgekapt tot 'Website-aanvra…'.
   Een menu-item hoort zijn eigen naam te kunnen dragen: 20px extra breedte. */
@media (min-width: 993px) { .shell-sidebar { width: 282px; } }

/* Op een breed scherm bleef het paneel steken op 1240px, met ruim 500px leegte
   aan weerszijden. Voor lopende tekst is dat goed (leesbare regellengte), maar een
   dashboard met een console en meters mag de ruimte gebruiken. */
@media (min-width: 1700px) {
  body.server-page .main { max-width: 1640px; }
  body.dashboard-page .main { max-width: 1480px; }
}

/* Serverstatus in de kopbalk — op een telefoon je enige houvast. */
.topbar-status {
  font-size: 11.5px; font-weight: 800; padding: 3px 9px; border-radius: 20px;
  white-space: nowrap; background: rgba(255,255,255,.06); color: var(--muted);
  border: 1px solid var(--border-strong);
}
.topbar-status.online { background: rgba(24,132,79,.18); color: #6ee7a8; border-color: rgba(24,132,79,.45); }
.topbar-status.busy   { background: rgba(234,179,8,.15); color: #f5cf6a; border-color: rgba(234,179,8,.4); }
.topbar-status.offline{ background: rgba(255,255,255,.05); color: #9aa3b5; border-color: var(--border-strong); }

/* ═══ Bestelpagina: de kopbalk op een telefoon ══════════════════════════════
   Vijf losse links naast een logo en een taalkiezer op 390px: 'Mijn paneel' brak
   over twee regels en 'Profiel' viel half buiten beeld. Dit is de pagina waar
   iemand besluit te betalen — daar mag niets rafelig zijn.
   Op een telefoon: logo op de eerste regel, de rest netjes eronder, en de
   gebruikersnaam weg (die weet je zelf wel).
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  .portal-order-page header {
    flex-wrap: wrap;
    row-gap: 8px;
    padding: 12px 16px;
  }
  .portal-order-page header a.logo { flex: 1 1 100%; }
  .portal-order-page .header-user {
    flex: 1 1 100%;
    gap: 6px;
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .portal-order-page .header-user::-webkit-scrollbar { display: none; }
  .portal-order-page .header-user a { white-space: nowrap; padding-inline: 8px; }
  /* De naam van de ingelogde gebruiker is op een telefoon ruimte die je niet hebt. */
  .portal-order-page .header-user > span:not([class]) { display: none; }
}
/* 'Mijn paneel' brak over twee regels — ook op een breed scherm. Een link in een
   kopbalk hoort nooit af te breken. */
header .header-user a, header .header-user span { white-space: nowrap; }

/* ╔═══════════════════════════════════════════════════════════════════════════╗
   ║  LEVENDIGHEID — hoe je een donker paneel laat leven zonder neon-rommel     ║
   ╠═══════════════════════════════════════════════════════════════════════════╣
   ║  Uit onderzoek naar hoe Linear, Vercel, Supabase en Railway dit doen:      ║
   ║                                                                            ║
   ║  1. Diepte op donker maak je NIET met schaduw (dat wordt een vieze vlek op ║
   ║     #0B0D13) maar met een oppervlakteladder + een 1px lichtrand bovenop de ║
   ║     kaart. Die lichtrand is precies wat een vlak 'gerenderd' laat voelen.  ║
   ║  2. Glow hoort op ÉÉN element. Als hover, actief, primair, badge én stip   ║
   ║     allemaal gloeien, popt er niets meer. Max twee gloeiende dingen in     ║
   ║     beeld: het actieve menu-item en de primaire knop.                      ║
   ║  3. Pulseren betekent 'er gebeurt nú iets' — niet 'alles is normaal'.      ║
   ║  4. Beweeg transform/opacity, nooit box-shadow (die herberekent elke frame ║
   ║     de blur — merkbaar traag bij 20 serverkaarten).                        ║
   ╚═══════════════════════════════════════════════════════════════════════════╝ */

/* ── De oppervlakteladder — tokens staan in het :root-blok bovenaan ──────── */

.card, .server-card, .dienst, body.server-page .card {
  box-shadow: var(--lift-1), var(--hair);
  border-color: transparent;                          /* de haarlijn ís de rand */
  transition: transform .18s cubic-bezier(.2,.8,.2,1),
              box-shadow .18s ease, background-color .18s ease;
}

/* ── Klikbare kaarten tillen op. Statische tegels niet: dan liegt de hover. ── */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .server-card:hover, .dienst:hover {
    transform: translateY(-2px);
    background-color: #171A24;
    box-shadow: inset 0 1px 0 0 rgba(255,255,255,.09),
                var(--hair-h),
                0 8px 24px -12px rgba(0,0,0,.6);
  }
}

/* ── Het actieve menu-item: één rail met glow, geen gloeiend blok ─────────── */
.sidebar-link.active, body.server-page .sidebar-link.active {
  position: relative;
  background: rgba(91,140,255,.10);
  color: #DCE4FF;
  box-shadow: inset 0 0 0 1px rgba(91,140,255,.22),
              inset 0 0 20px -8px rgba(91,140,255,.45);
  border: none;
}
.sidebar-link.active::before {
  content: "";
  position: absolute; left: 0; top: 6px; bottom: 6px; width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--accent);
  box-shadow: 0 0 12px 0 rgba(91,140,255,.55);   /* de enige echte glow in het menu */
}
/* Hover mag NOOIT gloeien — anders verdwijnt het verschil met 'actief'. */
.sidebar-link:hover:not(.active) {
  background: rgba(255,255,255,.045);
  color: #E6E8EE;
  box-shadow: none;
}

/* ── Statuskleuren: gestopt is geen storing ──────────────────────────────── */
/* Een rode stip bij elke gestopte server schreeuwt 'kapot' terwijl er niets aan
   de hand is. Grijs = uit. Rood houden we voor echte fouten. */
body.server-page .status-dot.off,
.status-dot.offline, .status-dot.stopped, .status-dot.off {
  background: #8A8F98;
  box-shadow: none;
  animation: none;
}
.status-dot.online, .status-dot.running, body.server-page .status-dot.on {
  background: #3FCF8E;
  box-shadow: 0 0 8px rgba(63,207,142,.55);
  animation: none;                       /* draaien is de rusttoestand: niet pulseren */
}
/* Pulseren alleen als er iets gebeurt: starten, stoppen, installeren. */
.status-dot.loading, .status-dot.starting, .status-dot.busy {
  background: #F5A524;
  box-shadow: 0 0 8px rgba(245,165,36,.5);
  position: relative;
  animation: none;
}
.status-dot.loading::after, .status-dot.starting::after, .status-dot.busy::after {
  content: "";
  position: absolute; inset: 0; border-radius: 50%;
  background: #F5A524;
}
@media (prefers-reduced-motion: no-preference) {
  .status-dot.loading::after, .status-dot.starting::after, .status-dot.busy::after {
    animation: cavePing 1.8s cubic-bezier(0,0,.2,1) infinite;
  }
}
@keyframes cavePing {          /* transform + opacity: geen blur-herberekening */
  0%   { transform: scale(1);   opacity: .55; }
  70%  { transform: scale(2.6); opacity: 0; }
  100% { transform: scale(2.6); opacity: 0; }
}

/* ── Knoppen: de indrukbeweging blijft, de vulling komt uit het contract ────
   Hier stond de laatste van de vier vullingslagen: een verloop van boven met een
   inset-glans, op `.btn-primary`/`.btn-green`/`.btn-red` én op hun
   `body.server-page`-tegenhangers. Dít was de gemeten winnaar in beide paneelschermen,
   en dus de reden dat "▶ Start" in het serverpaneel een verloop hield terwijl dezelfde
   knop in het adminpaneel al vlak was. Weg per 30 juli 2026 (§7b, regel 1.5: een
   kleurverloop is chroom, kleur hoort bij betekenis).

   De :active-verkleining blijft: dat is BEWEGING, geen kleur, en het contract zegt er
   niets over. Zonder deze regels voelt elke knop in het paneel dood bij indrukken. */
.btn-primary:active:not(:disabled),
.btn-green:active:not(:disabled),
.btn-red:active:not(:disabled),
.btn-start:active:not(:disabled),
.btn-stop:active:not(:disabled) { transform: scale(.97); }

/* ── Focusring in twee lagen: eerst een gat in de achtergrond, dan de ring ── */
:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px #7EA6FF;
}

/* ── Sfeer: één zachte gloed achter de kop, nooit achter data ────────────── */
body.dashboard-page::before, body.portal-order-page::before {
  content: "";
  position: fixed; inset: 0 0 auto 0; height: 420px;
  z-index: 0; pointer-events: none;
  background:
    radial-gradient(60% 60% at 15% 0%, rgba(91,140,255,.09), transparent 70%),
    radial-gradient(50% 50% at 85% 5%, rgba(91,140,255,.07), transparent 70%);
}
body.dashboard-page .shell-container,
body.portal-order-page header, body.portal-order-page main { position: relative; z-index: 1; }

/* ── Beweging uit als de gebruiker daarom vraagt ─────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ── Icoonchips: kleur zit in de chip, nooit in de tekst ──────────────────── */
/* Zo krijg je ritme en kleur zonder regenboogdashboard. De emoji houdt zijn eigen
   kleur; de chip geeft hem een vlak om op te staan, zodat alle iconen even groot
   ogen (emoji verschillen per besturingssysteem in breedte). */
.sidebar-link .icon {
  width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 9px;
  background: rgba(255,255,255,.05);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.06);
  font-size: 15px;
  transition: background .18s ease, box-shadow .18s ease;
}
.sidebar-link:hover .icon { background: rgba(255,255,255,.08); }
.sidebar-link.active .icon {
  background: rgba(91,140,255,.16);
  box-shadow: inset 0 0 0 1px rgba(91,140,255,.30);
}

/* ── Spotlight: de kaart licht op waar je cursor staat ────────────────────── */
/* Alleen op klikbare kaarten, alleen op apparaten mét een cursor, en met een lage
   dekking (.10): meer en het wordt een discolamp. */
@media (hover: hover) {
  .server-card, .dienst { position: relative; overflow: hidden; }
  .server-card::after, .dienst::after {
    content: "";
    position: absolute; inset: 0; pointer-events: none;
    opacity: 0; transition: opacity .3s ease;
    background: radial-gradient(280px circle at var(--mx, 50%) var(--my, 50%),
                rgba(91,140,255,.10), transparent 65%);
  }
  .dienst::after {
    background: radial-gradient(280px circle at var(--mx, 50%) var(--my, 50%),
                rgba(91,140,255,.12), transparent 65%);
  }
  .server-card:hover::after, .dienst:hover::after { opacity: 1; }
}

/* ╔═══════════════════════════════════════════════════════════════════════════╗
   ║  ÉÉN ONTWERPTAAL — het gameserverpaneel krijgt de look van het hoofdpaneel ║
   ╠═══════════════════════════════════════════════════════════════════════════╣
   ║  Gemeten verschil (berekende stijl, beide schermen naast elkaar):          ║
   ║    achtergrond  #0B0D13   vs  #06080B   (donkerder)                        ║
   ║    lettertype   Inter     vs  systeemfont                                  ║
   ║    kaart        #14161F, radius 16, lichtrand                              ║
   ║                          vs  doorzichtig, radius 12, zware zwarte schaduw  ║
   ║    kaartkop     grijs/hoofdletters/onderlijn  vs  wit/gewone tekst         ║
   ║    invoerveld   radius 9, 14px            vs  radius 7, 12px               ║
   ║  Het waren twee ontwerpsystemen. Dit maakt er één van.                     ║
   ╚═══════════════════════════════════════════════════════════════════════════╝ */

body.server-page {
  background: var(--bg);
  color: var(--text);
  font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* De kaart: hetzelfde vlak, dezelfde ronding, dezelfde lichtrand — en géén zware
   zwarte schaduw (die wordt op een donkere achtergrond alleen een vuile vlek). */
body.server-page .card {
  background: var(--card);
  border: none;
  border-radius: 16px;
  box-shadow: var(--lift-1), var(--hair);
}

/* De kaartkop: rustig grijs in hoofdletters met een onderlijn, zoals overal elders.
   In het gameserverpaneel schreeuwde elke kop nog in wit. */
body.server-page .card h2 {
  font-size: 15px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 1.2px;
  padding-bottom: 14px;
  margin-bottom: 14px;
  border-bottom: 1px solid rgba(255,255,255,.07);
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Invoervelden: hetzelfde formaat en dezelfde ronding als in het hoofdpaneel. */
body.server-page input[type=text],
body.server-page input[type=number],
body.server-page input[type=time],
body.server-page input[type=search],
body.server-page input[type=password],
body.server-page select,
body.server-page textarea {
  background: rgba(0,0,0,.25);
  border-radius: 9px;
  padding: 11px 14px;
  font-size: 14px;
  color: var(--text);
}
/* Uitzondering: de console en zijn zoekbalk blijven compact en monospace — dat is
   een terminal, geen formulier. */
body.server-page .console-tools input,
body.server-page .cmdrow input {
  padding: 8px 12px;
  font-size: 13px;
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
}

/* Het gameserverpaneel had zijn eigen tokens (een donkerdere achtergrond en een
   zware kaartschaduw). Eén paneel, één set. */
body.server-page {
  --bg: #0B0D13;
  --card: #14161F;
  --surface2: #1A1D28;
  --shadow-card: none;
  --muted: #99A1B3;
}

/* ── Bedieningselementen hebben een minimumhoogte ─────────────────────────── */
/* Verspreid over de beheertabbladen stonden keuzelijsten van 19-28px hoog en een
   invoerveld van 19px. Dat is niet te raken en het oogt slordig. Eén regel voor
   alles wat je bedient — op een telefoon de volle 44px (WCAG 2.5.5). */
/* UITSLUITEN in plaats van opsommen (herzien 28 juli 2026).
   Hier stond een lijst van `input[type=text]`, `[type=email]`, … En een
   attribuutselector matcht alleen als het attribuut er LETTERLIJK staat: een kaal
   `<input id="…" placeholder="…">` is wel degelijk een tekstveld, maar viel buiten
   élke regel hierboven. Gemeten: **75** van zulke velden over zes schermen, en op de
   admintab Website-aanvragen leverde dat invoervelden van 22 tot 26px hoog op --
   terwijl dit blok juist geschreven wás om "een invoerveld van 19px" op te lossen.
   De uitsluitingsvorm staat 1400 regels hoger al voor de randkleur; nu ook hier, zodat
   een nieuw veld zonder type niet opnieuw stil door de bodem zakt. */
/* ÉÉN `:not()` met een lijst, niet zes gestapelde (herzien 28 juli 2026).
   Inhoudelijk sluiten ze exact hetzelfde uit; het verschil zit in SPECIFICITEIT.
   Zes gestapelde `:not()`-jes tellen als zes klassen — (0,6,1) — en dat verslaat elke
   redelijke schermregel: `.profile-page .field input` is (0,2,1) en verloor dus, ook
   met een expliciete `min-height`. Gemeten: de profielvelden bleven op 42px staan
   terwijl er 44px gedeclareerd stond, en op 390px klopte het wél (daar wint de
   media-query hieronder). Dat is precies de val van `.server-page .ct-btn`, alleen
   omgekeerd: hier won de ALGEMENE regel van de specifieke.
   In Selectors 4 neemt `:not(a, b, c)` de specificiteit van zijn zwaarste argument,
   dus dit is (0,1,1) — een schermregel kan er weer overheen. */
select,
input:not([type=checkbox], [type=radio], [type=hidden], [type=file], [type=range], [type=color]) {
  min-height: 36px;
  box-sizing: border-box;
}
@media (max-width: 768px) {
  select,
  input:not([type=checkbox], [type=radio], [type=hidden], [type=file], [type=range], [type=color]) {
    min-height: 44px;
  }
}
/* Bestandskiezers apart, want `min-height` op het INPUT-element helpt daar niet: bij
   `<input type=file>` opent alleen de KNOP de bestandskiezer, niet het tekstdeel
   ernaast. Het element hoger maken vergroot dus wel de rij maar niet het raakvlak.
   `::file-selector-button` mikt op de knop zelf. Gemeten op staging (390px, admintab
   Website-aanvragen): vijf `impZip`-knoppen van 22px. */
input[type=file]::file-selector-button {
  min-height: 44px;
  padding: 0 14px;
  border-radius: 8px;
  border: 1px solid var(--border-interactive, #6b7689);
  background: var(--surface2, #1a1d28);
  color: var(--text, #e9edf6);
  font: inherit;
  cursor: pointer;
  margin-right: 10px;
}
input[type=file]::file-selector-button:hover { filter: brightness(1.12); }

/* Het logo-icoon had alleen een maat op de bestel- en bedankpagina. Op het profiel
   (waar ik het vanavond toevoegde) kreeg de afbeelding dus geen enkele afmeting en
   rendeerde hij op ware grootte: een blok van 200px in de kopbalk. Eén maat, overal. */
.logo-icon {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 8px;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.logo-icon img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* ── Aanraakvlakken op de inlog-/registratie-/storingspagina's ──────────────
   Deze schermen zaten niet in mijn visuele controle, dus de kleine links vielen
   niet op: de merknaam linksboven (28px hoog) en 'Wachtwoord vergeten?' /
   '← Terug naar inloggen' (16px). Het eerste wat een klant ziet hoort raakbaar
   te zijn. */
.auth-page .page-brand,
.auth-page .switch a,
.auth-page a.terug,
.status-page .page-brand,
.st-logo,
.status-page a {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding-inline: 4px;
  border-radius: 8px;
}
@media (max-width: 768px) {
  .auth-page .page-brand,
  .auth-page .switch a,
  .auth-page a.terug,
  .status-page .page-brand, .st-logo, .status-page a { min-height: 44px; }
}

/* ═══ Node-kaart: één vaste opmaak ══════════════════════════════════════════
   Was opgebouwd uit losse inline-stijlen; elke toevoeging liet de indeling
   verspringen. Nu een vaste structuur, zodat een nieuw veld of knop niets meer
   laat schuiven. ═══════════════════════════════════════════════════════════ */
.node-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(330px, 100%), 1fr)); gap: 14px; }
.node-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--node-accent, var(--muted));
  border-radius: 14px;
  padding: 16px 17px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  box-shadow: var(--lift-1), var(--hair);
}
.node-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.node-head .node-naam { font-size: 14.5px; font-weight: 800; color: var(--text); }
.node-head .node-hb { margin-left: auto; font-size: 11px; white-space: nowrap; }
.node-pill {
  font-size: 10px; font-weight: 800; padding: 2px 8px; border-radius: 20px;
  text-transform: uppercase; letter-spacing: .03em; white-space: nowrap;
}
.node-pill.cp { background: rgba(91,140,255,.15); color: #93b4ff; }

/* Label/waarde in een vast raster: labels links, waarden rechts uitgelijnd. */
.node-meta {
  display: grid; grid-template-columns: 92px minmax(0, 1fr);
  gap: 5px 12px; font-size: 12px; color: var(--muted); margin: 0;
}
.node-meta dt { color: var(--muted); }
.node-meta dd { color: var(--text); margin: 0; min-width: 0; overflow-wrap: anywhere; }
.node-meta dd.mono { font-family: ui-monospace, 'SF Mono', Menlo, monospace; }

.node-bars { display: flex; flex-direction: column; gap: 8px; }
.node-bar-top { display: flex; justify-content: space-between; font-size: 11px; color: var(--muted); margin-bottom: 3px; }
.node-bar-track { height: 7px; background: rgba(255,255,255,.08); border-radius: 20px; overflow: hidden; }
.node-bar-fill { height: 100%; border-radius: 20px; }
.node-note { font-size: 11.5px; padding: 2px 0; }
.node-note.warn { color: #f5cf6a; }
.node-note.muted { color: var(--muted); }

/* De voet: status links, knoppen rechts — altijd op deze plek, wat je ook toevoegt. */
.node-foot {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding-top: 12px; border-top: 1px solid var(--border);
}
.node-foot .node-foot-label { font-size: 11px; color: var(--muted); }
.node-foot .node-foot-acties { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }
.node-foot select {
  background: var(--surface2); border: 1px solid var(--border-strong); color: var(--text);
  border-radius: 8px; padding: 5px 8px; font-size: 12px; min-height:44px;
}

/* ── Scheduler-tab (geplande taken v2): presets, dag-kiezer, online-check ── */
.server-page .sch-presets { display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-top:8px; }
.server-page .sch-presets-label { font-size:12.5px; color:var(--muted); }
.server-page .sch-preset { background:var(--surface2); color:var(--text); border:1px solid var(--border); border-radius:999px; padding:8px 14px; font-size:12.5px; cursor:pointer; min-height:44px; transition:.15s; }
.server-page .sch-preset:hover { border-color:var(--accent); color:var(--accent); }
.server-page .sch-preset:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.server-page .sch-dagen { display:flex; gap:6px; flex-wrap:wrap; }
.server-page .sch-dag { min-width:46px; min-height:44px; border-radius:8px; border:1px solid var(--border); background:var(--surface2); color:var(--muted); font-size:12.5px; cursor:pointer; transition:.15s; }
.server-page .sch-dag.actief { background:linear-gradient(160deg,var(--accent2),var(--accent)); color:var(--wit); border-color:transparent; }
.server-page .sch-dag:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.server-page #schDagenField { margin-top:12px; }
.server-page .sch-online { display:flex; align-items:center; gap:8px; margin-top:12px; font-size:13px; color:var(--text); cursor:pointer; }
.server-page .sch-sub { font-size:11px; color:var(--muted); margin-top:2px; }

/* ── Console: logniveau-kleuren (fouten rood, waarschuwingen amber) ── */
.server-page #log .log-error { color:#ff8a80; }
.server-page #log .log-warn { color:#e3b341; }

/* ── Crash-uitleg-kaarten (console-tab) ── */
.server-page .crash-kaart { background:var(--surface2); border:1px solid var(--border); border-left:3px solid var(--accent); border-radius:10px; padding:10px 14px; margin:0 0 8px; font-size:13px; position:relative; }
.server-page .crash-kaart.crash-fout { border-left-color:#ff8a80; }
.server-page .crash-kaart.crash-ok { border-left-color:#5fd39a; }
.server-page .crash-titel { font-weight:600; }
.server-page .crash-uitleg { color:var(--muted); margin-top:4px; line-height:1.5; }
.server-page .crash-oplossing { margin-top:6px; line-height:1.5; }
.server-page .crash-bron { margin-top:6px; font-size:11px; color:var(--muted); }
.server-page .crash-sluit { background:none; border:1px solid var(--border); color:var(--muted); border-radius:7px; padding:4px 10px; cursor:pointer; min-height:44px; }
.server-page .crash-sluit:hover { color:var(--text); border-color:var(--accent); }

/* ── Wereld resetten (Wereld-tab) ── */
.server-page .world-reset-card { border-color: rgba(240,89,79,.35); }
.server-page .world-reset-intro { font-size: 13px; color: var(--muted); line-height: 1.6; margin: 4px 0 12px; }
/* `min-height:44px` op het LABEL, niet op het vakje: het selectievakje blijft 18px
   (groter oogt plomp), maar het hele label eromheen is het aanraakvlak. Dat is
   dezelfde oplossing als `.vak-doel` elders in dit bestand. Gemeten 28 juli 2026 op
   390px: deze rij was 39px. */
.server-page .world-reset-seedrow { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; margin-bottom: 10px; min-height: 44px; }
.server-page .world-reset-seed { margin-bottom: 12px; }
.server-page .world-reset-msg { margin-top: 10px; font-size: 13px; }
.server-page .world-reset-msg.ok { color: var(--green); }
.server-page .world-reset-msg.err { color: var(--red); }

/* ── Activiteitenlog (tijdlijn-tab) ── */
.server-page .activity-intro { font-size: 12.5px; color: var(--muted); margin: 0 0 12px; line-height: 1.6; }
.server-page .activity-list { display: flex; flex-direction: column; }
.server-page .activity-row { display: flex; gap: 12px; padding: 11px 4px; border-bottom: 1px solid var(--border); }
.server-page .activity-row:last-child { border-bottom: 0; }
.server-page .act-icon { font-size: 16px; flex-shrink: 0; width: 24px; text-align: center; }
.server-page .act-body { min-width: 0; }
.server-page .act-line { font-size: 13.5px; line-height: 1.5; word-break: break-word; }
.server-page .act-meta { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.server-page .act-chip { font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 999px; white-space: nowrap; }
.server-page .act-chip.act-team { background: rgba(91,140,255,.16); color: #93b4ff; border: 1px solid rgba(91,140,255,.3); }
.server-page .act-chip.act-sys { background: var(--surface2); color: var(--muted); border: 1px solid var(--border); }
.server-page .activity-empty { padding: 24px; text-align: center; color: var(--muted); }
.server-page .activity-pager { display: flex; gap: 8px; justify-content: center; margin-top: 12px; }

/* ── Kennisbank: help-drawer (slide-over) ── */
.server-page .help-drawer[hidden] { display: none; }
.server-page .help-drawer { position: fixed; inset: 0; z-index: 10001; }
.server-page .help-overlay { position: absolute; inset: 0; background: rgba(6,8,14,.55); opacity: 0; transition: opacity .2s; }
.server-page .help-drawer.open .help-overlay { opacity: 1; }
.server-page .help-panel { position: absolute; top: 0; right: 0; height: 100%; width: min(440px, 92vw);
  background: var(--card); border-left: 1px solid var(--border); box-shadow: -12px 0 40px rgba(0,0,0,.5);
  transform: translateX(100%); transition: transform .2s ease; display: flex; flex-direction: column; }
.server-page .help-drawer.open .help-panel { transform: translateX(0); }
.server-page .help-head { display: flex; align-items: center; justify-content: space-between; padding: 16px; border-bottom: 1px solid var(--border); }
.server-page .help-head strong { font-size: 15px; }
.server-page .help-x { background: none; border: 0; color: var(--muted); font-size: 18px; cursor: pointer; padding: 4px 8px; }
.server-page .help-x:hover { color: var(--text); }
.server-page .help-search { padding: 12px 16px; border-bottom: 1px solid var(--border); }
.server-page .help-search input { width: 100%; padding: 9px 12px; border-radius: 9px; background: var(--surface2); border: 1px solid var(--border); color: var(--text); font-size: 13.5px; }
.server-page .help-content { flex: 1; overflow-y: auto; padding: 12px 16px; }
.server-page .help-empty, #kbBody .help-empty { padding: 24px; text-align: center; color: var(--muted); font-size: 13px; }
.server-page .help-cat, #kbBody .help-cat { margin-bottom: 16px; }
.server-page .help-cat-title, #kbBody .help-cat-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-bottom: 6px; }
.server-page .help-item, #kbBody .help-item { display: block; width: 100%; text-align: left; background: var(--surface2); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; margin-bottom: 6px; cursor: pointer; transition: .12s; }
.server-page .help-item:hover, #kbBody .help-item:hover { border-color: var(--accent); }
.server-page .help-item-t, #kbBody .help-item-t { display: block; font-size: 13.5px; color: var(--text); font-weight: 600; }
.server-page .help-item-s, #kbBody .help-item-s { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }
.server-page .help-back, #kbBody .help-back { background: none; border: 0; color: var(--accent); cursor: pointer; font-size: 13px; padding: 4px 0; margin-bottom: 8px; }
.server-page .help-article h2, #kbBody .help-article h2 { font-size: 17px; margin: 4px 0 10px; }
.server-page .help-article h3, #kbBody .help-article h3, .server-page .help-article h4, #kbBody .help-article h4 { font-size: 14px; margin: 14px 0 6px; }
.server-page .help-article p, #kbBody .help-article p { font-size: 13.5px; line-height: 1.65; margin: 8px 0; color: var(--text); }
.server-page .help-article ul, #kbBody .help-article ul { margin: 8px 0 8px 4px; padding-left: 18px; font-size: 13.5px; line-height: 1.6; }
.server-page .help-article li, #kbBody .help-article li { margin: 3px 0; }
.server-page .help-article code, #kbBody .help-article code { background: var(--surface2); border: 1px solid var(--border); border-radius: 5px; padding: 1px 5px; font-size: 12.5px; }
.server-page .help-article a, #kbBody .help-article a { color: var(--accent); }
.server-page .helpbtn { white-space: nowrap; }
.server-page .crash-artikel { margin-top: 8px; background: none; border: 1px solid var(--border); color: var(--accent); border-radius: 7px; padding: 5px 11px; cursor: pointer; font-size: 12.5px; min-height:44px; }
.server-page .crash-artikel:hover { border-color: var(--accent); background: rgba(91,140,255,.08); }

/* ── Kennisbank-editor (admin): responsief formulierraster ── */
.kb-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }

/* ── Crash-uitleg: knoppenrij (actie + meer hulp) ── */
.server-page .crash-knoppen { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.server-page .crash-actie { background: rgba(95,211,154,.1); border: 1px solid rgba(95,211,154,.4); color: #5fd39a; border-radius: 7px; padding: 5px 11px; cursor: pointer; font-size: 12.5px; min-height:44px; }
.server-page .crash-actie:hover { background: rgba(95,211,154,.18); }

/* ── Prestatie-adviseur (dashboard) ── */
.server-page .prestatie-kaart { display: block; }
.server-page .perf-badge { font-size: 12px; font-weight: 700; padding: 2px 9px; border-radius: 999px; }
.server-page .perf-badge.perf-goed { background: rgba(95,211,154,.14); color: #5fd39a; }
.server-page .perf-badge.perf-matig { background: rgba(227,179,65,.14); color: #e3b341; }
.server-page .perf-badge.perf-zwaar { background: rgba(255,138,128,.14); color: #ff8a80; }
.server-page .perf-body { margin-top: 8px; }
.server-page .perf-empty { color: var(--muted); font-size: 13px; line-height: 1.5; padding: 6px 0; }
.server-page .perf-metrics { display: flex; gap: 16px; flex-wrap: wrap; font-size: 13.5px; margin-bottom: 10px; }
.server-page .perf-metrics strong { color: var(--text); font-variant-numeric: tabular-nums; }
.server-page .perf-bron { color: var(--muted); font-size: 11.5px; }

/* ── Discord-meldingen (Instellingen-tab) ── */
.server-page .discord-card { margin-top: 14px; }
.server-page .discord-badge { font-size: 12px; font-weight: 700; padding: 2px 9px; border-radius: 999px; margin-left: 4px; }
.server-page .discord-badge.discord-ok { background: rgba(95,211,154,.14); color: #5fd39a; }
.server-page .discord-badge.discord-err { background: rgba(255,138,128,.14); color: #ff8a80; }
.server-page .discord-intro { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin: 4px 0 12px; }
.server-page .discord-veld { margin-bottom: 12px; }
.server-page .discord-masker { display: block; font-size: 11.5px; color: var(--muted); margin-top: 4px; }
.server-page .discord-toggles { display: flex; gap: 16px; flex-wrap: wrap; font-size: 13px; margin-bottom: 12px; }
.server-page .discord-toggles label { display: flex; align-items: center; gap: 6px; cursor: pointer; min-height: 44px; }
.server-page .discord-knoppen { display: flex; gap: 8px; flex-wrap: wrap; }
.server-page .discord-msg { margin-top: 10px; font-size: 12.5px; min-height: 18px; }
.server-page .discord-msg.ok { color: var(--green); }
.server-page .discord-msg.err { color: var(--red); }

/* ── Publieke statuspagina (Instellingen-tab) ── */
.server-page .pubstatus-card { margin-top: 14px; }
.server-page .pubstatus-intro { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin: 4px 0 12px; }
.server-page .pubstatus-toggle { display: flex; align-items: center; gap: 8px; font-size: 13.5px; cursor: pointer; min-height: 44px; }
.server-page .pubstatus-link { display: flex; gap: 8px; align-items: center; margin: 12px 0; }
.server-page .pubstatus-link code { flex: 1; background: var(--surface2); border: 1px solid var(--border); border-radius: 9px; padding: 9px 12px; font-size: 12.5px; color: #93b4ff; word-break: break-all; -webkit-user-select: all; user-select: all; }
.server-page .pubstatus-opties { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; font-size: 13px; }
.server-page .pubstatus-opties label { display: flex; align-items: center; gap: 8px; cursor: pointer; min-height: 44px; }
.server-page .pubstatus-msg { margin-top: 8px; font-size: 12.5px; min-height: 16px; }
.server-page .pubstatus-msg.ok { color: var(--green); }
.server-page .pubstatus-msg.err { color: var(--red); }

/* ── Alle spelregels (Wereld-tab) ──────────────────────────────────────────
   De lijst wordt gegenereerd uit wat de wereld zelf kent, dus hij kan van 40
   tot 60+ rijen lang zijn. Vandaar het zoekveld en een eigen scrollgebied:
   de Wereld-tab blijft zo bruikbaar zonder eindeloos te scrollen. */
.server-page .gr-zoek { width: 100%; box-sizing: border-box; margin: 10px 0 8px;
  padding: 9px 12px; min-height: 44px; background: var(--surface2); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: 9px; font-size: 13.5px; }
.server-page .gr-zoek:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.server-page .gr-lijst { max-height: 420px; overflow-y: auto; padding-right: 4px; }
.server-page .gr-groep { font-size: 11px; color: var(--muted); text-transform: uppercase;
  letter-spacing: .07em; font-weight: 700; margin: 14px 0 4px; padding-top: 10px;
  border-top: 1px solid var(--border); }
.server-page .gr-groep:first-child { margin-top: 4px; padding-top: 0; border-top: none; }
.server-page .gr-rij { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.server-page .gr-rij:last-child { border-bottom: none; }
.server-page .gr-naam { font-size: 13px; font-family: ui-monospace, monospace;
  word-break: break-all; }
.server-page .gr-getal { width: 110px; flex-shrink: 0; min-height: 40px; padding: 6px 9px;
  background: var(--surface2); color: var(--text); border: 1px solid var(--border-strong);
  border-radius: 8px; font-size: 13px; text-align: right; }
.server-page .gr-leeg { font-size: 12.5px; color: var(--muted); }
.server-page .gr-rij.gr-bezig { opacity: .55; }
@media (max-width: 560px) {
  .server-page .gr-rij { flex-wrap: wrap; }
  .server-page .gr-getal { width: 100%; text-align: left; }
}

/* `clip` blokkeert zijwaarts schuiven ZONDER een scroll-container te maken, en laat
   `position: sticky` dus heel (de mobiele kopbalk met de menuknop). Alleen toepassen
   waar de browser het kent — Safari < 16 valt terug op `hidden` hierboven. */
@supports (overflow: clip) {
  html, body, html.server-page, body.server-page { overflow-x: clip; }
}

/* ── Gezondheid-tab (keuze C, 26 juli 2026) ──────────────────────────────────
   Eigen klassen i.p.v. inline stijl, zodat de contrast-governance (check_contrast)
   erover kan meekijken — inline `style=` ontsnapt daaraan. De statuskleuren zijn
   de *-diep-tokens: die halen 4,5:1 met witte tekst, de merkkleur zelf niet.
   Kleur is nooit de enige drager: elke toestand heeft ook een woord én een teken,
   zodat het bij kleurenblindheid leesbaar blijft (WCAG 1.4.1). */
.page-sub { color: var(--muted); font-size: 13px; margin-top: 2px; }
.page-header-acties { display: flex; gap: 8px; flex-wrap: wrap; }


.gez-gemeten { color: var(--muted); }
.gez-kaart { margin-top: 16px; }
/* `.gez-kop` is weg (31 juli 2026): het was een tweede kaartkop naast `.card h2`,
   zonder de padding die `.card` zelf niet heeft — vandaar de aangesneden koppen.
   De Gezondheid-kaarten gebruiken nu gewoon `.card h2` + `.card-body`. */

.gez-tegels {
  display: grid; gap: 10px; margin-bottom: 4px;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}
.gez-tegel {
  border: 1px solid var(--border); border-radius: 12px;
  padding: 12px 14px; background: var(--card);
}
.gez-tegel-cijfer { font-size: 26px; font-weight: 600; line-height: 1.1; }
.gez-tegel-label { color: var(--muted); font-size: 12px; margin-top: 2px; }
.gez-tegel.is-aandacht { border-color: var(--rood-diep); }

.gez-rij {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 2px; border-bottom: 1px solid var(--border);
  min-height: 44px;   /* aanraakvlak, WCAG 2.5.5 */
}
.gez-rij:last-child { border-bottom: 0; }
.gez-naam { font-weight: 500; }
.gez-detail { color: var(--muted); font-size: 12px; }
/* De actie ("bewust uit" / "weer in bedrijf") duwt zichzelf naar rechts, zodat de
   knop op elke rij op dezelfde plek staat. `margin-left:auto` en niet `justify-self`:
   .gez-rij is een flexbox, en daar doet `justify-self` niets. */
.gez-rij-actie { margin-left: auto; flex-shrink: 0; }
.gez-leeg { color: var(--muted); padding: 12px 2px; }   /* 5,0:1 met wit */   /* 5,3:1 met wit */

/* ── Console: structurele kleuring ─────────────────────────────────────────
   Hoort bij `kleurLogregel()` in index.html. Achtergrond is #06070a, dus élke
   kleur hieronder is tegen díe waarde doorgerekend -- niet op gevoel gekozen.
   AA voor gewone tekst is 4,5:1; de drie gedempte tinten kwamen eerst uit op
   2,77 / 3,38 / 4,30 en zijn opgetrokken tot ze passen. "Gedempt" mag, want het
   is ruis die je oog moet kunnen overslaan; onleesbaar mag niet, want het blijft
   tekst.

   Waarom dit meer is dan opsmuk: Pterodactyl en Pelican leunen op ANSI-doorgifte
   uit de jar, waardoor de kleur per serversoftware verschilt (Fabric-logs komen
   daar kleurloos binnen). Wij ontleden de regel, dus dit werkt op elke jar. */
.server-page #log .lg-tijd   { color:#727B8F; }            /* 4,74:1 */
.server-page #log .lg-thread { color:#727B8F; }            /* 4,74:1 */
.server-page #log .lg-stil   { color:#787F93; }            /* 5,04:1 */
.server-page #log .lg-info   { color:#8FA1C4; }            /* 7,73:1 */
.server-page #log .lg-warn   { color:#E3B341; font-weight:600; }   /* 10,35:1 */
.server-page #log .lg-fout   { color:#FF8A80; font-weight:600; }   /* 8,82:1 */
/* Stapelregels horen bij de fout erboven, maar zijn er tientallen. Gedempt rood:
   je ziet dat het bij elkaar hoort zonder dat twintig regels even hard roepen. */
.server-page #log .lg-stack  { color:#B4736D; }            /* 5,38:1 */
.server-page #log .lg-chat   { color:#F2CE60; }            /* 13,21:1 */
.server-page #log .lg-in     { color:#5FD39A; }            /* 10,81:1 */
.server-page #log .lg-uit    { color:#7C8698; }            /* 5,49:1 */
.server-page #log .lg-ok     { color:#5FD39A; font-weight:600; }   /* 10,81:1 */

/* Acht naamkleuren. De klasse volgt uit de naam zelf, dus dezelfde speler houdt
   altijd dezelfde kleur -- ook na een herstart en zonder iets op te slaan. Acht is
   genoeg om buren te onderscheiden en weinig genoeg om niet als confetti te lezen. */
.server-page #log .lg-n0 { color:var(--accent2); }   /*  8,10:1 */
.server-page #log .lg-n1 { color:#5FD39A; }   /* 10,81:1 */
.server-page #log .lg-n2 { color:#E3B341; }   /* 10,35:1 */
.server-page #log .lg-n3 { color:#F08FA8; }   /*  8,82:1 */
.server-page #log .lg-n4 { color:#7FD8E8; }   /* 12,36:1 */
.server-page #log .lg-n5 { color:#C79BF0; }   /*  8,99:1 */
.server-page #log .lg-n6 { color:#F0A46B; }   /*  9,81:1 */
.server-page #log .lg-n7 { color:#9BD46B; }   /* 11,53:1 */

/* De bestaande regelklasse `.log-error`/`.log-warn` kleurt de HELE regel. Nu de
   onderdelen hun eigen kleur hebben, zou die buitenste kleur er dwars doorheen
   winnen op alles wat geen eigen span heeft -- en dat is precies de bedoeling: de
   BOODSCHAP van een foutregel blijft rood, terwijl tijd, draad en niveau hun eigen
   tint houden. Daarom hier geen reset; de spans zijn specifieker en winnen vanzelf. */
/* Pluginnamen in een `/plugins`-antwoord ZONDER kleurcodes van de server. Accent en
   geen groen: groen zou "draait" beweren, en dat weten we hier niet. Stuurt de server
   wél §a/§c mee, dan renderen die codes en wint de echte status. */
.server-page #log .lg-plugin { color:#8FA1C4; }            /* 7,73:1 */
