/* Bundled fonts (see vendor/LICENSES.md). No requests leave the Komari host. */
@font-face {
  font-family: 'Twemoji Country Flags';
  src: url('vendor/fonts/TwemojiCountryFlags.woff2?v=1.3.7') format('woff2');
  unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E0063, U+E0065, U+E0067, U+E006C, U+E006E, U+E0073-E0074, U+E0077, U+E007F;
  font-display: swap;
}
@font-face {
  font-family: 'Archivo Black';
  src: url('vendor/fonts/archivo-black-latin-400-normal.woff2?v=1.3.7') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Space Grotesk';
  src: url('vendor/fonts/space-grotesk-latin-400-normal.woff2?v=1.3.7') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Space Grotesk';
  src: url('vendor/fonts/space-grotesk-latin-500-normal.woff2?v=1.3.7') format('woff2');
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: 'Space Grotesk';
  src: url('vendor/fonts/space-grotesk-latin-700-normal.woff2?v=1.3.7') format('woff2');
  font-weight: 700;
  font-display: swap;
}

:root {
  --black: #000000;
  --white: #ffffff;
  --shadow: #000000;
  --bg: #f5f5f5;
  --card-bg: #ffffff;
  --text: #000000;
  --text-muted: #666666;

  --accent-yellow: #FFE600;
  --accent-red: #FF3333;
  --accent-blue: #0066FF;
  --accent-green: #00CC66;
  --accent-purple: #9B5DE5;

  --accent: var(--accent-yellow);
  --border-width: 4px;
  --shadow-offset: 6px;
  --space-step: 0.75rem;
}

/* === Colour schemes ===
   Light schemes only swap the accent. Dark schemes swap the "ink on paper" pair:
   --black is the ink (borders, text), --white is the paper (surfaces), so every
   inverted block (black bg + white text) stays inverted in dark mode too. */
:root {
  --on-accent: #000000;
  --accent-orange: #FF9F1C;
  --hatch: rgba(0, 0, 0, 0.15);
  --dots: rgba(102, 102, 102, 0.3);
  --grid-line: rgba(0, 0, 0, 0.12);
  --chart-label: #555555;
  /* Thin lines inside the latency strip. Light schemes: paper-coloured gutters, so cells read as
     clean tiles on any signal colour; dark schemes override with a softened ink tone. */
  --strip-line: var(--card-bg);
  --row-hover: rgba(255, 230, 0, 0.08);

  --sig-1: #00CC66;
  --sig-2: #8FD14F;
  --sig-3: #FFE600;
  --sig-4: #FF9F1C;
  --sig-5: #FF3333;

  --ping-1: #FF3333;
  --ping-2: #00A896;
  --ping-3: #9B5DE5;
  --ping-4: #0066FF;
  --ping-5: #F59E0B;
  --ping-6: #EC4899;
  --ping-7: #10B981;
  --ping-8: #F97316;

  --chart-cpu: #E0C900;
  --chart-ram: #9B5DE5;
  --chart-disk: #00A854;
  --chart-up: #00A854;
  --chart-down: #0066FF;
  --chart-conn: #FF3333;
  --chart-proc: #0066FF;
}

:root {
  --sig-text-1: #007A3D;
  --sig-text-2: #4A7A0C;
  --sig-text-3: #8A6500;
  --sig-text-4: #B04A00;
  --sig-text-5: #C81E1E;
}

[data-scheme="red-light"] { --accent: var(--accent-red); }
[data-scheme="blue-light"] { --accent: #0d6eff; }  /* #0066FF lifted a hair: black text 4.34 -> 4.69 */
[data-scheme="green-light"] { --accent: var(--accent-green); }
[data-scheme="purple-light"] { --accent: var(--accent-purple); }

[data-scheme$="-dark"] {
  color-scheme: dark;
  --black: var(--ink);
  --white: var(--paper);
  --card-bg: var(--paper);
  --text: var(--ink);
  --hatch: rgba(255, 255, 255, 0.12);
  --dots: rgba(255, 255, 255, 0.10);
  --grid-line: rgba(255, 255, 255, 0.10);
  --chart-label: var(--text-muted);
  --strip-line: color-mix(in srgb, var(--black) 40%, var(--card-bg));
  --row-hover: color-mix(in srgb, var(--accent) 10%, transparent);

  --sig-1: var(--accent-green);
  --sig-2: color-mix(in srgb, var(--accent-green) 55%, var(--accent-yellow));
  --sig-3: var(--accent-yellow);
  --sig-4: var(--accent-orange);
  --sig-5: var(--accent-red);

  --ping-1: var(--accent-red);
  --ping-2: var(--accent-cyan);
  --ping-3: var(--accent-purple);
  --ping-4: var(--accent-blue);
  --ping-5: var(--accent-yellow);
  --ping-6: var(--accent-pink);
  --ping-7: var(--accent-green);
  --ping-8: var(--accent-orange);

  --sig-text-1: color-mix(in srgb, var(--sig-1) 70%, var(--ink));
  --sig-text-2: color-mix(in srgb, var(--sig-2) 70%, var(--ink));
  --sig-text-3: color-mix(in srgb, var(--sig-3) 70%, var(--ink));
  --sig-text-4: color-mix(in srgb, var(--sig-4) 70%, var(--ink));
  --sig-text-5: color-mix(in srgb, var(--sig-5) 70%, var(--ink));

  --chart-cpu: var(--accent-yellow);
  --chart-ram: var(--accent-purple);
  --chart-disk: var(--accent-green);
  --chart-up: var(--accent-green);
  --chart-down: var(--accent-blue);
  --chart-conn: var(--accent-red);
  --chart-proc: var(--accent-cyan);
}

/* === Light palettes ===
   Same ink-on-paper mapping as the dark schemes, but on light paper. Values checked for
   WCAG >= 4.5:1 (body text, muted text, header text on the accent, tiered numbers). */
[data-scheme="solarized-light"],
[data-scheme="github-light"],
[data-scheme="gruvbox-light"],
[data-scheme="catppuccin-light"],
[data-scheme="tokyonight-light"] {
  --black: var(--ink);
  --white: var(--paper);
  --card-bg: var(--paper);
  --text: var(--ink);
  --shadow: var(--ink);
  --hatch: color-mix(in srgb, var(--ink) 16%, transparent);
  --dots: color-mix(in srgb, var(--ink) 22%, transparent);
  --grid-line: color-mix(in srgb, var(--ink) 12%, transparent);
  --chart-label: var(--text-muted);
  --row-hover: color-mix(in srgb, var(--accent) 12%, transparent);

  --sig-1: var(--accent-green);
  --sig-2: color-mix(in srgb, var(--accent-green) 55%, var(--accent-yellow));
  --sig-3: var(--accent-yellow);
  --sig-4: var(--accent-orange);
  --sig-5: var(--accent-red);
  --sig-text-1: color-mix(in srgb, var(--sig-1) var(--sig-text-mix), #000);
  --sig-text-2: color-mix(in srgb, var(--sig-2) var(--sig-text-mix), #000);
  --sig-text-3: color-mix(in srgb, var(--sig-3) var(--sig-text-mix), #000);
  --sig-text-4: color-mix(in srgb, var(--sig-4) var(--sig-text-mix), #000);
  --sig-text-5: color-mix(in srgb, var(--sig-5) var(--sig-text-mix), #000);

  --ping-1: var(--accent-red);
  --ping-2: var(--accent-cyan);
  --ping-3: var(--accent-purple);
  --ping-4: var(--accent-blue);
  --ping-5: var(--accent-yellow);
  --ping-6: var(--accent-pink);
  --ping-7: var(--accent-green);
  --ping-8: var(--accent-orange);

  --chart-cpu: var(--accent-yellow);
  --chart-ram: var(--accent-purple);
  --chart-disk: var(--accent-green);
  --chart-up: var(--accent-green);
  --chart-down: var(--accent-blue);
  --chart-conn: var(--accent-red);
  --chart-proc: var(--accent-cyan);
}

/* Solarized Light */
[data-scheme="solarized-light"] {
  --ink: #073642; --paper: #fdf6e3; --bg: #eee8d5; --text-muted: #48636b; --sig-text-mix: 75%;
  --accent: #bc9417; --on-accent: #073642;
  --accent-red: #dc322f; --accent-orange: #cb4b16; --accent-yellow: #b58900; --accent-green: #859900;
  --accent-cyan: #2aa198; --accent-blue: #268bd2; --accent-purple: #6c71c4; --accent-pink: #d33682;
}

/* GitHub Light (Primer) */
[data-scheme="github-light"] {
  --ink: #1f2328; --paper: #ffffff; --bg: #f6f8fa; --text-muted: #59636e; --sig-text-mix: 65%;
  --accent: #54aeff; --on-accent: #1f2328;
  --accent-red: #cf222e; --accent-orange: #e16f24; --accent-yellow: #d4a72c; --accent-green: #2da44e;
  --accent-cyan: #1b7c83; --accent-blue: #0969da; --accent-purple: #8250df; --accent-pink: #bf3989;
}

/* Gruvbox Light */
[data-scheme="gruvbox-light"] {
  --ink: #282828; --paper: #fbf1c7; --bg: #ebdbb2; --text-muted: #665c54; --sig-text-mix: 65%;
  --accent: #d79921; --on-accent: #282828;
  --accent-red: #cc241d; --accent-orange: #d65d0e; --accent-yellow: #d79921; --accent-green: #98971a;
  --accent-cyan: #689d6a; --accent-blue: #458588; --accent-purple: #b16286; --accent-pink: #b16286;
}

/* Catppuccin Latte */
[data-scheme="catppuccin-light"] {
  --ink: #4c4f69; --paper: #eff1f5; --bg: #e6e9ef; --text-muted: #5c5f77; --sig-text-mix: 65%;
  --accent: #8839ef; --on-accent: #eff1f5;
  --accent-red: #d20f39; --accent-orange: #fe640b; --accent-yellow: #df8e1d; --accent-green: #40a02b;
  --accent-cyan: #179299; --accent-blue: #1e66f5; --accent-purple: #8839ef; --accent-pink: #ea76cb;
}

/* Tokyo Night Day */
[data-scheme="tokyonight-light"] {
  --ink: #3760bf; --paper: #e9e9ed; --bg: #e1e2e7; --text-muted: #536194; --sig-text-mix: 80%;
  --accent: #2564ba; --on-accent: #e9e9ed;
  --accent-red: #f52a65; --accent-orange: #b15c00; --accent-yellow: #8c6c3e; --accent-green: #587539;
  --accent-cyan: #007197; --accent-blue: #2e7de9; --accent-purple: #7847bd; --accent-pink: #9854f1;
}

/* Deep accents (Catppuccin mauve, Tokyo Night Day blue) carry light header text, like the dark schemes. */
[data-scheme="catppuccin-light"] .header,
[data-scheme="tokyonight-light"] .header {
  --black: var(--on-accent);
  --text: var(--on-accent);
  --white: var(--ink);
  --shadow: var(--on-accent);
  color: var(--on-accent);
}

/* Tokyo Night (night) */
[data-scheme="tokyonight-dark"] {
  --ink: #c0caf5; --paper: #24283b; --bg: #1a1b26; --text-muted: #8690ba; --deep: #0d0e15;
  --accent: #7aa2f7; --on-accent: #1a1b26;
  --accent-red: #f7768e; --accent-orange: #ff9e64; --accent-yellow: #e0af68; --accent-green: #9ece6a;
  --accent-cyan: #7dcfff; --accent-blue: #7aa2f7; --accent-purple: #bb9af7; --accent-pink: #ff007c;
}

/* Dracula */
[data-scheme="dracula-dark"] {
  --ink: #f8f8f2; --paper: #282a36; --bg: #1e1f29; --text-muted: #8a95c9; --deep: #0e0f14;
  --accent: #ff79c6; --on-accent: #21222c;
  --accent-red: #ff5555; --accent-orange: #ffb86c; --accent-yellow: #f1fa8c; --accent-green: #50fa7b;
  --accent-cyan: #8be9fd; --accent-blue: #8be9fd; --accent-purple: #bd93f9; --accent-pink: #ff79c6;
}

/* Monokai (classic) */
[data-scheme="monokai-dark"] {
  --ink: #f8f8f2; --paper: #272822; --bg: #1e1f1c; --text-muted: #a59f85; --deep: #0c0c0a;
  --accent: #e6db74; --on-accent: #272822;
  --accent-red: #f92672; --accent-orange: #fd971f; --accent-yellow: #e6db74; --accent-green: #a6e22e;
  --accent-cyan: #66d9ef; --accent-blue: #66d9ef; --accent-purple: #ae81ff; --accent-pink: #f92672;
}

/* Nord */
[data-scheme="nord-dark"] {
  --ink: #eceff4; --paper: #3b4252; --bg: #2e3440; --text-muted: #aab4c7; --deep: #1b1f27;
  --accent: #88c0d0; --on-accent: #2e3440;
  --accent-red: #bf616a; --accent-orange: #d08770; --accent-yellow: #ebcb8b; --accent-green: #a3be8c;
  --accent-cyan: #8fbcbb; --accent-blue: #81a1c1; --accent-purple: #b48ead; --accent-pink: #b48ead;
}

/* Gruvbox (dark, hard) */
[data-scheme="gruvbox-dark"] {
  --ink: #ebdbb2; --paper: #282828; --bg: #1d2021; --text-muted: #a89984; --deep: #0b0c0c;
  --accent: #fe8019; --on-accent: #1d2021;
  --accent-red: #fb4934; --accent-orange: #fe8019; --accent-yellow: #fabd2f; --accent-green: #b8bb26;
  --accent-cyan: #8ec07c; --accent-blue: #83a598; --accent-purple: #d3869b; --accent-pink: #d3869b;
}

/* Catppuccin Mocha */
[data-scheme="catppuccin-dark"] {
  --ink: #cdd6f4; --paper: #1e1e2e; --bg: #181825; --text-muted: #9399b2; --deep: #0b0b12;
  --accent: #cba6f7; --on-accent: #1e1e2e;
  --accent-red: #f38ba8; --accent-orange: #fab387; --accent-yellow: #f9e2af; --accent-green: #a6e3a1;
  --accent-cyan: #94e2d5; --accent-blue: #89b4fa; --accent-purple: #cba6f7; --accent-pink: #f5c2e7;
}

/* Dark schemes: hard shadows take a dim tint of the accent so cards keep their offset depth. */
[data-scheme$="-dark"] {
  --shadow: color-mix(in srgb, var(--accent) 38%, var(--bg));
}

/* Dark schemes: the footer is an ink block in light themes; keep it a dark band here. */
[data-scheme$="-dark"] .footer {
  --black: var(--deep);
  --white: var(--ink);
}

/* Dark schemes: the accent-coloured header keeps dark ink on a bright accent, like the light themes. */
/* Header labels sit on the accent colour in every scheme: full on-accent ink (labels are set apart by
   size and tracking, not opacity - a translucent label fell below 4.5:1 in most schemes). */
.header {
  --text-muted: var(--on-accent);
}

[data-scheme$="-dark"] .header {
  --black: var(--on-accent);
  --text: var(--on-accent);
  --white: var(--ink);
  --shadow: var(--on-accent);
  color: var(--on-accent);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: 'Twemoji Country Flags', 'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
  background-color: var(--bg);
  color: var(--text);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

h1, h2, h3, h4, h5, h6 {
  font-family: 'Twemoji Country Flags', 'Archivo Black', sans-serif;
  text-transform: uppercase;
  letter-spacing: -0.02em;
}

/* Header */
.header {
  background-color: var(--accent);
  border-bottom: var(--border-width) solid var(--black);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  transition: transform 0.2s ease-out;
}

.header.hidden {
  transform: translateY(-100%);
}

.main {
  padding-top: calc(var(--header-height, 120px) + 1.5rem);
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.5rem;
  border-bottom: 3px solid var(--black);
}

.logo {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.logo-icon {
  font-size: 1.5rem;
  color: var(--black);
}

.logo h1 {
  font-size: 1.5rem;
  color: var(--black);
}

.header-controls {
  display: flex;
  gap: 0.5rem;
}

.btn-view {
  width: 44px;
  height: 44px;
  background: var(--white);
  border: 3px solid var(--black);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.1s ease, box-shadow 0.1s ease;
  box-shadow: 3px 3px 0 var(--shadow);
}

.btn-view:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 var(--shadow);
}

.btn-view:active,
.btn-view.active {
  transform: translate(3px, 3px);
  box-shadow: none;
  background: var(--accent);
}

.btn-view svg {
  color: var(--black);
}

.btn-admin {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  height: 44px;
  padding: 0 1rem;
  background: var(--black);
  color: var(--white);
  border: 3px solid var(--black);
  text-decoration: none;
  font-family: 'Twemoji Country Flags', 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  transition: transform 0.1s ease, box-shadow 0.1s ease;
  box-shadow: 3px 3px 0 var(--shadow);
}

.btn-admin:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 var(--shadow);
  color: var(--white);
}

.btn-admin:active {
  transform: translate(3px, 3px);
  box-shadow: none;
}

.btn-admin svg {
  color: var(--accent);
}

/* Stats Bar */
.stats-bar {
  display: flex;
  gap: 0;
  overflow-x: auto;
}

.header.hidden {
  transform: translateY(-100%);
}

.stat-item {
  flex: 1;
  min-width: 80px;
  padding: 1rem 1.5rem;
  border-right: 3px solid var(--black);
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

.stat-item:last-child {
  border-right: none;
}

.stat-value {
  font-family: 'Twemoji Country Flags', 'Archivo Black', sans-serif;
  font-size: 1.5rem;
  display: block;
  color: var(--black);
}

.stat-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--text-muted);
}

#stat-net-in,
#stat-net-out {
  line-height: 1;
  white-space: pre-line;
}

/* Main Content */
.main {
  flex: 1;
  padding: 1.5rem;
}

/* Nodes Container */
.nodes-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 1.5rem;
}

.nodes-container.list-view {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
  background: var(--card-bg);
  border: var(--border-width) solid var(--black);
  box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--shadow);
  position: relative;
  overflow-x: auto;
  overscroll-behavior-x: none;
}

/* Node Card */
.node-card {
  background: var(--card-bg);
  border: var(--border-width) solid var(--black);
  box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--shadow);
  padding: 1.25rem;
  transition: transform 0.1s ease, box-shadow 0.1s ease;
  position: relative;
}

.node-card:hover {
  transform: translate(-3px, -3px);
  box-shadow: calc(var(--shadow-offset) + 3px) calc(var(--shadow-offset) + 3px) 0 var(--shadow);
}

.node-card.offline {
  background-image: radial-gradient(circle, var(--dots) 1px, transparent 1px);
  background-size: 4px 4px;
  opacity: 0.9;
}

.node-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 1rem;
  padding-bottom: 0.75rem;
  border-bottom: 3px solid var(--black);
}

.node-name {
  font-family: 'Twemoji Country Flags', 'Archivo Black', sans-serif;
  font-size: 1.1rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.node-status {
  width: 12px;
  height: 12px;
  background: var(--accent-green);
  border: 2px solid var(--black);
  flex-shrink: 0;
  margin-left: 0.5rem;
}

.node-status.offline {
  animation: pulse 1s step-end infinite;
}

@keyframes pulse {
  0%, 100% { background: var(--accent-red); }
  50% { background: var(--black); }
}

.node-info {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-top: 0.25rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Metrics */
.metrics {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.metric {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.metric-header {
  display: flex;
  justify-content: space-between;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.metric-value {
  font-family: 'Twemoji Country Flags', 'SF Mono', 'Consolas', 'Monaco', 'Space Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
  display: inline-block;
  min-width: 3.5ch;
  text-align: right;
}

.metric-bar {
  height: 16px;
  background: var(--bg);
  border: 2px solid var(--black);
  overflow: hidden;
}

.metric-bar.net-bar {
  position: relative;
}

.metric-bar.net-bar .metric-fill {
  position: absolute;
  top: 0;
  height: 100%;
}

.metric-bar.net-bar .metric-fill.net-in {
  left: 0;
}

.metric-bar.net-bar .metric-fill.net-out {
  left: 0;
  z-index: 1;
}

.metric-bar.net-bar .metric-fill.net-in {
  z-index: 2;
}

.net-bar.unlimited {
  background-image: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 4px,
    var(--hatch) 4px,
    var(--hatch) 8px
  );
  background-color: var(--bg);
  border: 2px solid var(--black);
}

.net-totals {
  display: flex;
  justify-content: space-between;
  margin-top: 0.25rem;
  font-size: 0.7rem;
  font-weight: 700;
}

.net-total-item {
  color: var(--text-muted);
  font-family: 'Twemoji Country Flags', 'Space Grotesk', 'SF Mono', 'Consolas', 'Monaco', monospace;
  font-variant-numeric: tabular-nums;
}

.net-total-item:first-child {
  color: var(--accent-green);
}

.net-total-item:last-child {
  color: var(--accent-blue);
}

.metric-fill.net-in {
  background: var(--accent-green);
}

.metric-fill.net-out {
  background: var(--accent-blue);
}

.metric-fill.dimmed {
  opacity: 0.3;
}

.metric-fill.hidden {
  display: none;
}

.metric-fill {
  height: 100%;
  background: var(--accent);
  transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.metric-fill::after,
.metric-fill::before {
  content: none !important;
  display: none !important;
  animation: none !important;
}

.metric-fill.high {
  background: var(--accent-red);
}

.metric-fill.medium {
  background: var(--accent-yellow);
}

.metric-fill.low {
  background: var(--accent-green);
}

/* Network & Uptime Row */
.node-footer {
  display: flex;
  justify-content: space-between;
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 3px solid var(--black);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.footer-stat {
  text-align: center;
  flex: none;
  width: 33.333%;
}

.footer-stat:not(:last-child) {
  border-right: 2px solid var(--black);
}

.footer-stat span {
  display: block;
  font-family: 'Twemoji Country Flags', 'Space Grotesk', 'SF Mono', 'Consolas', 'Monaco', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.75rem;
  font-weight: 700;
  margin-bottom: 0.25rem;
  color: var(--black);
  white-space: nowrap;
}

/* Loading */
.loading {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4rem 2rem;
}

.loading-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  background: var(--white);
  border: 3px solid var(--black);
  box-shadow: 4px 4px 0 var(--shadow);
}

/* Empty State */
.empty-state {
  grid-column: 1 / -1;
  text-align: center;
  padding: 4rem 2rem;
  border: 4px dashed var(--black);
  background: var(--card-bg);
}

.empty-state h2 {
  font-size: 1.5rem;
  margin-bottom: 0.5rem;
}

.empty-state p {
  color: var(--text-muted);
}

/* Footer */
.footer {
  background: var(--black);
  color: var(--white);
  padding: 1.25rem 1.5rem;
  margin-top: auto;
  border-top: var(--border-width) solid var(--black);
}

.footer-content {
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.footer-powered {
  font-size: 0.85rem;
  white-space: nowrap;
}

.footer-powered strong {
  color: var(--accent);
}

.footer-signature {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 34px;
  padding: 0.4rem 0.65rem;
  background: var(--white);
  color: var(--black);
  text-decoration: none;
  border: 2px solid var(--white);
  box-shadow: 4px 4px 0 var(--accent);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transform: rotate(-1deg);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.footer-signature:hover {
  transform: translate(-2px, -2px) rotate(0deg);
  box-shadow: 6px 6px 0 var(--accent);
  color: var(--black);
}

.footer-signature:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 4px;
  transform: rotate(0deg);
}

.footer-signature-github {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--black);
  transition: color 0.12s ease, transform 0.12s ease;
}

.footer-signature:hover .footer-signature-github,
.footer-signature:focus-visible .footer-signature-github {
  color: var(--accent);
  transform: rotate(-8deg) scale(1.08);
}

.footer-signature-build {
  font-family: 'Twemoji Country Flags', 'SF Mono', 'Consolas', monospace;
  font-variant-numeric: tabular-nums;
}

.footer-signature-divider {
  width: 2px;
  height: 18px;
  background: var(--black);
}

.footer-signature-label {
  color: var(--text-muted);
}

.footer-signature-author {
  color: var(--black);
  font-family: 'Twemoji Country Flags', 'Archivo Black', sans-serif;
  font-size: 0.7rem;
  letter-spacing: 0.02em;
}

@media (max-width: 680px) {
  .footer-content {
    flex-direction: column;
    justify-content: center;
    gap: 1rem;
  }

  .footer-signature {
    flex-wrap: wrap;
    justify-content: center;
  }
}


/* List View — base grid + cell styles (shared by all viewports; PC block below tweaks spacing) */
.node-row {
  display: grid;
  grid-template-columns:
    [status] 24px
    [name] minmax(140px, 1.4fr)
    [cpu] minmax(95px, 1fr)
    [ram] minmax(95px, 1fr)
    [disk] minmax(95px, 1fr)
    [net] minmax(110px, 1.1fr)
    [up] minmax(82px, 0.85fr)
    [down] minmax(82px, 0.85fr)
    [uptime] minmax(68px, 0.7fr);
  grid-template-areas: "status name cpu ram disk net up down uptime";
  align-items: stretch;
  gap: 0;
  padding: 0.55rem 0.85rem;
  background: var(--card-bg);
  position: relative;
  transition: background-color 0.1s ease;
  border-top: 2px solid var(--black);
  /* Cap the row to its grid track sum so overflow-x: auto on the container
     actually scrolls. Without this, long node names in the 1fr name track
     inflate the row past the container and the layout breaks; with a fixed
     min-width the row always overflows instead of silently clipping.
     Sum of track min widths is ~791px (status 24 + name 140 + cpu/ram/disk 95 + net 110 + up/down 82 + uptime 68);
     row padding is 0.85rem × 2 ≈ 27px so total min-width must be ≥ 818px to keep grid content inside row box.
     Otherwise border-top + OFFLINE dotted bg stop short of the row right edge. */
  min-width: 820px;
}

.node-row:first-child {
  border-top: 0;
}

.nodes-container.list-view {
  background-color: var(--card-bg);
}

.nodes-container.list-view::after {
  content: none;
}

.node-row:hover {
  background-color: var(--row-hover);
}

.node-row.offline {
  background-image: radial-gradient(circle, var(--dots) 1px, transparent 1px);
  background-size: 4px 4px;
  opacity: 0.9;
}

/* Group wrappers collapse into the parent grid so each leaf becomes a column. */
.row-head,
.row-metrics,
.row-speeds {
  display: contents;
}

.row-status {
  grid-area: status;
  width: 12px;
  height: 12px;
  background: var(--accent-green);
  border: 2px solid var(--black);
  align-self: center;
  justify-self: center;
}

.row-status.offline {
  animation: pulse 1s step-end infinite;
}

.row-name {
  grid-area: name;
  min-width: 0;
  padding: 0 0.65rem;
  border-right: 2px solid var(--black);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1px;
}

.row-node-name {
  font-family: 'Twemoji Country Flags', 'Archivo Black', sans-serif;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.15;
}

.row-node-info {
  font-size: 0.58rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.15;
}

.row-metric {
  display: grid;
  grid-template-rows: auto 8px;
  gap: 5px;
  min-width: 0;
  padding: 0 0.6rem;
  border-right: 2px solid var(--black);
  align-content: center;
}

.row-cpu { grid-area: cpu; }
.row-ram { grid-area: ram; }
.row-disk { grid-area: disk; }
.row-net { grid-area: net; }

.row-metric-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem;
  line-height: 1;
  min-width: 0;
}

.row-metric-label {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--text);
  white-space: nowrap;
  flex-shrink: 0;
  line-height: 1;
}

.row-metric-bar {
  height: 8px;
  background: var(--bg);
  border: 2px solid var(--black);
  overflow: hidden;
  position: relative;
  min-width: 0;
}

.row-metric-bar.net-bar {
  position: relative;
}

.row-metric-bar .row-fill {
  position: absolute;
  top: 0;
  height: 100%;
}

.row-metric-bar .row-fill.net-in {
  left: 0;
  z-index: 2;
}

.row-metric-bar .row-fill.net-out {
  left: 0;
  z-index: 1;
}

.row-metric-value {
  font-family: 'Twemoji Country Flags', 'SF Mono', 'Consolas', 'Monaco', 'Space Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.7rem;
  font-weight: 700;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1;
  min-width: 0;
}

.row-speed {
  display: grid;
  grid-template-rows: auto 1fr;
  row-gap: 4px;
  min-width: 0;
  padding: 0 0.55rem;
  border-right: 2px solid var(--black);
  align-content: center;
}

.row-up { grid-area: up; }
.row-down { grid-area: down; }

.row-arrow {
  font-family: 'Twemoji Country Flags', 'Archivo Black', sans-serif;
  font-size: 0.78rem;
  line-height: 1;
}

.row-speed-label {
  display: flex;
  align-items: center;
  gap: 0.2rem;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.row-speed-value {
  font-family: 'Twemoji Country Flags', 'SF Mono', 'Consolas', 'Monaco', 'Space Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.7rem;
  font-weight: 700;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1;
}

.row-down {
  border-right: 2px solid var(--black);
}

.row-up .row-arrow { color: var(--accent-green); }
.row-down .row-arrow { color: var(--accent-blue); }

.row-uptime {
  grid-area: uptime;
  display: grid;
  grid-template-rows: auto 1fr;
  row-gap: 4px;
  min-width: 0;
  padding: 0 0.4rem;
  align-content: center;
}

.row-uptime-label {
  justify-self: start;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-align: left;
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.row-uptime-value {
  align-self: end;
  justify-self: end;
  font-family: 'Twemoji Country Flags', 'SF Mono', 'Consolas', 'Monaco', 'Space Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.7rem;
  font-weight: 700;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1;
}

/* Net fill colours reused from .metric-fill series */
.row-fill {
  height: 100%;
  background: var(--accent);
  transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.row-fill.net-in {
  background: var(--accent-green);
}

.row-fill.net-out {
  background: var(--accent-blue);
}

.row-fill.dimmed {
  opacity: 0.3;
}

.row-fill.hidden {
  display: none;
}

.row-fill.high {
  background: var(--accent-red);
}

.row-fill.medium {
  background: var(--accent-yellow);
}

.row-fill.low {
  background: var(--accent-green);
}

/* Net unlimited gradient reused */
.row-metric-bar.net-bar.unlimited {
  background-image: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 4px,
    var(--hatch) 4px,
    var(--hatch) 8px
  );
  background-color: var(--bg);
  border: 2px solid var(--black);
}


/* Responsive — grid cards only; list rows keep the desktop presentation. */
@media (max-width: 768px) {
  .header-content {
    gap: 0.75rem;
    padding: 0.65rem 0.75rem;
  }

  .logo {
    min-width: 0;
    gap: 0.4rem;
  }

  .logo-icon {
    flex-shrink: 0;
    font-size: 1rem;
  }

  .logo h1 {
    min-width: 0;
    overflow: hidden;
    font-size: 1rem;
    line-height: 1.1;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .header-controls {
    flex-shrink: 0;
    gap: 0.3rem;
  }

  .btn-view,
  .btn-admin {
    width: 34px;
    height: 34px;
    border-width: 2px;
    box-shadow: 2px 2px 0 var(--shadow);
  }

  .btn-view svg,
  .btn-admin svg {
    width: 16px;
    height: 16px;
  }

  .btn-admin {
    justify-content: center;
    padding: 0;
  }

  .btn-admin span {
    display: none;
  }

  .stats-bar {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    overflow: visible;
  }

  .stat-item {
    min-width: 0;
    padding: 0.55rem 0.25rem;
    border-right: 3px solid var(--black);
  }

  .stat-item:nth-child(-n + 4) {
    border-bottom: 3px solid var(--black);
  }

  .stat-item:nth-child(4),
  .stat-item:nth-child(6) {
    border-right: 0;
  }

  .stat-item:nth-child(5) {
    grid-column: 1 / 3;
  }

  .stat-item:nth-child(6) {
    grid-column: 3 / 5;
  }

  .stat-value {
    font-size: 1rem;
  }

  #stat-net-in,
  #stat-net-out {
    white-space: normal;
  }

  .stat-label {
    font-size: 0.6rem;
  }

  .nodes-container:not(.list-view) {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }

}

/* Card Style Variations */
.card-style-thin .node-card,
.card-style-thin .nodes-container.list-view {
  border-width: 2px;
  box-shadow: 4px 4px 0 var(--shadow);
}

.card-style-double .node-card,
.card-style-double .nodes-container.list-view {
  border-width: 6px;
  box-shadow: 8px 8px 0 var(--shadow);
}

.card-style-double .node-card::before {
  content: '';
  position: absolute;
  inset: 6px;
  border: 2px solid var(--black);
  pointer-events: none;
}

.card-style-double .nodes-container.list-view::before {
  content: '';
  position: absolute;
  inset: 6px;
  border: 2px solid var(--black);
  pointer-events: none;
}

/* Modal */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.18s ease-out, visibility 0s linear 0.28s;
}

.modal-overlay.active {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.modal-container {
  background: var(--white);
  border: var(--border-width) solid var(--black);
  box-shadow: 12px 12px 0 var(--shadow);
  width: min(96vw, 1400px);
  max-width: 1400px;
  max-height: 90vh;
  position: relative;
  overflow-y: auto;
  padding: 2rem;
  transform: translate3d(0, 16px, 0) scale(0.98);
  opacity: 0;
  transition: transform 0.26s cubic-bezier(0.2, 0.85, 0.25, 1), opacity 0.16s ease-out;
  transform-origin: center center;
  will-change: transform, opacity;
}

.modal-overlay.active .modal-container {
  transform: translate3d(0, 0, 0) scale(1);
  opacity: 1;
}

.modal-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 44px;
  height: 44px;
  padding: 0;
  background: var(--black);
  color: var(--white);
  border: 3px solid var(--black);
  font-size: 24px;
  font-family: 'Twemoji Country Flags', 'Space Grotesk', sans-serif;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 3px 3px 0 var(--shadow);
  transition: transform 0.1s ease, box-shadow 0.1s ease;
  z-index: 1010;
}

.modal-close:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 var(--shadow);
  color: var(--accent);
}

.modal-close:active {
  transform: translate(3px, 3px);
  box-shadow: none;
}

/* Modal Content Styling */
.modal-content {
  font-family: 'Twemoji Country Flags', 'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
}

.modal-content h2,
.modal-content h3 {
  font-family: 'Twemoji Country Flags', 'Archivo Black', sans-serif;
  text-transform: uppercase;
  letter-spacing: -0.02em;
}

.modal-content .info-value,
.modal-content .storage-meter-value,
.modal-content .storage-meter-percent,
.modal-content .network-channel-speed,
.modal-content .network-channel-total strong,
.modal-content .network-connections strong,
.modal-content .load-chart-value {
  font-family: 'Twemoji Country Flags', 'Space Grotesk', 'SF Mono', 'Consolas', 'Monaco', monospace;
  font-variant-numeric: tabular-nums;
}

.modal-node-header {
  border-bottom: 6px solid var(--black);
  padding-bottom: 1.5rem;
  margin-bottom: 2rem;
}

.modal-node-title {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.modal-node-name {
  font-size: 2rem;
  margin: 0;
}

.modal-node-status-tag {
  padding: 0.25rem 0.75rem;
  border: 2px solid var(--black);
  font-family: 'Twemoji Country Flags', 'Archivo Black', sans-serif;
  text-transform: uppercase;
  font-size: 0.75rem;
}

.modal-node-status-tag.online {
  background: var(--accent-green);
  color: var(--on-accent);
}

.modal-node-status-tag.offline {
  background: var(--accent-red);
  color: var(--on-accent);
}

.modal-node-meta {
  color: var(--text-muted);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.85rem;
}

.modal-section-title {
  font-size: 1.2rem;
  margin-bottom: 1.5rem;
  border-bottom: 3px solid var(--black);
  display: inline-block;
}

.chart-container {
  min-height: 250px;
  background: var(--white);
  border: 2px solid var(--black);
  margin-top: 1rem;
}

.modal-info-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1rem;
}

.info-item {
  display: flex;
  flex-direction: column;
}

.info-label {
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
}

.info-value {
  font-family: 'Twemoji Country Flags', 'Space Grotesk', 'SF Mono', 'Consolas', 'Monaco', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
  font-weight: 700;
  word-break: break-all;
}

/* === ENHANCED MODAL STYLES === */

.modal-info-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem;
  margin-bottom: 2rem;
}

@media (max-width: 900px) {
  .modal-info-row {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
}

.modal-info-section {
  border: 3px solid var(--black);
  padding: 1rem 1.25rem;
  background: var(--bg);
  box-shadow: 4px 4px 0 var(--shadow);
}

.modal-info-section-title {
  font-size: 0.85rem;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid var(--black);
  display: inline-block;
}

.storage-stack {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.storage-meter {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.35rem 0.75rem;
  align-items: center;
}

.storage-meter-header {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}

.storage-meter-label,
.storage-meter-percent {
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}

.storage-meter-value {
  font-size: 0.75rem;
  font-weight: 700;
  text-align: right;
}

.storage-meter-track {
  height: 14px;
  background: var(--white);
  border: 2px solid var(--black);
  overflow: hidden;
}

.storage-meter-fill {
  display: block;
  height: 100%;
  background: var(--accent-green);
}

.storage-meter-fill.medium { background: var(--accent-yellow); }
.storage-meter-fill.high { background: var(--accent-red); }

.storage-meter.unlimited .storage-meter-track {
  background-color: var(--bg);
  background-image: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 4px,
    var(--hatch) 4px,
    var(--hatch) 8px
  );
}

.storage-meter.unlimited .storage-meter-value,
.storage-meter.unlimited .storage-meter-percent {
  color: var(--text-muted);
}

.storage-meter-percent {
  min-width: 6.5ch;
  text-align: right;
  color: var(--text-muted);
  white-space: nowrap;
}

.network-channels {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}

.network-channel {
  padding: 0.75rem;
  background: var(--bg);
  border: 2px solid var(--black);
  box-shadow: 3px 3px 0 var(--shadow);
  min-width: 0;
}

.network-channel.up { border-top: 6px solid var(--accent-green); }
.network-channel.down { border-top: 6px solid var(--accent-blue); }

.network-channel-direction {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}

.network-channel-arrow {
  font-size: 1rem;
  line-height: 1;
}

.network-channel.up .network-channel-arrow { color: var(--accent-green); }
.network-channel.down .network-channel-arrow { color: var(--accent-blue); }

.network-channel-speed {
  display: block;
  margin: 0.5rem 0 0.65rem;
  font-size: 1rem;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.network-channel-total {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  padding-top: 0.5rem;
  border-top: 2px solid var(--black);
  font-size: 0.6rem;
  font-weight: 700;
  color: var(--text-muted);
}

.network-channel-total strong {
  color: var(--black);
  text-align: right;
}

.network-connections {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 0.9rem;
  padding-top: 0.65rem;
  border-top: 2px solid var(--black);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.06em;
}

.network-connections strong {
  color: var(--black);
  text-align: right;
}

.modal-load-title-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid var(--black);
}

.modal-load-title {
  font-size: 1.2rem;
  margin-bottom: 0;
  border-bottom: none;
  display: inline-block;
}

.modal-load-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  margin-bottom: 0;
}

@media (min-width: 1050px) {
  .modal-load-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 700px) {
  .modal-load-grid {
    grid-template-columns: 1fr;
  }
}

.load-chart-card {
  border: 3px solid var(--black);
  padding: 0.75rem;
  background: var(--bg);
  box-shadow: 4px 4px 0 var(--shadow);
  min-width: 0;
}

.load-chart-label {
  font-size: 0.65rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: 0.25rem;
}

.load-chart-value {
  font-family: 'Twemoji Country Flags', 'SF Mono', monospace;
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.25;
  margin-bottom: 0.5rem;
  min-height: 1.4em;
  white-space: normal;
  word-break: keep-all;
}

.load-network-value {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.load-network-up { color: var(--accent-green); }
.load-network-down { color: var(--accent-blue); }
.load-network-separator { color: var(--black); }

.load-chart-container {
  height: 180px;
  min-width: 0;
  background: var(--bg);
  overflow: hidden;
}

.modal-chart-section {
  border: 3px solid var(--black);
  padding: 1rem 1.25rem;
  background: var(--bg);
  box-shadow: 4px 4px 0 var(--shadow);
  margin-bottom: 2rem;
  position: relative;
}

.chart-loading-overlay {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  opacity: 0;
  transition: opacity 0.25s ease;
  pointer-events: none;
}

.chart-loading-overlay.is-visible {
  opacity: 1;
  pointer-events: auto;
}

.chart-loading-overlay.is-leaving {
  opacity: 0;
}

.chart-loading-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  background: var(--white);
  border: 3px solid var(--black);
  box-shadow: 4px 4px 0 var(--shadow);
}

.chart-loading-pixels {
  display: grid;
  grid-template-columns: repeat(5, 8px);
  grid-template-rows: repeat(5, 8px);
  gap: 3px;
  padding: 5px;
  background: transparent;
  border: none;
}

.chart-loading-pixel {
  width: 8px;
  height: 8px;
  background: var(--accent);
  opacity: 0;
  transform: scale(0);
  animation: chart-pixel-resolution 1.6s steps(1, end) infinite;
  animation-delay: calc(var(--pixel-index) * 22ms);
}

.chart-loading-text {
  font-family: 'Twemoji Country Flags', 'SF Mono', monospace;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
}

.modal-chart-section .load-chart-container,
.modal-chart-section .chart-container {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.modal-chart-section.is-loading .load-chart-container,
.modal-chart-section.is-loading .chart-container {
  opacity: 0;
  transform: translateY(4px);
}

.modal-chart-section.is-loading .btn-timescale {
  pointer-events: none;
  opacity: 0.45;
}

@keyframes chart-pixel-resolution {
  0%, 12.5%, 87.5%, 100% {
    opacity: 0;
    transform: scale(0);
  }
  25%, 75% {
    opacity: 0.35;
    transform: scale(1);
  }
  37.5%, 62.5% {
    opacity: 0.7;
    transform: scale(1);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .modal-overlay,
  .modal-container {
    transition: none;
  }

  .modal-container {
    transform: none;
    filter: none;
  }

  .chart-loading-pixel {
    animation: none;
    opacity: 1;
    transform: none;
  }

  .chart-loading-overlay,
  .modal-chart-section .load-chart-container,
  .modal-chart-section .chart-container {
    transition: none;
  }
}

.modal-latency-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid var(--black);
}

.modal-latency-section .chart-container {
  margin-top: 0;
  background: var(--bg);
  border: none;
}

.modal-latency-tasks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1rem;
  align-items: start;
}

.latency-task-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border: 3px solid var(--black);
  box-shadow: 3px 3px 0 var(--shadow);
  min-width: 0;
  cursor: pointer;
  transition: opacity 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}

.modal-latency-tasks.has-active .latency-task-card:not(.is-active) {
  opacity: 0.3;
}

.latency-task-card.is-active {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 var(--shadow);
}

.latency-task-row {
  display: flex;
  flex: 0 0 auto;
  transition: opacity 0.18s ease;
}

.latency-task-strip {
  width: 6px;
  background: var(--task-color, var(--accent-yellow));
  flex-shrink: 0;
}

.latency-task-body {
  padding: 0.5rem 0.75rem 0;
  flex: 1;
  min-width: 0;
}

.latency-task-header {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.25rem;
}

.latency-task-name {
  font-weight: 700;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}

.latency-task-stats {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
  font-size: 0.85rem;
}

.latency-task-latest {
  font-family: 'Twemoji Country Flags', 'SF Mono', monospace;
  font-weight: 700;
  font-size: 0.95rem;
}

.latency-task-sep {
  color: var(--text-muted);
}

.latency-task-loss {
  font-family: 'Twemoji Country Flags', 'SF Mono', monospace;
  font-weight: 700;
  color: var(--text-muted);
}

.latency-task-loss.has-loss {
  color: var(--accent-red);
}

.latency-task-detail-wrap {
  display: none;
}

.latency-task-detail {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.4rem 0.75rem;

  padding: 0.5rem 0.75rem;
  background: var(--black);
  color: var(--white);
  font-size: 0.85rem;
}

.latency-task-detail .info-label,
.latency-task-detail .info-value {
  color: var(--white);
}

.modal-latency-header .modal-section-title {
  border-bottom: none;
  margin-bottom: 0;
}

.modal-timescale-selector {
  display: flex;
  gap: 0.25rem;
  background: var(--bg);
  padding: 0.25rem;
  border: none;
  box-shadow: 4px 4px 0 var(--shadow);
}

.btn-timescale {
  padding: 0.25rem 0.6rem;
  background: var(--white);
  color: var(--black);
  border: 2px solid var(--black);
  font-family: 'Twemoji Country Flags', 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 0.7rem;
  text-transform: uppercase;
  cursor: pointer;
  transition: all 0.1s ease;
}

.btn-timescale:hover {
  background: var(--accent-yellow);
  color: var(--on-accent);
}

.btn-timescale.active {
  background: var(--black);
  color: var(--white);
}

@media (max-width: 520px) {
  .storage-meter-header,
  .network-connections {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.25rem;
  }

  .storage-meter-value,
  .network-connections strong {
    text-align: left;
  }

  .network-channels {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 600px) {
  .modal-node-header {
    padding-right: 3.5rem;
  }

  .modal-node-title {
    align-items: flex-start;
    flex-wrap: wrap;
  }

  .modal-load-title-container,
  .modal-latency-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;
  }

  .modal-timescale-selector {
    flex-wrap: wrap;
    max-width: 100%;
  }
}

/* Authentication Dialog */
.auth-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  background: rgba(0, 0, 0, 0.68);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.18s ease, visibility 0s linear 0.18s;
}

.auth-overlay.active {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.auth-dialog {
  position: relative;
  width: min(100%, 460px);
  padding: 2rem;
  background: var(--card-bg);
  border: var(--border-width) solid var(--black);
  box-shadow: 12px 12px 0 var(--shadow);
  opacity: 0;
  transform: translateY(16px) scale(0.98);
  transition: opacity 0.16s ease, transform 0.24s cubic-bezier(0.2, 0.85, 0.25, 1);
}

.auth-overlay.active .auth-dialog {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.auth-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 38px;
  height: 38px;
  border: 3px solid var(--black);
  background: var(--black);
  color: var(--white);
  box-shadow: 3px 3px 0 var(--accent);
  font: 700 1.4rem/1 'Space Grotesk', sans-serif;
  cursor: pointer;
}

.auth-heading {
  padding-right: 2.5rem;
  margin-bottom: 1.5rem;
  padding-bottom: 1rem;
  border-bottom: 5px solid var(--black);
}

.auth-kicker {
  display: block;
  margin-bottom: 0.35rem;
  color: var(--text-muted);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.14em;
}

.auth-heading h2 {
  font-size: 2rem;
  line-height: 1;
}

.auth-heading p {
  margin-top: 0.65rem;
  color: var(--text-muted);
  font-size: 0.82rem;
}

.auth-field {
  display: grid;
  gap: 0.4rem;
  margin-bottom: 1rem;
}

.auth-field span {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
}

.auth-field input {
  width: 100%;
  height: 46px;
  padding: 0 0.75rem;
  border: 3px solid var(--black);
  border-radius: 0;
  outline: none;
  background: var(--bg);
  color: var(--text);
  box-shadow: 3px 3px 0 var(--shadow);
  font: 700 0.95rem 'Space Grotesk', sans-serif;
}

.auth-field input:focus {
  background: var(--white);
  box-shadow: 5px 5px 0 var(--accent);
  transform: translate(-2px, -2px);
}

.auth-message {
  min-height: 1.1rem;
  margin: 0.25rem 0 0.65rem;
  color: var(--accent-red);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.auth-submit,
.auth-back,
.auth-oauth a {
  border: 3px solid var(--black);
  border-radius: 0;
  font-family: 'Twemoji Country Flags', 'Space Grotesk', sans-serif;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-decoration: none;
  cursor: pointer;
}

.auth-submit {
  width: 100%;
  min-height: 46px;
  padding: 0.7rem 1rem;
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: 4px 4px 0 var(--shadow);
}

.auth-submit:hover:not(:disabled),
.auth-oauth a:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 var(--shadow);
}

.auth-submit:disabled {
  cursor: wait;
  opacity: 0.65;
}

.auth-back {
  margin-bottom: 1rem;
  padding: 0.35rem 0.6rem;
  background: var(--white);
  color: var(--black);
  box-shadow: 2px 2px 0 var(--shadow);
  font-size: 0.68rem;
}

.auth-oauth {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

.auth-oauth[hidden] {
  display: none;
}

.auth-oauth::before,
.auth-oauth::after {
  content: '';
  height: 3px;
  background: var(--black);
}

.auth-oauth span {
  font-size: 0.65rem;
  font-weight: 700;
}

.auth-oauth a {
  grid-column: 1 / -1;
  padding: 0.65rem;
  background: var(--black);
  color: var(--white);
  box-shadow: 4px 4px 0 var(--accent);
  text-align: center;
  font-size: 0.72rem;
}

@media (max-width: 520px) {
  .auth-dialog {
    padding: 1.35rem;
    box-shadow: 8px 8px 0 var(--shadow);
  }

  .auth-heading h2 {
    font-size: 1.6rem;
  }
}

.auth-oauth::before {
  grid-column: 1;
  grid-row: 1;
}

.auth-oauth > span {
  grid-column: 2;
  grid-row: 1;
}

.auth-oauth::after {
  grid-column: 3;
  grid-row: 1;
}

.auth-oauth > a {
  grid-row: 2;
}

/* === Fork extras: billing, traffic plan, CT/CU/CM latency === */

.node-extras {
  display: flex;
  flex-direction: column;
  gap: var(--space-step, 0.75rem);
  margin-top: var(--space-step, 0.75rem);
}

.node-extras[hidden] {
  display: none;
}

.x-kv {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  border: 2px solid var(--black);
  background: var(--bg);
}

.x-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 0.3rem 0.35rem;
}

.x-cell + .x-cell {
  border-left: 2px solid var(--black);
}

.x-label {
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.x-value,
.x-carrier-num {
  font-family: 'Twemoji Country Flags', 'SF Mono', 'Consolas', 'Monaco', 'Space Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  white-space: nowrap;
}

.x-value {
  font-size: 0.72rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

.x-cell.x-warn {
  background: var(--accent-yellow);
  color: var(--on-accent);
}

.x-cell.x-crit {
  background: var(--accent-red);
  color: var(--on-accent);
}

.x-cell.x-warn .x-label,
.x-cell.x-crit .x-label {
  color: inherit;
}

.x-carriers {
  display: flex;
  flex-direction: column;
  gap: calc(var(--space-step, 0.75rem) / 2);
}

.x-carrier {
  display: grid;
  /* Equal number columns on both sides of the strip, text hugging the strip from each side,
     so the strip sits symmetrically between its two numbers. */
  grid-template-columns: 2.1rem var(--num-col, 3.2rem) minmax(0, 1fr) var(--num-col, 3.2rem);
  align-items: center;
  gap: 0.5rem;
}

.x-carrier-label {
  font-family: 'Twemoji Country Flags', 'Archivo Black', sans-serif;
  font-size: 0.6rem;
  line-height: 1.4;
  text-align: center;
  border: 2px solid var(--black);
  cursor: help;
}

.x-ct { background: var(--accent-blue); color: var(--white); }
.x-cu { background: var(--accent-red); color: var(--white); }
.x-cm { background: var(--accent-green); color: var(--on-accent); }

.x-carrier-num {
  font-size: 0.72rem;
  text-align: right;
}

.x-carrier-num.x-loss {
  text-align: left;
}

/* Tiered number colours (same thresholds as the strip); ladders checked for >= 4.5:1 contrast. */
.x-t0 { color: var(--text-muted); }
.x-t1 { color: var(--sig-text-1); }
.x-t2 { color: var(--sig-text-2); }
.x-t3 { color: var(--sig-text-3); }
.x-t4 { color: var(--sig-text-4); }
.x-t5 { color: var(--sig-text-5); }


.x-track {
  display: block;
  position: relative;
  min-width: 0;
}

.x-strip-canvas {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  pointer-events: none;
  /* With the whole-pixel offset from alignCanvas this maps canvas pixels 1:1 to screen pixels. */
  image-rendering: pixelated;
}

/* Painted by the canvas underneath; the spans only provide hover tooltips. */
.x-strip.is-canvas,
.x-strip.is-canvas .x-seg {
  background: transparent !important;
  border-color: transparent !important;
  box-shadow: none !important;
}

/* Fallback rendering; with JS the strip is painted pixel-exact on a canvas (snapStrip). */
.x-strip {
  display: flex;
  height: 16px;
  border: 2px solid var(--black);
  background: var(--strip-line);
}

/* Separators are borders, not layout gaps: browsers snap border widths to whole device pixels,
   so every line renders equally thick at any zoom. 2px matches the frame and the other boxes. */
.x-seg {
  display: block;
  flex: 1 1 0;
  min-width: 0;
  background: var(--bg);
  border-left: 2px solid var(--strip-line);
}

.x-seg:first-child {
  border-left: 0;
}

.x-seg-empty {
  background: repeating-linear-gradient(45deg, var(--bg) 0 2px, var(--hatch) 2px 3px);
}

.x-seg.lat-1 { background: var(--sig-1); }
.x-seg.lat-2 { background: var(--sig-2); }
.x-seg.lat-3 { background: var(--sig-3); }
.x-seg.lat-4 { background: var(--sig-4); }
.x-seg.lat-5 { background: var(--sig-5); }

/* Loss marker: a 4px bottom band under a 2px divider (same weight as every other line). */
.x-seg.loss-2 { box-shadow: inset 0 -4px 0 var(--sig-3), inset 0 -6px 0 var(--strip-line); }
.x-seg.loss-3 { box-shadow: inset 0 -4px 0 var(--sig-4), inset 0 -6px 0 var(--strip-line); }
.x-seg.loss-4,
.x-seg.loss-5 { box-shadow: inset 0 -4px 0 var(--sig-5), inset 0 -6px 0 var(--strip-line); }

/* List view: extras form two aligned lines on the row's own columns (subgrid).
   Line 1: EXPIRES | VALUE | RESET | PER DAY under CPU | RAM | DISK | NET.
   Line 2: CT under CPU+RAM, CU under DISK+NET, CM under UP+DOWN+UPTIME. */
.node-row .node-extras {
  grid-column: name / -1;
  grid-row: 2;
  display: grid;
  grid-template-columns: subgrid;
  row-gap: var(--space-step, 0.75rem);
  column-gap: 0;
  margin-top: 0.55rem;
  padding-top: 0.55rem;
  border-top: 2px dashed var(--black);
}

.node-row .x-kv,
.node-row .x-carriers {
  display: contents;
}

.node-row .x-cell {
  grid-row: 1;
  margin: 0 0.6rem;
  border: 2px solid var(--black);
  background: var(--bg);
}

.node-row .x-cell + .x-cell {
  border-left: 2px solid var(--black);
}

.node-row .x-cell[data-k="expires"] { grid-column: 2; }
.node-row .x-cell[data-k="value"] { grid-column: 3; }
.node-row .x-cell[data-k="reset"] { grid-column: 4; }
.node-row .x-cell[data-k="perday"] { grid-column: 5; }

.node-row .x-carrier {
  grid-row: 2;
  margin: 0 0.6rem;
}

.node-row .x-carrier[data-k="ct"] { grid-column: 2 / 4; }
.node-row .x-carrier[data-k="cu"] { grid-column: 4 / 6; }
.node-row .x-carrier[data-k="cm"] { grid-column: 6 / 9; }

/* Without billing/traffic cells the carriers move up to line 1. */
.node-row .node-extras:not(:has(.x-cell)) .x-carrier {
  grid-row: 1;
}

/* Modal billing section spans the full info row. */
.modal-billing-section {
  grid-column: 1 / -1;
}

.modal-billing-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

@media (max-width: 680px) {
  .modal-billing-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* === Fork: header = 2 x 3 stats + pixel world map === */
@media (min-width: 769px) {
  .header.has-map .stats-bar {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr)) minmax(0, 1.6fr);
    grid-template-rows: 1fr 1fr;
    overflow: visible;
  }

  /* One line per value so both stat rows keep the same height. */
  .header.has-map #stat-net-in,
  .header.has-map #stat-net-out {
    white-space: nowrap;
  }

  .header.has-map .stat-value {
    font-size: clamp(1.05rem, 1.5vw, 1.5rem);
    white-space: nowrap;
  }

  .header.has-map .stat-item {
    padding: 0.6rem 1rem;
  }

  .header.has-map .stat-item:nth-child(-n + 3) {
    border-bottom: 3px solid var(--black);
  }

  .header.has-map .stat-item:nth-child(6) {
    border-right: 3px solid var(--black);
  }

  .stats-map {
    grid-column: 4;
    grid-row: 1 / span 2;
    position: relative;
    min-height: 0;
  }
}

.stats-map[hidden] {
  display: none;
}

.map-frame {
  position: absolute;
  inset: 0.35rem 0.5rem;
  container-type: size;
  display: flex;
  align-items: center;
  justify-content: center;
}

.map-box {
  position: relative;
  width: min(100cqw, calc(100cqh * 96 / 38));
  aspect-ratio: 96 / 38;
  overflow: hidden;
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
}

.map-box.is-dragging {
  cursor: grabbing;
}

/* Two copies of the world side by side; translating by up to one copy loops seamlessly. */
.map-strip {
  position: absolute;
  top: 0;
  left: 0;
  width: 200%;
  height: 100%;
  will-change: transform;
}

.map-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: block;
}

.map-land {
  fill: var(--black);
  opacity: 0.26;
  shape-rendering: crispEdges;
}

.map-link {
  fill: none;
  stroke: var(--black);
  stroke-width: 0.35;
  stroke-dasharray: 1 0.7;
  stroke-linecap: square;
  animation: map-flow 1.2s linear infinite;
}

.map-link.is-offline {
  opacity: 0.35;
  animation: none;
}

@keyframes map-flow {
  to { stroke-dashoffset: -1.7; }
}

.map-pin {
  position: absolute;
  transform: translate(-50%, -50%);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 0 2px;
  font-size: 10px;
  line-height: 1;
  white-space: nowrap;
  background: var(--white);
  border: 2px solid var(--black);
  box-shadow: 1px 1px 0 var(--black);
  cursor: default;
}

.map-pin b {
  font-family: 'Archivo Black', sans-serif;
  font-size: 9px;
  color: var(--black);
}

.map-pin:hover {
  z-index: 2;
}

.map-pin.is-offline {
  filter: grayscale(1);
  opacity: 0.6;
}

.map-hub {
  background: var(--black);
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  .map-link {
    animation: none;
  }
}

@media (max-width: 768px) {
  .stats-map {
    display: none !important;
  }
}

/* Country flag before node names */
.node-flag {
  margin-right: 0.35em;
  font-family: 'Twemoji Country Flags', 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
  font-weight: 400;
}

/* === Fork: keep every card's rows aligned ===
   Fixed line count per element; overflow is truncated (full text in the tooltip). */
.node-card {
  display: flex;
  flex-direction: column;
}

.node-header > div:first-child {
  flex: 1;
  min-width: 0;
}

.node-info-line {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.metric-header {
  gap: 0.5rem;
  white-space: nowrap;
}

.metric-header > span:first-child {
  flex-shrink: 0;
}

.metric-header .metric-value {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Footer sits at the bottom of the card, so footers line up across a row. */
.node-spacer {
  flex: 1 0 var(--space-step);
}

/* One vertical step everywhere in a card: around both rule lines and between all blocks. */
.node-card > .node-header {
  padding-bottom: var(--space-step);
  margin-bottom: var(--space-step);
}

.node-card .metrics {
  gap: var(--space-step);
}

.node-card > .node-footer {
  margin-top: 0;
  padding-top: var(--space-step);
}

/* Carrier block: the three rows share one set of columns, so every gap is the same and the
   loss figures end flush with the card's right edge like every other value. Number columns are
   at least 5 characters wide so strips line up across cards. */
.node-card .x-carriers {
  display: grid;
  grid-template-columns: auto minmax(5ch, auto) minmax(0, 1fr) minmax(5ch, auto);
  column-gap: var(--carrier-gap, 0.5rem);
  row-gap: calc(var(--space-step) / 2);
  align-items: center;
  font-family: 'Twemoji Country Flags', 'SF Mono', 'Consolas', 'Monaco', 'Space Mono', monospace;
  font-size: 0.72rem;
}

.node-card .x-carrier {
  display: contents;
}

.node-card .x-carrier-num.x-lat,
.node-card .x-carrier-num.x-loss {
  text-align: right;
}

.x-cell.x-empty .x-value {
  color: var(--text-muted);
}

/* Nord's signal colours are the softest; a stronger lift keeps numbers at >= 4.5:1. */
[data-scheme="nord-dark"] {
  --sig-text-1: color-mix(in srgb, var(--sig-1) 55%, var(--ink));
  --sig-text-2: color-mix(in srgb, var(--sig-2) 55%, var(--ink));
  --sig-text-3: color-mix(in srgb, var(--sig-3) 55%, var(--ink));
  --sig-text-4: color-mix(in srgb, var(--sig-4) 55%, var(--ink));
  --sig-text-5: color-mix(in srgb, var(--sig-5) 55%, var(--ink));
}

/* Optional page pattern: a fixed layer under everything; the tile is painted in device pixels. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: var(--page-pattern, none);
  background-size: var(--page-pattern-size, auto);
  image-rendering: pixelated;
}
