/* Dashboard – eigenes Design: Fenster wie btop/Hyprland, Monospace, Farbschemata aus dem Terminal.
   Farben, Schrift und Darstellung setzt theme-init.js als CSS-Variablen und data-Attribute auf <html>. */

/* ------------------------------------------------------------ Grundwerte */

:root {
  --bg: #0b0f14; --line: #233040; --fg: #d6e2ea; --muted: #6f8393;
  --red: #ff5d73; --green: #4fdc8b; --yellow: #f5d547; --blue: #5aa9ff; --magenta: #c58bff; --cyan: #22b7f2; --orange: #ff9a52;
  --accent: #22b7f2; --accent-2: #c58bff;
  --font: 'JetBrains Mono', ui-monospace, Consolas, monospace;
  --glow-strength: 0.5;
  --opacity: 0.72;
  --num: 13px;   /* Größe der Kennzahlen ("wie Text", "etwas größer", "groß") */
  --small: 13px; /* Beschriftungen und Zusatzzeilen */
  --icon-size: 32px;
  --gap: 18px;
  --side-w: min(400px, calc(100vw - 32px)); /* Breite der Einstellungs-Seitenleiste */

  --edge: color-mix(in srgb, var(--accent) 60%, var(--line));
  --title: var(--accent);
  --glow: color-mix(in srgb, var(--accent) calc(var(--glow-strength) * 70%), transparent);
  --glow-size: calc(2px + var(--glow-strength) * 16px);
  --win-bg: color-mix(in srgb, var(--bg) calc(var(--opacity) * 100%), transparent);
  --dim: color-mix(in srgb, var(--fg) 9%, var(--bg));
  --hover: color-mix(in srgb, var(--accent) 14%, transparent);
  color-scheme: dark;
}
[data-numbers="mid"] { --num: 17px; --small: 11px; }
[data-numbers="big"] { --num: 24px; --small: 11px; }
[data-background="oled"] { --bg: #000; }

*, *::before, *::after { box-sizing: border-box; }
html {
  background: var(--bg);
  color: var(--fg);
  font: 400 13px/1.55 var(--font);
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  min-height: 100vh;
  /* Unsichtbare Namen am rechten Rand sollen keine waagerechte Bildlaufleiste erzeugen */
  overflow-x: clip;
  transition: padding-right 0.3s ease; /* Platz für die Einstellungen ("nach links schieben") */
}
button, input, select { font: inherit; color: inherit; letter-spacing: inherit; }
a { color: inherit; }
[hidden] { display: none !important; }
:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; box-shadow: 0 0 8px var(--glow); }
.icon { width: 16px; height: 16px; flex: none; fill: currentColor; }
.ok { color: var(--green); } .warn { color: var(--yellow); } .crit { color: var(--red); } .mute { color: var(--muted); }

/* ------------------------------------------------------------ Hintergrund: Grundfarbe, leichter Schein von oben,
   Muster als Maske in der Akzentfarbe */

.wall {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: radial-gradient(circle at 50% -25%, color-mix(in srgb, var(--accent) 11%, transparent), transparent 60%), var(--bg);
}
.wall::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--accent);
  opacity: var(--pattern-opacity, 0.2);
  -webkit-mask: var(--pattern) 0 0 / var(--pattern-size) repeat;
  mask: var(--pattern) 0 0 / var(--pattern-size) repeat;
}
[data-background="plain"] .wall, [data-background="oled"] .wall { background: var(--bg); }
[data-background="plain"] .wall::after, [data-background="oled"] .wall::after { display: none; }
[data-background="dots"] { --pattern: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='22' height='22'><circle cx='11' cy='11' r='1.1'/></svg>"); --pattern-size: 22px 22px; --pattern-opacity: 0.32; }
[data-background="grid"] { --pattern: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32'><path d='M32 0V32H0' fill='none' stroke='black'/></svg>"); --pattern-size: 32px 32px; --pattern-opacity: 0.1; }
[data-background="crosses"] { --pattern: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30'><path d='M15 11V19M11 15H19' fill='none' stroke='black'/></svg>"); --pattern-size: 30px 30px; --pattern-opacity: 0.28; }
[data-background="diagonal"] { --pattern: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14'><path d='M-2 2L2 -2M0 14L14 0M12 16L16 12' fill='none' stroke='black'/></svg>"); --pattern-size: 14px 14px; --pattern-opacity: 0.07; }
[data-background="hex"] { --pattern: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='17.32'><path d='M5 0H15L20 8.66H30M20 8.66L15 17.32H5L0 8.66L5 0' fill='none' stroke='black'/></svg>"); --pattern-size: 30px 17.32px; --pattern-opacity: 0.11; }
[data-background="pixel"] { --pattern: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='48' height='48'><rect x='6' y='9' width='2' height='2'/><rect x='31' y='4' width='2' height='2'/><rect x='19' y='22' width='4' height='4'/><rect x='41' y='29' width='2' height='2'/><rect x='10' y='38' width='2' height='2'/><rect x='35' y='42' width='2' height='2'/><rect x='26' y='35' width='2' height='2' opacity='.5'/><rect x='2' y='26' width='2' height='2' opacity='.5'/></svg>"); --pattern-size: 48px 48px; --pattern-opacity: 0.35; }
[data-background="rows"] { --pattern: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='20'><rect y='19' width='5' height='1'/></svg>"); --pattern-size: 8px 20px; --pattern-opacity: 0.16; }

/* ------------------------------------------------------------ Fenster
   Der Rahmen ist ein eigenes Element aus Linienstücken (app.js: frame()). Titel und Status sitzen in
   echten Lücken der Linie, das Glühen (drop-shadow) folgt nur den Linien – nichts liegt über dem Rahmen. */

.win { position: relative; isolation: isolate; min-width: 0; padding: 18px 16px 16px; }
.win::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--win-bg);
  backdrop-filter: blur(8px);
  box-shadow: inset 0 0 calc(var(--glow-size) * 1.6) color-mix(in srgb, var(--glow) 30%, transparent);
}
.frame {
  position: absolute;
  inset: -9px 0;
  z-index: 2;
  display: grid;
  grid-template-rows: 18px 1fr 18px;
  pointer-events: none;
}
/* Glühen nur an den Linien und Eckwinkeln; der Titel leuchtet über seinen Textschatten */
.frame :is(.seg, .frame__mid, .corner) {
  filter: drop-shadow(0 0 calc(var(--glow-size) * 0.3) var(--glow)) drop-shadow(0 0 var(--glow-size) var(--glow));
}
.frame__top, .frame__bottom { display: flex; min-width: 0; }
.frame__top { align-items: flex-end; }
.frame__bottom { align-items: flex-start; }
.frame__mid { border: 0 solid var(--edge); border-width: 0 1px; }
.seg { flex: none; height: 10px; border: 0 solid var(--edge); }
.seg--fill { flex: 1; }
.frame__top .seg--fill { border-top-width: 1px; }
.frame__bottom .seg--fill { border-bottom-width: 1px; }
.seg--tl { width: 14px; border-width: 1px 0 0 1px; }
.seg--tr { width: 14px; border-width: 1px 1px 0 0; }
.seg--bl { width: 14px; border-width: 0 0 1px 1px; }
.seg--br { width: 14px; border-width: 0 1px 1px 0; }
.frame__title {
  flex: 0 1 auto;
  min-width: 0;
  margin: 0;
  padding: 0 7px;
  align-self: center;
  overflow: hidden;
  color: var(--title);
  font-size: inherit;
  font-weight: 700;
  line-height: 18px;
  text-overflow: ellipsis;
  text-transform: lowercase;
  text-shadow: 0 0 calc(var(--glow-size) / 2) var(--glow);
  white-space: nowrap;
}
/* Schwebende Fenster (Menü, Einstellungen, Dialog) liegen über anderem Inhalt:
   der Titel bekommt dort einen Hintergrund, damit nichts durchscheint */
:is(.menu, .settings-side, .dialog__win) .frame__title { background: color-mix(in srgb, var(--bg) 94%, transparent); }
.frame__title a { text-decoration: none; pointer-events: auto; }
.frame__title a:hover { text-decoration: underline; }
.frame__title .sub { color: var(--muted); font-weight: 400; }
.frame__actions { display: flex; align-self: center; gap: 2px; padding: 0 4px; pointer-events: auto; }
.frame__led { display: none; flex: none; align-self: center; width: 8px; height: 8px; margin: 0 7px 0 -1px; background: var(--st); box-shadow: 0 0 8px var(--st); }
.frame__status {
  display: none;
  flex: 0 1 auto;
  min-width: 0;
  align-self: center;
  padding: 0 7px;
  overflow: hidden;
  color: var(--st);
  font-size: var(--small);
  line-height: 18px;
  text-overflow: ellipsis;
  text-transform: lowercase;
  white-space: nowrap;
}
.statusline { display: none; margin: -4px 0 10px; color: var(--st); font-size: var(--small); text-transform: lowercase; }
.st { display: none; color: var(--st); text-transform: lowercase; }
.frame__status::before, .statusline::before, .st::before { content: '■ '; }
.frame__status:empty, .statusline:empty, .st:empty, .frame__led--off { display: none !important; }
[data-status="frame"] .frame__status { display: block; }
[data-status="head"] .frame__led, [data-status="head"] .statusline { display: block; }
[data-status="foot"] .frame__led { display: block; }
[data-status="foot"] .st { display: inline; }
/* Fußzeile, in der nur der (hier unsichtbare) Status steht: ganz weg, sonst bleibt eine leere Linie */
:root:not([data-status="foot"]) .widget__meta:has(> .st:only-child) { display: none; }

/* Eckwinkel: mittig auf der Linie (die Linie liegt 8px vom oberen/unteren Rand des Rahmens) */
.corner { display: none; position: absolute; width: 10px; height: 10px; border: 0 solid var(--title); }
.corner--tl { left: -1px; top: 7px; border-width: 3px 0 0 3px; }
.corner--tr { right: -1px; top: 7px; border-width: 3px 3px 0 0; }
.corner--bl { left: -1px; bottom: 7px; border-width: 0 0 3px 3px; }
.corner--br { right: -1px; bottom: 7px; border-width: 0 3px 3px 0; }
[data-corners="tlbr"] :is(.corner--tl, .corner--br),
[data-corners="trbl"] :is(.corner--tr, .corner--bl),
[data-corners="all"] .corner { display: block; }

/* Ton des Fensters: ok, Warnung, Störung – färbt Rahmen, Titel und Status */
.win { --st: var(--muted); }
.win[data-tone="ok"] { --st: var(--green); }
.win[data-tone="warn"] {
  --st: var(--yellow);
  --edge: color-mix(in srgb, var(--yellow) 60%, var(--line));
  --title: var(--yellow);
  --glow: color-mix(in srgb, var(--yellow) calc(var(--glow-strength) * 55%), transparent);
}
.win[data-tone="crit"] {
  --st: var(--red);
  --edge: color-mix(in srgb, var(--red) 60%, var(--line));
  --title: var(--red);
  --glow: color-mix(in srgb, var(--red) calc(var(--glow-strength) * 55%), transparent);
}

/* ------------------------------------------------------------ Leiste oben (wie eine Statusleiste) */

.bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 auto;
  padding: 10px var(--gap);
  transition: transform 0.2s ease;
}
/* Beim Runterscrollen weg, beim Hochscrollen oder mit "/" wieder da (app.js) */
.bar--hidden { transform: translateY(calc(-100% - 16px)); }
.mod {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 12px;
  border: 1px solid var(--edge);
  background: var(--win-bg);
  backdrop-filter: blur(8px);
  box-shadow: 0 0 var(--glow-size) var(--glow);
  white-space: nowrap;
}
.mod--brand { gap: 2px; color: var(--accent); }
.brand__title { margin: 0; font-size: inherit; font-weight: 700; text-transform: lowercase; }
.mod--search { flex: 1; min-width: 0; cursor: text; }
.search__prompt { color: var(--accent); font-weight: 700; }
.mod--search input { flex: 1; min-width: 0; border: 0; outline: 0; background: none; caret-color: var(--accent); }
.mod--search input::placeholder { color: var(--muted); }
.mod--search input::-webkit-search-cancel-button { display: none; }
.mod--search:focus-within { border-color: var(--accent); }
.search__hint { padding: 0 6px; border: 1px solid var(--line); color: var(--muted); font: inherit; font-size: 11px; }
.mod--summary::before { content: '■'; color: var(--st, var(--green)); }
.mod--summary[data-tone="crit"] { --st: var(--red); }
.mod--clock { color: var(--muted); }
.mod--button { padding: 0 10px; color: var(--accent); cursor: pointer; }
.mod--button:hover, .mod--button[aria-expanded="true"] { background: var(--hover); }
.settings { position: relative; }

/* ------------------------------------------------------------ Einstellungen */

/* Seitenleiste rechts über die volle Höhe, oben Reiter, darunter die Optionen des gewählten Reiters */
.settings-side {
  position: fixed;
  top: 16px;
  right: 16px;
  bottom: 16px;
  z-index: 40;
  display: flex;
  flex-direction: column;
  width: var(--side-w);
  padding: 18px 8px 12px 16px;
  animation: settings-in 0.25s ease;
}
@keyframes settings-in { from { transform: translateX(32px); opacity: 0; } }
.settings-side::before { background: color-mix(in srgb, var(--bg) 94%, transparent); }
.settings-close { padding: 0 4px; border: 0; background: none; color: var(--title); font-weight: 700; line-height: 18px; cursor: pointer; }
.settings-close:hover { color: var(--fg); }
.settings-tabs { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 0 8px 12px 0; padding-bottom: 8px; border-bottom: 1px dashed var(--line); }
.settings-tab { padding: 0; border: 0; background: none; color: var(--muted); cursor: pointer; text-transform: lowercase; }
.settings-tab:hover { color: var(--fg); }
.settings-tab[aria-selected="true"] { color: var(--accent); text-shadow: 0 0 8px var(--glow); }
.settings-tab[aria-selected="true"]::before { content: '['; }
.settings-tab[aria-selected="true"]::after { content: ']'; }
.settings-side__body { flex: 1; min-height: 0; overflow: hidden auto; padding: 2px 8px 2px 2px; }
.setting__label { display: block; margin: 12px 0 6px; color: var(--muted); font-size: 11px; font-weight: 400; text-transform: lowercase; }
.setting__label:first-child { margin-top: 0; }
.opts { display: flex; flex-wrap: wrap; gap: 6px; }
.opt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border: 1px solid var(--line);
  background: none;
  cursor: pointer;
  text-align: left;
}
.opt:hover { border-color: var(--edge); }
.opt[aria-checked="true"] { border-color: var(--accent); color: var(--accent); box-shadow: 0 0 8px var(--glow); }
.opt--wide { display: flex; flex-direction: column; align-items: flex-start; gap: 0; width: 100%; margin-top: 8px; padding: 6px 10px; }
.opt small, .switch-item small { color: var(--muted); font-size: 11px; }
.opt__dots { display: inline-flex; }
.opt__dots i { width: 7px; height: 12px; }
.opt--swatch { width: 24px; height: 24px; padding: 0; }
.opt--swatch i { display: block; width: 100%; height: 100%; }
.color-input { width: 30px; height: 24px; padding: 0; border: 1px solid var(--line); background: none; cursor: pointer; }
.select { width: 100%; padding: 3px 6px; border: 1px solid var(--line); background: var(--bg); cursor: pointer; }
.setting__range { display: grid; grid-template-columns: 1fr auto; align-items: center; column-gap: 8px; margin-top: 12px; }
.setting__range .setting__label { margin: 0; }
.setting__range output { color: var(--muted); font-size: 11px; }
.slider { grid-column: 1 / -1; width: 100%; height: 18px; margin: 4px 0 0; background: none; cursor: pointer; -webkit-appearance: none; appearance: none; }
.slider::-webkit-slider-runnable-track { height: 2px; background: var(--line); }
.slider::-moz-range-track { height: 2px; background: var(--line); }
.slider::-webkit-slider-thumb { width: 10px; height: 14px; margin-top: -6px; border: 0; background: var(--accent); box-shadow: 0 0 8px var(--glow); -webkit-appearance: none; appearance: none; }
.slider::-moz-range-thumb { width: 10px; height: 14px; border: 0; border-radius: 0; background: var(--accent); box-shadow: 0 0 8px var(--glow); }
.setting__rule { height: 0; margin: 14px 0 10px; border-top: 1px dashed var(--line); }
.switch-item { display: flex; align-items: flex-start; gap: 10px; width: 100%; padding: 4px 0; border: 0; background: none; cursor: pointer; text-align: left; }
.switch-item__text { display: flex; flex-direction: column; }
/* Schalter als Terminal-Kästchen: [ ] bzw. [x] */
.switch::before { content: '[ ]'; color: var(--muted); white-space: pre; }
[aria-checked="true"] > .switch::before { content: '[x]'; color: var(--accent); }

/* ------------------------------------------------------------ Seite */

.content { display: flex; flex-direction: column; gap: 30px; margin: 0 auto; padding: 16px var(--gap) 48px;
  transition: filter 0.25s ease, transform 0.3s ease, opacity 0.25s ease; }
/* Breite (Einstellung): begrenzt wie bisher auf 1480 px, sonst bis kurz vor den Rand */
[data-width="limited"] :is(.content, .bar, .top-row) { max-width: 1480px; }
/* Einstellungen offen: Dashboard unscharf und dunkler – oder es rückt nach links und macht Platz */
[data-effect="blur"][data-settings-open] :is(.content, .top-row) { filter: blur(4px) brightness(0.55); }
/* "Nach links schieben" (nur wenn die Leiste sonst Inhalt verdeckt, data-settings-push setzt app.js): rechts entsteht
   Platz in der Breite der Seitenleiste, Leiste und Inhalt zentrieren
   sich in der übrigen Fläche neu – alles bleibt sichtbar (Fenster packen sich dabei neu) */
[data-effect="slide"][data-settings-open][data-settings-push] body { padding-right: calc(var(--side-w) + 32px); }
.banner { padding: 8px 12px; border: 1px solid var(--red); color: var(--red); background: color-mix(in srgb, var(--red) 10%, var(--bg)); }
.banner p { margin: 0; }
.empty { margin: 0; color: var(--muted); }

/* Oben: fastfetch links, daneben die Lesezeichen */
.overview { display: flex; flex-wrap: wrap; align-items: stretch; gap: 30px var(--gap); }
.overview > .fetch { flex: 1 1 520px; }
.tools { display: grid; flex: 1 1 520px; grid-template-columns: repeat(auto-fit, minmax(max(240px, calc(50% - var(--gap))), 1fr)); gap: 30px var(--gap); align-content: stretch; }
.tool { display: flex; flex-direction: column; gap: 10px; min-height: 120px; }

/* Uhr */
.tool--clock { justify-content: center; }
.clock__time { font-size: 44px; font-weight: 700; line-height: 1; color: var(--accent); text-shadow: 0 0 var(--glow-size) var(--glow); font-variant-numeric: tabular-nums; }
.clock__time small { margin-left: 6px; color: var(--muted); font-size: 18px; font-weight: 400; text-shadow: none; }
.clock__date { color: var(--muted); text-transform: lowercase; }
.clock__date b { color: var(--fg); font-weight: 400; }
.clock__world { color: var(--muted); font-size: var(--small); text-transform: lowercase; }

/* Wetter: kleines ASCII-Bild, Temperatur, nächste Tage */
.weather { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 6px 18px; }
/* line-height 1: die Halbblöcke zweier Zeilen stoßen ohne Lücke aneinander */
.weather__art { margin: 0; font-size: 15px; line-height: 1; color: var(--muted); filter: drop-shadow(0 0 calc(var(--glow-strength) * 6px) var(--glow)); }
.weather__art .sun { color: var(--yellow); }
.weather__art .rain { color: var(--blue); }
.weather__art .snow { color: var(--fg); }
.weather__art .bolt { color: var(--yellow); }
.weather__art .cloud { color: color-mix(in srgb, var(--fg) 70%, var(--muted)); }
.weather__art--night .sun { color: var(--fg); } /* Mond */
.weather__now strong { display: block; font-size: 28px; line-height: 1.1; font-weight: 700; }
.weather__now span { display: block; color: var(--muted); font-size: var(--small); text-transform: lowercase; }
.weather__days { grid-column: 1 / -1; display: grid; grid-template-columns: max-content 1fr max-content; gap: 1px 12px; margin: 4px 0 0; padding-top: 8px; border-top: 1px dashed var(--line); font-size: var(--small); }
.weather__days dt { color: var(--accent); text-transform: lowercase; }
.weather__days dd { margin: 0; color: var(--muted); text-transform: lowercase; }
.weather__days .temp { color: var(--fg); text-align: right; font-variant-numeric: tabular-nums; }

/* Websuche mit Vorschlägen */
.websearch { position: relative; display: flex; align-items: center; gap: 8px; padding: 4px 8px; border: 1px solid var(--line); }
.websearch:focus-within { border-color: var(--accent); box-shadow: 0 0 8px var(--glow); }
.websearch input { flex: 1; min-width: 0; border: 0; outline: 0; background: none; caret-color: var(--accent); }
.websearch input::placeholder { color: var(--muted); }
.websearch input::-webkit-search-cancel-button { display: none; }
/* Kopfbereich: Uhr · Websuche · Wetter in einer Reihe über dem Inhalt, im selben Spaltenraster wie die eigene
   Anordnung (24, breit 48), damit die Kanten mit den Fenstern darunter fluchten. Spalten, Reihenfolge und Höhe setzt
   app.js (applyTop); die drei sind gleich hoch – so hoch wie das höchste oder wie eingestellt. Die Reihe liegt über
   dem Inhalt, damit die Vorschläge der Websuche darüber schweben (jedes Fenster ist eine eigene Ebene). */
.top-row {
  position: relative;
  z-index: 15;
  display: grid;
  grid-template-columns: repeat(var(--board-cols, 24), minmax(0, 1fr));
  margin: 16px auto 14px;
  padding-inline: calc(var(--gap) / 2);
  transition: filter 0.25s ease;
}
.top-row > .tool { min-height: 0; margin: 0 calc(var(--gap) / 2); }
.tool--search { justify-content: center; }
.tool--search .widget__hint { text-align: center; }
/* Ist die Reihe niedriger als ihr Inhalt, endet er vor dem Rahmen: die Uhrzeit bleibt immer ganz, das Wetter scrollt,
   die Websuche bleibt offen für ihre Vorschlagsliste */
.top-row > .tool > :not(.frame, .board-resize, .websearch) { flex-shrink: 1; min-height: 0; overflow: hidden; }
.top-row > .tool > .clock__time { flex-shrink: 0; }
.top-row .tool--clock { justify-content: safe center; }
.top-row .weather { flex: 1 1 auto; overflow: auto; scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
/* Dezente Trennlinie zwischen Übersicht und Widgets (Wunsch von Enis) – nur automatisch, mit eigener Anordnung
   gibt es keine festen Bereiche; sie liegt mitten im Abstand von 30 px */
:root:not([data-board]) .overview { position: relative; }
:root:not([data-board]) .overview::after { content: ''; position: absolute; right: 0; bottom: -15px; left: 0; border-top: 1px dashed var(--line); }
.websearch__list {
  position: absolute; z-index: 30; top: calc(100% + 4px); left: -1px; right: -1px;
  margin: 0; padding: 4px 0; list-style: none;
  border: 1px solid var(--accent); background: var(--bg); box-shadow: 0 0 12px var(--glow);
}
.websearch__list li { padding: 2px 8px; cursor: pointer; }
.websearch__list li::before { content: '› '; color: var(--muted); }
.websearch__list li[aria-selected="true"], .websearch__list li:hover { background: var(--hover); color: var(--accent); }

/* Lesezeichen */
.bookmarks { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
.bookmarks a { display: flex; align-items: baseline; gap: 8px; padding: 2px 6px; text-decoration: none; }
.bookmarks a::before { content: '›'; color: var(--accent); }
.bookmarks a:hover, .bookmarks a:focus-visible { background: var(--hover); color: var(--accent); }
.bookmarks small { overflow: hidden; color: var(--muted); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
.tool--bookmarks .opt--wide { margin-top: auto; }

/* Übersicht wie fastfetch */
.fetch { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 32px; padding: 22px 24px 18px; }
[data-header="off"] .fetch { display: none; }
.logo {
  margin: 0 0 0 4px;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.1;
  background: linear-gradient(180deg, var(--accent), var(--accent-2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 calc(var(--glow-size) / 2) var(--glow));
}
.fetch__text { min-width: 0; }
.fetch__info { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 1px 18px; margin: 0; }
.fetch__who { font-weight: 700; }
.fetch__who b { color: var(--accent); }
.fetch__rule { max-width: 100%; overflow: hidden; color: var(--muted); white-space: nowrap; }
.fetch__info dt { color: var(--accent); font-weight: 700; }
.fetch__info dd { min-width: 0; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fetch__swatches { display: flex; margin-top: 8px; }
.fetch__swatches i { width: 26px; height: 14px; }

/* ------------------------------------------------------------ Widgets */

.widgets { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 30px var(--gap); }
/* Anordnung setzt app.js (packWidgets): "dynamisch" = 2-px-Zeilen, Fenster so hoch wie ihr Inhalt;
   "bento" = feste Einheiten, Fenster füllen ihre Zellen */
@media (min-width: 761px) {
  .widgets { grid-auto-rows: 2px; row-gap: 0; align-items: start; }
  [data-size="bento"] .widgets { grid-auto-rows: 60px; row-gap: 30px; align-items: stretch; }
  .widgets.widgets--measuring { align-items: start; } /* zum Messen die natürliche Höhe */
  [data-size="bento"] .widget .widget__body { overflow: hidden; }
}
.widget { display: flex; flex-direction: column; }
.widget__body { display: flex; flex: 1; flex-direction: column; gap: 12px; min-width: 0; }
/* Gruppe (type: group): Abschnitte untereinander, getrennt durch eine gestrichelte Linie; jeder mit Kopfzeile
   (Überschrift + Status). Ist nichts los (data-quiet), bleibt nur die Kopfzeile mit einer Kurzinfo (app.js). */
.widget__parts { display: flex; flex: 1; flex-direction: column; }
.widget__part { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.widget__part + .widget__part { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--line); }
.widget__part[data-quiet] > .widget__body { display: none; }
/* Die Linie trennt die Abschnitte – Fußzeilen darin ohne eigene; nichts bricht um, zu Langes endet mit "…" */
.widget__part .widget__meta { padding-top: 0; border-top: 0; }
.widget__part .stat__meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.part__title {
  display: flex; align-items: baseline; gap: 10px; margin: 0;
  color: var(--accent); font-size: var(--small); font-weight: 700; text-transform: lowercase; white-space: nowrap;
}
.part__title a { color: inherit; text-decoration: none; }
.part__title a:hover, .part__title a:focus-visible { text-decoration: underline; }
.part__status { min-width: 0; margin-left: auto; overflow: hidden; color: var(--muted); font-weight: 400; text-overflow: ellipsis; }
.part__status:not(:empty)::before { content: '■ '; }
.part__status[data-tone="ok"]::before { color: var(--green); }
.part__status[data-tone="warn"] { color: var(--yellow); }
.part__status[data-tone="crit"] { color: var(--red); }
.widget__stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 16px; }
.stat { display: flex; flex-direction: column; min-width: 0; }
.stat__label { color: var(--muted); font-size: var(--small); text-transform: lowercase; }
.stat__value { font-size: var(--num); font-weight: 700; line-height: 1.3; font-variant-numeric: tabular-nums; }
[data-numbers="mid"] .stat__value, [data-numbers="big"] .stat__value { text-shadow: 0 0 calc(var(--glow-size) / 2) var(--glow); }
.stat__value--text { font-size: max(13px, calc(var(--num) * 0.8)); }
.stat__unit { margin-left: 4px; color: var(--muted); font-size: min(var(--num), 13px); font-weight: 400; text-shadow: none; }
.stat__meta { color: var(--muted); font-size: var(--small); }
.stat .meter { margin: 5px 0 3px; }

/* Balken aus Blöcken: Verlauf grün → gelb → rot über die ganze Länge (wie btop) oder Akzentfarbe;
   der unbelegte Teil wird abgedeckt */
.meter {
  position: relative;
  height: 10px;
  min-width: 48px;
  background: linear-gradient(90deg, var(--green), var(--yellow) 72%, var(--red));
  -webkit-mask: repeating-linear-gradient(90deg, #000 0 5px, transparent 5px 7px);
  mask: repeating-linear-gradient(90deg, #000 0 5px, transparent 5px 7px);
}
[data-bars="accent"] .meter { background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
[data-bars="accent"] .meter[data-level="warning"] { background: var(--yellow); }
[data-bars="accent"] .meter[data-level="critical"] { background: var(--red); }
.meter__rest { position: absolute; top: 0; right: 0; bottom: 0; background: var(--dim); }

/* Zeilen mit Balken: Name, Balken, Prozent – darunter die Angabe (z. B. "1,3 TiB frei") */
.widget__rows { display: flex; flex-direction: column; gap: 7px; }
.usage-row { display: grid; grid-template-columns: minmax(40px, max-content) minmax(48px, 1fr) 5ch; align-items: center; gap: 0 10px; }
.usage-row__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.usage-row__percent { color: var(--muted); text-align: right; font-variant-numeric: tabular-nums; }
.usage-row__value { grid-column: 2 / -1; color: var(--muted); font-size: var(--small); }
/* Mehrere Balkenzeilen untereinander teilen sich die Spalten (subgrid): der längste Name gibt die Breite vor,
   alle Balken beginnen bündig (vorher maß jede Zeile ihren Namen für sich, z. B. "unfertig"/"fertig") */
.widget__rows:has(> .usage-row:not(.usage-row--stack)) { display: grid; grid-template-columns: minmax(40px, max-content) minmax(48px, 1fr) 5ch; column-gap: 10px; }
.widget__rows:has(> .usage-row:not(.usage-row--stack)) > * { grid-column: 1 / -1; }
.widget__rows > .usage-row:not(.usage-row--stack) { grid-template-columns: subgrid; }
/* Laufende Downloads und Streams: Name, darunter Balken + Prozent, darunter die Angabe – jede Zeile über die ganze
   Breite, damit ein langer Name die Angabe nicht in eine schmale Spalte drückt; zu Langes endet mit "…" */
.usage-row--stack { grid-template-columns: minmax(48px, 1fr) 5ch; row-gap: 3px; }
.usage-row--stack > :is(.usage-row__name, .usage-row__value) { grid-column: 1 / -1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.widget__rows > .stat__label { margin-bottom: -2px; }
/* Zeile mit Details per Rechtsklick (Downloads) */
.usage-row--menu { margin: -2px -4px; padding: 2px 4px; cursor: context-menu; }
.usage-row--menu:hover { background: var(--hover); }

.widget__list { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; }
.widget__list li {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 3px 8px;
  border-left: 2px solid var(--red);
  background: color-mix(in srgb, var(--red) 10%, transparent);
}
.widget__list-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.widget__list-name small { display: block; color: var(--muted); font-size: var(--small); }
.widget__list-state { flex: none; color: var(--red); text-align: right; }
.widget__list-state small { display: block; color: var(--muted); font-size: var(--small); }
.widget__list--neutral li { border-left-color: var(--line); background: color-mix(in srgb, var(--fg) 4%, transparent); }
.widget__list--neutral .widget__list-state { color: var(--fg); }
.widget__list--wrap .widget__list-name { white-space: normal; }
.widget__list-state.upd { color: var(--accent-2); }
/* Status-Verlauf: Name, Balken, Verfügbarkeit, Antwortzeit je Zeile; die Balken sind ein Verlauf, die Maske
   schneidet ihn in gleich breite Blöcke mit Lücke (--bars = Anzahl, app.js) */
.widget--history .widget__body { container-type: inline-size; }
.history { display: grid; grid-template-columns: minmax(0, 18ch) minmax(96px, 1fr) max-content max-content; align-items: center; gap: 3px 10px; }
.history__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Lücke = ein Viertel des Blocks, damit die Balken auch in schmalen Fenstern sichtbar bleiben */
.history__bar {
  height: 10px;
  -webkit-mask: linear-gradient(to right, #000 75%, transparent 0) 0 0 / calc(100% / var(--bars, 48)) 100%;
  mask: linear-gradient(to right, #000 75%, transparent 0) 0 0 / calc(100% / var(--bars, 48)) 100%;
}
/* Schmales Fenster (z. B. am Handy): ohne Spalte Antwortzeit – sie steht dann im Hinweis am Balken */
@container (max-width: 480px) {
  .history { grid-template-columns: minmax(0, 14ch) minmax(96px, 1fr) max-content; }
  .history__ms { display: none; }
}
.history__uptime { text-align: right; font-variant-numeric: tabular-nums; }
.history__ms { color: var(--muted); font-size: var(--small); white-space: nowrap; font-variant-numeric: tabular-nums; }
.history__outages li.is-open { border-left-color: var(--red); background: color-mix(in srgb, var(--red) 10%, transparent); }
/* Release-Feed: Name verlinkt auf die Release-Notes, "↑ neu" wie die Update-Ecke an den Kacheln */
.releases a.widget__list-name { text-decoration: none; }
.releases a.widget__list-name:hover, .releases a.widget__list-name:focus-visible { color: var(--accent); }
.releases .releases__new { color: var(--accent-2); }
.widget__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 14px;
  margin: auto 0 0;
  padding-top: 9px;
  border-top: 1px dashed var(--line);
  color: var(--muted);
  font-size: var(--small);
}
.widget__meta > span { white-space: nowrap; }
.widget__hint { margin: 0; color: var(--muted); }
.widget__error { display: flex; align-items: center; gap: 6px; margin: 0; color: var(--red); }

/* ------------------------------------------------------------ Eigene Anordnung (freies Raster, app.js) */

/* Die Bereiche lösen sich auf, alle Fenster liegen direkt im Raster von main: 24 Spalten, Zeilen zu 10 px.
   Zeile 1 gehört der Fehlermeldung. Der Abstand steckt im Rand der Fenster: seitlich je ein halber, unten 30 px. */
[data-board] .content {
  display: grid;
  grid-template-columns: repeat(var(--board-cols, 24), minmax(0, 1fr)); /* 24, breit 48 (app.js) */
  grid-template-rows: auto;
  grid-auto-rows: 10px;
  gap: 0;
  padding-inline: calc(var(--gap) / 2);
}
[data-board] :is(.overview, .tools, .widgets, .groups) { display: contents; }
[data-board] .content > .banner { grid-column: 1 / -1; grid-row: 1; margin: 0 calc(var(--gap) / 2) 30px; }
[data-board] [data-win] { min-width: 0; min-height: 0; margin: 0 calc(var(--gap) / 2) 30px; }
/* Ist das Fenster kleiner als sein Inhalt, endet der Inhalt vor dem Rahmen (der ragt über das Fenster hinaus):
   alles außer Rahmen und Griff darf schrumpfen und wird abgeschnitten, Listen und Kennzahlen scrollen (Regel danach). */
[data-board] :is(.group, .widget, .tool) { display: flex; flex-direction: column; }
[data-board] [data-win] > :not(.frame, .board-resize) { flex-shrink: 1; min-height: 0; overflow: hidden; }
[data-board] :is(.widget > .widget__body, .widget > .widget__parts, .group > .grid, .bookmarks, .fetch__text) {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
[data-board] .group > .grid { align-content: flex-start; }
[data-board] .fetch { grid-template-rows: minmax(0, 1fr); align-items: stretch; }
/* mittig, solange Platz ist – sonst oben anfangen statt über den Rahmen hinaus */
[data-board] .fetch > :is(.logo, .fetch__text) { display: flex; flex-direction: column; justify-content: safe center; }

/* Bearbeiten: Spaltenlinien als Hilfe, Fenster gestrichelt; ihr Inhalt reagiert nicht, nur Ziehen zählt
   (auch im Kopfbereich – dort bleibt alles in der eigenen Reihe) */
[data-editing] :is(.content, .top-row) {
  background: linear-gradient(to right, color-mix(in srgb, var(--accent) 12%, transparent) 1px, transparent 1px) content-box;
  background-size: calc(100% / var(--board-cols, 24)) 100%;
}
[data-editing] :is(main [data-win], .top-row > [data-top]) {
  outline: 1px dashed color-mix(in srgb, var(--accent) 55%, transparent);
  outline-offset: 5px;
  cursor: grab;
  user-select: none;
  touch-action: none;
}
[data-editing] :is(main [data-win], .top-row > [data-top]) * { pointer-events: none !important; }
[data-editing] :is(main [data-win], .top-row > [data-top]) > .board-resize { pointer-events: auto !important; }
.board-moving { z-index: 10; cursor: grabbing !important; opacity: 0.9; box-shadow: 0 14px 34px rgb(0 0 0 / 0.5); }
.board-ghost {
  margin: 0 calc(var(--gap) / 2) 30px;
  border: 1px dashed var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  pointer-events: none;
}
/* Größe ändern: rechte Kante = Breite, untere Kante = Höhe, Ecke unten rechts = beides (Wahl von Enis).
   Kein sichtbarer Griff – beim Überfahren oder Ziehen leuchtet die Kante in der Akzentfarbe auf. */
.board-resize { position: absolute; z-index: 3; }
.board-resize--r { top: 0; right: -6px; bottom: 0; width: 12px; cursor: ew-resize; }
.board-resize--b { right: 0; bottom: -6px; left: 0; height: 12px; cursor: ns-resize; }
.board-resize--rb { z-index: 4; right: -10px; bottom: -10px; width: 22px; height: 22px; cursor: nwse-resize; }
.board-resize--r::before, .board-resize--b::before {
  content: '';
  position: absolute;
  background: var(--accent);
  box-shadow: 0 0 8px var(--glow), 0 0 2px var(--accent);
  opacity: 0;
  transition: opacity 0.12s;
}
.board-resize--r::before { top: 0; bottom: 0; left: 5px; width: 2px; }
.board-resize--b::before { top: 5px; right: 0; left: 0; height: 2px; }
.board-resize:hover::before,
[data-win]:has(> .board-resize--rb:hover) > :is(.board-resize--r, .board-resize--b)::before,
[data-resizing*="r"] > .board-resize--r::before,
[data-resizing*="b"] > .board-resize--b::before { opacity: 1; }

/* Leiste fertig/abbrechen/zurücksetzen als Fußleiste über die ganze Breite (Vorschlag von Enis): deckend,
   oben eine Linie in der Akzentfarbe mit dem Titel darin – so vom Dashboard getrennt. Die Seite bekommt unten
   Platz dafür, die Einstellungen enden darüber. */
:root { --edit-h: 58px; }
.edit-bar {
  --edge: var(--accent);
  --title: var(--accent);
  position: fixed;
  z-index: 45;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px 24px;
  height: var(--edit-h);
  padding: 0 var(--gap);
}
.edit-bar::before { background: color-mix(in srgb, var(--bg) 96%, transparent); box-shadow: 0 -12px 28px rgb(0 0 0 / 0.4); }
.edit-bar :is(.frame__mid, .frame__bottom, .corner) { display: none; }
.edit-bar .frame { inset: -9px 0 auto; grid-template-rows: 18px; }
/* nur die obere Linie; der Titel steht über dem linken Rand des Inhalts */
.edit-bar .seg--tl { width: max(14px, var(--gap)); border-left-width: 0; }
[data-width="limited"] .edit-bar .seg--tl { width: max(14px, calc((100vw - 1480px) / 2 + var(--gap))); }
.edit-bar .seg--tr { border-right-width: 0; }
.edit-bar .frame__title { background: color-mix(in srgb, var(--bg) 96%, transparent); }
.edit-bar__hint, .edit-bar__error { min-width: 0; margin: 0; overflow: hidden; font-size: var(--small); text-overflow: ellipsis; white-space: nowrap; }
.edit-bar__hint { color: var(--muted); text-transform: lowercase; }
.edit-bar__error { color: var(--yellow); }
.edit-bar__actions { display: flex; flex: none; gap: 8px; }
[data-editing] .content { padding-bottom: calc(var(--edit-h) + 48px); }
[data-editing] .settings-side { bottom: calc(var(--edit-h) + 16px); }
/* Aktualisieren: das Symbol dreht sich, bis der Server fertig ist */
#refresh-button.is-busy .icon { animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
#edit-button[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); box-shadow: 0 0 8px var(--glow); }

/* ------------------------------------------------------------ Gruppen und Kacheln */

.groups { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 30px var(--gap); }
.group { flex: 1 1 auto; max-width: 100%; }
.group--custom { --title: var(--accent-2); }
.group__menu { padding: 0 4px; border: 0; background: none; color: var(--title); font-weight: 700; cursor: pointer; line-height: 18px; }
.group__menu:hover { color: var(--fg); }
/* Einklappen per Klick auf den Namen (app.js): eingeklappt bleibt nur die Kopfzeile, der Status steht im Rahmen */
.group__toggle { padding: 0; border: 0; background: none; color: inherit; font: inherit; text-transform: inherit; cursor: pointer; pointer-events: auto; }
.group__toggle::before { content: '▾ '; color: var(--muted); }
.group[data-collapsed] .group__toggle::before { content: '▸ '; }
.group__toggle:hover, .group__toggle:focus-visible { outline: 0; text-decoration: underline; }
.group[data-collapsed] > :not(.frame, .statusline) { display: none; }
.group__empty { margin: 0; color: var(--muted); }
.group__foot { display: none; margin: 4px 0 0; padding-top: 9px; border-top: 1px dashed var(--line); font-size: var(--small); }
[data-status="foot"] .group__foot { display: block; }

.grid { display: flex; flex-wrap: wrap; gap: 14px 12px; }
.tile { position: relative; }
.tile__main {
  position: relative;
  display: grid;
  place-items: center;
  width: calc(var(--icon-size) + 26px);
  height: calc(var(--icon-size) + 26px);
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--fg) 3%, transparent);
  color: inherit;
  text-decoration: none;
  outline: none;
  transition: border-color 0.12s, box-shadow 0.12s, background 0.12s;
}
.tile__main--static { cursor: default; }
.tile__icon { display: grid; place-items: center; width: var(--icon-size); height: var(--icon-size); }
.tile__img { width: 100%; height: 100%; object-fit: contain; }
.tile__mono {
  display: none;
  width: 100%;
  height: 100%;
  background: var(--accent);
  -webkit-mask: center / contain no-repeat;
  mask: center / contain no-repeat;
  filter: drop-shadow(0 0 calc(var(--glow-size) / 3) var(--glow));
}
.tile__letter { color: var(--accent); font-size: calc(var(--icon-size) * 0.62); font-weight: 700; line-height: 1; }
/* Einfarbig: Silhouette in der Akzentfarbe; ohne Silhouette färbt der Filter #tint das Logo ein */
[data-icons="mono"] .tile__icon--mono .tile__img { display: none; }
[data-icons="mono"] .tile__icon--mono .tile__mono { display: block; }
[data-icons="mono"] .tile__icon:not(.tile__icon--mono) .tile__img { filter: url(#tint) drop-shadow(0 0 calc(var(--glow-size) / 3) var(--glow)); }
.tint-flood { flood-color: var(--accent); }
.tint-flood-off { flood-color: var(--red); }
/* Status als schmale Leuchtleiste am unteren Rand der Kachel – im freien Rand, nie über dem Logo */
.tile__badge {
  position: absolute;
  right: 8px;
  bottom: 4px;
  left: 8px;
  height: 2px;
  background: var(--line);
}
.tile[data-state="online"] .tile__badge { background: var(--green); box-shadow: 0 0 6px var(--green); }
.tile[data-state="offline"] .tile__badge { background: var(--red); box-shadow: 0 0 8px var(--red); }
.tile[data-state="unchecked"] .tile__badge { display: none; }
.tile[data-state="offline"] .tile__main {
  border-color: color-mix(in srgb, var(--red) 70%, var(--line));
  background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--red) 12%, transparent) 0 4px, transparent 4px 9px);
}
[data-icons="mono"] .tile[data-state="offline"] .tile__mono { background: var(--red); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--red) 60%, transparent)); }
[data-icons="mono"] .tile[data-state="offline"] .tile__icon:not(.tile__icon--mono) .tile__img { filter: url(#tint-off); }
.tile[data-state="offline"] .tile__letter { color: var(--red); }
/* Neue Version verfügbar: kleine Ecke oben rechts in der zweiten Farbe des Schemas, weg vom Logo */
.tile[data-update] .tile__main::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  border-style: solid;
  border-width: 0 9px 9px 0;
  border-color: transparent var(--accent-2) transparent transparent;
  filter: drop-shadow(0 0 4px color-mix(in srgb, var(--accent-2) 70%, transparent));
}
.tile--hidden-service { opacity: 0.4; }
.tile__caption { display: flex; }
.tile__name { text-decoration: none; }

/* Desktop mit Maus: nur Icons; beim Überfahren steht der Name unter der Kachel – im freien Zeilenabstand,
   der dafür reserviert ist. So wird nie eine andere Kachel verdeckt. */
@media (hover: hover) and (pointer: fine) {
  .grid { row-gap: 26px; padding-bottom: 18px; }
  .tile:hover .tile__main, .tile:focus-within .tile__main {
    border-color: var(--accent);
    background: var(--hover);
    box-shadow: 0 0 var(--glow-size) var(--glow), inset 0 0 12px color-mix(in srgb, var(--accent) 20%, transparent);
  }
  .tile[data-state="offline"]:hover .tile__main, .tile[data-state="offline"]:focus-within .tile__main {
    border-color: var(--red);
    box-shadow: 0 0 var(--glow-size) color-mix(in srgb, var(--red) 50%, transparent);
  }
  .tile__caption {
    --caption-x: -50%;
    position: absolute;
    top: calc(100% + 3px);
    left: 50%;
    z-index: 6;
    padding: 0 6px;
    background: var(--accent);
    color: var(--bg);
    font-size: 11px;
    line-height: 17px;
    white-space: nowrap;
    opacity: 0;
    visibility: hidden;
    transform: translateX(var(--caption-x));
    transition: opacity 0.12s linear, visibility 0s linear 0.12s;
  }
  .tile__caption::before { content: '› '; }
  .tile[data-state="offline"] .tile__caption { background: var(--red); }
  .tile__name { text-transform: lowercase; }
  .tile--caption-start .tile__caption { --caption-x: 0; left: 0; }
  .tile--caption-end .tile__caption { --caption-x: 0; left: auto; right: 0; }
  .tile:hover .tile__caption, .tile:focus-within .tile__caption { opacity: 1; visibility: visible; transition: opacity 0.12s linear, visibility 0s; }
}

/* Touch (Handy/Tablet): App-Raster, Icon über Name; die ganze Kachel ist der Link. Gruppen in voller Breite. */
@media (hover: none), (pointer: coarse) {
  .group { flex-basis: 100%; }
  .grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(max(76px, calc(var(--icon-size) + 40px)), 1fr));
    gap: 14px 8px;
  }
  .tile { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; }
  .tile__main::after { content: ''; position: absolute; inset: 0; }
  .tile:active .tile__main { border-color: var(--accent); background: var(--hover); }
  .tile__caption { width: 100%; justify-content: center; pointer-events: none; }
  .tile__name {
    display: -webkit-box;
    overflow: hidden;
    font-size: 11px;
    line-height: 15px;
    text-transform: lowercase;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
  }
}

/* ------------------------------------------------------------ Kontextmenü (Rechtsklick auf eine Kachel) */

.menu {
  position: fixed;
  z-index: 40;
  width: max-content;
  min-width: 260px;
  max-width: min(380px, calc(100vw - 16px));
  padding: 16px 8px 10px;
}
.menu::before { background: color-mix(in srgb, var(--bg) 94%, transparent); }
.menu__facts { display: grid; grid-template-columns: max-content 1fr; gap: 2px 14px; margin: 0 8px 8px; }
.menu__facts dt { color: var(--muted); text-transform: lowercase; }
.menu__facts dd { margin: 0; }
.menu__state { text-transform: lowercase; }
.menu__state[data-state="online"] { color: var(--green); }
.menu__state[data-state="offline"] { color: var(--red); }
.menu__update { color: var(--accent-2); }
.menu__divider { height: 0; margin: 6px 8px; border-top: 1px dashed var(--line); }
.menu__item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  padding: 3px 8px;
  border: 0;
  background: none;
  color: var(--fg);
  cursor: pointer;
  text-align: left;
  text-decoration: none;
  text-transform: lowercase;
}
.menu__item::before { content: '›'; color: var(--accent); }
.menu__item:hover, .menu__item:focus-visible { outline: 0; box-shadow: none; background: var(--hover); color: var(--accent); }
.menu__item small { color: var(--muted); font-size: 11px; text-transform: none; }

/* Schnelloptionen: unter dem Knopf in der Leiste; ist die Liste länger als der Bildschirm, scrollt sie innen */
.quick-menu { padding: 16px 0 10px; }
.quick-menu__body { max-height: calc(100vh - 140px); overflow: hidden auto; padding: 0 16px 2px; }

/* ------------------------------------------------------------ Dialog */

.dialog { max-width: min(420px, calc(100vw - 32px)); padding: 9px 0; border: 0; background: none; color: var(--fg); overflow: visible; }
.dialog::backdrop { background: rgb(0 0 0 / 0.55); backdrop-filter: blur(2px); }
.dialog__win { display: flex; flex-direction: column; gap: 14px; width: min(420px, calc(100vw - 32px)); padding: 22px 18px 18px; }
.dialog__win::before { background: color-mix(in srgb, var(--bg) 96%, transparent); }
.dialog__text { margin: 0; color: var(--muted); }
.field { display: flex; flex-direction: column; gap: 4px; }
.field__label { color: var(--muted); font-size: 11px; text-transform: lowercase; }
.field__input { padding: 6px 8px; border: 1px solid var(--line); background: var(--bg); outline: 0; caret-color: var(--accent); }
.field__input:focus { border-color: var(--accent); box-shadow: 0 0 8px var(--glow); }
.dialog__actions { display: flex; justify-content: flex-end; gap: 8px; }

/* ------------------------------------------------------------ Anmeldung (login.html) */

.login { display: grid; place-items: center; min-height: 100vh; padding: 24px var(--gap); }
.login__win { width: min(420px, 100%); padding: 26px 20px 20px; }
.login__win::before { background: color-mix(in srgb, var(--bg) 94%, transparent); }
.login__form { display: flex; flex-direction: column; gap: 14px; }
.login__text { margin: 0; color: var(--muted); }
/* QR-Code auf Weiß, damit jede Kamera ihn liest; scharfe Kanten statt weichgezeichneter Pixel */
.login__qr { align-self: center; width: 200px; height: 200px; background: #fff; image-rendering: pixelated; }
.login__secret { margin: 0; color: var(--muted); font-size: var(--small); overflow-wrap: anywhere; }
.login__secret code { color: var(--fg); font-family: inherit; }
.login__codes { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px 16px; margin: 0; padding: 10px 12px 10px 32px; border: 1px dashed var(--line); font-variant-numeric: tabular-nums; }
.login__or { margin: 0; color: var(--muted); text-align: center; text-transform: lowercase; }
.login__link { align-self: center; padding: 0; border: 0; background: none; color: var(--muted); cursor: pointer; text-decoration: underline; text-transform: lowercase; }
.login__link:hover { color: var(--accent); }
.login__error { margin: 0; color: var(--red); }

/* Einstellungen → sicherheit */
.security { display: flex; flex-direction: column; gap: 8px; }
.security .setting__label { margin-bottom: 0; }
.security .opt--wide { margin-top: 0; }
.security .opt--wide:disabled { cursor: default; opacity: 0.55; }
.security__line { margin: 0; color: var(--muted); }
.security__list { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; }
.security__list li { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 0 10px; padding: 4px 8px; border-left: 2px solid var(--accent); background: color-mix(in srgb, var(--fg) 4%, transparent); }
.security__list small { grid-column: 1; color: var(--muted); font-size: 11px; }
.security__remove { grid-row: 1 / span 2; grid-column: 2; padding: 2px 6px; border: 1px solid var(--line); background: none; color: var(--muted); cursor: pointer; text-transform: lowercase; }
.security__remove:hover { border-color: var(--red); color: var(--red); }
.security__enroll, .security__codes { display: flex; flex-direction: column; gap: 10px; }
.security__enroll:empty, .security__codes:empty { display: none; }
.security__error { margin: 12px 0 0; color: var(--red); }
.button { padding: 4px 12px; border: 1px solid var(--line); background: none; cursor: pointer; text-transform: lowercase; }
.button::before { content: '[ '; color: var(--muted); }
.button::after { content: ' ]'; color: var(--muted); }
.button:hover { border-color: var(--edge); }
.button--accent { border-color: var(--accent); color: var(--accent); box-shadow: 0 0 8px var(--glow); }

.svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ------------------------------------------------------------ Schmale Bildschirme */

@media (max-width: 760px) {
  :root { --gap: 12px; }
  /* Einstellungen am Handy über den ganzen Bildschirm; Platz machen lohnt sich dort nicht */
  .settings-side { top: 8px; right: 8px; bottom: 8px; left: 8px; width: auto; }
  [data-effect="slide"][data-settings-open] body { padding-right: 0; }
  .bar { flex-wrap: wrap; padding-top: 8px; padding-bottom: 8px; }
  .mod--search { order: 1; flex-basis: 100%; }
  .mod--clock { display: none; }
  #edit-button { display: none; } /* freies Raster nur am Desktop */
  /* Kopfbereich am Handy: nur die Websuche (Wahl von Enis – die Uhrzeit hat das Handy selbst) */
  .top-row { display: block; margin: 12px 0 0; padding-inline: var(--gap); }
  .top-row > :not(#tool-search) { display: none; }
  .top-row > .tool { margin: 0; }
  .mod--summary { margin-left: auto; }
  .fetch { grid-template-columns: 1fr; gap: 14px; }
  .logo { font-size: 13px; }
  /* Widgets als Zeile zum Wischen; oben Platz für den Titel im Rahmen, seitlich für das Glühen */
  .widgets {
    display: flex;
    gap: 14px;
    margin: 0 calc(var(--gap) * -1);
    padding: 12px var(--gap) 14px;
    overflow-x: auto;
    scroll-padding: 0 var(--gap);
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .widgets::-webkit-scrollbar { display: none; }
  .widget { flex: 0 0 min(86vw, 360px); scroll-snap-align: start; }
  /* Die Medien-Gruppe ist am Handy sehr hoch – die anderen Fenster nicht auf ihre Höhe strecken */
  .widgets { align-items: flex-start; }
}

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