/* VIT-huisstijl over wg-portal v2.3.1 heen.
 *
 * Werkt via web.frontend_filepath: de binary blijft ongewijzigd, wij serveren
 * een kopie van zijn eigen frontend met dit bestand erbij. Na een upgrade van
 * wg-portal moet die kopie opnieuw gemaakt worden -- zie uitrollen.sh.
 *
 * Palet gelijk aan de authentik- en Nextcloud-huisstijl:
 *   oranje #ff8514, hover #e8700b, link #cf6408, donkere tekst #2a1a0a.
 *
 * De grondvorm van Bootstrap is hoekig en luid: hoofdletters met veel
 * letterafstand, harde randen om elk vlak, knoppen zo breed als hun kolom. Dat
 * is hier overal teruggebracht naar één rustige kaartvorm met veel wit, en de
 * enige luide kleur is de oranje actieknop.
 */

:root {
  --vit-oranje: #ff8514;
  --vit-oranje-diep: #e8700b;
  --vit-link: #cf6408;
  --vit-inkt: #2a1a0a;
  --vit-papier: #fdfaf7;
  --vit-lijn: rgba(42, 26, 10, 0.1);
  --vit-zacht: rgba(42, 26, 10, 0.66);

  --bs-primary: var(--vit-oranje);
  --bs-primary-rgb: 255, 133, 20;
  --bs-link-color: var(--vit-link);
  --bs-link-color-rgb: 207, 100, 8;
  --bs-link-hover-color: var(--vit-oranje-diep);
  --bs-border-radius: 10px;
  --bs-border-radius-lg: 16px;
  --bs-body-bg: var(--vit-papier);
}

body {
  font-family: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
  color: var(--vit-inkt);
  background-color: var(--vit-papier);
  -webkit-font-smoothing: antialiased;
}

.container {
  max-width: 1080px;
}

/* ---------- balk ---------- */

/* Bootstrap zet hier bg-primary + navbar-dark neer. Nu --bs-primary oranje is
   zou de hele balk oranje worden, en dat is te veel van het goede op een
   scherm waar mensen moeten wérken. */
.navbar.bg-primary {
  background-color: #ffffff !important;
  border-bottom: 1px solid var(--vit-lijn);
  box-shadow: 0 1px 2px rgba(51, 41, 29, 0.04), 0 10px 30px rgba(51, 41, 29, 0.05);
}
.navbar.navbar-dark .nav-link,
.navbar.navbar-dark .navbar-brand,
.navbar.navbar-dark .navbar-text {
  color: var(--vit-inkt);
}
.navbar.navbar-dark .nav-link {
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}
.navbar.navbar-dark .nav-link:hover,
.navbar.navbar-dark .nav-link:focus-visible {
  color: var(--vit-oranje-diep);
}
.navbar.navbar-dark .nav-link.active {
  color: var(--vit-oranje-diep);
  font-weight: 600;
}
.navbar.navbar-dark .navbar-toggler {
  border-color: var(--vit-lijn);
}
.navbar.navbar-dark .navbar-toggler-icon {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2842,26,10,0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

/* Het logo. De app zet een vaste <img src="/img/header-logo.png"> neer en
   serveert dat pad uit de binary -- onze map hangt onder /app/, dus daar
   kunnen we niet overheen. Met content: url() wijzen we hem naar ons eigen
   woordmerk; het pad is relatief aan dit CSS-bestand (/app/vit.css). */
.navbar-brand img {
  content: url("./img/vit-logo-horizontaal.svg");
  height: 38px;
  width: auto;
}

/* ---------- kop van de pagina ---------- */

.page-header {
  border: 0;
  padding: 0;
  margin: 3.5rem 0 0;
}
.page-header h1 {
  font-size: clamp(2rem, 4vw, 2.75rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  text-transform: none;
  max-width: 26ch;
  /* Zonder dit brak de kop af als "... met VIT / VPN" -- de merknaam hoort
     bij elkaar te blijven. */
  text-wrap: balance;
}
p.lead {
  font-size: 1.075rem;
  line-height: 1.65;
  color: var(--vit-zacht);
  max-width: 62ch;
  margin-top: 1.1rem;
}

/* Tussenkop als klein label: rustiger dan een tweede grote regel, en het
   scheidt de uitleg van de stappen zonder er een balk tussen te leggen. */
.container > h3 {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--vit-link);
  margin-top: 3.5rem !important;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--vit-lijn);
}

/* ---------- kaarten ---------- */

.card {
  border: 1px solid var(--vit-lijn);
  border-radius: 16px;
  background: #ffffff;
  box-shadow: 0 1px 2px rgba(51, 41, 29, 0.04);
  transition: box-shadow 0.18s ease, transform 0.18s ease;
  overflow: hidden;
}
.card:hover {
  box-shadow: 0 2px 4px rgba(51, 41, 29, 0.05), 0 14px 34px rgba(51, 41, 29, 0.09);
  transform: translateY(-2px);
}
.row > [class^="col"] > .card {
  min-height: 0 !important;
  height: calc(100% - 1.5rem);
}

/* De kopstrook van Bootstrap is een grijze balk met een lijn eronder. Hier is
   het het stapnummer: klein, oranje, zonder vlak. */
.card-header {
  background: transparent;
  border: 0;
  padding: 1.5rem 1.5rem 0;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--vit-oranje-diep);
}
.card-body {
  padding: 0.6rem 1.5rem 1.6rem;
}
.card-title {
  font-size: 1.2rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  text-transform: none;
  margin-bottom: 0.5rem;
}
.card-text {
  color: var(--vit-zacht);
  line-height: 1.6;
  font-size: 0.95rem;
}

/* ---------- knoppen ---------- */

.btn {
  border-radius: 10px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  padding: 0.5rem 1.1rem;
}
.btn-sm {
  font-size: 0.9rem;
}
/* Een knop hoeft niet zo breed als zijn kolom; dat is wat de pagina blokkerig
   maakt. Alleen de knop op het aanmeldscherm blijft over de volle breedte --
   daar is hij het enige wat je moet doen. */
.card-body .btn {
  align-self: flex-start;
}
.btn-primary {
  --bs-btn-bg: var(--vit-oranje);
  --bs-btn-border-color: var(--vit-oranje);
  --bs-btn-hover-bg: var(--vit-oranje-diep);
  --bs-btn-hover-border-color: var(--vit-oranje-diep);
  --bs-btn-active-bg: var(--vit-oranje-diep);
  --bs-btn-active-border-color: var(--vit-oranje-diep);
  --bs-btn-color: #ffffff;
  --bs-btn-hover-color: #ffffff;
  --bs-btn-active-color: #ffffff;
  box-shadow: 0 1px 2px rgba(232, 112, 11, 0.25);
}
.btn-outline-primary {
  --bs-btn-color: var(--vit-link);
  --bs-btn-border-color: var(--vit-oranje);
  --bs-btn-hover-bg: var(--vit-oranje);
  --bs-btn-hover-border-color: var(--vit-oranje);
  --bs-btn-hover-color: #ffffff;
}
.btn:focus-visible {
  outline: 2px solid var(--vit-oranje-diep);
  outline-offset: 2px;
  box-shadow: none;
}

/* ---------- aanmeldscherm ---------- */

/* Eén kaart, midden op de pagina, met één knop. Alles wat daar niet aan
   bijdraagt is weg. */
#app .card:has(.btn-outline-primary),
#app .card:has(form) {
  max-width: 26rem;
  margin-left: auto;
  margin-right: auto;
}
#app .card:has(.btn-outline-primary) .card-header,
#app .card:has(form) .card-header {
  font-size: 1.15rem;
  font-weight: 650;
  text-transform: none;
  letter-spacing: -0.01em;
  color: var(--vit-inkt);
  padding: 1.6rem 1.6rem 0;
}
#app .card:has(.btn-outline-primary) .card-body .btn,
#app .card:has(form) .card-body .btn {
  align-self: stretch;
  width: 100%;
  padding: 0.7rem 1rem;
}

/* ---------- formulieren en tabellen ---------- */

.form-control, .form-select, .input-group-text {
  border-radius: 10px;
  border-color: var(--vit-lijn);
}
.form-control:focus, .form-select:focus {
  border-color: var(--vit-oranje);
  box-shadow: 0 0 0 0.2rem rgba(255, 133, 20, 0.2);
}
.table > thead {
  border-bottom: 2px solid rgba(255, 133, 20, 0.35);
}
.table > thead th {
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
}
.modal-content, .list-group {
  border-radius: 16px;
  border-color: var(--vit-lijn);
}

footer {
  border-top: 1px solid var(--vit-lijn);
  color: rgba(42, 26, 10, 0.55);
  font-size: 0.9rem;
  padding-bottom: 1.5rem;
}

/* De knop onder stap 3 linkt hard naar wgportal.org -- dat stuurt de klant naar
   de verkeerde partij. Weg ermee. De knop onder stap 2 wees naar
   wireguard.com; vit-toegang.js maakt daar een knop naar het eigen profiel van,
   en die krijgt dan de klasse vit-eigen-knop. */
a[href="https://wgportal.org/"],
a[href="https://www.wireguard.com/"]:not(.vit-eigen-knop) {
  display: none;
}

/* Gereedschap voor beheerders hoort niet in het menu van een klant. */
html:not(.vit-beheerder) .navbar-nav a[href="#/key-generator"],
html:not(.vit-beheerder) .navbar-nav a[href="#/ip-calculator"] {
  display: none;
}

/* Taalkiezer weg. Het portaal is Nederlands doordat we de Engelse teksten
   vervangen hebben; wie hier een andere taal kiest krijgt het originele
   Engels/Duits/Frans van wg-portal terug, en de vlag ernaast staat op de
   Verenigde Staten. Voor een klantportaal is dat alleen verwarrend. */
footer [aria-label="Taal wisselen"] {
  display: none;
}

/* ---------- afgeschermd voor wie niet is aangemeld ---------- */

/* vit-toegang.js zet deze klasse en stuurt naar het aanmeldscherm. De menu-
   items die naar openbare pagina's leiden horen er dan ook niet te staan. */
.vit-anoniem .navbar-nav {
  display: none;
}

/* ---------- donkere modus ---------- */

[data-bs-theme="dark"] {
  --vit-papier: #17120e;
  --vit-lijn: rgba(246, 239, 232, 0.12);
  --vit-zacht: rgba(242, 236, 230, 0.7);
}
[data-bs-theme="dark"] body {
  color: #f2ece6;
  background-color: var(--vit-papier);
}
[data-bs-theme="dark"] .navbar.bg-primary {
  background-color: #1c1611 !important;
}
[data-bs-theme="dark"] .navbar.navbar-dark .nav-link,
[data-bs-theme="dark"] .navbar.navbar-dark .navbar-brand {
  color: #f6efe8;
}
[data-bs-theme="dark"] .navbar-brand img {
  background: #ffffff;
  border-radius: 8px;
  padding: 4px 8px;
}
[data-bs-theme="dark"] .card {
  background: #201a15;
  border-color: var(--vit-lijn);
}
[data-bs-theme="dark"] .container > h3,
[data-bs-theme="dark"] .card-header {
  color: var(--vit-oranje);
}

@media (prefers-reduced-motion: reduce) {
  .card, .card:hover {
    transition: none;
    transform: none;
  }
}

/* ---------- startpagina als gebruikersscherm ---------- */

/* vit-toegang.js merkt de blokken; de volgorde gebeurt hier. Eerst wat je moet
   doen, dan waar je het doet, dan de uitleg, en beheer als laatste.

   Met flex-order in plaats van met verplaatsen: de knopen zijn van Vue en
   verslepen maakt de app kapot. */
#app .container {
  display: flex;
  flex-direction: column;
}
#app .container > * { order: 6; }
#app .container > .vit-stappen-kop { order: 1; }
#app .container > .vit-stappen { order: 2; }
#app .container > .vit-profielen { order: 3; }
#app .container > .page-header { order: 4; }
#app .container > p.lead { order: 5; }
#app .container > .vit-beheerblok { order: 7; }

.vit-stappen-kop {
  margin-top: 2.5rem !important;
}

/* Het blok met de knop naar het eigen profiel is waar de gebruiker heen moet.
   Dat mag opvallen: zacht oranje vlak in plaats van een kaart als alle andere. */
.card.vit-profielen {
  padding: 1.75rem !important;
  margin-top: 1.5rem;
  border-color: rgba(255, 133, 20, 0.35);
  background: linear-gradient(180deg, rgba(255, 133, 20, 0.07), rgba(255, 133, 20, 0.02));
}
.card.vit-profielen :is(h1, h2, h3, h4, h5) {
  font-size: 1.35rem;
  font-weight: 650;
  text-transform: none;
  letter-spacing: -0.01em;
  margin-bottom: 0.4rem;
}
.card.vit-profielen p {
  color: var(--vit-zacht);
  margin-bottom: 0.4rem;
}
.card.vit-profielen hr {
  display: none;
}
.card.vit-profielen .btn {
  margin-top: 0.8rem;
}

/* Beheer is voor ons, niet voor de klant. Het staat onderaan en het mag er ook
   uitzien als bijzaak. */
.card.vit-beheerblok {
  padding: 1.5rem !important;
  margin-top: 2.5rem;
  background: transparent;
  border-style: dashed;
  box-shadow: none;
}
.card.vit-beheerblok:hover {
  transform: none;
  box-shadow: none;
}
.card.vit-beheerblok :is(h1, h2, h3, h4, h5) {
  font-size: 1rem;
  font-weight: 650;
  text-transform: none;
  letter-spacing: 0;
}
.card.vit-beheerblok p,
.card.vit-beheerblok .btn {
  font-size: 0.9rem;
}
.card.vit-beheerblok .btn {
  --bs-btn-bg: transparent;
  --bs-btn-color: var(--vit-link);
  --bs-btn-border-color: var(--vit-lijn);
  --bs-btn-hover-bg: rgba(255, 133, 20, 0.1);
  --bs-btn-hover-color: var(--vit-oranje-diep);
  --bs-btn-hover-border-color: var(--vit-oranje);
  box-shadow: none;
}

/* De kop van de pagina is na de stappen een toelichting, geen aankondiging. */
.vit-stappen ~ .page-header h1,
.container > .page-header h1 {
  font-size: clamp(1.5rem, 2.4vw, 1.9rem);
}

/* ---------- profielscherm ---------- */

/* Het thema zet elke kop in kapitalen met veel letterafstand. Op een
   overzichtsscherm leest dat als geschreeuw. */
#app h1, #app h2, #app h4, #app h5 {
  text-transform: none;
  letter-spacing: -0.01em;
}
#app h2 {
  font-size: 1.65rem;
  font-weight: 700;
}
#app h4 {
  font-size: 1.05rem;
  font-weight: 650;
}

/* vit-toegang.js hangt een tekst achter de plusknop; zonder die tekst is het
   een icoon waarvan je moet raden wat het doet. */
.vit-knoptekst {
  margin-left: 0.45rem;
}
button[title="Profiel toevoegen"] {
  white-space: nowrap;
}

/* ---------- profieltabel leesbaar maken ---------- */

/* Er stond geen woord uitleg boven die tabel: een regel met een sleutelnaam,
   RX/TX en "Serverinterface" zegt een gebruiker niets. */
#app .row:has(button[title="Profiel toevoegen"]) .col-12.col-lg-5::after {
  content: "Eén profiel is één apparaat. Klik op het oogje om de QR-code te tonen, en scan die met de WireGuard-app.";
  display: block;
  margin-top: 0.5rem;
  max-width: 46ch;
  color: var(--vit-zacht);
  font-size: 0.95rem;
  line-height: 1.55;
}

/* Kolommen die alleen een beheerder iets zeggen: het vinkje om te selecteren,
   de lege kolom ervoor, het verkeersvolume en de naam van de serverinterface. */
html:not(.vit-beheerder) #app table :is(th, td):nth-child(1),
html:not(.vit-beheerder) #app table :is(th, td):nth-child(2),
html:not(.vit-beheerder) #app table :is(th, td):nth-child(6),
html:not(.vit-beheerder) #app table :is(th, td):nth-child(7) {
  display: none;
}

/* De twee icoontjes achteraan zijn een oogje en een tandwiel. Zonder tekst is
   het gokken welke van de twee je QR-code laat zien. */
#app table a[title="Profiel tonen"]::after {
  content: "QR-code";
  margin-left: 0.35rem;
}
#app table a[title="Profiel bewerken"]::after {
  content: "Naam wijzigen";
  margin-left: 0.35rem;
}
#app table a[title="Profiel tonen"],
#app table a[title="Profiel bewerken"] {
  white-space: nowrap;
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  margin-left: 0.9rem;
}

/* Het statusicoontje is een doorgesneden schakel; dat leest niemand als
   "niet verbonden". */
#app table .badge:has(.fa-link-slash)::after {
  content: "Niet verbonden";
  margin-left: 0.35rem;
}
#app table .badge:has(.fa-link)::after {
  content: "Verbonden";
  margin-left: 0.35rem;
}
#app table .badge:has(.fa-link-slash),
#app table .badge:has(.fa-link) {
  font-weight: 500;
  color: var(--vit-zacht);
}

/* ---------- het profielvenster ---------- */

/* Wat de gebruiker hier komt halen is de QR-code. Die stond klein rechts naast
   een lijst met sleutel, IP-reeksen en een notitieregel van de machine. Voor
   een beheerder is die lijst nuttig, voor een klant is het ruis. */
.modal-title {
  text-transform: none;
  letter-spacing: -0.01em;
  font-size: 1.15rem;
  font-weight: 650;
}
.modal img.config-qr-img {
  display: block;
  width: 100%;
  max-width: 260px;
  margin: 0 auto;
  border-radius: 12px;
}

html:not(.vit-beheerder) .modal .accordion-body .row > .col-md-8:has(ul) {
  display: none;
}
html:not(.vit-beheerder) .modal .accordion-body .row > .col-md-4:has(img.config-qr-img) {
  flex: 0 0 100%;
  max-width: 100%;
  width: 100%;
}
html:not(.vit-beheerder) .modal .accordion-body .row > .col-md-4:has(img.config-qr-img)::after {
  content: "Scan deze code met de WireGuard-app op je telefoon. Op een laptop kun je in plaats daarvan het configuratiebestand downloaden.";
  display: block;
  margin: 1rem auto 0;
  max-width: 42ch;
  text-align: center;
  color: var(--vit-zacht);
  font-size: 0.95rem;
  line-height: 1.55;
}

/* De accordeon-kopjes (Profielgegevens, Huidige status, Configuratie) zijn
   beheerdersgereedschap; een klant heeft aan één scherm genoeg. */
html:not(.vit-beheerder) .modal .accordion-button,
html:not(.vit-beheerder) .modal .accordion-item:nth-child(2),
html:not(.vit-beheerder) .modal .accordion-item:nth-child(3) {
  display: none;
}
html:not(.vit-beheerder) .modal .accordion-collapse {
  display: block !important;
  height: auto !important;
  visibility: visible !important;
}
html:not(.vit-beheerder) .modal .accordion-item {
  border: 0;
}

/* De keuze tussen "Raw" en "WG-Quick" is een keuze over bestandsformaat. Wie
   een QR-code scant merkt er niets van; alleen een beheerder heeft hem nodig. */
html:not(.vit-beheerder) .modal .modal-body > .row:has(.btn-group),
html:not(.vit-beheerder) .modal [class*="config-style"] {
  display: none;
}
