/*
Theme Name: vStack Blueprint
Theme URI: https://vstack.it/
Author: vStack.it
Description: Thema voor vstack.it. 1.6 in aanbouw: de site wordt de rackkast K-3, met een manpage als artikelvorm. Eén donker palet, groen en amber als accenten. Lettertypen in het thema zelf. Klassiek PHP-thema, geen blokthema.
Version: 1.6.81
Requires at least: 6.4
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: vstack-blueprint
*/

/* ============================================================
   0. Lettertypen
   Alle vier in de map fonts/ van het thema, als variabele woff2,
   beperkt tot de Latijnse tekens. Licenties: fonts/OFL-*.txt.
   ============================================================ */

/* Playfair Display is vervallen in 1.6.52. Hij droeg het woordmerk van de
   krant, en daarna alleen nog de koppen in een bericht en het blokcitaat. De
   koppen worden binnen de manpage allang door monospace overschreven, en van
   de 52 berichten heeft er geen enkele een citaat. Twee bestanden van samen
   ruim 100 kB, waarvan er één op elke pagina werd voorgeladen. */
@font-face {
  font-family: "Space Grotesk";
  src: url("fonts/spacegrotesk.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/jetbrainsmono.woff2") format("woff2");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

/* ============================================================
   1. Palet
   1.6: de site is de rackkast. Eén donker palet, geen Paper.
   Groen en amber zijn de accenten, blauw alleen voor PowerCLI.
   ============================================================ */

:root {
  --bg: #101215;            /* de vloer van het gangpad */
  --laid: rgba(var(--sheen-rgb),.016);
  --laid-img: repeating-linear-gradient(to bottom, var(--laid) 0, var(--laid) 1px, transparent 1px, transparent 4px); /* heel flauwe scanlijn, opvolger van de vezellijnen */
  --ink: #e7eaee;            /* zware lijnen en knoppen */
  --line: rgba(var(--sheen-rgb),.22);
  --line-2: rgba(var(--sheen-rgb),.10);
  --tx: #c3cad2;
  --hd: #eef3f7;
  --dim: #8d959e;
  --dim-2: #6b747d;
  --acc: #7fe3bd;            /* schermgroen, contrast ruim 9:1 op deze achtergrond */
  --code-bg: rgba(255,255,255,.05);
  --img-mat: #1b1f24;            /* passe-partout rond schermafbeeldingen */
  --img-edge: rgba(var(--sheen-rgb),.18);
  --sel: rgba(127,227,189,.22);
  --btn-tx: #101215;

  /* statuskleuren, gelijk aan de lampjes in het rack */
  --ok: #57d08a;
  --ok-ink: #57d08a;   /* als tekst; in de verlichte zaal donkerder dan het lampje */
  --warn: #f0b34a;
  --warn-ink: #f0b34a;
  --uid: #4aa3ff;
  --uid-ink: #4aa3ff;

  /* staal, voor rack en chassis in de volgende stap */

  /* 1280 en niet 1120. Die 1120 was een leesbreedte uit de krant, en dat is
     voor een kast een willekeurig getal: op een breed scherm stond de kast in
     een veld zwart en moest je inzoomen om de blades te lezen. Het is een
     maximum, dus op smallere schermen verandert er niets. 1400 is geprobeerd
     en teruggezet naar 1280: de tekstkolom van een artikel blijft 700 px, dus
     hoe breder de bezel, hoe meer donkere ruimte er naast de tekst staat.
     Boven 1400 wordt de kast bovendien geen kast meer maar een rij van heel
     lange strepen. */
  --wrap: 1280px;
  --gutter: 28px;
  /* --font-serif is vervallen in 1.6: Newsreader was de lopende tekst van
     gewone pagina's, en die staan sinds alpha150 als manpage in de kast. */
  --font-ui: "Space Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* codeblokken: shell donker, uitvoer apart, PowerCLI blauw */
  --term-bg: #191d22;
  --term-bar: #1f242a;
  --term-tx: #d7e6df;
  --term-dim: #6f7d78;
  --term-line: rgba(255,255,255,.07);
  --out-bg: #20262c;
  --out-mark: #ffd166;
  --ps-bg: #071426;
  --ps-tx: #dce8fb;
  --ps-acc: #ffe479;
}

/* De paletknop staat nog in de voetregel; zolang die er is levert
   graphite hetzelfde palet op. De knop zelf vervalt in een latere stap. */


/* ============================================================
   1b. De grijsladder en de kleuren van het rack
   Alle kleuren van het rack, het chassis, de blades, de deur, de
   voedingen en de sensorstrip staan hier, en nergens anders meer.
   Tot 1.6.49 stonden ze verspreid over 1.260 regels als 96 losse
   hexwaarden; 80 daarvan waren grijstinten die onderling hoogstens
   zes punten per kanaal verschilden. Die zijn samengetrokken tot
   dertig treden, donker naar licht genummerd. De ladder begint bij --k-02;
   --k-01 was het zwart van het deurmasker en is teruggezet naar een vaste
   waarde, want in een masker is zwart geen kleur maar volledige dekking.

   De doorschijnende waarden werken anders: daar staat alleen het
   kleurkanaal in een variabele en blijft de dekking in de regel
   zelf staan. Twaalf verschillende witte dekkingen zijn immers
   twaalf keer dezelfde lichtval, geen twaalf kleuren.

   Dit hoofdstuk is de voorbereiding op een tweede set waarden voor
   een verlichte zaal. Die bestaat nog niet; hier verandert niets
   aan hoe de site eruitziet.
   ============================================================ */

:root {
  --k-02: #12151a;  /* #11151a, #14171b, #171a1f */
  --k-03: #1b1f24;
  /* De lichtval per front. In het donker subtiel, want daar doet de gloed van
     de lampjes het werk; met het licht aan moet het plaatwerk zijn dikte uit
     de schaduw halen. --drop staat in het donker op nul, zodat er geen
     slagschaduw onder een front valt die er nu ook niet is. */

  --glans-1: .085;
  --glans-2: .03;
  --glans-rand: .16;
  --schaduw-1: .14;
  --drop: 0;
  /* De schaduw die de kast zelf op de vloer werpt. In het donker nul: daar is
     de vloer al zwart en zou een schaduw alleen maar vuil geven. */
  --kast-drop: 0;
  --kast-boven: #1b1f24;
  --kast-onder: #1b1f24;
  --rail-gaten: linear-gradient(rgba(0,0,0,0) 0 4%, var(--k-02) 4% 25%, rgba(0,0,0,0) 25% 39%, var(--k-02) 39% 60%, rgba(0,0,0,0) 60% 75%, var(--k-02) 75% 96%, rgba(0,0,0,0) 96%);
  --rail-buiten: #1b1f24;
  --rail-binnen: #1b1f24;
  --kant: 0;
  /* De onderrand van de menubalk. In het donker een gewone lijn; met het licht
     aan doorzichtig, want die lijn houdt op bij de rand van de wikkel en dat
     zie je zodra er donkere kast onder schuift. */
  --nav-line: #2b3037;

  /* De scanlijnen op het glas van het scherm. Wit op ruim een procent: het
     moet een scherm suggereren, geen filter zijn. Met het licht aan moet die
     lijn donker zijn, anders is er niets te zien. */
  --glaslijn: rgba(var(--sheen-rgb),.012);

  /* De greep van de deur en de losse greep als de deur open is. Eigen tokens,
     want met het licht aan hoort de greep donkerder te zijn dan de deur waar
     hij op zit, en de treden die hij gebruikte zijn daar lichtvlakken. */
  --k-grip-1: #8a939d;
  --k-grip-2: #6e767f;
  --k-grip-3: #4d535b;
  --k-grip-4: #3a4048;

  --k-rail: #1b1f24;
  /* De ventilatorbladen en hun as. Eigen tokens, want een blad is geen
     lichtrand: met het licht aan moet het blad donkerder zijn dan de schijf,
     en de lichtrand juist lichter. */
  --k-fan-1: #7b848e;
  --k-fan-2: #4d535b;
  --k-fan-as: #565d66;
  --k-fan-bg: #22262b;    /* de opening waar de ventilator in draait */
  --k-fan-kern: #2b3037;
  --oabar-top: #3a4048;  /* gelijk aan de waarde van k-08, zodat de OA-balk in het donker een vlak vlak blijft */
  --k-u: #646b75;      /* de U-nummers op de rails; --k-14 is ook een rand */
  --k-04: #22262b;  /* #20242a, #23272c, #232830, #26282c */
  --k-05: #2a2620;
  --k-06: #2b3037;  /* #2a2f35, #2b3036, #2c3138, #2c323a, #2d3239, #2d323a, #2f343a, #2f343b */
  --k-07: #2f353c;  /* #31363c, #343a42 */
  --k-08: #3a4048;  /* #363b42, #363c43, #373d44, #3a3d42, #3a4046, #3a4148 */
  --k-09: #3c424a;  /* #3b424a, #3d434a, #3e444c, #3f454c, #3f464f, #40464e */
  --k-10: #454b54;  /* #434a52, #454b53, #454c55, #464d55 */
  --k-11: #4d535b;  /* #4a5159, #4a515a, #4d545c */
  --k-12: #545b64;  /* #55585e, #525a64 */
  --k-13: #565d66;  /* #575f69, #5b636c */
  --k-14: #646b75;  /* #5f6772 */
  --k-15: #6b747d;  /* #666e78 */
  --k-16: #6e767f;
  --k-17: #767d86;  /* #78818b */
  --k-18: #7b848e;
  --k-19: #8d8f95;
  --k-20: #8a939d;  /* #8b949d, #8d959e */
  --k-21: #9a958a;
  --k-22: #9aa4ae;
  --k-23: #a3acb6;
  --k-24: #cfcbbe;
  --k-25: #c9ced4;  /* #c7ced5 */
  --k-26: #d8d4c9;
  --k-27: #cfd6dd;
  --k-28: #e7e3d6;
  --k-29: #dfe5eb;  /* #dfe6ec */
  /* Vijf treden dragen zowel een vlak als een tekst. In het donker valt dat
     samen, want die teksten staan op lichte stickers en de vlakken op donker
     staal. In een verlichte zaal lopen ze uiteen: de sticker blijft licht met
     donkere letters terwijl het staal juist licht wordt. Daarom een eigen
     tekstversie, voorlopig met dezelfde waarde.
       -04-ink  de tekst op de filtersticker
       -08-ink  de tekst op de vendorsticker
       -17-ink  het opschrift op de blindplaat
       -18-ink  het nummer op de assetsticker en op de hoofdautomaat
       -20-ink  het zijlabel en het serienummer in de VM-weergave */
  --k-04-ink: #22262b;
  --k-08-ink: #3a4048;
  --k-17-ink: #767d86;
  --k-18-ink: #7b848e;
  --k-20-ink: #8a939d;

  /* Zeven treden waren zowel het vlak als de rand eromheen. In het donker is
     een rand lichter dan het vlak, want dat is de lichtrand op staal; met het
     licht aan is een rand juist donkerder. Daarom een eigen lijnversie, in het
     donker met dezelfde waarde. */
  --k-06-ln: #2b3037;
  --k-08-ln: #3a4048;
  --k-09-ln: #3c424a;
  --k-10-ln: #454b54;
  --k-11-ln: #4d535b;
  --k-12-ln: #545b64;
  --k-13-ln: #565d66;


  --k-30: #eef1f4;

  --k-airnote-bg: #d9cfae;
  --k-airnote-edge: #b7ab84;
  --k-airnote-ink: #b9b3a2;
  --k-airnote-line: #a8a293;
  --k-cold: #6fb0ff;
  --k-earth-1: #d7c93a;
  --k-earth-2: #d7b13a;
  --k-fiber: #7fd3b3;
  --k-fiber-2: #4f9e79;
  --k-fiber-blue: #3f78c0;
  --k-leak-1: #2f6f8f;
  --k-leak-2: #24505f;
  --k-leak-dry: #9fc4e8;
  --k-mcb: #c0483f;
  --k-port-uplink: #101a20;
  --k-port-uplink-edge: #4f6b7a;
  --k-uplink-label: #7fb0ff;

  --k-door-rgb: 38,43,50;
  --shadow-rgb: 0,0,0;
  --acc-rgb: 127,227,189;
  --ps-acc-rgb: 127,176,255;
  --sheen-rgb: 255,255,255;
  --ok-rgb: 87,208,138;
  --uid-rgb: 74,163,255;
  --warn-rgb: 240,179,74;
}

/* ============================================================
   1c. De verlichte zaal
   Dezelfde kast met het licht aan. De ladder uit 1b keert om: wat in
   het donker licht is, is hier donker. Dat klopt voor randen, voor
   tekst en voor de lichtrand op staal, en het is de reden dat de
   ladder op volgorde van helderheid genummerd is.

   Met de hand rechtgezet zijn de holtes, want een poortopening en de
   bodem van de kast blijven donker als het licht aangaat, en de
   voorwerpen die van zichzelf licht zijn: de vendorsticker, de
   filtersticker en het hendeltje van de hoofdautomaat. Hun opschrift
   blijft daarom ook donker.

   Wat hier bewust niet in staat: de codeblokken, het PSOD, het
   bulletinboard en het ANSI-scherm. Een terminal is zwart, ook in een
   verlichte zaal.

   Standaard volgt de site de systeeminstelling. Zet iemand de
   schakelaar om, dan komt er een data-theme op html te staan en die
   wint van de systeeminstelling. */

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
  /* de zaal en het scherm: een lichte vloer, en lampjes die op grijs nog leesbaar zijn */
  --bg: #e9ebed;
  --ink: #0a0d10;
  --tx: #14181c;
  --hd: #07090b;
  --dim: #23282d;
  --dim-2: #4a5055;
  --acc: #086042;
  --acc-rgb: 8,96,66;
  --code-bg: rgba(var(--shadow-rgb),.06);
  --img-mat: #c2c7cb;
  --sel: rgba(var(--acc-rgb),.18);
  --btn-tx: #eef1f3;
  --glass: #fbfcfc;
  --glassline: #aeb4ba;
  --grule: #c2c7cb;
  --ok: #1f8f57;
  --ok-ink: #07502c;
  --ok-rgb: 31,143,87;
  --warn: #8a5a00;
  --warn-ink: #5c3b00;
  --warn-rgb: 138,90,0;
  --uid: #0a5c8f;
  --uid-ink: #084566;
  --uid-rgb: 10,92,143;
  --k-door-rgb: 150,157,163;

  /* de ladder, omgekeerd; met de hand gezet waar het een holte of een voorwerp is */
  --k-02: #31373d;
  --k-03: #5f666d;
  --k-rail: #5f666d;
  --glaslijn: rgba(var(--shadow-rgb),.045);
  --k-grip-1: #737b82;
  --k-grip-2: #5a6167;
  --k-grip-3: #3f4549;
  --k-grip-4: #2c3135;
  --k-fan-1: #c4c9ce;
  --k-fan-2: #949ba2;
  --k-fan-as: #dee2e5;
  --k-fan-bg: #5a6167;
  --k-fan-kern: #4b5157;
  --oabar-top: #cbd0d4;
  --laid: rgba(var(--shadow-rgb),.05);
  --k-u: #c6cbcf;
  --glans-1: .5;
  --glans-2: .18;
  --glans-rand: .95;
  --schaduw-1: .22;
  --drop: .34;
  --kast-drop: .38;
  --kast-boven: #545b62;
  --kast-onder: #6a7178;
  --rail-buiten: #4a5157;
  --rail-binnen: #737a81;
  --kant: .45;
  --nav-line: transparent;
  --k-04: #979ea5;
  --k-05: #4a4335;
  --k-06: #7b8288;
  --k-07: #cbd0d4;
  --k-08: #9ca2a9;
  --k-09: #b9bfc4;
  --k-10: #cbd0d4;
  --k-11: #d4d9dc;
  --k-12: #8d949b;
  --k-13: #dee2e5;
  --k-14: #7a7e82;
  --k-15: #73777b;
  --k-16: #6c7074;
  --k-17: #666a6d;
  --k-18: #5f6366;
  --k-19: #585c5f;
  --k-20: #515558;
  --k-21: #4a4e51;
  --k-22: #43474a;
  --k-23: #3c4043;
  --k-24: #cfcbbe;
  --k-25: #2e3235;
  --k-26: #d8d4c9;
  --k-27: #212427;
  --k-28: #e7e3d6;
  --k-29: #3a4046;
  --k-30: #0c0f12;

  /* de randen: in een verlichte zaal donkerder dan het vlak eromheen */
  --k-06-ln: #474d53;
  --k-08-ln: #3f4449;
  --k-09-ln: #575e65;
  --k-10-ln: #6b7279;
  --k-11-ln: #575e65;
  --k-12-ln: #6b7279;
  --k-13-ln: #474d53;

  /* tekst op stickers blijft donker, want de sticker blijft licht */
  --k-04-ink: #22262b;
  --k-08-ink: #3a4048;
  --k-17-ink: #767d86;
  --k-18-ink: #7b848e;
  --k-20-ink: #4f5357;

  /* de benoemde kleuren */
  --k-cold: #0a5c8f;
  --k-uplink-label: #0a5c8f;
  --k-fiber: #14795a;
  --k-fiber-2: #2f8f68;
  --k-fiber-blue: #2a5f9e;
  --k-leak-dry: #17557d;
  --k-port-uplink: #6f7a82;
  --k-port-uplink-edge: #526e7c;
  }
}

:root[data-theme="light"] {
  /* de zaal en het scherm: een lichte vloer, en lampjes die op grijs nog leesbaar zijn */
  --bg: #e9ebed;
  --ink: #0a0d10;
  --tx: #14181c;
  --hd: #07090b;
  --dim: #23282d;
  --dim-2: #4a5055;
  --acc: #086042;
  --acc-rgb: 8,96,66;
  --code-bg: rgba(var(--shadow-rgb),.06);
  --img-mat: #c2c7cb;
  --sel: rgba(var(--acc-rgb),.18);
  --btn-tx: #eef1f3;
  --glass: #fbfcfc;
  --glassline: #aeb4ba;
  --grule: #c2c7cb;
  --ok: #1f8f57;
  --ok-ink: #07502c;
  --ok-rgb: 31,143,87;
  --warn: #8a5a00;
  --warn-ink: #5c3b00;
  --warn-rgb: 138,90,0;
  --uid: #0a5c8f;
  --uid-ink: #084566;
  --uid-rgb: 10,92,143;
  --k-door-rgb: 150,157,163;

  /* de ladder, omgekeerd; met de hand gezet waar het een holte of een voorwerp is */
  --k-02: #31373d;
  --k-03: #5f666d;
  --k-rail: #5f666d;
  --glaslijn: rgba(var(--shadow-rgb),.045);
  --k-grip-1: #737b82;
  --k-grip-2: #5a6167;
  --k-grip-3: #3f4549;
  --k-grip-4: #2c3135;
  --k-fan-1: #c4c9ce;
  --k-fan-2: #949ba2;
  --k-fan-as: #dee2e5;
  --k-fan-bg: #5a6167;
  --k-fan-kern: #4b5157;
  --oabar-top: #cbd0d4;
  --laid: rgba(var(--shadow-rgb),.05);
  --k-u: #c6cbcf;
  --glans-1: .5;
  --glans-2: .18;
  --glans-rand: .95;
  --schaduw-1: .22;
  --drop: .34;
  --kast-drop: .38;
  --kast-boven: #545b62;
  --kast-onder: #6a7178;
  --rail-buiten: #4a5157;
  --rail-binnen: #737a81;
  --kant: .45;
  --nav-line: transparent;
  --k-04: #979ea5;
  --k-05: #4a4335;
  --k-06: #7b8288;
  --k-07: #cbd0d4;
  --k-08: #9ca2a9;
  --k-09: #b9bfc4;
  --k-10: #cbd0d4;
  --k-11: #d4d9dc;
  --k-12: #8d949b;
  --k-13: #dee2e5;
  --k-14: #7a7e82;
  --k-15: #73777b;
  --k-16: #6c7074;
  --k-17: #666a6d;
  --k-18: #5f6366;
  --k-19: #585c5f;
  --k-20: #515558;
  --k-21: #4a4e51;
  --k-22: #43474a;
  --k-23: #3c4043;
  --k-24: #cfcbbe;
  --k-25: #2e3235;
  --k-26: #d8d4c9;
  --k-27: #212427;
  --k-28: #e7e3d6;
  --k-29: #3a4046;
  --k-30: #0c0f12;

  /* de randen: in een verlichte zaal donkerder dan het vlak eromheen */
  --k-06-ln: #474d53;
  --k-08-ln: #3f4449;
  --k-09-ln: #575e65;
  --k-10-ln: #6b7279;
  --k-11-ln: #575e65;
  --k-12-ln: #6b7279;
  --k-13-ln: #474d53;

  /* tekst op stickers blijft donker, want de sticker blijft licht */
  --k-04-ink: #22262b;
  --k-08-ink: #3a4048;
  --k-17-ink: #767d86;
  --k-18-ink: #7b848e;
  --k-20-ink: #4f5357;

  /* de benoemde kleuren */
  --k-cold: #0a5c8f;
  --k-uplink-label: #0a5c8f;
  --k-fiber: #14795a;
  --k-fiber-2: #2f8f68;
  --k-fiber-blue: #2a5f9e;
  --k-leak-dry: #17557d;
  --k-port-uplink: #6f7a82;
  --k-port-uplink-edge: #526e7c;
}

/* ============================================================
   2. Basis
   ============================================================ */

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

/* De standaardletter van de pagina is monospace, want in 1.6 staat alles
   daarin: rack, artikel, boot log, colofon, losse pagina's en de 404. De
   schreefletter voor gewone pagina's is in alpha151 vervallen; hij stond nog
   op twee pagina's en kostte daar 139 kB. */
body {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 18px;
  line-height: 1.6;
  color: var(--tx);
  background-color: var(--bg);
  /* vergé-papier: heel fijne horizontale lijnen, om de vier pixels. Het
     patroon staat in --laid-img, want de menubalk heeft het ook nodig: die is
     dekkend om tijdens het scrollen leesbaar te blijven, en wiste de strepen
     daarmee over de volle breedte. */
  background-image: var(--laid-img);
  /* Aan het venster gehangen en niet aan de pagina. De menubalk blijft staan
     tijdens het scrollen en draagt hetzelfde streepbeeld; hangt dat aan de
     pagina, dan schuift de vloer eronder door en lopen de twee patronen uit
     fase. Zichtbaar als een naad aan weerszijden van de balk. Zo staan de
     strepen stil en sluiten ze altijd aan. */
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--sel); }

a { color: var(--acc); text-decoration: none; }
a:hover, a:focus-visible { text-decoration: underline; text-underline-offset: 3px; }

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

img, iframe, video { max-width: 100%; height: auto; }

.screen-reader-text {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(1px,1px,1px,1px); white-space: nowrap;
}
.skip-link:focus {
  position: fixed; top: 8px; left: 8px; width: auto; height: auto; clip: auto;
  background: var(--bg); color: var(--hd); border: 1px solid var(--line);
  padding: 8px 12px; z-index: 999;
}

/* kleine, wijd gespatieerde sans: kickers, meta, navigatie */
.section-row, .sheet-foot,
.search-submit {
  font-family: var(--font-ui);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
}

/* ============================================================
   3. Kop, raamwerk en voet
   Wat hier staat is in 1.6 herschreven en heet alleen nog zo in de
   geschiedenis: de masthead, de tagline, de dateline, de navigatierij,
   het vel eromheen en de voetregel. Geen krantrestanten.
   ============================================================ */

.sheet {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* De masthead en de dateline zijn vervallen in 1.6.0. Woordmerk, tagline en
   datum stonden samen ongeveer 140 px boven elke pagina en scrolden weg
   terwijl de menubalk bleef staan; bij het doorklikken begon je daardoor
   steeds opnieuw boven een blok dat je al kende. De naam staat nu als eerste
   item in het menu. Zie header.php. */

/* navigatierij: naam links, menu en knop rechts, daaronder een zware lijn */
/* drie delen: naam links, menu gecentreerd, knop rechts */
/* Nog één kolom: het kleine woordmerk en de zoekknop zijn eruit, dus het
   menu hoeft niet meer tussen twee lege cellen gecentreerd te worden. */
.nav-row {
  display: block; text-align: center;
  padding: 12px 0 14px;
  border-bottom: 1px solid var(--nav-line);
  background: var(--bg) var(--laid-img);
  background-attachment: fixed;
  /* Geen schaduw onder deze balk. Geprobeerd in 1.6.71 om hem als zwevende
     laag te laten lezen, en dat werkte averechts: de schaduw tekent juist de
     onderrand over de volle breedte van de wikkel, en dan zie je precies waar
     de balk ophoudt. In het donker viel dat weg, met het licht aan niet. */
}

/* De menubalk blijft staan tijdens het scrollen op de pagina's waar een scherm
   in de kast staat. Halverwege een artikel van negen minuten stond de enige
   weg naar het rack of naar een ander bericht boven- of onderaan de pagina, en
   dat is een eind scrollen. Alternatief was het menu in het naambordje zetten,
   maar dan verdwijnt het ook boven aan de pagina, waar je het verwacht. */
.nav-row { position: sticky; top: 0; z-index: 7; }
.admin-bar .nav-row { top: 32px; }
@media (max-width: 782px) { .admin-bar .nav-row { top: 46px; } }
.nav-row .right { display: contents; }
.nav { justify-self: center; }
/* align-items: baseline, want de naam is 16 px en de twee labels 10,5 px. Bij
   center worden de vakjes gecentreerd en niet de letters, en omdat een letter
   niet in het midden van zijn vakje zit, zweeft de naam dan net te hoog naast
   de twee labels. Op de basislijn staan de drie woorden op dezelfde
   denkbeeldige schrijflijn, zoals woorden in een zin. */
.nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: 22px; }
/* De letterafstand van 0,14em wordt ook bij de spatie opgeteld, en daardoor
   viel "BOOT LOG" uiteen in twee woorden die op twee links leken. De
   woordafstand haalt dat er weer af: binnen een item ongeveer 3,8 px, tussen
   de items 22 px, dus de rij valt vanzelf in de goede groepjes. Verder dan dit
   kan niet veel: bij ongeveer -0,45em is de spatie weg en plakken de woorden
   aan elkaar. */
.nav a {
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 400;
  letter-spacing: .14em; word-spacing: -0.38em; text-transform: uppercase;
}
/* de voetregel lijnt op de basislijn uit; het pictogram heeft er geen,
   dus de cel eromheen centreert zelf */
.sheet-foot > span { display: inline-flex; align-items: center; }
.sheet-foot > span:first-child { justify-self: start; }
.sheet-foot > span:last-child { justify-self: end; }
.sheet-foot .foot-nav { justify-self: center; }
.nav a { color: var(--hd); }
.nav a:hover, .nav a:focus-visible { color: var(--acc); text-decoration: none; }
/* De naam van de site is het eerste menu-item en wijst naar de voorpagina.
   Die krijgt geen hoofdletters: als VSTACK verdwijnt de hoofdletter-S die de
   naam maakt. Eén item in gemengde schrijfwijze tussen twee labels in
   hoofdletters leest als een naam, en dat is precies wat het is. WordPress
   Aan het eerste item en niet aan menu-item-home: die klasse geeft WordPress
   alleen als het item echt naar de voorpagina wijst, en in het menu van deze
   site is het een gewone pagina. Aan de volgorde hangen werkt altijd, en de
   naam hoort per definitie vooraan te staan.

   Dezelfde letter en dezelfde maat als de twee items ernaast. Space Grotesk op
   16 px is geprobeerd en teruggedraaid: een naam in een andere letter, een
   andere grootte en gemengde schrijfwijze viel naast twee labels in monospace
   uit de toon, en hij bleef optisch scheef staan omdat de x-hoogte niet
   overeenkomt. Het onderscheid zit nu in de schrijfwijze: het label luidt
   vSTACK, met een kleine v, en daarom staat text-transform hier uit. De
   hoofdletters komen dus uit het menu-item zelf en niet uit de opmaak. */
.nav li:first-child a { text-transform: none; }

/* Het actieve item. WordPress gebruikt verschillende klassen naargelang het
   soort pagina: current-menu-item voor een pagina in het menu, current_page_item
   idem, en current_page_parent op een los bericht, dat dan Rack markeert als de
   plek waar dat bericht vandaan komt. Zonder die drie werkt de onderstreping
   alleen op de voorpagina. */
.nav .current-menu-item > a,
.nav .current_page_item > a,
.nav .current-menu-ancestor > a,
.nav .current_page_parent > a {
  color: var(--acc); border-bottom: 1px solid var(--acc); padding-bottom: 2px;
}

/* De naam licht op in plaats van onderstreept te worden. Een streep is de
   opmaak van een link; bij een naam leest dat als een verwijzing naar iets
   anders. Oplichten is bovendien de taal van de kast: licht betekent dat er
   iets aanstaat, en de voorpagina is waar je bent. De gloed blijft op 7 px,
   want daarboven wordt tekst van 16 px zichtbaar onscherp. */
.nav li:first-child.current-menu-item > a,
.nav li:first-child.current_page_item > a,
.nav li:first-child.current-menu-ancestor > a,
.nav li:first-child.current_page_parent > a {
  border-bottom: 0; padding-bottom: 0;
  text-shadow: 0 0 7px rgba(var(--acc-rgb), .35);
}


/* op andere pagina's dan de voorpagina blijft alleen de navigatierij over */

/* sectiekop: FRONT PAGE links, iets rechts, dunne lijn eronder */
.section-row {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  padding: 26px 0 10px;
  border-bottom: 1px solid var(--line);
  color: var(--hd);
}
.section-row .r { color: var(--dim); }

/* ============================================================
   4. Vervallen: berichten op de voorpagina in krantvorm
   .grid en .cell tekenden de kolommen van de krant en zijn met
   template-parts/cell.php verdwenen. De voorpagina is het rack,
   het archief is het boot log en zoekresultaten zijn blades.
   ============================================================ */


/* ============================================================
   5. Artikel
   ============================================================ */

/* De kop van een krantenartikel (.entry-head) is vervallen: het artikel is
   sinds 1.6 een manpage en tekent zijn eigen kopregel. Geen enkel sjabloon
   gebruikte de klasse nog. */

.entry-content { padding: 30px 40px 44px 0; min-width: 0; }
.entry-content > * { max-width: none; }
.entry-content p { margin: 0 0 18px; text-align: justify; hyphens: auto; -webkit-hyphens: auto; }

/* De zijkolom van het krantenartikel (.entry-rail met zijn inhoudsopgave en
   labels) is vervallen: het artikel is een manpage en heeft rechts de
   sectie-index uit hoofdstuk 31. Geen sjabloon gebruikte deze klassen nog. */
.entry-content h2 { font-family: var(--font-mono); font-size: 30px; font-weight: 400; letter-spacing: -.015em; color: var(--hd); margin: 40px 0 14px; padding-bottom: 8px; border-bottom: 1px solid var(--line-2); }
.entry-content h3 { font-family: var(--font-mono); font-size: 23px; font-weight: 400; color: var(--hd); margin: 30px 0 10px; }
.entry-content h4 { font-family: var(--font-ui); font-size: 12.5px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--hd); margin: 24px 0 8px; }
.entry-content hr,
.entry-content hr.wp-block-separator:not(.is-style-dots) {
  border: 0; height: 0; border-top: 1px solid var(--line-2);
  width: 46%; max-width: 46%; margin: 34px auto;
}
.entry-content ul, .entry-content ol { margin: 0 0 18px; padding-left: 22px; }
.entry-content li { margin-bottom: 6px; }
.entry-content li::marker { color: var(--dim-2); }
.entry-content strong { color: var(--hd); }
.entry-content blockquote {
  margin: 28px 0 30px; padding: 20px 8px;
  border-top: 2px solid var(--ink); border-bottom: 1px solid var(--line);
  text-align: center;
  font-family: var(--font-mono); font-style: italic; font-size: 15px; line-height: 1.35; color: var(--hd);
}
.entry-content blockquote p { margin: 0; text-align: center; hyphens: manual; }
.entry-content blockquote cite { display: block; margin-top: 10px; font-family: var(--font-ui); font-style: normal; font-size: 11px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--dim); }
.entry-content code {
  font-family: var(--font-mono); font-size: 13.5px;
  color: var(--tx);
  background: rgba(var(--sheen-rgb),.055); padding: 1px 5px; border: 0; border-radius: 3px;
}
/* vensters, figuren en koppen nooit naast een zwevende initiaal */
.entry-content pre, .entry-content figure, .entry-content h2, .entry-content h3 { clear: both; }

/* codeblok als terminalvenster: titelbalk met drie knoppen, donkere inhoud.
   !important omdat oudere berichten en plugins inline kleuren meegeven. */
.entry-content pre {
  position: relative;
  font-family: var(--font-mono) !important; font-size: 13.5px !important; line-height: 1.65 !important;
  color: var(--term-tx) !important;
  background: var(--term-bg) !important;
  border: 1px solid var(--term-line) !important; border-radius: 7px;
  padding: 30px 18px 16px !important; margin: 4px 0 24px !important;
  overflow-x: auto; max-width: 100%;
  box-shadow: 0 1px 0 rgba(var(--shadow-rgb),.25), 0 10px 24px -18px rgba(var(--shadow-rgb),.5);
  text-shadow: none !important;
  tab-size: 4;
}
.entry-content pre::before {
  content: "shell";
  position: absolute; left: 0; right: 0; top: 0; height: 18px;
  background: transparent;
  border-bottom: 1px solid var(--term-line);
  border-radius: 7px 7px 0 0;
  /* taal als label rechts in de balk, verticaal gecentreerd in plaats van
     op een vaste padding, zodat het meebeweegt met de hoogte van de balk */
  display: flex; align-items: center; justify-content: flex-start;
  font-family: var(--font-mono); font-size: 9.5px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase;
  color: var(--term-dim); padding: 0 0 0 16px; line-height: 1;
}
.entry-content pre[data-lang]::before { content: attr(data-lang); }

/* PowerCLI: het blauw van de console, zonder Windows-titelbalk */
.entry-content pre[data-lang="powershell"] {
  --term-bg:   var(--ps-bg);
  --term-tx:   var(--ps-tx);
  --term-dim:  #8fa9cc;
  --term-line: rgba(var(--sheen-rgb),.10);
  border-color: rgba(var(--ps-acc-rgb),.28) !important;
}
.entry-content pre[data-lang="powershell"]::after { background: var(--ps-acc); }
.entry-content pre[data-lang="powershell"]::-webkit-scrollbar-thumb { background: rgba(var(--sheen-rgb),.24); }
.entry-content pre[data-lang="powershell"] { scrollbar-color: rgba(var(--sheen-rgb),.24) transparent; }
/* geen knopjes meer: een manpage is geen schermafbeelding uit macOS.
   In plaats daarvan een gekleurde streep links, die het soort blok aangeeft. */
.entry-content pre::after {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  border-radius: 7px 0 0 7px;
  background: var(--acc);
}
.entry-content pre code {
  background: none !important; border: 0 !important; padding: 0 !important;
  font: inherit !important; color: inherit !important; white-space: pre;
}
/* dunne schuifbalk in het venster zelf */
.entry-content pre::-webkit-scrollbar { height: 8px; }
.entry-content pre::-webkit-scrollbar-track { background: transparent; }
.entry-content pre::-webkit-scrollbar-thumb { background: rgba(var(--sheen-rgb),.14); border-radius: 4px; }
.entry-content pre { scrollbar-width: thin; scrollbar-color: rgba(var(--sheen-rgb),.14) transparent; }
.entry-content pre ::selection { background: rgba(var(--sheen-rgb),.18); }
.entry-content table { width: 100%; border-collapse: collapse; font-size: 15px; margin: 0 0 22px; }
.entry-content th, .entry-content td { border-bottom: 1px solid var(--line-2); padding: 8px 11px; text-align: left; vertical-align: top; }
.entry-content th { font-family: var(--font-ui); font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--hd); font-weight: 600; border-bottom: 1px solid var(--ink); }
/* de kernstijlen van het tabelblok zetten een rand rond elke cel; een krant
   heeft alleen horizontale lijnen, dus die randen gaan er hier weer af */
.entry-content figure.wp-block-table { margin: 0 0 22px; }
.entry-content figure.wp-block-table table { border-top: 2px solid var(--ink); }
.entry-content figure.wp-block-table td,
.entry-content figure.wp-block-table th { border: 0; border-bottom: 1px solid var(--line-2); }
.entry-content figure.wp-block-table thead th { border-bottom: 1px solid var(--ink); }
.entry-content figure.wp-block-table figcaption { text-align: left; }

/* schermafbeeldingen: lichte interfaces snijden anders in de donkere pagina.
   Een passe-partout van een tint lichter dan de achtergrond geeft ze een rand
   en houdt ze op de pagina in plaats van erin. */
.entry-content img {
  display: block; max-width: 100%; height: auto;
  border: 1px solid var(--img-edge);
  border-radius: 3px;
}
.entry-content figure {
  margin: 0 0 24px; max-width: 100%;
  background: var(--img-mat);
  border: 1px solid var(--line-2);
  border-radius: 5px;
  padding: 10px;
}
.entry-content figure.wp-block-table { background: none; border: 0; padding: 0; }
/* losse afbeeldingen zonder figure krijgen dezelfde lucht */
.entry-content > img, .entry-content p > img {
  margin: 4px 0 24px;
  outline: 10px solid var(--img-mat);
}
.entry-content figcaption { font-family: var(--font-ui); font-size: 12px; color: var(--dim); margin-top: 8px; }

/* De buren onder een artikel: een module in de kast, geen losse tekst. Alles
   binnen de rails heeft een front met een rand en een schaduw; deze twee
   links stonden er als enige zonder, en dan lezen ze als iets wat er per
   ongeluk staat. De contactregel die hier ook stond is vervallen en zit nu
   in REPORTING BUGS op het colofon. */
.adj {
  background: linear-gradient(180deg,var(--k-10) 0%,var(--k-08) 42%,var(--k-06) 100%);
  border: 1px solid var(--k-11-ln); border-radius: 2px; overflow: hidden;
}
.adj-head {
  display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap;
  border-bottom: 1px solid var(--k-11-ln); padding: 6px 11px;
}
.adj-head .lbl { font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em; color: var(--dim); }
.adj-head .lbl b { color: var(--hd); font-weight: 500; }
.adj-halves { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 9px 11px 11px; }
.adj.solo .adj-halves { grid-template-columns: 1fr; }
.adj-slot {
  display: flex; align-items: center; gap: 12px; position: relative; min-width: 0;
  background: linear-gradient(180deg,var(--k-07),var(--k-04));
  border: 1px solid var(--k-10-ln); border-radius: 2px;
  padding: 9px 14px 9px 10px; text-decoration: none;
}
.adj-slot:hover, .adj-slot:focus-visible { border-color: var(--acc); text-decoration: none; }
.adj-slot .dir { font-family: var(--font-mono); font-size: 9px; letter-spacing: .14em; color: var(--dim-2); white-space: nowrap; }
/* De titel wordt afgekapt: een front heeft een vaste hoogte, en twee helften
   die verschillend afbreken zetten de module scheef. */
.adj-slot .ti { font-family: var(--font-mono); font-size: 13px; color: var(--k-30); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.adj-slot .handle {
  position: absolute; right: 0; top: 0; bottom: 0; width: 5px;
  background: repeating-linear-gradient(180deg,var(--k-13) 0 2px,var(--k-10) 2px 4px);
  border-left: 1px solid var(--k-06-ln);
}

/* Op een smal scherm passen twee fronten niet naast elkaar. */
@media (max-width: 760px) {
  .adj-halves { grid-template-columns: 1fr; gap: 5px; }
}

/* ============================================================
   6. Voet, paginering, losse pagina's
   ============================================================ */

.sheet-foot {
  margin-top: 8px;
  padding: 14px 0 46px;
  border-top: 2px solid var(--ink);
  color: var(--dim);
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px;
  font-weight: 500;
}
.sheet-foot a { color: var(--dim); }
.foot-nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 22px; }
.sheet-foot .rss { margin-left: 18px; }
.foot-nav a:hover, .foot-nav a:focus-visible { color: var(--acc); text-decoration: none; }

/* .pagination is vervallen: het archief en de zoekpagina tonen alles in één
   keer, en het rack pagineert niet.
   .page-head, de krantenkop boven een archief of losse pagina, is vervallen:
   die pagina's dragen nu de kop- en voetregel van een manpage. */

/* zoekformulier */
.search-form { display: flex; align-items: stretch; gap: 14px; max-width: 480px; }
.search-form input[type="search"] {
  flex: 1; font: inherit; font-size: 16px; padding: 8px 0;
  border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
  background: transparent; color: var(--hd);
  -webkit-appearance: none; appearance: none;
}
.search-form input[type="search"]::placeholder { color: var(--dim); opacity: 1; }
.search-form input[type="search"]:focus { outline: 0; border-bottom-color: var(--acc); }
.search-form .search-submit {
  background: none; color: var(--hd); border: 0; border-bottom: 1px solid var(--line);
  padding: 0 2px; cursor: pointer;
}
.search-form .search-submit:hover, .search-form .search-submit:focus-visible {
  background: none; color: var(--acc); border-bottom-color: var(--acc);
}

/* ============================================================
   7. Smal scherm
   ============================================================ */

@media (max-width: 760px) {
  :root { --gutter: 18px; }
  .nav ul { gap: 14px 18px; }
  .entry-content { padding-right: 0; padding-bottom: 24px; }
  /* Twee rijen in plaats van drie. RSS stond als enige op een eigen regel,
     terwijl het net zo goed een link in de rij is; nu staat hij achter
     Disclaimer en Privacy Policy met dezelfde tussenruimte van 22 px, en
     zakt alleen het jaartal naar de tweede rij. Flex in plaats van grid,
     want twee items op één rij en het derde op een eigen rij is precies wat
     flex-basis: 100% doet.

     De 18 px links van RSS komt uit de tijd dat er ook een zoeklink en een
     berichtenteller in dat vak stonden. Op een gecentreerde regel duwde die
     marge de tekst 9 px uit het midden. */
  .sheet-foot {
    display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline;
    gap: 12px 22px; text-align: center; padding-bottom: 30px;
  }
  /* justify-content en niet text-align. Deze spans staan in hoofdstuk 2 op
     display: inline-flex, en in flex doet text-align niets: de inhoud gaat
     naar flex-start en dus naar links. Dat gold alleen voor het jaartal, want
     de rij met links is een nav met een gewone ul erin. */
  .sheet-foot > span { white-space: nowrap; justify-content: center; }
  .sheet-foot .foot-nav { order: 1; }
  .sheet-foot > span:last-child { order: 2; }
  .sheet-foot > span:first-child { order: 3; flex-basis: 100%; }
  .sheet-foot .rss { margin-left: 0; }
  .foot-nav ul { justify-content: center; gap: 14px 22px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* afdrukken: altijd licht, geen papierlijnen */
@media print {
  body { background: #fff; color: #000; }
  .nav-row, .adj { display: none; }
}

/* ============================================================
   404: het bulletinboard
   Klassieke ANSI-kleuren op blauw. Alleen hier, nergens anders.
   ============================================================ */

.bbs {
  --bbs-bg:   #0000aa;
  --bbs-tx:   #c8c8ff;
  --bbs-cy:   #55ffff;
  --bbs-ye:   #ffff55;
  --bbs-ma:   #ff55ff;
  --bbs-gr:   #55ff55;
  --bbs-rd:   #ff5555;
  margin: 26px 0 40px;
  font-family: var(--font-mono);
}
.bbs-screen { background: var(--bbs-bg); color: var(--bbs-tx); padding: 22px 24px; }
.bbs-box { border: 3px double var(--bbs-cy); padding: 14px 18px; margin: 0 0 18px; }
.bbs-title { font-family: var(--font-mono); font-size: 30px; font-weight: 700; letter-spacing: .14em; color: var(--bbs-ye); margin: 0; line-height: 1.1; }
.bbs-sub { color: var(--bbs-cy); margin: 6px 0 0; font-size: 13px; letter-spacing: .06em; }
.bbs-msg { color: #fff; margin: 0 0 10px; font-size: 13.5px; }
.bbs-msg b { color: var(--bbs-rd); font-weight: 400; }
.bbs-list { list-style: none; margin: 0 0 4px; padding: 0; }
.bbs-list li { padding: 2px 0; }
.bbs-list a {
  display: grid; grid-template-columns: 44px 96px 1fr 78px; gap: 12px;
  padding: 2px 6px; color: inherit; text-decoration: none; font-size: 13.5px;
}
.bbs-list a:hover, .bbs-list li.sel a { background: var(--bbs-cy); color: var(--bbs-bg); }
.bbs-list a:hover .n, .bbs-list a:hover .c, .bbs-list a:hover .d,
.bbs-list li.sel a .n, .bbs-list li.sel a .c, .bbs-list li.sel a .d { color: var(--bbs-bg); }
.bbs-list .n { color: var(--bbs-ma); }
.bbs-list .c { color: var(--bbs-gr); }
.bbs-list .t { color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bbs-list .d { color: #8888dd; text-align: right; }
.bbs-prompt { margin-top: 14px; }
.bbs-cur { display: inline-block; width: 9px; height: 15px; background: var(--bbs-tx); vertical-align: -3px; animation: bbs-blink 1.05s steps(1) infinite; }
@keyframes bbs-blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .bbs-cur { animation: none; } }
.bbs-keys { background: #c8c8c8; color: var(--bbs-bg); display: flex; gap: 20px; flex-wrap: wrap; padding: 6px 24px; font-size: 13px; }
.bbs-keys b { background: #0000aa; color: #fff; padding: 0 6px; font-weight: 400; }
.bbs-keys a { color: var(--bbs-bg); text-decoration: none; }
.bbs-keys a:hover { text-decoration: underline; }

@media (max-width: 640px) {
  .bbs-screen { padding: 16px 14px; }
  .bbs-list a { grid-template-columns: 34px 1fr; }
  .bbs-list .c, .bbs-list .d { display: none; }
  .bbs-title { font-size: 24px; }
}

/* ============================================================
   Boot log: alle berichten op één scherm, per jaar gemount
   ============================================================ */

.log-tools { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 14px; }
.log-chip {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  border: 1px solid var(--line-2); color: var(--dim); padding: 4px 10px; text-decoration: none;
}
.log-chip:hover { border-color: var(--acc); color: var(--acc); }
.log-chip.on { background: var(--acc); border-color: var(--acc); color: var(--btn-tx); }

.log { font-family: var(--font-mono); font-size: 12.5px; line-height: 1.75; margin: 0 0 40px; }
.log-line { color: var(--dim); }
.log-boot { color: var(--dim-2); }
.log-warn { color: var(--warn-ink); margin-top: 16px; }
.log-prompt { color: var(--acc); margin-top: 4px; }
.log-year { color: var(--dim); letter-spacing: .06em; margin: 18px 0 2px; }
.log-year b { color: var(--acc); font-weight: 500; }
.log-year .ok { color: var(--ok-ink); }
.log-row {
  display: grid; grid-template-columns: 104px 96px 1fr 112px; gap: 12px;
  padding: 2px 6px 2px 4px; text-decoration: none; color: var(--tx);
}
/* Zelfde reden als bij de blade: de rij is een link, dus de algemene regel
   onderstreept tijdstempel, categorie, titel en leestijd tegelijk. De
   oplichtende achtergrond is hier de terugkoppeling. */
.log-row:hover, .log-row:focus-visible { background: rgba(var(--sheen-rgb),.04); text-decoration: none; }
.log-chip:hover, .log-chip:focus-visible { text-decoration: none; }
.log-row:hover .ti { color: var(--hd); }
.log-row .ts { color: var(--dim-2); }
.log-row .ct { color: var(--acc); }
.log-row .ti { font-family: var(--font-mono); font-size: 12.5px; letter-spacing: 0; color: var(--tx); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.log-row:hover .ti { color: var(--hd); }
.log-row .rt { color: var(--dim-2); text-align: right; white-space: nowrap; }

@media (max-width: 760px) {
  .log-row { grid-template-columns: 96px 1fr; gap: 8px; }
  .log-row .ct, .log-row .rt { display: none; }
  .log-row .ti { white-space: normal; }
}

/* ============================================================
   Voorpagina: rackkast K-3
   ============================================================ */

/* Geen ruimte boven de kast. Die 26 px was er toen de masthead erboven stond;
   sinds de menubalk vastzit schuift de kast er bij het scrollen toch onderdoor
   tot de sensorstrip vastklikt, en dan is de ruimte weg. Twee toestanden voor
   hetzelfde beeld. Op nul sluit de bovenkant van de kast in rust precies aan
   op de lijn onder het menu, net zoals na het scrollen. Onder de kast blijft
   de lucht wel staan. */
.rack { margin: 0 0 44px; font-family: var(--font-mono); }

.nameplate {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 14px;
  background: linear-gradient(180deg,var(--k-11) 0%,var(--k-09) 48%,var(--k-06) 100%);
  border: 1px solid var(--k-13-ln); border-bottom: 0; border-radius: 3px 3px 0 0; padding: 10px 14px;
  box-shadow: inset 0 1px 0 rgba(var(--sheen-rgb),.14);
}
.nameplate .tagplate {
  justify-self: center;
  background: linear-gradient(180deg,var(--k-13) 0%,var(--k-10) 55%,var(--k-08) 100%);
  border: 1px solid var(--k-14); border-radius: 2px; padding: 5px 18px;
  font-size: 16px; font-weight: 700; letter-spacing: .32em; text-indent: .32em; color: var(--k-29);
  text-shadow: 0 1px 0 rgba(var(--shadow-rgb),.6), 0 -1px 0 rgba(var(--sheen-rgb),.12);
  box-shadow: inset 0 1px 0 rgba(var(--sheen-rgb),.16), inset 0 -1px 2px rgba(var(--shadow-rgb),.4);
}
.nameplate .screw {
  width: 8px; height: 8px; border-radius: 50%; display: block; position: relative;
  background: radial-gradient(circle at 35% 32%,var(--k-17),var(--k-06)); box-shadow: inset 0 0 2px rgba(var(--shadow-rgb),.8);
}
.nameplate .screw::after { content: ""; position: absolute; left: 1px; right: 1px; top: 3px; height: 1px; background: rgba(var(--shadow-rgb),.65); }

/* Op een telefoon een maat terug. Met de sensorstrip op 8,5 px en de
   bladetitels op 10,5 was K-3 op 16 px de grootste letter van de pagina, en
   het is een label op plaatstaal, geen kop. De balk gaat van 59 naar ongeveer
   45 px: de plaat krijgt 11 px letter met 4 px padding, de balk 8 px.
   Direct onder de twee regels die het overschrijft, want .nameplate .tagplate
   is met twee klassen specifieker dan de plaat alleen. */
@media (max-width: 480px) {
  .nameplate { padding: 8px 12px; }
  /* De plaat blijft het aanraakvlak van het ei, zes klikken op K-3. Ongeveer
     28 px hoog is krap voor een duim maar nog raakbaar; kleiner niet. */
  .nameplate .tagplate { font-size: 11px; padding: 4px 12px; }
}

.cab {
  position: relative; display: grid;
  grid-template-columns: var(--rail-w) 1fr var(--rail-w) var(--pdu-w);
  /* De binnenkant van de kast is niet één vlak: onder het dak komt het licht
     niet, en naar onderen loopt hij op. In het donker staan beide stops op
     dezelfde waarde, dus daar is het een verloop van niets. */
  background: linear-gradient(180deg, var(--kast-boven), var(--kast-onder));
  border: 1px solid var(--k-08-ln); padding: 10px 0;
  /* Alleen een bodemschaduw. De zijschaduwen zijn vervallen: die steken
     buiten de wikkel uit en worden door de dekkende menubalk afgesneden zodra
     je scrolt, en die afsnijding leest als een verticale lijn naast de kast. */
  box-shadow:
    0 30px 44px -18px rgba(var(--shadow-rgb),var(--kast-drop)),
    inset 1px 0 0 rgba(var(--sheen-rgb),var(--kant)),
    inset -1px 0 0 rgba(var(--sheen-rgb),var(--kant)),
    inset 0 1px 0 rgba(var(--sheen-rgb),var(--kant));
}
.cab::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background: linear-gradient(180deg,rgba(var(--sheen-rgb),.055),rgba(255,255,255,0) 32%,rgba(var(--shadow-rgb),.22));
}
.rail { background: var(--k-rail); display: flex; flex-direction: column; align-items: center; justify-content: space-between; padding: 8px 0; }
/* De nummers staan aan de binnenkant van beide rails, naast de apparatuur waar
   je ze afleest, en de kooimoergaten aan de buitenkant. Zo flankeren ze de bays
   symmetrisch. Twee andere opstellingen zijn geprobeerd: allebei links
   uitgelijnd (dan vielen de nummers rechts onder de binnenschaduw weg) en
   gespiegeld per rail (dan plakten ze rechts tegen de PDU). Iets lichter dan
   eerst, want tegen de schaduw in moeten ze wel leesbaar blijven. */
.rail .u { font-size: 7.5px; color: var(--k-u); line-height: 1; align-self: flex-end; padding-right: 6px; }
.rail { background-position: 7px 0, 0 0; }

/* De rechterrail is gespiegeld: nummers aan de buitenkant, gaten aan de
   binnenkant. Ongespiegeld stonden de nummers daar tegen de bays aan, onder de
   binnenschaduw, en waren ze niet te lezen; de kast leek dan maar aan één kant
   genummerd. Op een echte kast staat de markering aan de buitenzijde van beide
   stijlen. */
.rail-r .u { align-self: flex-start; padding-right: 0; padding-left: 6px; }
.rail-r { background-position: calc(100% - 7px) 0, 0 0; }
/* Kooimoergaten: drie per U, met de ongelijke steek van EIA-310. Binnen een U
   staan ze op 15,875 / 15,875 mm en over de U-grens op 12,7 mm, en dat ritme
   zie je op een echte rail. Eerder stond er één moer per vier U, wat netjes
   oogde maar nergens op sloeg. Als achtergrond en niet als element, want
   126 extra elementjes per rail is decor dat de pagina laat betalen. */
.rail {
  background-image: var(--rail-gaten);
  background-size: 6px calc(100% / 42), 100% 100%;
  /* De gaten staan aan één kant van de rail en de nummers aan de andere,
     anders lopen ze door elkaar heen. De kant verschilt per rail, zie hieronder. */
  background-repeat: repeat-y, no-repeat;
}
/* De twee stijlen zijn gebogen plaatwerk: licht aan de kant die naar de bays
   wijst, donker naar de buitenrand toe. Als tweede achtergrondlaag onder de
   kooimoergaten. In het donker staan beide stops op dezelfde waarde, dus daar
   is het een verloop van niets. */
.rail  { background-image: var(--rail-gaten), linear-gradient(90deg, var(--rail-buiten), var(--rail-binnen)); }
.rail-r { background-image: var(--rail-gaten), linear-gradient(90deg, var(--rail-binnen), var(--rail-buiten)); }
.bays { display: flex; flex-direction: column; gap: 20px; padding: 0 9px; box-shadow: inset 6px 0 12px -6px rgba(var(--shadow-rgb),.85), inset -6px 0 12px -6px rgba(var(--shadow-rgb),.85); }

/* Een lege sleuf tussen de chassis, zoals je die voor warmte laat. */
.chassis + .chassis { margin-top: 12px; }

/* De U-nummers zijn schaalverdeling en geen meetlat: ze staan gelijk verdeeld
   over de hoogte en niet op de maat van de apparatuur. Dat is twee keer
   geprobeerd en twee keer teruggedraaid. Met een U van 32 px (alpha80) paste
   de inhoud niet meer in zijn front; met 44 px (alpha85) paste het wel, maar
   de onderkant van de kast werd er lelijk van: alles even hoog, geen adem
   tussen de onderdelen, en de voedingen die met een hoge lege ruimte erboven
   op de bodem plakten. Het aanzicht weegt hier zwaarder dan de telbaarheid.
   Wie meetelt komt dus niet uit, en dat is een bewuste afweging. */

/* De U-nummers op de rails staan gelijk verdeeld over de hoogte en niet op
   de maat van de apparatuur. Dat is één keer geprobeerd, in alpha80: elk
   onderdeel een heel aantal U en de tussenruimte eruit. Het resultaat was
   dat de inhoud niet meer in zijn eigen front paste, de vendorsticker over
   de poorten van de switch viel en onderin alles aan elkaar plakte. De
   onderdelen hebben nu eenmaal niet de hoogte die een U zou voorschrijven,
   en de tussenruimte van 20 px is wat de kast leesbaar houdt. De rails zijn
   dus schaalverdeling, geen meetlat. */

/* ToR en kabelgeleider */
.tor { box-shadow: 0 2px 5px rgba(var(--shadow-rgb),var(--drop)); position: relative; background: linear-gradient(180deg,var(--k-10) 0%,var(--k-08) 45%,var(--k-06) 100%); border: 1px solid var(--k-13-ln); border-radius: 2px; padding: 8px 11px; }
.tor-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 7px; }
.tor .lbl, .cablemgr .lbl, .chead .lbl { font-size: 10px; letter-spacing: .12em; color: var(--dim); }
.tor .lbl b, .cablemgr .lbl b, .chead .lbl b { color: var(--hd); font-weight: 500; }
.tor .lbl b.ok { color: var(--ok-ink); }
/* Bovenaan uitlijnen en niet onderaan. De uplinkgroep heeft onder zijn twee
   poorten een tekstregel in plaats van een tweede rij poorten, en die regel is
   13,6 px tegen 7 voor een poortrij. Onderaan uitgelijnd kwam dat verschil er
   bovenaan uit: het oranje paar stond 6,6 px hoger dan de groene rij ernaast,
   terwijl het poorten op hetzelfde front zijn. Nu liggen alle bovenste rijen
   op één lijn en hangt 40G onder zijn eigen poorten, zoals het opschrift op
   een echte switch. De switch wordt er niet hoger van; die 22,6 px stond er
   al. */
.tor .ports { display: flex; gap: 9px; align-items: flex-start; flex-wrap: wrap; }
.tor .grp { display: grid; grid-template-rows: auto auto; gap: 2px; }
.tor .prow { display: flex; gap: 2px; }
.tor .p { width: 9px; height: 7px; background: var(--k-02); border: 1px solid var(--k-12-ln); border-radius: 1px; position: relative; }
.tor .p.up { background: var(--k-port-uplink); border-color: var(--k-port-uplink-edge); }
.tor .p i { position: absolute; left: 2px; top: 1.5px; width: 3px; height: 3px; border-radius: 50%; background: var(--k-03); display: block; }
/* De groene poortlampjes knipperen met hetzelfde act-ritme als de chassis:
   dat is verkeer over de poort. De amberkleurige uplinks blijven constant,
   want een knipperende uplink zou iets anders betekenen. Elke poort krijgt
   een eigen vertraging, anders knippert de hele switch als één lamp. */
.tor .p i.g {
  background: var(--ok); box-shadow: 0 0 4px rgba(var(--ok-rgb),.75);
  animation: vbp-act 1.9s steps(1) infinite;
  animation-delay: var(--d, 0s);
}
@media (prefers-reduced-motion: reduce) { .tor .p i.g { animation: none; } }
.tor .p i.a { background: var(--warn); box-shadow: 0 0 4px rgba(var(--warn-rgb),.7); }
.tor .up40 { font-size: 8.5px; color: var(--k-uplink-label); letter-spacing: .1em; align-self: center; }

.cablemgr { box-shadow: 0 2px 5px rgba(var(--shadow-rgb),var(--drop)); position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 12px; background: linear-gradient(180deg,var(--k-09),var(--k-06)); border: 1px solid var(--k-11-ln); border-radius: 2px; padding: 7px 11px; }
.cablemgr .fingers { flex: 1; display: flex; gap: 4px; justify-content: center; }
.cablemgr .fingers i { display: block; width: 7px; height: 16px; border-radius: 3px; background: linear-gradient(180deg,var(--k-13),var(--k-09)); border: 1px solid var(--k-15); box-shadow: inset 0 1px 0 rgba(var(--sheen-rgb),.18); }

/* chassis */
/* Geen zijstijl meer. De spine droeg de naam van de categorie en het aantal,
   allebei verticaal, terwijl de kopregel een centimeter naar rechts hetzelfde
   leesbaar toont. Dat was de enige plek in de kast waar iets twee keer stond.

   Belangrijker nog: het chassis was daardoor het enige onderdeel waarvan de
   inhoud niet op dezelfde kantlijn begon als de switch, de kabelgeleider, de
   KVM-lade, de OA-balk en de voedingen. Nu begint alles op dezelfde lijn.

   Op een telefoon levert het bovendien 30 px op voor de bladetitels, van 219
   naar 249 px, dus 39 tekens per regel in plaats van 34. */
.chassis { box-shadow: 0 2px 5px rgba(var(--shadow-rgb),var(--drop)); position: relative; background: linear-gradient(180deg,var(--k-10) 0%,var(--k-08) 42%,var(--k-06) 100%); border: 1px solid var(--k-11-ln); border-radius: 2px; overflow: hidden; }
.chassis::after { content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: 2px; background: linear-gradient(118deg,rgba(var(--sheen-rgb),var(--glans-1)) 0%,rgba(var(--sheen-rgb),var(--glans-2)) 26%,rgba(255,255,255,0) 52%,rgba(var(--shadow-rgb),var(--schaduw-1)) 100%); }
.chassis .inner { position: relative; z-index: 1; }
.chassis .inner { padding: 9px 11px 11px; }
.chead { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; border-bottom: 1px solid var(--k-11-ln); padding-bottom: 7px; margin-bottom: 8px; }

/* lampjes */
.leds { display: flex; gap: 5px; align-items: center; }
.led, i.led { width: 7px; height: 7px; border-radius: 50%; background: var(--k-03); box-shadow: inset 0 0 2px rgba(var(--shadow-rgb),.9); display: block; font-style: normal; }
.led.pwr { background: var(--ok); box-shadow: 0 0 6px rgba(var(--ok-rgb),.75); }
.led.act { background: var(--ok); animation: vbp-act 1.7s steps(1) infinite; }
.led.slow { background: var(--warn); animation: vbp-slow 3.4s ease-in-out infinite; }
.chassis:nth-of-type(2) .chead .led.act { animation-duration: 2.3s; animation-delay: .4s; }
.chassis:nth-of-type(3) .chead .led.act { animation-duration: 1.1s; animation-delay: .9s; }
@keyframes vbp-act { 0%,42%{opacity:1} 43%,58%{opacity:.18} 59%,74%{opacity:1} 75%,86%{opacity:.18} 87%,100%{opacity:1} }
@keyframes vbp-slow { 0%,100%{opacity:.22} 50%{opacity:1; box-shadow:0 0 7px rgba(var(--warn-rgb),.7)} }
@media (prefers-reduced-motion: reduce) { .led.act, .led.slow { animation: none; opacity: 1; } }

/* blades */
.blade {
  box-shadow: 0 1px 2px rgba(var(--shadow-rgb),var(--drop));
  display: grid; grid-template-columns: auto auto 1fr auto; gap: 13px; align-items: center;
  background: linear-gradient(180deg,var(--k-11) 0%,var(--k-09) 60%,var(--k-08) 100%);
  border: 1px solid var(--k-12-ln); border-radius: 2px; padding: 8px 104px 8px 11px; margin-bottom: 5px;
  position: relative; text-decoration: none; color: inherit;
}
/* De rechterkant is gereserveerd voor de twee knoppen, PEEK en UID. Zonder
   die ruimte leggen ze zich over de datum en de leestijd heen, want ze zijn
   absoluut geplaatst en tellen niet mee in het raster. Sinds PEEK een woord
   is in plaats van een vierkantje van 16 px is die strook breder: 104 px. */
/* Geen onderstreping bij zweven. De blade is een link, dus de algemene
   regel voor links pakt hem, maar op een rij met vier kolommen streept
   die alles tegelijk aan. De groene rand is hier de terugkoppeling. */
.blade:hover, .blade:focus-visible { border-color: var(--ok); box-shadow: 0 0 0 1px rgba(var(--ok-rgb),.3); text-decoration: none; }

/* Lichtval bij zweven. Bewust géén gekleurde gloed: op deze kast betekent
   licht iets (groen online, amber herzien, blauw UID), en een groene halo om
   een blade zou in diezelfde taal iets zeggen wat niets met de status te
   maken heeft. Dit is alleen helderheid: het plaatstaal vangt het licht van
   het gangpad, schuin van linksboven, met een dunne oplichtende bovenrand.
   De groene rand blijft ernaast staan, want die zegt iets anders: klikbaar.
   Eerste stuk van de lichtval per front uit het ontwerp. */
.blade::after {
  content: ""; position: absolute; inset: 0; border-radius: 2px;
  pointer-events: none; opacity: .38; transition: opacity .18s ease;
  background:
    linear-gradient(118deg, rgba(var(--sheen-rgb),var(--glans-1)) 0%, rgba(var(--sheen-rgb),var(--glans-2)) 34%, rgba(255,255,255,0) 68%);
  box-shadow: inset 0 1px 0 rgba(var(--sheen-rgb),var(--glans-rand));
}
.blade:hover::after, .blade:focus-visible::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .blade::after { transition: none; } }
/* De handgreep hoort boven de lichtval te blijven: die zit er fysiek voor. */
.blade .handle { z-index: 1; }
.more:hover, .more:focus-visible { text-decoration: none; color: var(--ink); }
/* 13,5 px, gelijk aan de lopende tekst van een artikel. In 1.6.0 stond hier
   15 px, maar naast een chassiskop van 10 en een serienummer van 9 was de
   titel daarmee het zwaarste element van de kast. De ruimte is er wel, zo'n
   713 px bij een pagina van 1280, maar die is niet het argument: een blade is
   een front met een opschrift, geen kop. */
.blade .ti { display: block; font-size: 13.5px; color: var(--k-30); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.blade .rt { font-size: 10.5px; color: var(--dim); white-space: nowrap; }
.blade .handle { position: absolute; right: 0; top: 0; bottom: 0; width: 5px; background: repeating-linear-gradient(180deg,var(--k-13) 0 2px,var(--k-10) 2px 4px); border-left: 1px solid var(--k-06-ln); }

.more { display: block; text-align: center; font-size: 11px; color: var(--dim); background: var(--k-07); border: 1px dashed var(--k-12-ln); border-radius: 2px; padding: 6px; text-decoration: none; }
.more:hover { color: var(--hd); border-color: var(--ok); }
/* Blindplaten iets lichter: op de oude tint leek een lege positie een gat in
   plaats van een afgedekte sleuf, terwijl het plaatwerk is. */
.blank { background: repeating-linear-gradient(180deg,var(--k-09) 0 3px,var(--k-07) 3px 6px); border: 1px solid var(--k-12-ln); border-radius: 2px; display: flex; align-items: center; justify-content: center; gap: 10px; height: 26px; color: var(--k-17-ink); font-size: 9.5px; letter-spacing: .14em; margin-bottom: 5px; }

/* voedingen, plaatje en legenda */
.psus { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 0; }
/* Twee hoogte-eenheden, en dat is geen smaak: de voedingen van een
   enclosure zijn diepe modules en geen plak van 1U, anders dan de KVM-lade,
   de OA-balk en de switch die alle drie wel echt 1U zijn. Een blade is hier
   ongeveer 31 px inclusief tussenruimte, dus 62 px leest tegen de rails als
   2U. De ventilator krijgt daarmee de ruimte die hij nodig had. */
.psu { box-shadow: 0 2px 5px rgba(var(--shadow-rgb),var(--drop)); background: linear-gradient(180deg,var(--k-08),var(--k-06)); border: 1px solid var(--k-11-ln); border-radius: 2px; padding: 12px 14px; min-height: 62px; display: flex; justify-content: space-between; align-items: center; gap: 10px; font-size: 9.5px; color: var(--dim); letter-spacing: .1em; }
.psu b { color: var(--hd); font-weight: 500; }
.psu .fan { width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--k-13-ln); position: relative; overflow: hidden; background: radial-gradient(circle at 50% 50%,var(--k-fan-kern) 0 4px,var(--k-fan-bg) 4px); }
.psu .fan i { position: absolute; left: 50%; top: 50%; width: 3px; height: 15px; margin: -15px 0 0 -1.5px; transform-origin: 50% 100%; background: linear-gradient(180deg,var(--k-fan-1),var(--k-fan-2)); border-radius: 1px; display: block; }
.psu .fan i:nth-child(1) { transform: rotate(0deg); }
.psu .fan i:nth-child(2) { transform: rotate(72deg); }
.psu .fan i:nth-child(3) { transform: rotate(144deg); }
.psu .fan i:nth-child(4) { transform: rotate(216deg); }
.psu .fan i:nth-child(5) { transform: rotate(288deg); }
.psu .fan::after { content: ""; position: absolute; left: 50%; top: 50%; width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%; background: var(--k-fan-as); box-shadow: inset 0 0 2px rgba(var(--shadow-rgb),.8); }
/* Allebei de voedingen draaien: een redundante voeding deelt de last en staat
   niet stil.

   Even snel, want dat is wat er gebeurt. De ventilatorregeling volgt de
   temperatuur en de belasting, en bij 54 tegen 46 procent is dat verschil te
   klein om een andere stap te halen. Verschillende toerentallen zie je pas bij
   een storing of een flink verschil in inlaattemperatuur. Wel uit de pas: twee
   losse apparaten lopen nooit synchroon, en daar zie je aan dat het er twee
   zijn. Een negatieve vertraging start de tweede midden in zijn ronde. */
/* Beide ventilatoren even snel: hun regeling stuurt op temperatuur, en bij 54
   tegen 46 procent van de last valt dat binnen dezelfde stap. Zichtbaar
   verschillende toerentallen horen bij een storing. Wel uit de pas, want twee
   losse apparaten lopen nooit synchroon. */
.psu.run .fan { animation: vbp-spin 1.6s linear infinite; }
.psu.run.slow .fan { animation-delay: -0.7s; }
@keyframes vbp-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .psu.run .fan { animation: none; } }

/* De legenda deelt de linkerkant met de lekkagesensor en de aardedraad: het is
   onderschrift bij de kast, geen apparatuur, en drie regels met dezelfde
   kantlijn lezen als één blok. Gecentreerd zou het een sierstrook worden,
   zonder iets om zich aan uit te lijnen nu de rails erboven ophouden. */
.legend { display: flex; gap: 18px; flex-wrap: wrap; font-size: 10.5px; color: var(--dim); padding: 10px 12px 0; }
.legend span { display: flex; align-items: center; gap: 7px; }

@media (max-width: 760px) {
  .cab { grid-template-columns: 18px 1fr 18px; }
  /* Op een telefoon is de rail 18 px in plaats van 30, en dan lopen de
     kooimoergaten en de nummering door elkaar: de gaten zijn 6 px breed en
     staan op x=7, het nummer beslaat rechts uitgelijnd ongeveer 1 tot 12.
     Hier staan de gaten tegen de buitenrand en schuift het nummer op, met
     een kleinere letter zodat er tussen de twee nog lucht zit. */
  .rail { background-position: 0 0, 0 0; }
  .rail-r { background-position: 100% 0, 0 0; }
  .rail .u { font-size: 6.5px; padding-right: 1px; }
  .rail-r .u { padding-left: 1px; padding-right: 0; }
  .blade { grid-template-columns: auto 1fr; gap: 10px; padding-right: 96px; }
  .blade .rt { display: none; }
  .tor .ports { gap: 6px; }
  .psus { grid-template-columns: 1fr; }
}

/* Onder 480 px staat de titel op twee regels. De reden is rekenkundig: op een
   venster van 390 px houdt de titel 94 px over, en dat is bij 13,5 px
   JetBrains Mono ongeveer elf tekens. De keten ernaartoe is 18 px gutter,
   twee rails van 18, 9 px bays, 11 px inner, 96 px voor
   PEEK en UID, 11 px links en de lampjes met hun tussenruimte. Er valt aan
   die 96 px niets te winnen: de twee knoppen meten samen met hun tussenruimte
   en de 13 px vanaf de rand al 88 px.

   Twee regels dus, en niet de knoppen eronder: dat maakte de blade 20 px
   hoger in plaats van 13, en de kast op een telefoon is al lang.

   Regelafstand 1,35 in plaats van de 1,6 van de pagina. Bij 1,6 staan twee
   regels van een titel te los uit elkaar om als één titel te lezen, en de
   blade wordt er onnodig hoog van. */
@media (max-width: 480px) {
  /* PEEK en UID vervallen op een telefoon. De inkijk is daar een venster van
     ongeveer 330 px tekst in dezelfde letter als het artikel, afgekapt op
     twaalf regels: even breed als doorklikken, minder inhoud, en een knop om
     er weer uit te komen. Op een breed scherm is dat wel iets anders dan
     doorklikken, dus boven 480 px blijven ze staan.

     Dit draait de reden om waarmee PEEK het QR-label verving: dat was op
     smalle schermen verborgen en daarmee de inkijk onbereikbaar. Het verschil
     is dat het QR-label onleesbaar was, terwijl PEEK leesbaar maar overbodig
     is. Verbergen met display, en op .bl-slot .bl-btns, want dáár staat
     display: flex en een regel met minder klassen komt daar niet overheen.

     Er komt 85 px vrij: de titel gaat van 134 naar 219 px op een venster van
     430, dus ongeveer 27 tekens per regel en 54 over twee regels.

     Het verbergen zelf staat niet hier maar in hoofdstuk 17, direct onder de
     regel die `display: flex` zet. Hier stond het eerst, en toen won die
     latere regel: even specifiek, dus de laatste in het bestand. */
  .blade { align-items: start; padding-top: 7px; padding-bottom: 7px; padding-right: 11px; }
  .blade .ti {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
    white-space: normal; line-height: 1.35; font-size: 10.5px;
    /* Altijd twee regels hoog, ook bij een korte titel. Een blade is 1U en
       blijft dat, of er nu veertig tekens op staan of tien; anders zit er een
       kast in met sleuven van verschillende hoogte. In em en niet in px, dan
       volgt de hoogte de lettergrootte vanzelf als die ooit weer verandert:
       2 x 1,35. */
    min-height: 2.7em;
  }
  /* 10,5 px en niet 13,5. In vier stappen gegaan: 12,5, 12, en na een
     preview met vier maten naast elkaar 10,5. Dat geeft 34 tekens per regel,
     dus 68 over de twee regels, tegen 27 bij de oorspronkelijke maat.

     Let op bij een volgende wijziging: de titel is hiermee even groot als de
     chassiskop erboven (10 px) en maar twee stappen van de sensorstrip
     (8,5 px). De hiërarchie op een blade hangt daarmee aan kleur en plaats en
     niet meer aan grootte. Valt dat tegen, dan is de weg terug de kop
     verkleinen en niet de titel vergroten, want die 34 tekens zijn hier de
     hoofdzaak. */
  /* De lampjes staan met align-items: start tegen de bovenrand en dan naast
     de bovenkant van de eerste letter in plaats van naast de regel. Een halve
     regelhoogte min een halve lamp zet ze op het midden van de eerste regel:
     (14,2 - 7) / 2. */
  .blade .leds { padding-top: 3.5px; }
}

/* De switch en de kabelgeleider op een telefoon. Samen ongeveer 95 px minder
   bovenaan de voorpagina.

   De kabelgeleider liep de doos uit, en dat was een fout: `.fingers` stond op
   `flex: 1` zonder `min-width: 0`, dus de 22 vingers van samen 282 px krompen
   niet terwijl er maar 274 px is. Wat niet paste duwde het rechterlabel naar
   buiten. Nu mogen ze krimpen en wordt wat niet past afgesneden, zoals bij
   een echte geleider die breder is dan het zicht.

   Uit de switch verdwijnen de poortspecificatie en STATUS OK. Dan past de
   kopregel op één regel in plaats van twee, en STATUS OK zei hetzelfde als de
   groene lampjes drie millimeter lager. Het aantal poorten blijft 48: een
   switch die zich in het colofon 48x10G noemt en er twaalf toont, is precies
   het soort claim dat hier niet hoort. Ze worden alleen kleiner. */
@media (max-width: 480px) {
  /* De labels op de twee units van 10 naar 9 px. Sinds de switch geen twee
     regels meer heeft, was `tor-k3-01 · UPTIME 2551d` het zwaarste op de
     bovenkant van de kast, terwijl het opschrift op apparatuur is. Daarmee
     staan er drie lagen: de omgeving eromheen op 8,5, de opschriften op
     apparatuur op 9, en de chassiskop op 10, want die noemt een categorie met
     48 berichten en is dus inhoud. */
  .tor .lbl, .cablemgr .lbl { font-size: 9px; }
  .tor .spec, .tor .st { display: none; }
  .tor .ports { gap: 5px; }
  .tor .prow { gap: 1px; }
  .tor .p { width: 7px; height: 6px; }
  .tor .p i { left: 1.5px; top: 1px; width: 2.5px; height: 2.5px; }
  .cablemgr .lbl { white-space: nowrap; }
  /* Het aantal vezels staat als strengen boven de geleider al in beeld. */
  .cablemgr .lbl:last-child { display: none; }
  .cablemgr .fingers { min-width: 0; overflow: hidden; }
}

/* ============================================================
   12. Artikel als manpage (single.php)
   Het scherm in de kast. Kop- en voetregel met de slug en (8),
   sectiekoppen in mono-groen, de sectie-inhoud ingesprongen.
   De lopende tekst staat in monospace; dat is getoetst met het
   langste bericht en blijft zo. Eén variabele: --man-font.
   ============================================================ */

:root {
  --man-font: var(--font-mono); --man-col: 760px;
  /* De kolommen van de kast. Alles wat eronder in de rails hoort te staan
     lijnt hierop uit, zodat 1U-apparatuur niet buiten de rails uitsteekt. */
  --rail-w: 30px; --pdu-w: 26px; --bay-pad: 9px;
  /* Binnen het scherm van de kast: donkerder dan de pagina, met een groenige
     tekstkleur. Uit het ontwerpmodel, en sinds alpha148 drie stappen lichter
     (#0a0f12 was te zwart naast de kast). Het glas moet donkerder blijven dan
     de pagina (#101215): gelijk maakt het scherm vlak, lichter laat het lezen
     als een vel dat op de kast ligt in plaats van iets wat erin zit. */
  --glass: #0d1216; --glassline: #1b2228; --grule: #1d2a26;
}

/* Het artikel is één kolom van tachtig kolommen breed, gecentreerd in de
   pagina. De kolom van 1120 px is van de krant; de lopende tekst stopt bij
   78 tekens en dan blijft rechts een lege helft over. Kop- en voetregel,
   titel, tekst en codeblokken delen nu dezelfde maat, zoals een terminal
   dat ook doet. Eén getal om aan te draaien: --man-col. */
/* De contactregel en de berichtnavigatie staan onder de bezel en lijnen uit
   met de rand daarvan. Sinds het artikel net zo breed is als rack, boot log en
   colofon lopen ze dus door tot de sheet, niet tot de oude kolom van 760 px:
   uitlijnen op iets wat er niet meer staat leest als een fout. De leesregel
   zelf blijft beschermd door de 78 tekens op .man-body p. */

.man { padding: 26px 0 0; }

.man-hdr, .man-ftr {
  display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 500;
  letter-spacing: .08em; color: var(--dim);
}
.man-hdr { border-bottom: 1px solid var(--line-2); padding-bottom: 16px; }

/* De sprong naar het vorige en volgende bericht, op de plek waar de
   sectieverwijzing stond. De kopregel houdt daarmee zijn driedeling uit de
   manpage en er komt geen knoppenbalkje in het midden bij. Gedempt als de rest
   van de regel: het is een uitgang, geen aanbeveling. */
.man-hdr a { color: var(--dim); text-decoration: none; white-space: nowrap; }
/* De driehoekjes staan in deze letter net onder het midden van de hoofdletters
   ernaast. Eén pixel omhoog zet ze op dezelfde optische hoogte als PREV en
   NEXT. Een aparte cursieve stijl hoort er niet bij, vandaar font-style. */
.man-hdr .ar { position: relative; top: -1px; font-style: normal; }

/* In de inkijk niet. Daar staat previous en next al in de voetregel, een halve
   handbreedte lager, en dan zeggen twee paren hetzelfde. Op het artikel zelf
   zit er een heel artikel tussen boven en onder en is het geen herhaling maar
   een tweede ingang. De voetregel is bovendien de plek waar de muis al ligt:
   die is met opzet stil gehouden bij het doorklikken. */
.peek .man-hdr a { display: none; }
.man-hdr a:hover, .man-hdr a:focus-visible { color: var(--acc); text-decoration: none; }
.man-ftr { border-top: 1px solid var(--line-2); margin-top: 30px; padding-top: 11px; }

.man-title {
  font-family: var(--font-mono); font-size: 22px; font-weight: 700;
  line-height: 1.35; letter-spacing: 0; color: var(--hd); margin: 18px 0 6px;
}
.man-meta { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em; color: var(--dim); margin: 0 0 4px; }
.man-meta a { color: inherit; }

/* Sectiekoppen en inspringing. Alles springt in behalve de
   sectiekoppen zelf, zoals bij een echte manpage. De dubbele klasse
   .entry-content.man-body is nodig om de krantregels op p, pre en
   figure te overstemmen; pre heeft daarbovenop !important nodig. */
.entry-content.man-body { padding: 4px 0 0; }
.entry-content.man-body > * { margin-left: 26px; }
.entry-content.man-body > pre { margin-left: 26px !important; max-width: 690px; }
/* Een tabel stond als enige tegen de kantlijn van de sectiekop in plaats van
   ingesprongen bij de rest. Oorzaak: .entry-content figure.wp-block-table zet
   zijn marge met een afkorting, en die zet de linkermarge weer op nul; die
   regel is specifieker dan de algemene inspringing hierboven. Lijsten en
   citaten hebben dit niet, want daar wint de algemene regel wel. */
.entry-content.man-body > figure.wp-block-table { margin-left: 26px; }
/* 690 px is 80 kolommen JetBrains Mono op 13,5 px plus de binnenmarge van
   het blok. Zonder deze maat lopen de codeblokken tot de rand van de pagina
   terwijl de lopende tekst bij 78 tekens stopt, en dat zijn twee kolommen
   in één artikel. Regels die er niet in passen schuiven zoals voorheen. */
.entry-content.man-body > h2.man-sec { margin-left: 0; }
.man-body h2.man-sec {
  font-family: var(--font-mono); font-size: 12.5px; font-weight: 700;
  letter-spacing: .16em; color: var(--acc);
  margin-top: 30px; margin-bottom: 8px; padding-bottom: 0; border-bottom: 0;
}
.man-body > h2.man-sec:first-child { margin-top: 22px; }

/* Lopende tekst: mono, links uitgelijnd, regelbreedte van een terminal. */
.man-body p, .man-body li {
  font-family: var(--man-font); font-size: 13.5px; line-height: 1.75;
}
/* 92ch en niet 78ch, in de maat van de artikelletter zelf. Zonder deze twee
   regels mee te verhogen wordt de kolom wel breder maar de tekst niet, want
   de alinea houdt dan zijn eigen maximum aan. */
.man-body p { text-align: left; hyphens: manual; -webkit-hyphens: manual; max-width: 92ch; }
.man-body li { max-width: 88ch; }

/* Subkoppen binnen een sectie: kleiner mono, ingesprongen. De marge alleen
   boven en onder zetten, niet als afkorting, anders wist die de inspringing
   van .entry-content.man-body > * en staat zo een kop tegen de kantlijn
   alsof hij een sectienaam is. */
.man-body h2:not(.man-sec), .man-body h3 {
  font-family: var(--font-mono); font-size: 14px; font-weight: 700;
  letter-spacing: .06em; color: var(--hd);
  margin-top: 24px; margin-bottom: 8px; padding-bottom: 0; border-bottom: 0;
}
.man-body h4 { font-family: var(--font-mono); }

/* Koppen zonder eigen regel vielen terug op de standaard van de browser: een
   h1 in een berichttekst werd twee keer de basisgrootte en sprong door het
   artikel heen. Alle zes de niveaus krijgen daarom dezelfde subkopstijl; een
   sectienaam is een h2 met .man-sec en heeft zijn eigen regel hierboven. */
.man-body h1, .man-body h5, .man-body h6 {
  font-family: var(--font-mono); font-size: 14px; font-weight: 700;
  letter-spacing: .06em; color: var(--hd);
  margin-top: 24px; margin-bottom: 8px; padding-bottom: 0; border-bottom: 0;
}

/* De lettergrootteklassen van de blokeditor. Twaalf van de 52 berichten dragen
   er een, uit de tijd van het vorige thema, en binnen een manpage zetten ze
   hele alinea's op 22 px terwijl de rest op 13,5 px staat. Dat breekt ook de
   inkijk, want die rekent met regels van 13,5 px.

   Met !important, en dat is hier geen luiheid: WordPress zet deze klassen zelf
   met !important, dus een gewone regel verliest hoe specifiek hij ook is. Dat
   is precies waarom de eerste poging in alpha160 niets deed. Het blijft krap
   gehouden tot .man-body, dus alleen de tekst van een artikel of pagina; een
   maat in de opmaak van een bericht zelf wordt hier niet door geraakt.
   Terugdraaien is deze regel schrappen; aan de berichten verandert niets. */
.man-body .has-small-font-size,
.man-body .has-medium-font-size,
.man-body .has-large-font-size,
.man-body .has-huge-font-size { font-size: 13.5px !important; }
.man-body blockquote { font-family: var(--man-font); }
.man-body blockquote p { text-align: left; }

.man-see-also a { color: var(--acc); }

/* Contactregel en berichtnavigatie horen bij het artikel, dus ze gaan mee
   in monospace. De cursieve schreefletter en de displaykop van 20 px komen
   uit de krant en vallen naast een manpage meteen uit de toon. */
/* Op de body-klasse en niet op de buurschap met .man: het artikel zit in de
   bezel en de contactregel en berichtnavigatie staan daarbuiten, dus ze zijn
   geen broer of zus van .man en die selectors pakten niets. Daardoor stond
   onderaan een artikel nog steeds de krantopmaak. */

/* De NAME-regel draagt zonder handle de hele slug, en die kan lang zijn.
   Afbreken op een streepje in plaats van de kolom uitduwen. */
.man-body p.man-name { overflow-wrap: anywhere; }

/* Knipperende cursor in de voetregel. */
.man-ftr .cur {
  display: inline-block; width: 8px; height: 13px; vertical-align: -2px;
  background: var(--acc); animation: vbp-cur 1.1s steps(1) infinite;
}
@keyframes vbp-cur { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .man-ftr .cur { animation: none; } }

@media (max-width: 760px) {
  .entry-content.man-body > * { margin-left: 12px; }
  .entry-content.man-body > pre { margin-left: 12px !important; }
  .entry-content.man-body > figure.wp-block-table { margin-left: 12px; }
  /* De rechterkant van de kopregel stond hier op display:none uit de tijd dat
     daar de sectieverwijzing VMWARE(8) in stond; die mocht op een telefoon
     wijken. Sinds alpha161 zit NEXT in diezelfde span, en dan verdween op een
     telefoon de helft van de navigatie terwijl PREV bleef staan. PREV, het
     midden en NEXT meten samen ongeveer 250 px en er is er 308. */
  .man-title { font-size: 19px; }
}

/* ============================================================
   13. De prompt in het boot log
   Een echte invoerregel in plaats van de vaste regel "read _".
   Het invoerveld is kaal gemaakt zodat het niet als formulier
   leest maar als de regel waar de cursor staat.
   ============================================================ */

.log-cli { display: flex; align-items: baseline; gap: 8px; margin-top: 4px; }
.log-cli .log-prompt { margin-top: 0; flex: none; cursor: text; }
.log-cli-in {
  flex: 1 1 auto; min-width: 0;
  font-family: var(--font-mono); font-size: 12.5px; line-height: 1.75;
  color: var(--tx); background: none; border: 0; padding: 0; margin: 0;
  outline: none; caret-color: transparent;
}
/* De knipperende blokcursor staat rechts van het veld en is dus alleen
   waar zolang er niets ingetypt is. Bij invoer schuift hij mee naar
   achteren, wat precies is wat een terminalcursor doet. */
.log-cli-in:focus { caret-color: var(--acc); }
.log-cli-in:focus + .bbs-cur { display: none; }

.log-out {
  font-family: var(--font-mono); font-size: 12.5px; line-height: 1.75;
  color: var(--dim); background: none; border: 0; padding: 0;
  margin: 10px 0; white-space: pre-wrap; overflow-x: auto;
}
.log-out:empty { margin: 0; }
.log-out .ok { color: var(--acc); }
.log-out .w  { color: var(--warn-ink); }

.log-hint { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; color: var(--dim-2); margin-top: 16px; }
.log-hintcmd {
  font: inherit; color: var(--acc); background: none; border: 0;
  padding: 0; cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
}
.log-hintcmd:hover { color: var(--ok-ink); }

/* ============================================================
   14. Het paarse scherm
   Verschijnt alleen als iemand psod, panic of crash typt in de
   prompt. Geen knop, geen link: het is een ei, geen functie.
   Kleuren naar een echte PSOD van ESXi 7.0: fel paars, witte
   tekst, gele kopregel, en geen balk erboven.
   ============================================================ */

.psod {
  position: fixed; inset: 0; z-index: 9999;
  background: #9b1fd4; color: #fff;
  font-family: var(--font-mono); font-size: 12px; line-height: 1.35;
  padding: 0; overflow: auto; cursor: pointer;
}
.psod pre {
  margin: 0; padding: 6px 10px 22px;
  font-family: inherit; font-size: inherit; line-height: inherit;
  color: #fff; background: none; border: 0;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.psod-hd { color: #ffe14d; font-weight: 700; }
.psod-back { padding: 0 10px 22px; color: #f0d9fb; font-size: 11.5px; }

@media (max-width: 760px) { .psod { font-size: 10.5px; } }

/* ============================================================
   15. Het ANSI-scherm als ei op de voorpagina
   Hetzelfde scherm als de 404, hier over de pagina heen. De
   opmaak van .bbs komt uit hoofdstuk 11 en wordt hergebruikt.
   ============================================================ */

.vbp-ansi-egg {
  position: fixed; inset: 0; z-index: 9998;
  background: rgba(0,0,0,.82);
  overflow: auto; padding: 26px 16px;
  display: flex; align-items: flex-start; justify-content: center;
}
.vbp-ansi-egg .bbs { width: 100%; max-width: 860px; }

/* Het naambordje knippert vanaf de vierde klik, zodat je merkt dat er iets
   gebeurt voordat het scherm verschijnt. */
.tagplate { cursor: default; transition: opacity .08s linear; }
.tagplate.blip { opacity: .5; }
@media (prefers-reduced-motion: reduce) { .tagplate { transition: none; } }

/* ============================================================
   16. UID-beacon, beheerbalk en KVM-lade
   ============================================================ */

/* De blade zit in een omhulsel zodat de UID-knop ernaast kan staan in
   plaats van erin; een knop in een anker is geen geldige HTML. */
.bl-slot { position: relative; }
.bl-slot .blade .rt { padding-right: 0; }
.bl-slot.dim { opacity: .28; }

.led.uid { background: var(--k-03); }
.bl-slot.uidon .led.uid {
  background: var(--uid); box-shadow: 0 0 7px rgba(var(--uid-rgb),.9);
  animation: vbp-uid 1s steps(1) infinite;
}
@keyframes vbp-uid { 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .bl-slot.uidon .led.uid { animation: none; } }

/* De twee knopjes staan in één rij rechts op de blade in plaats van elk op
   een eigen coördinaat. Zo lijnen ze vanzelf uit en houden ze onderlinge
   afstand, ook als er ooit een derde bij komt. */
.bl-slot .bl-btns {
  position: absolute; right: 13px; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; gap: 8px;
}
/* De twee knoppen delen één vorm. PEEK was tot alpha157 een QR-plaatje, maar
   dat leest op 16 px als een lichte vlek: een QR herken je aan drie
   zoekvierkanten en een onregelmatige vulling, en die passen daar niet in.
   Bovendien beloofde het iets om te scannen terwijl het een knop is, en op
   een telefoon was het label helemaal verborgen. */
.uidbtn, .peekbtn {
  font-family: var(--font-mono); font-size: 8.5px; letter-spacing: .12em;
  background: var(--k-06); color: var(--dim); border: 1px solid var(--k-13-ln);
  border-radius: 2px; padding: 2px 5px; cursor: pointer; line-height: 1.2;
  opacity: .45; transition: opacity .12s linear;
}
/* Niet verstoppen achter zweven: op een telefoon bestaat zweven niet en dan
   is de knop onbereikbaar. Gedempt zichtbaar, vol bij aandacht. */
.bl-slot:hover .uidbtn, .uidbtn:focus-visible, .bl-slot.uidon .uidbtn,
.bl-slot:hover .peekbtn, .peekbtn:focus-visible { opacity: 1; }
.peekbtn:hover { color: var(--acc); border-color: var(--acc); }
.bl-slot.uidon .uidbtn { color: var(--uid-ink); border-color: var(--uid); }

/* Allebei weg op een telefoon; de blade krijgt die 85 px voor de titel. De
   afweging staat bij de blade-regels in hoofdstuk 11. Deze regel moet hier
   staan en niet daar: `display: flex` hierboven is even specifiek, dus alleen
   een latere plaats in het bestand wint. */
@media (max-width: 480px) {
  .bl-slot .bl-btns { display: none; }
}

/* De light show laat het rack even los van de vaste ritmes. */
.rack.lightshow .led.act { animation-duration: .4s; }

/* De beheerbalk staat binnen de rails, tussen de KVM-lade en de voedingen:
   de Onboard Administrator is in een echte kast ook een module en geen los
   kastje ernaast. Geen eigen marge dus, .bays regelt de tussenruimte. */
/* De prompt staat vast en beweegt niet mee met de lengte van de melding.
   Zelfde besluit als in het boot log: verspringt de regel bij elke actie, dan
   lees je de verspringing in plaats van wat er staat. Poorten en prompt staan
   links vast, de knoppen tegen de rechterkant, en alleen de melding groeit de
   lege ruimte in. Past hij niet, dan kapt hij af met een beletsel in plaats
   van de knoppen weg te duwen: die moeten bereikbaar blijven. */
.oabar {
  box-shadow: 0 2px 5px rgba(var(--shadow-rgb),var(--drop));
  display: flex; justify-content: flex-start; align-items: center; gap: 14px;
  flex-wrap: wrap; margin: 0; padding: 7px 12px;
  background: linear-gradient(180deg,var(--oabar-top),var(--k-08)); border: 1px solid var(--k-11-ln); border-radius: 2px;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em;
}
.oaprompt { color: var(--ok-ink); flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.oaprompt #vbp-oaline { color: var(--dim); }
.oabtns { display: flex; gap: 7px; flex-wrap: wrap; margin-left: auto; flex: 0 0 auto; }
.oabtns button {
  font: inherit; letter-spacing: .1em;
  background: var(--k-06); color: var(--dim); border: 1px solid var(--k-13-ln);
  border-radius: 2px; padding: 3px 8px; cursor: pointer;
}
.oabtns button:hover, .oabtns button:focus-visible { color: var(--acc); border-color: var(--acc); }

/* Onder 480 px passen de knoppen niet meer naast de melding: samen zijn ze
   297 px en is de balk van binnen 312. Ze vallen dan naar een eigen regel, en
   daar duwde `margin-left: auto` ze nog steeds tegen de rechterkant, met een
   gat van 36 px links. Die marge is voor de ene regel bedoeld, niet voor twee.
   Op een eigen regel gecentreerd: de vier knoppen zijn samen één ding en er is
   geen kolom om links op uit te lijnen, want de melding erboven begint bij de
   kantlijn en de knoppenrij vult die bijna helemaal. */
@media (max-width: 480px) {
  .oabtns { margin-left: 0; width: 100%; justify-content: center; }
  /* Het beletsel is er voor de desktop, waar de melding ruimte moet laten aan
     de knoppen ernaast. Hier staat ze alleen op haar regel en is er niets om
     voor te wijken, terwijl er maar ongeveer 45 tekens op passen. De twee
     langste meldingen zijn 53 en tot 65 tekens, allebei UID, en die eindigden
     dus precies in een beletsel. Nu breken ze af. De balk wordt daarmee één
     regel hoger op het moment dat je zelf op een knop drukt; op dat moment
     kijk je naar de melding en niet naar de knoppen. */
  .oaprompt { white-space: normal; overflow: visible; text-overflow: clip; }
}

.kvm { margin: 0; }
.kvm-front {
  box-shadow: 0 2px 5px rgba(var(--shadow-rgb),var(--drop));
  width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 12px;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em;
  background: linear-gradient(180deg,var(--k-10) 0%,var(--k-08) 100%);
  border: 1px solid var(--k-11-ln); border-radius: 2px; padding: 8px 12px;
  color: var(--dim); cursor: pointer; text-transform: uppercase;
}
.kvm-front:hover, .kvm-front:focus-visible { border-color: var(--acc); color: var(--acc); }
.kvm-hint { color: var(--dim-2); }
.kvm.out .kvm-front { border-bottom-color: transparent; }
.kvm-body {
  border: 1px solid var(--k-11-ln); border-top: 0; border-radius: 0 0 2px 2px;
  background: var(--k-06); padding: 12px;
}
.kvm-body input[type="search"] {
  width: 100%; font-family: var(--font-mono); font-size: 12.5px;
  background: var(--k-02); color: var(--tx); border: 1px solid var(--k-11-ln);
  border-radius: 2px; padding: 8px 10px;
}
.kvm-body input[type="search"]:focus { outline: none; border-color: var(--acc); }
.kvm-hits { font-family: var(--font-mono); font-size: 10.5px; color: var(--dim-2); margin: 8px 0 0; }
.kvm-hits:empty { margin: 0; }

/* ============================================================
   17. De voordeur
   Open bij binnenkomst. Dicht is een geperforeerd paneel over
   de hele kast met een filtersticker linksonder.
   ============================================================ */

/* De melding staat boven en niet in het midden. De deur beslaat de hele kast,
   dus gecentreerd komt hij ergens halverwege een paneel van meer dan duizend
   pixels hoog te staan, ver van waar iemand binnenkomt. Bovenaan is hij het
   eerste wat je ziet en staat hij bij de bovenkant van de kast, waar ook het
   naambordje zit. */
.door {
  position: absolute; inset: 0; z-index: 5;
  display: flex; align-items: flex-start; justify-content: center;
  border: 1px solid var(--k-10-ln); border-radius: 3px;
  cursor: pointer; padding: 0;
  backdrop-filter: blur(1.5px); -webkit-backdrop-filter: blur(1.5px);

  background-color: transparent;
  box-shadow: inset 0 0 50px rgba(var(--shadow-rgb),.5);
}

/* Geperforeerd plaatstaal.

   Een echte rackdeur is 64 tot 80 procent open: dat is de eis waar
   garanties op apparatuur aan hangen, want daaronder krijgt de koude gang
   de lucht niet door de kast. De gaten zijn 3 tot 5 mm en staan
   verspringend, want alleen zo haal je dat open oppervlak zonder dat het
   staal ertussen te dun wordt om nog stijf te zijn.

   Terugval hieronder: één recht rooster, ongeveer 57 procent open. Dat
   werkt overal.

   Daaronder het verspringende patroon, en dit is nadrukkelijk niet
   opnieuw twee roosters over elkaar: dat leverde eerder een volledig dicht
   paneel op, omdat elk rooster zijn eigen plaat meebrengt en het staal van
   de een over de gaten van de ander valt. Hier is er één plaat staal, en
   twee maskerlagen bepalen samen waar de gaten zitten. Met
   mask-composite: intersect blijft het staal alleen staan waar beide lagen
   staal willen; een gat in een van de twee is dus een gat. Steek 8 px in
   alle richtingen, gat 6,7 px, ongeveer 64 procent open.

   Het plaatwerk zit op een pseudo-element en niet op de knop zelf, want een
   masker geldt ook voor de inhoud, en dan zouden de tekst, de greep en de
   filtersticker mee geperforeerd worden. */
.door::before {
  content: ""; position: absolute; inset: 0; z-index: 0; border-radius: 2px;
  background-image:
    radial-gradient(circle at 50% 50%, rgba(0,0,0,0) 0 3px, rgba(var(--k-door-rgb),.96) 3.4px);
  background-size: 7px 7px;
}

@supports ((mask-composite: intersect) or (-webkit-mask-composite: source-in)) {
  .door::before {
    background-image: none;
    background-color: rgba(var(--k-door-rgb),.96);
    -webkit-mask-image:
      radial-gradient(circle at 50% 50%, rgba(0,0,0,0) 0 3.35px, #000 3.65px),
      radial-gradient(circle at 50% 50%, rgba(0,0,0,0) 0 3.35px, #000 3.65px);
    mask-image:
      radial-gradient(circle at 50% 50%, rgba(0,0,0,0) 0 3.35px, #000 3.65px),
      radial-gradient(circle at 50% 50%, rgba(0,0,0,0) 0 3.35px, #000 3.65px);
    -webkit-mask-size: 8px 13.86px;
    mask-size: 8px 13.86px;
    -webkit-mask-position: 0 0, 4px 6.93px;
    mask-position: 0 0, 4px 6.93px;
    -webkit-mask-composite: source-in;
    mask-composite: intersect;
  }
}
/* De tekst en de sticker moeten boven het plaatwerk liggen, niet erachter. */
.door-txt, .door-grip, .filtersticker { position: relative; z-index: 1; }
/* Hetzelfde plaatje als boven de kast. De kast heeft precies één manier om
   iets te benoemen, namelijk een stalen plaat met een rand en twee schroeven,
   en dat is het naambordje K-3. Door de deur dezelfde plaat te geven is hij
   onderdeel van de kast in plaats van een paneel dat ervoor hangt. Wat er
   stond was een donker vlak op 82 procent dekking: geen rand, geen dikte en
   geen relatie tot het plaatstaal eronder.

   text-indent compenseert de letterafstand achter de laatste letter, anders
   staat de tekst een fractie links van het midden. Zelfde truc als op de
   tagplate.

   Twee andere richtingen zijn gebouwd en afgevallen. Een verzonken versie van
   het donkere vlak, met een schaduw binnenin: mooier dan wat er stond, maar
   het blijft een vlak zonder materiaal. En een dichte bovenstijl over de
   volle breedte, die bij het openen met de deur mee verdween en een gat
   achterliet op de zwaarste plek van de kast. Die stijl kon blijven staan als
   schakelaar, maar dan staat er 41 px permanent in beeld voor een deur die
   één keer per sessie dicht is, en dat is het tegendeel van wat er vandaag
   aan de bovenkant is weggehaald. */
.door-txt {
  margin-top: 18px; padding: 7px 30px; border-radius: 2px;
  background: linear-gradient(180deg,var(--k-13) 0%,var(--k-10) 55%,var(--k-08) 100%);
  border: 1px solid var(--k-14);
  text-shadow: 0 1px 0 rgba(var(--shadow-rgb),.6), 0 -1px 0 rgba(var(--sheen-rgb),.10);
  box-shadow: inset 0 1px 0 rgba(var(--sheen-rgb),.16), inset 0 -1px 2px rgba(var(--shadow-rgb),.4), 0 2px 6px rgba(var(--shadow-rgb),.45);
}
/* De schroeven, gelijk aan die op het naambordje. */
.door-txt::before, .door-txt::after {
  content: ""; position: absolute; top: 50%; margin-top: -4px;
  width: 7px; height: 7px; border-radius: 50%;
  background: radial-gradient(circle at 35% 32%,var(--k-17),var(--k-06));
  box-shadow: inset 0 0 2px rgba(var(--shadow-rgb),.8);
}
.door-txt::before { left: 10px; }
.door-txt::after { right: 10px; }
.door-txt { font-family: var(--font-mono); font-size: 11px; letter-spacing: .2em; text-indent: .2em; color: var(--k-27); }
.door:hover .door-txt, .door:focus-visible .door-txt { color: var(--acc); }
/* De greep als een echte greep: een rond profiel in plaats van een strook.
   Het verloop loopt over de breedte en niet over de hoogte, want dan vangt
   de linkerkant het licht en de rechterkant niet, en dat is wat een buis
   doet. Twee bevestigingspunten boven en onder, een schaduw eronder en een
   lichtlijn bovenop. Prominenter, maar niets dat oplicht of van kleur
   verandert: kleur betekent hier iets anders. */
.door-grip {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  width: 11px; height: 64px; border-radius: 6px;
  background: linear-gradient(90deg,var(--k-grip-1) 0%,var(--k-grip-2) 34%,var(--k-grip-3) 70%,var(--k-grip-4) 100%);
  box-shadow: 0 2px 5px rgba(var(--shadow-rgb),.55), inset 0 1px 0 rgba(var(--sheen-rgb),.24);
}
.door-grip::before, .door-grip::after,
.sidehandle .bar::before, .sidehandle .bar::after {
  content: ""; position: absolute; left: 50%; margin-left: -2.5px;
  width: 5px; height: 5px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--k-23), var(--k-09));
  box-shadow: inset 0 0 1px rgba(var(--shadow-rgb),.7);
}
.door-grip::before, .sidehandle .bar::before { top: 7px; }
.door-grip::after, .sidehandle .bar::after { bottom: 7px; }
.filtersticker {
  position: absolute; left: 14px; bottom: 14px;
  background: var(--k-28); color: var(--k-04-ink); border: 1px solid var(--k-airnote-ink);
  font-family: var(--font-mono); font-size: 8.5px; line-height: 1.45;
  letter-spacing: .04em; text-align: left; padding: 5px 8px; border-radius: 1px;
}
.filtersticker b { display: block; font-weight: 700; }

/* De handgreep aan de zijkant sluit de deur weer. Staat er alleen zolang de
   kast open is. */
/* Dezelfde plek als de greep op de dichte deur, zodat hij blijft staan
   terwijl de deur eromheen verschijnt en verdwijnt: het is één greep, geen
   twee knoppen. Het label staat absoluut onder de staaf en niet in een kolom
   ernaast, want anders schuift het de staaf omhoog en staat de greep in de
   open stand hoger dan in de dichte. */
.sidehandle {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  z-index: 6; display: block; background: none; border: 0; padding: 0; cursor: pointer;
}
.sidehandle .cap {
  position: absolute; top: calc(100% + 7px); left: 50%; transform: translateX(-50%);
}
.sidehandle .bar {
  width: 11px; height: 64px; border-radius: 6px; display: block; position: relative;
  background: linear-gradient(90deg,var(--k-grip-1) 0%,var(--k-grip-2) 34%,var(--k-grip-3) 70%,var(--k-grip-4) 100%);
  box-shadow: 0 2px 5px rgba(var(--shadow-rgb),.55), inset 0 1px 0 rgba(var(--sheen-rgb),.24);
  transition: filter .18s ease;
}
/* Bij zweven vangt hij iets meer licht. Zelfde keuze als op de blade: alleen
   helderheid, geen kleur. */
.sidehandle:hover .bar, .sidehandle:focus-visible .bar { filter: brightness(1.18); }
@media (prefers-reduced-motion: reduce) { .sidehandle .bar { transition: none; } }
.sidehandle .cap {
  font-family: var(--font-mono); font-size: 7.5px; letter-spacing: .12em;
  color: var(--dim-2); writing-mode: vertical-rl; white-space: nowrap;
}
.sidehandle:hover .cap, .sidehandle:focus-visible .cap { color: var(--acc); }

/* Achter een dichte deur valt er niets te klikken. */
.cab.shut .bays { pointer-events: none; }

@media (max-width: 760px) {
  /* De greep stond hier op display: none, zonder reden erbij. Dat maakte de
     twee standen ongelijk: dicht zie je wel een greep, want die zit op de
     deur zelf, en open niets meer. De enige weg terug was dan de knop DOOR
     onderin de balk, en die staat onderaan een kast van een paar schermen
     hoog.

     Wel opgeschoven, van 12 naar 4 px. De rails zijn hier 18 px in plaats
     van 30, en op 12 px stak de staaf van 11 px vijf pixels over de bays
     heen. Hij ligt nu netjes op de rail en pakt daar geen tik van een blade
     af. De greep op de dichte deur schuift mee, want die twee horen op
     dezelfde plek te staan. */
  .sidehandle { display: block; }
  .sidehandle, .door-grip { right: 4px; }
  .filtersticker { font-size: 7.5px; }
}

/* Het hidden-attribuut werkt via display:none uit de opmaak van de browser
   zelf, en elke eigen display-regel wint daarvan. Voor elk element dat hier
   een display krijgt en met hidden wordt gestuurd, moet dat dus expliciet
   terug. Zonder deze regel staat de deur er altijd. */
.door[hidden], .sidehandle[hidden], .oabar[hidden], .kvm-body[hidden] { display: none; }

/* ============================================================
   18. Stickers en serienummers
   De details die een kast een kast maken: een assetsticker per
   chassis en een serienummer per blade. Allebei aria-hidden:
   het is decor, geen inhoud.
   ============================================================ */

/* De handle op de voorkant van de blade, op de plek waar tot 1.6.43 een
   verzonnen serienummer stond. SN 0052 bestond nergens; de handle staat in
   _vbp_man_name, is de naam van het bericht in de manpage en staat ook in de
   NAME-regel van het artikel zelf. Decor vervangen door iets dat klopt.

   Groter en lichter dan het serienummer was, 11 px tegen 9 en var(--k-22) tegen
   var(--k-17): een serienummer mag wegvallen, een naam moet je kunnen lezen. De
   letterafstand gaat naar .02em, want een slug met streepjes valt uit elkaar
   zodra je er ruimte tussen zet.

   aria-hidden blijft staan. De titel ernaast is de naam van de link; zou de
   handle meegelezen worden, dan begint elke blade met een reeks streepjes. */
.blade .sn {
  font-family: var(--font-mono); font-size: 11px; color: var(--k-22);
  letter-spacing: .02em; white-space: nowrap;
}

.asset {
  display: flex; align-items: center; gap: 7px;
  margin-top: 8px; padding-top: 7px; border-top: 1px dashed var(--k-11-ln);
}
.asset .code {
  height: 13px; width: 74px; opacity: .7;
  background: repeating-linear-gradient(90deg,
    var(--k-25) 0 1px, transparent 1px 2px, var(--k-25) 2px 4px,
    transparent 4px 5px, var(--k-25) 5px 7px, transparent 7px 9px);
}
.asset .no {
  font-family: var(--font-mono); font-size: 8.5px;
  color: var(--k-18-ink); letter-spacing: .1em;
}


@media (max-width: 760px) {
  .blade .sn { display: none; }
  .asset .code { width: 52px; }
}

/* ============================================================
   19. Patchkabels en onder in de kast
   Overgenomen uit het ontwerpmodel in plaats van opnieuw bedacht.
   ============================================================ */

/* De kabelbaan tussen de switch en de geleider. De negatieve marges laten
   de kabels net onder de switch beginnen en in de geleider verdwijnen. */
/* De bundel moet boven uit de poorten komen en onder in de geleider
   verdwijnen. Met de tussenruimte van 20 px tussen de onderdelen zweefde hij
   aan allebei de kanten, dus die ruimte wordt hier weggenomen: boven tot
   tegen de switch, onder tot óver de geleider heen. De geleider ligt met een
   hogere z-index bovenop, zodat de kabeluiteinden achter de vingers
   verdwijnen in plaats van erop te eindigen. */
/* De strook schuift 22 px onder de switch, en de switch ligt er met z-index
   overheen. Dat stuk van elke draad verdwijnt dus achter het front en de draad
   komt precies onder de onderrand tevoorschijn. Zonder die laag liep hij
   zichtbaar over het front heen; met de laag maar een kleinere overlap bleef
   er een gat tussen de rand en het begin van de draad, en dan zweven ze. */
.cabletray { display: block; width: 100%; height: 44px; margin: -22px 0 -30px; position: relative; z-index: 0; }
.cabletray path { fill: none; stroke-linecap: round; vector-effect: non-scaling-stroke; }

/* Onder in de kast. */
.leak {
  display: flex; align-items: center; gap: 8px; padding: 6px 12px 0;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em; color: var(--k-15);
}
.leak .strip {
  flex: 1; height: 3px; border-radius: 2px;
  background: repeating-linear-gradient(90deg, var(--k-leak-1) 0 10px, var(--k-leak-2) 10px 20px);
}
.leak b { color: var(--k-fiber); font-weight: 500; }

.floorwrap { position: relative; margin-top: 2px; }

.feet { display: flex; justify-content: space-between; padding: 0 16px; position: relative; z-index: 2; }
.feet i {
  display: block; width: 16px; height: 9px; position: relative;
  background: linear-gradient(180deg,var(--k-11),var(--k-06));
  border: 1px solid var(--k-13-ln); border-radius: 0 0 3px 3px;
}
.feet i::after {
  content: ""; position: absolute; left: 3px; right: 3px; top: 3px;
  height: 1px; background: rgba(var(--shadow-rgb),.6);
}

/* De borstelplaat ligt over de poten heen, als vloerdoorvoer. */
.brush {
  position: relative; z-index: 3; height: 16px; margin: 3px 10px 0;
  background: repeating-linear-gradient(90deg, var(--k-04) 0 2px, var(--k-02) 2px 4px);
  border: 1px solid var(--k-06-ln); border-radius: 2px;
}

.ground {
  display: flex; align-items: center; gap: 7px; padding: 8px 12px 0;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em; color: var(--k-15);
}
.ground .wire {
  width: 52px; height: 3px; border-radius: 2px;
  background: repeating-linear-gradient(90deg, var(--k-earth-1) 0 6px, var(--k-fiber-2) 6px 12px);
}

@media (max-width: 760px) {
  .cabletray { height: 30px; }
  .ground span:last-child, .leak span:first-child { font-size: 8px; }
}

/* ============================================================
   20. De PDU, vierde kolom in de kast
   Over de volle hoogte rechts, met de stroomsterkte verticaal,
   acht contactdozen waarvan zes bezet, en onderaan de noodstop.
   ============================================================ */

.pdu {
  background: linear-gradient(180deg,var(--k-06),var(--k-04));
  border-left: 1px solid var(--k-08-ln);
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 8px 3px;
}
.pdu .amp {
  font-family: var(--font-mono); font-size: 8.5px; color: var(--k-fiber);
  writing-mode: vertical-rl; transform: rotate(180deg); letter-spacing: .12em;
}
.pdu .sock {
  width: 12px; height: 8px; position: relative;
  background: var(--k-02); border: 1px solid var(--k-10-ln); border-radius: 1px;
}
.pdu .sock.live::after {
  content: ""; position: absolute; left: 3px; top: 2px;
  width: 3px; height: 3px; border-radius: 50%;
  background: var(--ok); box-shadow: 0 0 4px rgba(var(--ok-rgb),.8);
}
.pdu .cables { display: flex; flex-direction: column; gap: 3px; margin-top: 4px; }
.pdu .cables i { display: block; width: 12px; height: 3px; border-radius: 2px; }
.pdu .c-y { background: var(--k-earth-2); }
.pdu .c-r { background: var(--k-mcb); }
.pdu .c-b { background: var(--k-fiber-blue); }

/* De hoofdautomaat van de strip: een installatieautomaat met een hendeltje,
   wit kastje, en C16 als karakteristiek. Dat is wat er onderaan een rack-PDU
   zit. De rode noodstop die hier stond is een voorziening van de zaal, bij de
   deur, en hoort niet op een PDU. */
.mcb {
  margin-top: auto; display: flex; flex-direction: column; align-items: center;
  gap: 3px; padding-top: 8px;
}
.mcb .lever {
  width: 13px; height: 20px; border-radius: 1px;
  background: linear-gradient(180deg,var(--k-26) 0 42%, var(--k-06) 42%);
  border: 1px solid var(--k-21); box-shadow: 0 1px 3px rgba(var(--shadow-rgb),.7);
  position: relative;
}
/* Het hendeltje staat omhoog: ingeschakeld. */
.mcb .lever::after {
  content: ""; position: absolute; left: 50%; top: 3px; margin-left: -2px;
  width: 4px; height: 6px; border-radius: 1px; background: var(--k-09);
}
.mcb .cap { font-family: var(--font-mono); font-size: 6.5px; color: var(--k-18-ink); letter-spacing: .06em; }

@media (max-width: 760px) { .pdu { display: none; } }

/* ============================================================
   21. De kast binnen zijn eigen breedte houden
   Een kolom van 1fr in een grid krimpt niet onder de breedte van
   zijn inhoud, tenzij je dat expliciet toestaat. De bladetitels
   zijn lang, dus zonder deze regels duwen ze de kolom op, loopt
   de kast rechts uit zijn container, en lijkt alles eronder naar
   links geschoven. Elke schakel van kast tot titel heeft het nodig.
   ============================================================ */

.bays { min-width: 0; }
.chassis { min-width: 0; }
.chassis .inner { min-width: 0; }
.bl-slot { min-width: 0; }
.blade { min-width: 0; }
.bl-main { min-width: 0; }
.tor, .cablemgr { min-width: 0; }

/* ============================================================
   22. Wat in de rails hoort, en wat om de kast heen
   De voedingen en de KVM-lade zijn apparatuur en lijnen uit met
   de servers. De lekkagesensor, de vloer en de beheerbalk horen
   bij de kast zelf en houden de volle breedte.
   ============================================================ */

/* De voedingen en de KVM-lade staan nu binnen de rails, als vierde en vijfde
   onderdeel in de kast. Daarmee lijnen ze vanzelf uit met de chassis erboven
   en is er niets uit te rekenen. De eerdere poging met marges is daarmee
   vervallen. Buiten de kast blijven: de vloer eronder en de beheerbalk. */

/* De sticker op de switch: klein en dof. */
.vendor {
  position: absolute; right: 9px; bottom: 6px; z-index: 2;
  background: var(--k-24); color: var(--k-08-ink); border: 1px solid var(--k-airnote-line);
  font-family: var(--font-mono); font-size: 6px; letter-spacing: .04em;
  padding: 1px 4px; border-radius: 1px; opacity: .58;
}

@media (max-width: 760px) {
  .vendor { display: none; }
}

/* ============================================================
   23. Het colofon
   Dezelfde manpage-vorm als een artikel, met sectienummer (7)
   want dit is een beschrijving en geen beheertaak. Wat er nog
   staat is de POST-tabel; de capture en de grafiek zijn weg.
   ============================================================ */

.colophon .post-table { border-collapse: collapse; font-family: var(--font-mono); font-size: 12.5px; margin: 8px 0 6px 26px; }
.colophon .post-table td { padding: 1px 18px 1px 0; border: 0; }
.colophon .post-table .ok { color: var(--ok-ink); }
.colophon .post-table .w  { color: var(--warn-ink); }
.colophon .post-warn { color: var(--warn-ink); }

/* De capture-tabel, de uitkomstregel en de meetdatum zijn vervallen met de
   capture zelf, alpha156. */

/* De opmaak van de staafgrafiek is vervallen met de grafiek zelf, alpha101. */

@media (max-width: 760px) {
  .colophon .post-table { margin-left: 12px; }
  .colophon .axis { gap: 5px; font-size: 8.5px; }
}

/* ============================================================
   24. De bezel: het scherm in de kast
   Artikel, boot log en colofon zitten in een stalen omlijsting
   met statuslampjes, en daarbinnen in een glas met een eigen,
   donkerder achtergrond en fijne scanlijnen. Zonder dit zijn
   het drie donkere pagina's en ontbreekt de helft van de
   metafoor: het rack is de kast, dit is het scherm erin.
   ============================================================ */

/* De bovenrand is krapper dan de rest: boven de strook met de lampjes zit
   alleen deze rand, eronder de eigen ruimte van de strook. Waren ze allebei
   11 px, dan telt de onderkant dubbel en zakt de groep lampjes optisch onder
   het midden. Zijkanten en onderkant blijven op 11 px, zodat het glas zelf
   niet verschuift. */
.bezel {
  background: linear-gradient(180deg,var(--k-07),var(--k-04));
  border: 1px solid var(--k-09-ln); border-radius: 4px;
  padding: 7px 11px 11px; margin: 26px 0 0;
  box-shadow: 0 14px 34px rgba(var(--shadow-rgb),.5);
}
/* Alleen het artikel houdt de kolombreedte vast, zodat de tekst niet opnieuw
   hoeft te centreren. Het boot log heeft de volle breedte nodig voor zijn
   kolommen, en het colofon staat sinds 1.6.0-alpha135 net zo breed: die drie
   staan naast elkaar in het menu en een van de drie smaller leest als een
   fout. De lopende tekst blijft daar wel op 78 tekens staan. */
/* bezel-man wordt sinds alpha104 nergens meer gezet: eerst het colofon en nu
   ook het artikel staan op de volle breedte, gelijk aan rack en boot log. De
   regel blijft staan voor het geval een sjabloon de smalle kolom terug wil. */
.bezel-man { max-width: calc(var(--man-col) + 70px); margin-left: auto; margin-right: auto; }

/* De strook met de statuslampjes is de bovenkant van de omlijsting. Krap
   gehouden: hij draagt drie lampjes en drie woorden van 9 px, en alles wat
   daarboven of daaronder aan ruimte bij komt duwt het scherm naar beneden op
   drie pagina's tegelijk. */
.bleds {
  display: flex; gap: 14px; justify-content: flex-end; align-items: center; padding: 0 4px 7px;
}
/* Het kruisje rechts in de strook, waar een venster zijn sluitknop heeft. Het
   scherm sluiten is hier teruggaan naar de kast, dus het is een link naar de
   voorpagina en geen knop. Tot 1.6.44 had een artikel daar niets: de regel
   .back-rack onder de berichtnavigatie is in alpha118 uit de markup gehaald, en
   de menubalk was sindsdien de enige uitgang. Zelfde maat en plek als .peek-x,
   zodat het in de inkijk en op een artikel hetzelfde ding is. */
.bezel-x {
  margin-left: 6px; font-size: 15px; line-height: 1; color: var(--dim);
  text-decoration: none; padding: 0 2px;
}
.bezel-x:hover, .bezel-x:focus-visible { color: var(--acc); text-decoration: none; }
.bleds span {
  display: flex; align-items: center; gap: 5px;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .14em; color: var(--dim-2);
}

.glass {
  background: var(--glass); border: 1px solid var(--glassline); border-radius: 2px;
  /* 16 px boven, zodat de kopregel samen met de 16 px onder zich precies
     midden in zijn band staat. Was 22 om 11, en dan hing hij te hoog. */
  padding: 16px 24px 24px; position: relative; overflow: hidden;
  animation: vbp-poweron .9s ease-out both;
}
/* Scanlijnen. Heel licht: het moet een scherm suggereren, geen filter zijn. */
.glass::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(transparent 0 3px, var(--glaslijn) 3px 4px);
}
@keyframes vbp-poweron {
  0%   { opacity: 0; filter: brightness(2.4); transform: scaleY(.985); }
  18%  { opacity: 1; filter: brightness(1.8); }
  45%  { filter: brightness(.92); }
  100% { opacity: 1; filter: brightness(1); transform: none; }
}
@media (prefers-reduced-motion: reduce) { .glass { animation: none; } }

/* Binnen het glas zijn de scheidingslijnen groeniger dan op de pagina. */
.glass .man-hdr, .glass .man-ftr, .glass .man-sec { border-color: var(--grule); }
.glass .man-ftr { border-top-color: var(--grule); }
.glass .man { padding-top: 0; max-width: none; }

@media (max-width: 760px) {
  .bezel { padding: 7px; margin-top: 16px; }
  .glass { padding: 16px 14px 18px; }
}

/* ============================================================
   25. Sensorstrip en zijlabel
   Boven de kast een strook met de omgevingswaarden, en tegen de
   linkerkant het label dat in een gang vertelt waar je staat.
   ============================================================ */

/* Drie delen die de ruimte verdelen zetten het middelste niet in het midden:
   waar het uitkomt hangt af van hoe breed links en rechts toevallig zijn, en
   links staat hier meer. Met 1fr auto 1fr staat ROW K - CAB 3 - 42U wel echt
   in het midden van de balk, en dus recht onder het naambordje. Dezelfde
   oplossing als eerder bij de voetregel. */
.sensors {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px;
  background: var(--k-03); border: 1px solid var(--k-06-ln); border-bottom: 0;
  padding: 6px 12px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .08em; color: var(--dim);
}
.sensors > span:first-child { justify-self: start; }
.sensors .pdu-long { justify-self: end; text-align: right; }
/* De korte schrijfwijze van de stroomsterkte bestaat alleen op een telefoon.
   Twee spans met dezelfde twee waarden erin, en niet één span met stukjes die
   aan en uit gaan: dat laatste leverde losse spaties op bij de verkeerde
   toestand. De cijfers komen uit dezelfde twee variabelen, dus er is nog
   steeds één bron. */
.sensors .pdu-short { display: none; }
/* De schakelaar voor de zaalverlichting, achter de stroomsterkte. Hij is een
   knop en geen link: er verandert niets aan het adres. Het lampje toont de
   stand, niet de bestemming, want dat is wat een schakelaar in een zaal doet. */
.sensors .pwr { justify-self: end; display: inline-flex; align-items: center; gap: 10px; }
.sensors .pwr::before { content: ""; }
.lights {
  font: inherit; letter-spacing: .08em; color: var(--dim);
  background: none; border: 0; padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
}
.lights:hover, .lights:focus-visible { color: var(--acc); }
.lamp {
  width: 9px; height: 9px; border-radius: 50%; display: inline-block;
  background: var(--k-03); border: 1px solid var(--k-11-ln);
}
.lights[aria-pressed="true"] .lamp {
  background: #ffd76a; border-color: #e0b64f; box-shadow: 0 0 7px rgba(255,205,80,.85);
}

/* De strook blijft bovenin staan tijdens het scrollen, maar alleen waar er een
   scherm in de kast staat. Het rack doet sinds alpha130 mee: eerst stond het
   daar niet vast, met als argument dat het bordje bij de kast hoort en niet
   moet losraken, maar het bordje ís de bovenkant van de kast en dat die in
   beeld blijft klopt juist. Dezelfde kast op elke pagina, dus ook hetzelfde
   gedrag.

   Dit is de middenweg. De kast zelf laten scrollen is overwogen en afgewezen:
   scrollen in scrollen loopt vast met een muis, de sectie-index volgt dan het
   verkeerde vlak, en een lang artikel in een klein venster leest zwaarder dan
   gewoon doorscrollen. */
/* Het bordje plakt onder de menubalk. De hoogte daarvan wordt door rack.js
   gemeten en in --vbp-navh gezet, inclusief de beheerbalk van WordPress als
   die er staat. Die maat is drie keer geschat en drie keer net verkeerd: hij
   hangt af van de lettergrootte, van het aantal menu-items en van of je
   ingelogd bent. De 38 px hieronder is alleen de terugval zonder JavaScript,
   bewust aan de lage kant, want een overlap valt weg onder de dekkende balk
   en een kier niet. */
/* De bovenrand van de kast, dus de strook en het naambordje, blijft alleen
   staan waar er een scherm in de kast zit: op een artikel, het boot log en het
   colofon. Daar is de kast een lijst waar je doorheen scrolt.

   Op het rack niet. Daar is de kast een ding met een boven en een onder, en
   scroll je naar de voedingen, dan staat de bovenkant van de kast opeens vlak
   boven de onderkant ervan: 42U volgens de rails, een handbreedte in beeld.
   Dat is geprobeerd in alpha131 en meteen weer teruggedraaid.

   De menubalk staat wél overal vast. Die hoort niet bij de kast en lost op
   waar het om begonnen was: halverwege een lang artikel of een lange
   voorpagina kun je weg zonder eerst terug te scrollen.

   Sinds 19 september alleen nog op het artikel. Op het boot log en het
   colofon scrolt de bovenkant van de kast gewoon mee, net als op het rack:
   dat zijn allebei één lange lijst die je van boven naar beneden leest, en
   dan is een strook die blijft hangen meer een dak dan een oriëntatiepunt. */
.single .sensors { position: sticky; top: var(--vbp-navh, 38px); z-index: 5; }

.single .nameplate {
  position: sticky; top: calc(var(--vbp-navh, 38px) + var(--vbp-sensh, 26px)); z-index: 6;
}

/* Het naambordje blijft staan en niet de sensorstrip. De strook is drie
   groepen cijfers in drie kleuren en die permanent in beeld houden is druk;
   het bordje is grijs plaatstaal met één label, en het is letterlijk de
   bovenkant van de kast. Blijft dat staan, dan zie je dat je nog in het rack
   zit in plaats van dat er meetwaarden blijven meekijken. De temperatuur en de
   ampères scrollen gewoon weg: dat is sfeer, geen navigatie. */

/* De beheerbalk van WordPress zit al in de gemeten waarde verwerkt, dus deze
   regels gebruiken diezelfde variabele. Stonden ze op een vast getal, dan
   overrulden ze de meting: ze komen later in het bestand en zijn even
   specifiek, en dan wint het vaste getal. Precies daardoor plakte het bordje
   ingelogd op 70 px terwijl de balk op 87 eindigde, en schoof de bovenkant
   eronder weg. De getallen hieronder zijn alleen nog terugval zonder
   JavaScript. */
.admin-bar .single .nameplate, .admin-bar .nameplate { top: calc(var(--vbp-navh, 70px) + var(--vbp-sensh, 26px)); }
@media (max-width: 782px) { .admin-bar .nameplate { top: calc(var(--vbp-navh, 84px) + var(--vbp-sensh, 26px)); } }

@media (max-width: 760px) {
  /* Op een telefoon past die rij niet naast elkaar; dan gestapeld en
     gecentreerd, net als de voetregel daar. Het naambordje blijft daar ook
     niet staan: op een telefoon is elke vaste balk een hap uit het scherm.

     De menubalk blijft wél plakken, ook hier. Sinds de masthead weg is staat
     de naam alleen nog daar, en halverwege een artikel van negen minuten was
     er anders geen uitgang. Dat kost ongeveer 40 px; de strook en het bordje
     erbij zou op een scherm van 844 px op ruim 145 px uitkomen.

     De twee regels hieronder herhalen de paginaselector uit hoofdstuk 25.
     Zonder die herhaling wint daar `position: sticky`: een media query telt
     niet mee voor specificiteit, dus .single .sensors (0-2-0) wint van
     .sensors (0-1-0) ongeacht waar hij staat. Het gevolg was zichtbaar op de
     telefoon: de strook plakte op var(--vbp-navh) terwijl de menubalk daar
     toen niet stond, en in die kier van 40 px schoof de tekst achterlangs
     door. */
  .nameplate, .sensors,
  .single .sensors,
  .single .nameplate { position: static; }
  .sensors { grid-template-columns: auto auto; justify-content: center; }
  /* Eén regel in plaats van drie, van 66 naar 27 px. Wat vervalt is niet
     ingekort maar dubbel: ROW K en CAB 3 staan als K-3 op het naambordje een
     regel lager, en 42U staat aan weerskanten op de rails. De omgeving en de
     stroomsterkte staan nergens anders, want de PDU is hier verborgen, dus
     die blijven allebei staan. Samen ongeveer 306 px van de 394 op een
     telefoon van 430 px; onder 360 px valt het netjes op twee regels terug. */
  .sensors .loc, .sensors .pdu-long { display: none; }
  /* Alleen het lampje, net als ROW en CAB hierboven. Een lampje dat aan of uit
     is zegt het zelf; het woord kost 62 px die de strook niet heeft. De padding
     maakt er een aanraakvlak van 28 px van zonder dat het lampje groeit. */
  .lights .lights-txt { display: none; }
  .lights { padding: 6px; margin: -6px; }
  .sensors .pdu-short { display: inline; }
  .sensors .pdu-short::before { content: "\00B7"; margin-right: 10px; color: var(--dim-2); }
  .sensors > span:first-child,
  .sensors .pdu-short { justify-self: center; text-align: left; }
}
.sensors b { color: var(--k-25); font-weight: 500; }
.sensors .cold { color: var(--k-cold); }

.sidelabel {
  position: absolute; left: -30px; top: 96px; z-index: 4;
  writing-mode: vertical-rl; transform: rotate(180deg);
  background: var(--k-06); border: 1px solid var(--k-09-ln); color: var(--k-20-ink);
  font-family: var(--font-mono); font-size: 8.5px; letter-spacing: .22em;
  padding: 9px 4px;
}
/* Onder 900 px is er naast de kast geen ruimte meer voor een label. */
@media (max-width: 900px) { .sidelabel { display: none; } }
@media (max-width: 760px) { .sensors { font-size: 8.5px; } }

/* Het QR-servicelabel is vervallen in alpha157. De knop heet nu PEEK en deelt
   zijn vorm met UID; zie hoofdstuk 16. Hij blijft ook op een smal scherm
   staan, want verborgen was de inkijk op een telefoon onbereikbaar. */

/* ============================================================
   26. De inkijk
   Het servicelabel op een blade opent het bericht boven het rack,
   in dezelfde bezel als een echt artikel. De inhoud wordt van de
   artikelpagina zelf gehaald, dus er staat nooit een nagebouwde
   versie naast de echte.
   ============================================================ */

/* De inkijk is een kolom die precies het scherm vult, niet een blok met een
   gekozen hoogte dat toevallig past. Eerst stond het glas op 70vh en werd de
   rest erbij opgeteld: de ruimte boven, de rand van de bezel en de balk
   eronder. Die som klopte niet op elke vensterhoogte, en dan viel de
   voetregel met previous en next onder die balk. Nu begrenst de opmaak het:
   de overlay is zo hoog als het scherm, de doos mag niet groter, en het glas
   krijgt wat er overblijft. Een som die niet bestaat kan ook niet misgaan. */
.peek {
  position: fixed; inset: 0; z-index: 9997;
  background: rgba(0,0,0,.82);
  overflow: hidden;
  padding: clamp(16px, 5vh, 70px) 16px 16px;
  /* Een kolom, en niet een rij met max-height op de doos. Die grens werd op
     een laag venster genegeerd zodra de inhoud niet wilde krimpen, en dan viel
     de voetregel er alsnog onder. In een kolom is krimpen de basis van de
     opmaak: een item kan niet groter zijn dan de kolom waar het in staat. */
  /* Verticaal gecentreerd in plaats van tegen de bovenrand. Er staat dan boven
     en onder evenveel ruimte, op elke vensterhoogte, zonder dat er een getal
     gekozen hoeft te worden dat op het ene scherm klopt en op het andere niet.
     Op een laag venster verandert er niets: dan vult de inkijk de hoogte toch
     al en blijft alleen de marge over. */
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
/* Breder dan een artikel. De inkijk toont drie korte secties, en dan is de
   leesmaat van 78 tekens niet nodig; smal en hoog leest hier slechter dan
   breed en kort. */
.peek-box {
  /* 960 px breed: de tekstkolom van 700 px plus de sectie-index van 150 px met
     tussenruimte is 878, en met de randen van het glas en de bezel erbij kom je
     op ongeveer 950. Alles daarboven was lege ruimte rechts van de index. */
  width: 100%; max-width: min(960px, 100%);
  /* Groeien en niet alleen krimpen. Met flex: 0 1 auto werd de doos zo hoog
     als het bericht dat erin stond, en dan sprong de voetregel met previous en
     next bij elk volgend bericht naar een andere hoogte: je moest de muis
     verplaatsen om twee keer achter elkaar op previous te klikken. Nu vult de
     doos altijd de kolom, dus de knoppen staan bij elk bericht op dezelfde
     plek. Op een hoog venster stopt het glas op zijn maximum en blijft de
     hoogte daar constant. */
  flex: 1 1 auto; min-height: 0; max-height: min(100%, 700px);
  display: flex; flex-direction: column;
}
/* De hele keten moet meegroeien. Alleen de doos laten groeien hielp niet: de
   bezel bleef op zijn eigen inhoud staan, en de voetregel hangt aan de bezel.
   Dus groeit de bezel mee, en het glas daarbinnen ook. De begrenzing zit op de
   doos en niet op het glas, want anders blijft er onder het glas een strook
   staal over binnen een bezel die wel is opgerekt. */
.peek .bezel { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.peek .man-body p, .peek .man-body li { max-width: none; }
.peek .bezel { margin-top: 0; }
.peek-loading { font-family: var(--font-mono); font-size: 12.5px; color: var(--dim); margin: 0; }

.peek-foot {
  flex: 0 0 auto;
  display: flex; justify-content: space-between; align-items: center; gap: 14px;
  flex-wrap: wrap; margin: 12px 2px 0;
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .06em;
}
.peek-foot a { color: var(--acc); }
.peek-close {
  font: inherit; letter-spacing: inherit; color: var(--dim);
  background: none; border: 0; padding: 0; cursor: pointer;
}
.peek-close:hover, .peek-close:focus-visible { color: var(--acc); }

/* Binnen de inkijk is de kolom al door de bezel begrensd. */
.peek .man { max-width: none; padding-top: 0; }

/* Het sluitkruisje in de lampjesbalk, waar bij een venster de sluitknop hoort.
   De knop onder de bezel blijft staan voor wie doorscrollt. */
.peek-x {
  margin-left: 6px; font: inherit; font-size: 15px; line-height: 1;
  background: none; border: 0; padding: 0 2px; cursor: pointer; color: var(--dim);
}
.peek-x:hover, .peek-x:focus-visible { color: var(--acc); }

/* De voetregel van de inkijk is navigatie: vorige links, volgende rechts.
   Aan het begin of het eind van de reeks blijft de tekst staan maar dooft
   hij, zodat de regel niet inzakt en je ziet dat je aan het eind bent. */
.peek .man-ftr a { color: var(--acc); }
.peek .man-ftr a:hover, .peek .man-ftr a:focus-visible { color: var(--ok-ink); }
.peek .man-ftr .peek-end { color: var(--dim-2); }
.peek .man-ftr .cur { display: none; }

/* Elke inkijk even groot, en zonder schuifbalk. Zonder vaste hoogte springt
   het venster bij elke sprong naar een ander bericht; met een schuifbalk is
   het geen inkijk meer maar een tweede leesvenster. De tekst wordt daarom
   afgekapt op een vast aantal regels, zodat hij altijd past. */
.peek .glass {
  /* Geen eigen hoogte: het glas vult wat de bezel overlaat en krimpt mee als
     het venster lager wordt. De grens van 880 px staat op de doos, zodat de
     inkijk op een groot scherm een inkijk blijft en geen tweede leesvenster.
     Van 880 naar 700: de inkijk kapt de tekst toch af op wat er past, dus een
     lager venster betekent alleen iets eerder afkappen. Bij de meeste berichten
     zijn de secties al op voordat de ruimte op is, en dan stond er onderin een
     leeg vlak. */
  flex: 1 1 auto; min-height: 0;
  overflow: hidden;
  display: flex; flex-direction: column;
}

/* Afkappen per regelaantal. De titel en de NAME-regel mogen twee regels en
   SEE ALSO drie. Wat niet past eindigt met een beletsel en staat voluit in
   het artikel zelf.

   Het getal bij de beschrijving is alleen een terugval voor het geval er
   geen JavaScript is: rack.js meet de ruimte die overblijft en zet het
   regelaantal daarop. Zonder die meting vechten twee knoppen om dezelfde
   ruimte, de hoogte van het glas en het aantal regels, en dan valt er geen
   getal te kiezen dat voor alle 52 berichten klopt. */
.peek .man-title,
.peek .man-name,
.peek .man-see-also { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.peek .man-title { -webkit-line-clamp: 2; }
.peek .man-name { -webkit-line-clamp: 2; }
.peek .man-see-also { -webkit-line-clamp: 3; }
.peek .man-body > p:not(.man-name):not(.man-see-also) {
  display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;
  -webkit-line-clamp: 12;
}
.peek .glass > .man,
.peek .glass > .peek-loading { flex: 1 1 auto; display: flex; flex-direction: column; }
.peek .glass > .peek-loading { justify-content: center; text-align: center; }

/* De voetregel is navigatie en mag daarom nooit wegvallen. Zonder deze drie
   regels duwt te veel tekst hem het glas uit, en dan lijkt het alsof er geen
   previous en next zijn terwijl het één afgesneden regel is. De tekst is de
   laag die krimpt, de kop en de voetregel blijven staan. */
.peek .glass > .man { min-height: 0; }
.peek .man-body { flex: 1 1 auto; min-height: 0; overflow: hidden; }
.peek .man-ftr { margin-top: auto; flex: 0 0 auto; }

/* ============================================================
   27. De VM-weergave
   Dezelfde kast, andere labels. Alleen wat een VM-lijst anders
   maakt dan een bladelijst staat hier: de naam in monospace,
   want een VM-naam is een machinenaam, en de power state in de
   statuskleur die op het rack al online betekent. De kleuren
   van de lampjes blijven wat ze waren, want die betekenis ligt
   vast en verandert niet mee met een weergave.
   ============================================================ */

.rack.vmview .blade .ti {
  font-family: var(--font-mono); font-size: 12.5px; letter-spacing: -.01em; color: var(--k-29);
}
.rack.vmview .blade .sn { color: var(--k-20-ink); }
.rack.vmview .blade .rt { color: var(--dim); }
.rack.vmview .chead .lbl { letter-spacing: .12em; }
.rack.vmview .blade .rt .snap { color: var(--warn-ink); }

/* ============================================================
   28. AIRFLOW
   Blauw gaat er aan de voorkant in, amber komt er aan de
   achterkant uit. Dat zijn de enige twee kleuren die hier
   mochten: het zijn dezelfde tinten als de UID-beacon en het
   amber van herzien, maar ze staan nooit tegelijk met de
   lampjes aan dezelfde kant van de kast, dus ze botsen niet.
   Alles beweegt alleen zolang de knop aan staat, en niets
   beweegt bij prefers-reduced-motion: dan staan de stromen er
   wel, maar stil.
   ============================================================ */

.rack.airflow .chassis { box-shadow: 0 2px 5px rgba(var(--shadow-rgb),var(--drop)); position: relative; }
.rack.airflow .chassis::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  border-radius: 2px;
  background:
    linear-gradient(90deg, rgba(var(--uid-rgb),.16) 0%, rgba(var(--uid-rgb),.05) 22%, rgba(0,0,0,0) 46%),
    linear-gradient(270deg, rgba(var(--warn-rgb),.15) 0%, rgba(var(--warn-rgb),.05) 20%, rgba(0,0,0,0) 44%);
  animation: vbp-air 3.2s ease-in-out infinite;
}
@keyframes vbp-air {
  0%, 100% { opacity: .55; }
  50%      { opacity: 1; }
}

/* De pijltjes op de blindplaten wijzen de kant op waar de lucht heen gaat en
   pulseren mee. Zonder luchtstroom blijven het gewoon merktekens. */
.rack.airflow .blank { border-color: rgba(var(--uid-rgb),.5); color: var(--k-leak-dry); }
.rack.airflow .blank span { animation: vbp-airmark 3.2s ease-in-out infinite; }
.rack.airflow .blank span:last-child { animation-delay: .5s; }
@keyframes vbp-airmark {
  0%, 100% { opacity: .35; }
  50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .rack.airflow .chassis::before,
  .rack.airflow .blank span { animation: none; opacity: 1; }
}

/* Het bordje met de anekdote. Vergeeld papier, licht scheef noch versleten:
   slijtage leest op een scherm als vuil, en dat besluit staat vast. */
.airnote {
  display: flex; gap: 12px; align-items: flex-start;
  margin: 0 0 5px; padding: 11px 14px;
  background: var(--k-airnote-bg); border: 1px solid var(--k-airnote-edge); border-radius: 2px;
  color: var(--k-05); font-family: var(--font-mono); font-size: 11.5px; line-height: 1.55;
  box-shadow: 0 6px 16px rgba(var(--shadow-rgb),.4);
}
.airnote p { margin: 0; max-width: 78ch; }
.airnote b { letter-spacing: .06em; }
.airnote .pin {
  width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; margin-top: 4px;
  background: radial-gradient(circle at 35% 35%, var(--k-19), var(--k-12));
  box-shadow: 0 1px 2px rgba(var(--shadow-rgb),.5);
}
.airnote[hidden] { display: none; }

/* Een schakelaar die aan staat laat dat zien. De kleur is die van de balk
   zelf, groen, behalve bij UID: die zet blauwe beacons aan en draagt dus
   blauw. Zo zegt de knop hetzelfde als wat er in de kast gebeurt.

   Gevuld en niet omlijnd. Omlijnd waren aan en zojuist aangeraakt precies
   dezelfde twee eigenschappen, color en border-color op de accentkleur, en
   dan is een knop die uit staat niet te onderscheiden van een knop die aan
   staat. Op een telefoon valt dat het hardst op, want daar blijft de focus
   staan op de knop die je het laatst hebt ingedrukt. Dezelfde vorm als de
   filterchips in het boot log, waar aan ook gevuld is. */
.oabtns button[aria-pressed="true"] { background: var(--acc); border-color: var(--acc); color: var(--btn-tx); }
.oabtns button[data-oa="uid"][aria-pressed="true"] { background: var(--uid); border-color: var(--uid); color: var(--btn-tx); }

/* ============================================================
   29. Aansluitingen aan de voorkant
   Een consolelade heeft er in het echt één USB naast de greep;
   het echte aansluitwerk van een enclosure zit op de Onboard
   Administrator, waar de crashkar in gaat: VGA plus twee USB.
   Alles is decor en aria-hidden, want een poort die zou werken
   belooft iets wat er niet is. Dezelfde reden waarom het
   QR-label op de blade is vervallen.
   ============================================================ */

.usb {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 9px; flex: 0 0 auto;
  background: var(--k-04); border: 1px solid var(--k-13-ln); border-radius: 1px;
}
.usb i {
  display: block; width: 9px; height: 3px;
  background: var(--k-11); border-radius: .5px;
}
.kvm-front .usb { margin-left: 12px; }

.oaports { display: inline-flex; align-items: center; gap: 8px; margin-right: 12px; }
.oaports .vga {
  display: inline-flex; align-items: center; justify-content: space-between;
  width: 22px; height: 10px; padding: 0 2px;
  background: var(--k-04); border: 1px solid var(--k-13-ln);
  border-radius: 5px / 4px;
}
.oaports .vga i { display: block; width: 2px; height: 2px; border-radius: 50%; background: var(--k-11); }

@media (max-width: 760px) {
  /* Op een telefoon is de balk al krap; de poorten zijn het eerste dat mag
     wijken, want ze dragen geen informatie. */
  .oaports { display: none; }
}


/* ============================================================
   30. Lichtval per front
   Er lag al een verloop over de hele kast, maar dat maakt er
   één vlak van met lijnen erin. Plafondverlichting valt op elk
   front apart, schuin van linksboven, en dat is wat losse
   platen van elkaar scheidt. Dezelfde hoek als de sheen op het
   chassis (118 graden), zodat alles hetzelfde licht vangt.
   ============================================================ */

.tor, .cablemgr, .kvm-front, .oabar, .psu { position: relative; }
/* De switch ligt boven de vezelstrook, zodat de draden erachter verdwijnen in
   plaats van over het front te lopen. */
.tor { z-index: 2; }
.tor::after, .cablemgr::after, .kvm-front::after, .oabar::after, .psu::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: 2px;
  background: linear-gradient(118deg, rgba(var(--sheen-rgb),var(--glans-1)) 0%, rgba(var(--sheen-rgb),var(--glans-2)) 28%, rgba(255,255,255,0) 58%, rgba(var(--shadow-rgb),var(--schaduw-1)) 100%);
}
/* De inhoud van die fronten moet boven de lichtval blijven. */
.tor > *, .cablemgr > *, .kvm-front > *, .oabar > *, .psu > * { position: relative; z-index: 1; }
/* Uitzondering: wat zelf absoluut geplaatst is moet dat blijven. Deze regel
   zette de vendorsticker op relatief, waardoor hij van rechtsonder naar
   linksboven sprong en onder het label van de switch belandde. */
.tor > .vendor { position: absolute; right: 9px; bottom: 6px; z-index: 2; }

/* ============================================================
   31. De sectie-index naast het artikel
   De tekst stopt bij 78 tekens, en sinds het artikel de volle
   breedte heeft bleef daar rechts een lege strook over. Die
   krijgt hier een taak in plaats van dat de tekst breder wordt
   gemaakt: een register van de secties, dat meeloopt bij het
   scrollen en de sectie markeert waar je bent. Dat is ook wat
   man zelf biedt.

   Verschijnt pas vanaf twee secties (klasse has-index vanuit
   single.php) en verdwijnt op smalle schermen, waar de ruimte
   er niet is.
   ============================================================ */

/* De index staat naast de tekst en niet tegen de rechterrand. De tekstkolom
   is zo breed als de leesregel (78 tekens), dus met 1fr voor de tekst bleef er
   een gat van zo'n 200 px tussen de twee staan en plakte het register aan de
   rand. Nu krijgt de tekstkolom de breedte van zijn inhoud, met de leesregel
   als bovengrens, en volgt de index daar direct op. Wat overblijft valt rechts
   buiten, zoals een terminal ook links begint en stopt waar hij stopt. */
.man-cols.has-index {
  display: grid;
  /* 780 px: 26 px inspringing plus ongeveer 92 tekens JetBrains Mono van
     13,5 px. Dat is ruimer dan de 78 tekens waar de manpage-vorm op mikt, en
     dus een bewuste afweging: in een bezel van 1280 px oogde een kolom van
     700 px smal. In ch rekenen werkt hier niet, want die eenheid volgt de
     lettergrootte van de pagina en niet die van het artikel.

     Tekst en index staan links, met het overschot rechts. Let op: dit is
     eerder andersom besloten. Gecentreerd stond er links en rechts evenveel
     ruimte, en links uitlijnen was toen afgekeurd omdat het overschot van
     ongeveer 190 px aan één kant kwam te staan. Sinds de pagina van 1120 naar
     1280 px ging is dat overschot groter, en toch is links uitlijnen de keuze:
     het blok hing anders midden in een brede bezel te zweven. */
  grid-template-columns: minmax(0, 780px) 150px;
  justify-content: start;
  /* Niet helemaal tegen de linkerrand. Het overschot is ongeveer 270 px; een
     kwart daarvan komt links te staan, zodat het blok tussen de randen hangt
     in plaats van tegen de ene aan te plakken. De kop- en voetregel lopen wel
     gewoon van rand tot rand, dat is de manpage-vorm. */
  padding-left: 64px;
  gap: 28px;
}

.man-toc {
  position: sticky; top: 18px; align-self: start;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em;
}
.man-toc .t {
  color: var(--dim-2); border-bottom: 1px solid var(--grule);
  padding-bottom: 7px; margin-bottom: 9px;
}
.man-toc a {
  display: block; color: var(--dim); text-decoration: none;
  padding: 3px 0 3px 9px; border-left: 1px solid transparent;
}
.man-toc a:hover, .man-toc a:focus-visible { color: var(--ink); text-decoration: none; }
.man-toc a.on { color: var(--acc); border-left-color: var(--acc); }

@media (max-width: 860px) {
  .man-cols.has-index { grid-template-columns: 1fr; padding-left: 0; }
  .man-toc { display: none; }
}

/* De weg terug naar het rack stond hier als .back-rack onder de
   berichtnavigatie. Het element is in alpha118 uit de markup gehaald en de
   opmaak bleef staan; in 1.6.52 is die opgeruimd. De uitgang is nu het
   kruisje rechts in de lampjesstrook. */
