/* CSNETWORKS Cloud-Kalkulator – Oberfläche im Stil des STACKIT Calculators */

/* --------------------------------------------------------------------------
   Schrift: Mozilla Text.

   Eingebunden aus dem eigenen Haus, nicht von einem Schriftendienst. Ein
   Einbinden über Google Fonts hieße, dass der Browser jedes Kunden bei jedem
   Aufruf eine fremde Adresse anfragt — mit seiner IP-Adresse. Das widerspricht
   allem, was diese Anwendung sonst tut, und wäre für ein Angebotswerkzeug im
   deutschen Mittelstand schlicht nicht vermittelbar.

   Die Dateien liegen unter assets/fonts/. Fehlen sie, greift der Rückfall
   darunter und die Anwendung sieht aus wie zuvor — kein leerer Text, kein
   Fehler. Eingespielt werden sie unter Verwaltung → Wartung → Schriftart, oder
   von Hand in diesen Ordner gelegt.

   local() steht voran: wer Mozilla Text auf seinem Rechner installiert hat,
   braucht die Datei gar nicht erst zu laden.
   -------------------------------------------------------------------------- */
@font-face{
  font-family:"Mozilla Text";
  font-style:normal;font-weight:400;font-display:swap;
  src:local("Mozilla Text Regular"),local("MozillaText-Regular"),
      url("fonts/MozillaText-Regular.woff2") format("woff2");
}
@font-face{
  font-family:"Mozilla Text";
  font-style:normal;font-weight:500;font-display:swap;
  src:local("Mozilla Text Medium"),local("MozillaText-Medium"),
      url("fonts/MozillaText-Medium.woff2") format("woff2");
}
@font-face{
  font-family:"Mozilla Text";
  font-style:normal;font-weight:600;font-display:swap;
  src:local("Mozilla Text SemiBold"),local("MozillaText-SemiBold"),
      url("fonts/MozillaText-SemiBold.woff2") format("woff2");
}
@font-face{
  font-family:"Mozilla Text";
  font-style:normal;font-weight:700;font-display:swap;
  src:local("Mozilla Text Bold"),local("MozillaText-Bold"),
      url("fonts/MozillaText-Bold.woff2") format("woff2");
}

/* --------------------------------------------------------------------------
   Farbwelt.

   CSNETWORKS: Blau #124FFF, Dunkelton #001828 – beides von csnetworks.de.
   Alles hängt an diesen Werten; für eine Anpassung genügen die beiden Blöcke.

   Zwei Ansichten, dunkel und hell. Gewählt wird sie über den Umschalter oben
   rechts; ohne eigene Wahl folgt sie der Einstellung des Geräts. Das Attribut
   data-theme am <html> entscheidet und wird von einem kurzen Skript im Kopf
   gesetzt, noch bevor gezeichnet wird — sonst blitzt beim Laden kurz die
   falsche Ansicht auf.
   -------------------------------------------------------------------------- */
:root{
  --bg:#00121E;
  --bg-2:#001828;
  --panel:#04202F;
  --panel-2:#082B3D;
  --line:#123249;
  --line-2:#1C4463;
  --ink:#E8F0F8;
  --ink-2:#B6C9DA;
  --muted:#7C93A9;
  --accent:#124FFF;
  --accent-2:#6E9BFF;
  --accent-ink:#FFFFFF;
  --warn:#E8B44A;
  --danger:#FF6B7A;
  --schatten:0 1px 2px rgba(0,0,0,.3);
  --r:8px;
  --f:"Mozilla Text","Inter","Helvetica Neue",Arial,system-ui,sans-serif;
  --fm:"JetBrains Mono","IBM Plex Mono",SFMono-Regular,Consolas,monospace;
  color-scheme:dark;
}

/* Die helle Ansicht. Dieselben Rollen, andere Werte — kein einziger Baustein
   unten muss davon wissen. Das Blau ist etwas dunkler als im Dunkelmodus:
   auf Weiß hätte #124FFF zu wenig Abstand zum Hintergrund für Fließtext. */
:root[data-theme="hell"]{
  --bg:#F4F7FA;
  --bg-2:#FFFFFF;
  --panel:#FFFFFF;
  --panel-2:#F0F4F8;
  --line:#DCE4EC;
  --line-2:#C3CFDB;
  --ink:#0B1F2E;
  --ink-2:#33485C;
  --muted:#5E7387;
  --accent:#0B3FD6;
  --accent-2:#0B3FD6;
  --accent-ink:#FFFFFF;
  --warn:#A8700A;
  --danger:#C2333F;
  --schatten:0 1px 2px rgba(11,31,46,.07);
  color-scheme:light;
}

*{box-sizing:border-box}
/* Ein display: auf einer Klasse schlägt sonst das hidden-Attribut des Browsers.
   Einmal hier festgelegt, damit es nicht bei jedem neuen Element auffällt. */
[hidden]{display:none !important}
html,body{height:100%}
/* Der Seitenkörper ist eine Spalte, damit der Fuß unten steht — auch auf kurzen
   Seiten, wo sonst eine graue Fläche darunter bliebe und die Angaben mitten im
   Bild hingen. */
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--f);font-size:14px;line-height:1.5;
  -webkit-font-smoothing:antialiased;
  min-height:100%;display:flex;flex-direction:column;
}
/* Die mittigen Behälter brauchen ausdrücklich die volle Breite.

   Der Seitenkörper ist ein Flex-Container (Spalte, damit der Fuß unten steht). Darin
   bedeutet „margin:0 auto" auf einem Kind aber nicht mehr nur „mittig", sondern hebt
   das Strecken auf: Das Kind wird so breit wie sein Inhalt. Für das Raster des
   Kalkulators heißt das, dass die ganze Seite mit der Kategorie schmaler und breiter
   wird — bei „Compute Engine" mit langen Beschreibungen sah es richtig aus, bei
   „Network" mit einer Zeile schnurrte alles zusammen. Mit width:100% bleibt max-width
   die Grenze und auto die Mitte.

   Wer hier einen weiteren mittigen Behälter anlegt, trägt ihn mit ein. */
.shell,.admin-wrap,main.start,main.rechtsseite{width:100%}

a{color:var(--accent-2);text-decoration:none}
a:hover{text-decoration:underline}
button,input,select,textarea{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
/* Zahlen laufen in einer Zeile. Ein Betrag, dessen Eurozeichen in die nächste Zeile
   rutscht, sieht nicht nach einer engen Spalte aus, sondern nach einem Fehler — und
   wo es wirklich zu eng wird, ist ein waagerechter Schieber die ehrlichere Antwort
   als ein zerrissener Betrag. (Die Gegenüberstellung weiter unten nimmt das für ihre
   Artikelnummern ausdrücklich zurück.) */
.num{font-variant-numeric:tabular-nums;white-space:nowrap}
.mono{font-family:var(--fm)}

/* ---------------- Kopfzeile ---------------- */
.appbar{
  display:flex;align-items:center;gap:20px;
  background:var(--bg-2);border-bottom:1px solid var(--line);
  padding:0 22px;height:60px;position:sticky;top:0;z-index:30;
}
.appbar .logo{display:flex;align-items:center;gap:12px;min-width:0}
.appbar .logo img{height:26px;width:auto;display:block}
.appbar .app-title{
  font-weight:600;font-size:15px;letter-spacing:.02em;white-space:nowrap;
  padding-left:14px;margin-left:2px;border-left:1px solid var(--line-2);color:var(--ink-2);
}
/* Die Fassungsnummer. Sie steht klein neben dem Titel und muss keine Aufmerksamkeit
   auf sich ziehen — man sucht sie erst, wenn eine Rückfrage im Raum steht. */
.appbar .ver{
  display:inline-flex;align-items:center;gap:8px;
  font-size:11.5px;font-weight:600;letter-spacing:.04em;color:var(--muted);
  padding:2px 9px;margin-left:10px;border:1px solid var(--line-2);border-radius:999px;
  white-space:nowrap;cursor:default;
}
/* Das Datum der Auslieferung neben der Nummer. Es beantwortet die Frage, die bei
   einer Rückfrage als erste kommt: „auf welchem Stand läuft das bei euch?" */
.appbar .ver-datum{
  font-weight:400;letter-spacing:0;opacity:.8;
  padding-left:8px;border-left:1px solid var(--line-2);
}
/* Das Datum weicht früher als früher: Seit im Kopf zusätzlich das Zeichen des
   Moduls steht, wird es darunter eng, und zwei Angaben, die sich überlappen, sind
   schlechter als eine, die fehlt. */
@media (max-width:1400px){ .appbar .ver-datum{display:none} }
/* Und wenn es trotzdem eng wird, schrumpft der Titel, nicht die Angaben rechts. */
.appbar .logo{flex:0 1 auto;overflow:hidden}
.appbar .logo .app-title{overflow:hidden;text-overflow:ellipsis}
.appbar .spacer{margin-left:auto}
.who{display:flex;align-items:center;gap:14px;font-size:13px;color:var(--muted);white-space:nowrap}
.who b{color:var(--ink);font-weight:600}
.valid{
  display:inline-flex;align-items:center;gap:7px;font-size:12.5px;
  border:1px solid var(--line-2);border-radius:20px;padding:4px 12px;color:var(--ink-2);
}
.valid.soon{border-color:var(--warn);color:var(--warn)}
.valid.over{border-color:var(--danger);color:var(--danger)}

/* ---------------- Grundraster ---------------- */
.shell{
  display:grid;grid-template-columns:236px minmax(0,1fr) 350px;
  gap:18px;padding:18px 22px 120px;max-width:1720px;margin:0 auto;align-items:start;
}
@media (max-width:1280px){ .shell{grid-template-columns:220px minmax(0,1fr)} .est{grid-column:1/-1;position:static} }
@media (max-width:820px){ .shell{grid-template-columns:minmax(0,1fr)} .side{position:static} }

.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r)}
.card-h{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:12px 15px;border-bottom:1px solid var(--line);
  font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--muted);font-weight:600;
}

/* ---------------- Kategorien / Filter ---------------- */
.side{position:sticky;top:78px;display:flex;flex-direction:column;gap:16px}
.cats{display:flex;flex-direction:column;padding:6px}
.cat{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  background:none;border:0;border-radius:6px;padding:9px 11px;cursor:pointer;
  color:var(--ink-2);font-size:13.5px;text-align:left;width:100%;
}
.cat:hover{background:var(--panel-2);color:var(--ink)}
.cat[aria-pressed="true"]{background:var(--accent);color:var(--accent-ink);font-weight:600}
.cat[aria-pressed="true"] .n{color:var(--accent-ink);opacity:.7}
.cat .n{font-family:var(--fm);font-size:11.5px;color:var(--muted)}

.fgroup{padding:13px 15px;display:flex;flex-direction:column;gap:9px}
.fgroup+.fgroup{border-top:1px solid var(--line)}
.flabel{font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-weight:600}
.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{
  background:transparent;border:1px solid var(--line-2);color:var(--ink-2);
  border-radius:16px;padding:3px 11px;font-size:12px;cursor:pointer;font-family:var(--fm);
}
.chip:hover{border-color:var(--accent);color:var(--accent-2)}
.chip[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:600}
.field{width:100%;background:var(--bg-2);border:1px solid var(--line-2);border-radius:6px;padding:7px 10px;font-size:13px;color:var(--ink)}
.field::placeholder{color:var(--muted)}
.two{display:flex;gap:7px}
.linkbtn{background:none;border:0;color:var(--muted);font-size:11.5px;cursor:pointer;text-decoration:underline;text-underline-offset:2px;padding:0}
.linkbtn:hover{color:var(--accent-2)}

/* ---------------- Produkttabelle ---------------- */
.tablewrap{overflow:auto;max-height:calc(100vh - 152px);min-height:340px}
table.grid{border-collapse:collapse;width:100%;min-width:720px}
table.grid thead th{
  position:sticky;top:0;z-index:2;background:var(--panel);
  font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:600;
  text-align:left;padding:10px;border-bottom:1px solid var(--line-2);white-space:nowrap;cursor:pointer;user-select:none;
}
table.grid thead th.r{text-align:right}
table.grid tbody td{padding:7px 10px;border-bottom:1px solid var(--line);white-space:nowrap}
table.grid tbody tr:hover{background:var(--panel-2)}
table.grid td.r{text-align:right}
.flavor{font-family:var(--fm);font-size:13px;font-weight:500;color:var(--ink)}
.klasse{font-size:12.5px;color:var(--ink-2)}
.dim{color:var(--muted)}
.pm{font-family:var(--fm);font-size:13px;font-weight:600;color:var(--accent-2)}
.pill{
  display:inline-block;font-family:var(--fm);font-size:10px;padding:1px 7px;border-radius:10px;
  border:1px solid var(--line-2);color:var(--muted);
}
.pill.metro{border-color:var(--warn);color:var(--warn)}
.addbtn{
  border:1px solid var(--line-2);background:var(--bg-2);border-radius:6px;
  width:26px;height:24px;line-height:1;cursor:pointer;color:var(--ink-2);font-size:16px;
}
.addbtn:hover{border-color:var(--accent);background:var(--accent);color:var(--accent-ink)}
.nothing{padding:30px 16px;color:var(--muted)}

/* ---------------- Kalkulation ---------------- */
.est{position:sticky;top:78px;display:flex;flex-direction:column}
.line{display:grid;grid-template-columns:1fr auto;gap:3px 10px;padding:10px 15px;border-bottom:1px solid var(--line)}
.line .nm{font-family:var(--fm);font-size:12.5px;min-width:0;overflow-wrap:anywhere}
.line .sm{
  font-family:var(--fm);font-size:13px;font-weight:600;color:var(--accent-2);
  text-align:right;white-space:nowrap;
}
.line .meta{grid-column:1/-1;display:flex;align-items:center;gap:7px;color:var(--muted);font-size:11.5px}
.line .meta input{
  width:58px;background:var(--bg-2);border:1px solid var(--line-2);border-radius:5px;
  padding:2px 6px;font-family:var(--fm);font-size:11.5px;text-align:right;color:var(--ink);
}
.line .del{background:none;border:0;color:var(--muted);cursor:pointer;font-size:15px;margin-left:auto;padding:0 3px}
.line .del:hover{color:var(--danger)}
.sums{padding:14px 15px;display:flex;flex-direction:column;gap:7px;border-top:2px solid var(--line-2)}
/* Beschriftung links, Betrag rechts — und der Betrag bleibt in einer Zeile. Ein
   Umbruch zwischen Zahl und Eurozeichen sieht nicht nach Enge aus, sondern nach
   Fehler. Umbrechen darf die Beschriftung. */
.srow{display:flex;justify-content:space-between;align-items:baseline;gap:12px;font-size:13px}
.srow span{color:var(--muted);min-width:0}
.srow b{font-family:var(--fm);font-weight:500;flex:0 0 auto;white-space:nowrap;text-align:right}
/* Windows auf dediziertem Kern: ein Sonderweg am offiziellen Rechner vorbei.
   Fällt bewusst auf, damit niemand ihn versehentlich anbietet. */
.tag-ded{
  display:inline-block;font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;
  font-weight:700;padding:1px 5px;border-radius:4px;margin-left:6px;vertical-align:1px;
  background:#7A3E00;color:#FFD9A8;border:1px solid #A85E12
}
/* Metro Availability: zwei Rechenzentren statt eines. Im Zonenkürzel steht dafür ein
   angehängtes „-M" — das übersieht man, und dann steht die Frage im Raum, warum diese
   Maschine teurer ist als die daneben. Im Blau des Hauses, nicht in der Warnfarbe:
   Es ist eine Eigenschaft, keine Warnung. */
.tag-metro{
  display:inline-block;font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;
  font-weight:700;padding:1px 5px;border-radius:4px;margin-left:6px;vertical-align:1px;
  background:var(--accent);color:var(--accent-ink);border:1px solid var(--accent);
}
.sblock{margin-bottom:11px}
.sblock-h{
  font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--muted);
  font-weight:600;margin-bottom:4px;opacity:.8
}
.srow.metro span{color:var(--accent-2)}

/* Aufstellung oben, Rechnung unten.

   Der Endbetrag stand früher als weitere Zeile unter einem Strich — und klebte
   damit an der letzten Aufstellungszeile, als wäre er deren Fortsetzung. Er hat
   jetzt ein eigenes Feld: erst die drei Aufstellungen, dann abgesetzt die
   Herleitung (Listenpreis, Nachlass in Euro), dann der Betrag selbst mit Luft
   darum. Es ist die Zahl, die am Telefon vorgelesen wird. */
.sgruppen .sblock:last-child{margin-bottom:0}
.sabschluss{
  margin-top:15px;padding-top:13px;border-top:1px solid var(--line-2);
  display:flex;flex-direction:column;gap:7px;
}
.sabschluss .sblock-h{margin-bottom:0}
.sendbetrag{
  margin-top:8px;padding:12px 13px;border-radius:var(--r);
  background:var(--panel-2);border:1px solid var(--line);
  display:flex;flex-direction:column;gap:6px;
}
.srow.total{margin:0;padding:0;border-top:0}
.srow.total span{color:var(--ink);font-size:12px;letter-spacing:.08em;text-transform:uppercase;font-weight:600}
.srow.total b{font-size:21px;color:var(--accent-2);font-weight:700;line-height:1.15}
.srow.jahr{font-size:12px}
.srow.jahr b{color:var(--ink-2)}
.actions{display:flex;flex-direction:column;gap:8px;padding:0 15px 15px}
.btn{
  border:1px solid var(--line-2);background:var(--panel-2);border-radius:6px;
  padding:9px 12px;font-size:13px;cursor:pointer;color:var(--ink-2);text-align:center;
}
.btn:hover{border-color:var(--accent);color:var(--accent-2)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:600}
.btn.primary:hover{background:var(--accent-2);color:var(--accent-ink)}
.btn:disabled{opacity:.45;cursor:not-allowed}
.hint{padding:14px 15px;color:var(--muted);font-size:12px;line-height:1.5}
.saved{padding:10px 15px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:6px}
.saved .row{display:flex;align-items:center;gap:8px;font-size:12.5px}
.saved .row .nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---------------- Anmeldung ---------------- */
.auth{
  min-height:100vh;display:grid;place-items:center;padding:40px 20px;
  background:radial-gradient(1100px 500px at 50% -12%, #0A2F5C 0%, var(--bg) 62%);
}
.auth .box{width:100%;max-width:400px;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:30px}
.auth .box img.brand{height:30px;margin-bottom:22px;display:block}
.auth h1{font-size:19px;margin:0 0 4px;font-weight:600}
.auth p.lead{color:var(--muted);font-size:13px;margin:0 0 22px}
.auth label{display:block;font-size:12px;color:var(--muted);margin:0 0 5px}
.auth .fld{margin-bottom:14px}
.auth .field{padding:10px 12px}
.err{background:rgba(255,107,122,.12);border:1px solid var(--danger);color:#FFC2C9;border-radius:6px;padding:9px 12px;font-size:13px;margin-bottom:16px}
.ok{background:rgba(18,79,255,.14);border:1px solid var(--accent);color:var(--accent-2);border-radius:6px;padding:9px 12px;font-size:13px;margin-bottom:16px}
.warn{background:rgba(232,180,74,.12);border:1px solid var(--warn);color:#F0D296;border-radius:6px;padding:9px 12px;font-size:13px;margin-bottom:16px}
#importmsg{margin:10px 0 0;line-height:1.5}

/* ---------------- Admin ---------------- */
.admin-wrap{max-width:1200px;margin:0 auto;padding:22px 22px 80px}
.admin-nav{display:flex;gap:6px;margin-bottom:20px}
.admin-nav a{
  padding:7px 14px;border-radius:6px;border:1px solid var(--line-2);color:var(--ink-2);font-size:13px;text-decoration:none;
}
.admin-nav a.on{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:600}
h2.sec{font-size:16px;margin:0 0 14px;font-weight:600}
table.list{border-collapse:collapse;width:100%}
table.list th{
  text-align:left;font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--muted);
  font-weight:600;padding:10px;border-bottom:1px solid var(--line-2);
}
table.list td{padding:10px;border-bottom:1px solid var(--line);font-size:13.5px;vertical-align:middle}
table.list tr:hover td{background:var(--panel-2)}
.badge{display:inline-block;font-size:11px;padding:2px 9px;border-radius:10px;border:1px solid var(--line-2);color:var(--muted)}
.badge.on{border-color:var(--accent);color:var(--accent-2)}
.badge.off{border-color:var(--danger);color:var(--danger)}

/* Das × in der Sperrliste. Unauffällig, bis jemand darauf zielt: Eine Sperre
   aufzuheben ist eine Entscheidung, kein Nebenbei — aber wer deshalb anruft,
   soll den Knopf auch finden. */
/* Die Freigabe zum Schreiben in die Warenwirtschaft.

   Abgesetzt und in der Warnfarbe: Alles darüber im Formular ist Einrichtung, dieser
   eine Haken entscheidet, ob diese Anwendung drüben etwas anlegen darf. Ein Schalter
   mit dieser Tragweite darf nicht aussehen wie ein Häkchen unter vielen. */
.freigabe{
  margin-top:18px;padding:13px 15px;border-radius:var(--r);
  border:1px solid var(--warn);background:rgba(232,180,74,.08);
}
.freigabe label{display:inline-flex;align-items:center;gap:9px;cursor:pointer;color:var(--warn)}
.freigabe input{accent-color:var(--warn);margin:0;width:15px;height:15px}

.entsperren{
  background:none;border:1px solid var(--line-2);border-radius:6px;color:var(--muted);
  cursor:pointer;font-size:16px;line-height:1;padding:3px 9px 5px;
}
.entsperren:hover{border-color:var(--danger);color:var(--danger)}
.entsperren:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
@media (max-width:720px){ .form-grid{grid-template-columns:minmax(0,1fr)} }
.form-grid .full{grid-column:1/-1}
.lbl{display:block;font-size:12px;color:var(--muted);margin:0 0 5px}
.help{font-size:11.5px;color:var(--muted);margin:5px 0 0}
.stack{display:flex;flex-direction:column;gap:18px}
.inline{display:flex;gap:8px;align-items:flex-end;flex-wrap:wrap}
.urlbox{font-family:var(--fm);font-size:12.5px;color:var(--accent-2);background:var(--bg-2);border:1px solid var(--line-2);border-radius:6px;padding:8px 11px;display:inline-block}

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

/* ---------------- Druck ---------------- */
@media print{
  .appbar,.side,.actions,.card-h{display:none!important}
  body{background:#fff;color:#000}
}

/* ---------------- Produktkarten ---------------- */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:14px;padding:16px}
.pcard{
  background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r);
  padding:16px;text-align:left;cursor:pointer;color:var(--ink);display:flex;gap:13px;align-items:flex-start;
}
.pcard:hover{border-color:var(--accent)}
.pcard .ic{
  width:38px;height:38px;flex:0 0 38px;border-radius:8px;background:var(--bg-2);
  border:1px solid var(--line-2);display:grid;place-items:center;color:var(--accent-2);font-size:17px;
}
.pcard h3{margin:0 0 3px;font-size:14.5px;font-weight:600}
.pcard p{margin:0;font-size:12.5px;color:var(--muted);line-height:1.45}

/* ---------------- Dialog ---------------- */
.modal{position:fixed;inset:0;background:rgba(4,9,11,.72);display:grid;place-items:center;padding:24px;z-index:60}
.modal[hidden]{display:none}
.dlg{
  background:var(--panel);border:1px solid var(--line-2);border-radius:12px;
  width:min(760px,100%);max-height:88vh;display:flex;flex-direction:column;
}
.dlg-h{padding:18px 22px;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;gap:14px}
.dlg-h h2{margin:0;font-size:17px;font-weight:600}
.dlg-h .x{background:none;border:0;color:var(--muted);font-size:22px;cursor:pointer;line-height:1;padding:0 4px}
.dlg-h .x:hover{color:var(--ink)}
.dlg-b{padding:6px 22px 18px;overflow-y:auto}
.dlg-f{
  padding:16px 22px;border-top:1px solid var(--line);display:flex;align-items:center;
  justify-content:space-between;gap:16px;flex-wrap:wrap;
}
.dlg-f .tot{font-family:var(--fm);font-size:19px;font-weight:700;color:var(--accent-2)}
.dlg-f .tot small{display:block;font-family:var(--f);font-size:11px;font-weight:600;color:var(--muted);
  letter-spacing:.08em;text-transform:uppercase}
.sect{padding:16px 0;border-bottom:1px solid var(--line)}
.sect:last-child{border-bottom:0}
.sect > h4{
  margin:0 0 12px;font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-weight:600;
}
.grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
@media (max-width:620px){ .grid2{grid-template-columns:minmax(0,1fr)} }
.grid2 .wide{grid-column:1/-1}
.lbl2{display:block;font-size:12px;color:var(--muted);margin:0 0 5px}
select.field{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),linear-gradient(135deg,var(--muted) 50%,transparent 50%);
  background-position:calc(100% - 16px) 52%,calc(100% - 11px) 52%;background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:34px}
.seg{display:flex;gap:0;border:1px solid var(--line-2);border-radius:6px;overflow:hidden}
.seg button{
  flex:1;background:var(--bg-2);border:0;border-right:1px solid var(--line-2);
  padding:8px 10px;font-size:13px;color:var(--ink-2);cursor:pointer;
}
.seg button:last-child{border-right:0}
.seg button[aria-pressed="true"]{background:var(--accent);color:var(--accent-ink);font-weight:600}
.seg button:disabled{opacity:.35;cursor:not-allowed}
.check{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;padding:7px 0;cursor:pointer}
.check input{margin-top:3px}
.check span small{display:block;color:var(--muted);font-size:12px;margin-top:2px}
.check.tight{padding:8px 0 0;font-size:12.5px}
.projectcard{display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:18px 20px;text-decoration:none;color:inherit;transition:border-color .12s,background .12s}
.projectcard:hover{border-color:var(--accent);background:var(--panel-2);text-decoration:none}
.projectcard .pname{display:block;font-size:15px;color:var(--ink)}
.projectcard .pnote{display:block;margin-top:3px;font-size:12.5px;color:var(--muted)}
.projpick{display:flex;align-items:center;gap:8px}
.projpick select{background:var(--bg-2);border:1px solid var(--line-2);border-radius:6px;
  padding:4px 8px;font-size:12.5px;color:var(--ink);max-width:220px}
.field.code{font-family:var(--fm);font-size:22px;letter-spacing:.32em;text-align:center;padding:12px 10px}
.smtplog{margin:6px 0 0;padding:12px;background:var(--bg-2);border:1px solid var(--line);
  border-radius:6px;font-size:11.5px;max-height:280px;overflow:auto;white-space:pre-wrap;color:var(--ink-2)}
.field option:disabled{color:var(--muted)}
.breakdown{margin-top:14px;border-top:1px dashed var(--line-2);padding-top:12px}
.breakdown div{
  display:flex;justify-content:space-between;align-items:baseline;gap:12px;
  font-size:12.5px;padding:3px 0;color:var(--ink-2);
}
.breakdown div span:first-child{min-width:0;overflow-wrap:anywhere}
.breakdown div span:last-child{font-family:var(--fm);flex:0 0 auto;white-space:nowrap}
/* Bestandteile einer Position: Bezeichnung links, Betrag rechts.

   Der Betrag bleibt ganz: Er darf weder umbrechen noch schmaler werden, als er ist —
   sonst rutscht bei einer langen Bezeichnung („Performance Class 10 — 15.000 IOPS,
   300 MB/s") das Eurozeichen in die nächste Zeile und steht dort allein. Umbrechen
   darf die Bezeichnung, und nur sie; dafür braucht sie min-width:0, weil ein
   Flex-Element sonst nicht unter seine Inhaltsbreite schrumpft. */
.line .parts{grid-column:1/-1;margin-top:5px;display:flex;flex-direction:column;gap:2px}
.line .parts div{
  display:flex;justify-content:space-between;align-items:baseline;gap:10px;
  font-size:11.5px;color:var(--muted);
}
.line .parts div span:first-child{min-width:0;overflow-wrap:anywhere}
.line .parts div span:last-child{
  font-family:var(--fm);flex:0 0 auto;white-space:nowrap;text-align:right;
}
.line .edit{background:none;border:0;color:var(--muted);cursor:pointer;font-size:11.5px;
  text-decoration:underline;text-underline-offset:2px;padding:0}
.line .edit:hover{color:var(--accent-2)}

#sumrows{display:flex;flex-direction:column;gap:7px}

/* Gegenüberstellung STACKIT ↔ Azure: acht Spalten, dazu Anmerkungen in ganzen
   Sätzen. Ohne Umbruch schiebt ein langer Satz die Zahlenspalten aus dem Bild,
   deshalb hier feste Spaltenbreiten und umbrechender Text. */
table.grid.vergleich{table-layout:fixed;min-width:0}
table.grid.vergleich tbody td{white-space:normal;vertical-align:top}
table.grid.vergleich tbody td.r,
table.grid.vergleich tfoot td.r{white-space:nowrap}
table.grid.vergleich .flavor,
table.grid.vergleich .mono{overflow-wrap:anywhere}

/* ------------------------------------------------------------------
   Vertretung: Verwaltung oder Vertrieb arbeitet im Projekt eines Kunden.

   Die einzige rote Fläche der Anwendung, und das mit Absicht — sie ist kein
   Schmuck, sondern eine Warnung. Sie klebt oben, damit sie auch nach langem
   Scrollen im Blick bleibt, und nimmt den Weg hinaus gleich mit.
   ------------------------------------------------------------------ */
.standin{
  position:sticky;top:0;z-index:60;
  background:linear-gradient(180deg,#8E1220,#6E0C18);
  border-bottom:1px solid #B4202F;
  color:#FFE9EB;box-shadow:0 2px 10px rgba(0,0,0,.35);
}
.standin-in{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:9px 18px;max-width:1680px;margin:0 auto;font-size:13px;
}
.standin-dot{
  width:9px;height:9px;border-radius:50%;background:#FF8E99;flex:none;
  box-shadow:0 0 0 3px rgba(255,142,153,.22);
}
.standin-txt{flex:1 1 320px;min-width:0}
.standin-txt strong{color:#FFFFFF}
.standin-who{display:block;color:#F2BFC4;font-size:11.5px;margin-top:1px}
.standin-out{
  flex:none;color:#FFFFFF;border:1px solid rgba(255,255,255,.5);
  border-radius:6px;padding:5px 13px;font-size:12.5px;text-decoration:none;
}
.standin-out:hover{background:rgba(255,255,255,.14);text-decoration:none}
@media (max-width:640px){ .standin-in{padding:9px 14px} }

/* Projektwahl mit Beschriftung */
.projpick .plabel{color:var(--muted);font-size:11.5px;letter-spacing:.04em;text-transform:uppercase}
.projpick .pone{font-size:12.5px;color:var(--ink-2)}
.confsrc{display:block;font-size:10.5px;color:var(--muted);margin-top:1px}

/* ------------------------------------------------------------------
   Projektliste des Kunden: auswählen links, Gültigkeit in der Mitte,
   umbenennen und löschen rechts. Die Zeile ist kein Verweis mehr als
   Ganzes — sonst ließe sich darin nichts anklicken.
   ------------------------------------------------------------------ */
.projrow{
  display:flex;align-items:center;gap:18px;flex-wrap:wrap;padding:16px 20px;
  transition:border-color .12s,background .12s;
}
.projrow:hover{border-color:var(--line-2);background:var(--panel-2)}
.projrow.on{border-color:var(--accent)}
.projmain{flex:1 1 300px;min-width:0;text-decoration:none;color:inherit}
.projmain:hover{text-decoration:none}
.projmain:hover .pname{color:var(--accent-2)}
.projrow .pname{display:block;font-size:15px;color:var(--ink)}
.projrow .pnote{display:block;margin-top:3px;font-size:12.5px;color:var(--muted)}
.projacts{display:flex;align-items:center;gap:14px;font-size:12.5px;flex:none}
.projacts a{color:var(--muted);text-decoration:underline;text-underline-offset:2px}
.projacts a:hover{color:var(--accent-2)}
.linkbtn.danger:hover{color:var(--danger)}
.newproj{display:flex;align-items:flex-end;gap:14px;flex-wrap:wrap}
.renameform{display:flex;align-items:center;gap:10px;flex:1 1 100%;flex-wrap:wrap}
.renameform .field{flex:1 1 260px;min-width:0}
.renameform .btn{flex:none;min-width:150px;text-align:center;text-decoration:none}

/* Pluszeichen neben der Projektwahl im Kalkulator */
.projpick .plus{
  display:inline-flex;align-items:center;justify-content:center;
  width:24px;height:24px;flex:none;border:1px solid var(--line-2);border-radius:6px;
  background:var(--bg-2);color:var(--ink-2);font-size:16px;line-height:1;text-decoration:none;
}
.projpick .plus:hover{border-color:var(--accent);background:var(--accent);color:var(--accent-ink);text-decoration:none}

/* Bezeichnung wird erst beim Speichern erfragt */
.namebox{
  display:flex;flex-direction:column;gap:8px;padding:12px;margin-bottom:2px;
  background:var(--bg-2);border:1px solid var(--line-2);border-radius:6px;
}
.namebox .two{display:flex;gap:8px}
.namebox .two .btn{flex:1}

/* Unwiderrufliches: getrennt vom Rest, damit es nicht aus Versehen getroffen wird */
.card.danger-card{border-color:rgba(255,107,122,.35)}
.btn.danger{border-color:rgba(255,107,122,.5);color:var(--danger);background:transparent}
.btn.danger:hover{background:var(--danger);border-color:var(--danger);color:#2A0209}

/* ------------------------------------------------------------------
   Anbieterzeichen. Die Marken bleiben in ihren eigenen Farben — ein
   umgefärbtes fremdes Logo sieht falsch aus und darf auch nicht einfach
   geändert werden. Lesbar werden sie über die helle Fläche darunter.
   ------------------------------------------------------------------ */
.brand{display:inline-flex;align-items:center;gap:9px;vertical-align:middle}
.brand .mark{
  display:inline-flex;align-items:center;justify-content:center;flex:none;
  background:#FFFFFF;border-radius:5px;padding:3px 7px;line-height:0;
  box-shadow:0 1px 2px rgba(0,0,0,.25);
}
.brand .mark img{display:block;width:auto}
.brand .bname{white-space:nowrap}
/* Im Tabellenkopf steht das Zeichen für sich, der Name daneben klein */
th .brand{gap:7px}
th .brand .mark{padding:2px 5px;border-radius:4px}
h2.sec .brand{margin-left:2px}

/* ------------------------------------------------------------------
   Unverbindlichkeitsvermerk. Steht auf jeder Seite mit Preisen und in
   jedem PDF. Auffällig genug, dass ihn niemand überlesen kann, ohne die
   Seite zu beherrschen — deshalb gelb und nicht rot: Rot ist in dieser
   Anwendung für Fehler und für die Vertretung reserviert.
   ------------------------------------------------------------------ */
.unverbindlich{
  display:flex;align-items:center;gap:11px;
  margin:0 0 16px;padding:10px 16px;
  background:rgba(232,180,74,.12);
  border:1px solid rgba(232,180,74,.55);
  border-left:4px solid var(--warn);
  border-radius:6px;
  color:var(--warn);font-size:13px;font-weight:600;letter-spacing:.01em;
}
/* Der zweite Satz steht unter dem ersten, etwas ruhiger: Die Herkunft ist die
   Aussage, auf die es ankommt; dass die Zahlen kein Angebot sind, kommt danach. */
.unverbindlich .uv-zweit{display:block;font-weight:500;opacity:.85;margin-top:2px}
.unverbindlich .uv-zeichen{
  display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:20px;height:20px;border-radius:50%;
  background:var(--warn);color:#2A1D00;font-weight:700;font-size:13px;line-height:1;
}
/* Im Kalkulator steht der Vermerk unter der Arbeitsfläche, mittig und in der
   Breite begrenzt. Oben als Band nahm er jedem Aufruf eine Zeile weg, ohne je
   wieder gelesen zu werden; unten steht er dort, wo der Blick nach dem Rechnen
   ohnehin hinfällt — unter der Summe. */
.unverbindlich.unten{
  margin:26px auto 30px;max-width:70ch;
  justify-content:center;text-align:center;
  border-left:1px solid rgba(232,180,74,.55);
}
/* Der Kasten und der Vermerk stehen untereinander in der Mitte. */
.auth{grid-auto-rows:min-content;align-content:center;justify-items:center}

/* --------------------------------------------------------------------------
   Seitenzahlen unter langen Listen.

   Bis zum 13.09.2026 standen Protokolle ungekürzt auf der Seite — nach ein paar
   Wochen Betrieb waren das mehrere Bildschirmhöhen, durch die niemand mehr scrollte.
   Jetzt sind es zehn Zeilen und darunter diese Leiste.
   -------------------------------------------------------------------------- */
.pager{
  display:flex;align-items:center;gap:4px;flex-wrap:wrap;
  padding:14px 12px;font-size:13px;
}
.pager a,.pager .hier,.pager .aus,.pager .luecke{
  min-width:30px;padding:5px 9px;border-radius:7px;text-align:center;
  border:1px solid transparent;
}
.pager a{color:var(--ink-2);text-decoration:none;border-color:var(--line-2)}
.pager a:hover{background:var(--panel-2);color:var(--ink)}
.pager .hier{background:var(--accent);color:#fff;font-weight:600}
.pager .aus{color:var(--muted);opacity:.45}
.pager .luecke{color:var(--muted);border:0;min-width:0;padding:5px 2px}

/* Ein Verweis, der etwas endgültig entfernt, sieht anders aus als einer, der
   irgendwohin führt. Er ruft die Rückfrageseite auf, nicht die Löschung selbst. */
a.loeschen{color:var(--danger)}
a.loeschen:hover{text-decoration:underline}

/* --------------------------------------------------------------------------
   Die Startseite des Kunden: welche Anwendungen für ihn freigeschaltet sind.

   Bis zum 13.09.2026 führte die Anmeldung geradewegs in den Kalkulator. Seit es
   mehrere Werkzeuge gibt, steht diese Auswahl davor.
   -------------------------------------------------------------------------- */
main.start{max-width:1080px;margin:0 auto;padding:44px 24px 60px}
.start-h{font-size:26px;font-weight:650;letter-spacing:-.01em;margin:0 0 8px;color:var(--ink)}
.start-lead{margin:0 0 30px;color:var(--muted);font-size:14.5px;max-width:76ch;line-height:1.6}

.kacheln{
  display:grid;gap:18px;
  grid-template-columns:repeat(auto-fill,minmax(290px,1fr));
}
.kachel{
  display:flex;flex-direction:column;gap:8px;
  padding:24px 22px 20px;text-decoration:none;
  background:var(--panel);border:1px solid var(--line);border-radius:14px;
  transition:border-color .12s,background .12s,transform .12s;
}
.kachel:hover{background:var(--panel-2);border-color:var(--line-2);transform:translateY(-2px)}
.kachel:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.kachel-icon{
  display:inline-flex;align-items:center;justify-content:center;
  width:60px;height:60px;margin-bottom:8px;border-radius:13px;
  background:var(--bg-2);border:1px solid var(--line);
}
.kachel-name{font-size:17px;font-weight:640;color:var(--ink)}
.kachel-kurz{font-size:13px;color:var(--muted);line-height:1.55;flex:1}
.kachel-los{font-size:13px;font-weight:600;color:var(--accent-2);margin-top:6px}

/* Dieselben Kacheln in der Verwaltung, nur ruhiger — dort stehen sie neben
   Abschnitten, die nichts mit Modulen zu tun haben. */
.kacheln.klein{grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px}
.kacheln.klein .kachel{padding:18px 18px 16px}
.kacheln.klein .kachel-icon{width:46px;height:46px;border-radius:11px;margin-bottom:4px}
.kacheln.klein .kachel-name{font-size:15px}
.kacheln.klein .kachel-kurz{font-size:12.5px}

/* Der Weg zurück aus einer Modulseite in die Übersicht. */
.zurueck{
  display:inline-flex;align-items:center;gap:7px;
  font-size:13px;color:var(--ink-2);text-decoration:none;
  margin-bottom:14px;
}
.zurueck:hover{color:var(--ink);text-decoration:underline}

/* Der Titel im Kopf eines Moduls führt zurück zur Auswahl. */
.appbar a.modlink{
  display:inline-flex;align-items:center;gap:8px;
  color:var(--ink-2);text-decoration:none;
}
.appbar a.modlink:hover{color:var(--ink)}
.appbar a.modlink .modicon{flex:none}

/* Die Flagge neben einer Adresse. Etwas größer als der Text daneben, damit sie
   auf einen Blick erkennbar ist, und in der Schrift des Systems — Bilddateien
   braucht es dafür nicht. */
.flagge{
  font-size:1.15em;line-height:1;vertical-align:-.08em;
  font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif;
}

/* Listenpreis und Nachlass über dem Endpreis. Der Listenpreis steht ruhig da, der
   Nachlass in der Akzentfarbe: er ist das, was der Kunde davon hat. */
.srow.liste span,.srow.liste b{color:var(--muted)}
.srow.liste b{font-weight:500}
.srow.nachlass span{color:var(--ink-2)}
.srow.nachlass small{color:var(--muted);font-size:11.5px;margin-left:5px}
.srow.nachlass b{color:var(--accent-2)}
/* Der durchgestrichene Listenpreis an einem Bestandteil. */
.parts s.lp{color:var(--muted);opacity:.75;margin-right:6px;text-decoration-thickness:1px}

/* --------------------------------------------------------------------------
   Das Warnzeichen im Anbietervergleich.

   Rot, wo STACKIT teurer ist als der Wettbewerb — dort besteht Handlungsbedarf.
   Wo STACKIT günstiger ist, steht ein ruhiger Haken: das ist der Normalfall und
   soll nicht um dieselbe Aufmerksamkeit werben.
   -------------------------------------------------------------------------- */
.ampel{display:inline-flex;align-items:center;gap:4px;font-size:12px;white-space:nowrap}
.ampel b{font-weight:650}
.ampel.teuer{
  color:var(--danger);font-weight:600;
  background:rgba(255,107,122,.1);border:1px solid rgba(255,107,122,.32);
  border-radius:6px;padding:2px 7px;
}
.ampel.guenstig{color:#57C98A}
.ampel.gleich{color:var(--muted)}

/* --------------------------------------------------------------------------
   Die Farbe eines Moduls.

   Jedes Modul hat eine eigene; der Cloud-Kalkulator ist gelb. Sie zieht sich
   durch die Kachel beim Kunden, die Übersicht der Verwaltung und die Abschnitte
   in den Stammdaten, die zu diesem Modul gehören — dort stehen sonst Angaben
   nebeneinander, die für alles gelten, und solche, die nur ein Werkzeug betreffen,
   ohne dass man es sieht.
   -------------------------------------------------------------------------- */
.modmarke{
  display:inline-flex;align-items:center;gap:6px;
  font-size:11px;font-weight:600;letter-spacing:.03em;text-transform:uppercase;
  color:var(--modfarbe);
  padding:3px 9px 3px 7px;border-radius:999px;
  border:1px solid color-mix(in srgb,var(--modfarbe) 42%,transparent);
  background:color-mix(in srgb,var(--modfarbe) 12%,transparent);
  white-space:nowrap;vertical-align:middle;
}
.modmarke .modicon{flex:none}

/* Ein Abschnitt, der zu einem Modul gehört, trägt links dessen Farbe. */
.card.modul{border-left:3px solid var(--modfarbe)}
.card.modul .sec{display:flex;align-items:center;gap:12px;flex-wrap:wrap}

/* Die Kachel eines Moduls nimmt die Farbe auf: Rahmen des Sinnbilds, der Rand
   beim Überfahren und der Weiterverweis darunter. */
.kachel{--modfarbe:var(--accent-2)}
.kachel:hover{border-color:color-mix(in srgb,var(--modfarbe) 55%,var(--line-2))}
.kachel .kachel-icon{
  border-color:color-mix(in srgb,var(--modfarbe) 38%,var(--line));
  background:color-mix(in srgb,var(--modfarbe) 10%,var(--bg-2));
}
.kachel .kachel-los{color:var(--modfarbe)}

/* Gegenstück zur Modulmarke: was für alle Anwendungen gilt, sagt es auch. */
.zentral{
  display:inline-flex;align-items:center;
  font-size:11px;font-weight:600;letter-spacing:.03em;text-transform:uppercase;
  color:var(--muted);padding:3px 9px;border-radius:999px;
  border:1px solid var(--line-2);white-space:nowrap;vertical-align:middle;
}

/* Die Modulauswahl in den Stammdaten trägt die Farbe des jeweiligen Moduls —
   dieselbe, mit der seine Abschnitte weiter unten markiert sind. */
.check.modwahl{
  padding:10px 14px;border-radius:10px;
  border:1px solid var(--line);background:var(--bg-2);
}
.check.modwahl:hover{border-color:color-mix(in srgb,var(--modfarbe) 45%,var(--line-2))}
.check.modwahl:has(input:checked){
  border-color:color-mix(in srgb,var(--modfarbe) 55%,transparent);
  background:color-mix(in srgb,var(--modfarbe) 9%,var(--bg-2));
}

/* --------------------------------------------------------------------------
   Der Umschalter zwischen heller und dunkler Ansicht.

   Gezeigt wird das Sinnbild der Ansicht, in die es geht — nicht das der
   aktuellen. Ein Schalter, der zeigt, wo man ist, lässt jeden zweimal klicken.
   -------------------------------------------------------------------------- */
.ansicht{
  display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;flex:none;
  background:none;border:1px solid var(--line-2);border-radius:9px;
  color:var(--ink-2);cursor:pointer;
  transition:background .12s,color .12s,border-color .12s;
}
.ansicht:hover{background:var(--panel-2);color:var(--ink);border-color:var(--ink-2)}
.ansicht svg{display:block}
/* In der dunklen Ansicht führt der Weg ins Helle: Sonne. Und umgekehrt. */
.ansicht .ans-mond{display:none}
:root[data-theme="hell"] .ansicht .ans-sonne{display:none}
:root[data-theme="hell"] .ansicht .ans-mond{display:block}

/* Auf den Anmeldeseiten gibt es keine Kopfzeile — dort schwebt der Schalter. */
.ansicht-frei{position:fixed;top:16px;right:16px;z-index:40}
.ansicht-frei .ansicht{background:var(--panel);box-shadow:var(--schatten)}

/* Das Hauszeichen liegt in zwei Fassungen vor; sichtbar ist die zur Ansicht
   passende. Weiß auf weiß wäre nichts. */
/* Beide Fassungen stehen im Text, verborgen wird die unpassende. Die Auswahl muss
   spezifischer sein als „.appbar .logo img", sonst gewinnt dort die Höhenangabe
   samt display:block und es stehen zwei Zeichen nebeneinander. */
:root:not([data-theme="hell"]) img.hz-hell,
:root[data-theme="hell"] img.hz-dunkel{display:none}

/* In der hellen Ansicht ist der Kopf hell — die Trennlinie darunter trägt dann
   die Abgrenzung, nicht mehr der Farbunterschied. */
:root[data-theme="hell"] .appbar{box-shadow:var(--schatten)}
/* Der Sternenhimmel hinter der Anmeldung passt nur ins Dunkle. */
:root[data-theme="hell"] .auth{
  background:radial-gradient(1100px 500px at 50% -12%, #E3ECF7 0%, var(--bg) 62%);
}

/* ==========================================================================
   Tablet und Telefon
   ==========================================================================
   Die Anwendung ist für einen breiten Bildschirm entworfen — drei Spalten,
   eine Tabelle mit zwölf Feldern je Zeile. Auf einem Telefon ist davon nichts
   zu halten, also wird umgeräumt statt verkleinert: Spalten untereinander,
   Tabellen in einen eigenen Schiebebereich, Knöpfe groß genug für einen Daumen.

   Zwei Stufen reichen: ab 1000px liegt ein Tablet quer oder ein kleines
   Fenster vor, ab 640px ein Telefon. Was dazwischen schon eng wurde, ist oben
   an Ort und Stelle geregelt (etwa das Raster des Kalkulators).

   Eine Regel gilt überall: nichts darf seitlich hinausragen. Wo eine Tabelle
   breiter ist als der Bildschirm, schiebt sie sich in ihrem eigenen Kasten —
   die Seite selbst bleibt stehen.
   ========================================================================== */

@media (max-width:1000px){
  /* Kopfzeile: darf umbrechen und wächst dann mit, statt zu quetschen. */
  .appbar{
    height:auto;min-height:56px;gap:12px 14px;padding:9px 16px;flex-wrap:wrap;
    align-items:center;
  }
  .appbar .spacer{display:none}
  .who{margin-left:auto;gap:10px;flex-wrap:wrap;justify-content:flex-end}

  .shell{padding:14px 16px 90px;gap:14px}
  .admin-wrap{padding:18px 16px 70px}
  main.start{padding:30px 18px 50px}

  /* Die Produkttabelle hat keine feste Höhe mehr: auf einem kurzen Bildschirm
     stünde sonst ein Fenster im Fenster, und man scrollt zweimal. */
  .tablewrap{max-height:none;min-height:0}
  .est,.side{position:static}

  .kacheln{grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:14px}

  /* Eine breite Tabelle schiebt sich in ihrem Kasten, statt die Seite
     hinauszuschieben. Schon auf dem Tablet nötig: die Zugangsliste hat allein
     sechs Spalten, und eine davon ist ein Formular. */
  .card{overflow-x:auto}
}

@media (max-width:640px){
  /* Auf dem Telefon zählt jede Zeile Höhe. Der Titel weicht, die Fassungsnummer
     bleibt — sie ist die Frage, die am Telefon gestellt wird. */
  .appbar{padding:8px 12px;gap:8px 10px}
  .appbar .app-title{
    padding-left:0;margin-left:0;border-left:0;font-size:14px;
  }
  .appbar .ver{margin-left:0;font-size:11px;padding:1px 7px}
  .appbar .logo{gap:9px}
  .appbar .logo img{height:22px}
  .who{font-size:12.5px;gap:9px;width:100%;justify-content:flex-start}

  .shell{padding:12px 12px 80px;gap:12px}
  .admin-wrap{padding:14px 12px 60px}
  main.start{padding:24px 14px 40px}
  .start-h{font-size:22px}
  .start-lead{font-size:13.5px;margin-bottom:22px}

  /* Karten und Kacheln stehen untereinander — nebeneinander wären sie
     schmaler als ihr eigener Text. */
  .kacheln,.kacheln.klein{grid-template-columns:minmax(0,1fr)}
  .cards{grid-template-columns:minmax(0,1fr);padding:12px;gap:10px}
  .grid2{grid-template-columns:minmax(0,1fr)}

  /* Ohne die Mindestbreite fielen die Spalten auf Buchstabenbreite zusammen
     und die Zahlen brächen in drei Zeilen um — lesbar ist das nicht mehr. */
  .admin-wrap table.list{min-width:560px}
  table.grid{min-width:660px}
  .tablewrap{overflow-x:auto}

  /* Formulare einspaltig, Eingabefelder auf volle Breite. */
  .form-grid{grid-template-columns:minmax(0,1fr);gap:13px}
  .inline{gap:8px}
  .inline .field{flex:1 1 100%;min-width:0}
  .field{font-size:16px}   /* darunter zoomt iOS beim Antippen hinein */

  /* Etwas zum Treffen: 38px hoch ist die untere Grenze für einen Daumen. */
  .btn,.admin-nav a{min-height:38px;display:inline-flex;align-items:center;
                    justify-content:center;padding:8px 13px}
  .addbtn{width:32px;height:30px;font-size:17px}
  .cat{padding:11px}
  .chip{padding:5px 12px}

  /* Die Navigation der Verwaltung als schiebbare Leiste statt als Knäuel. */
  .admin-nav{
    overflow-x:auto;flex-wrap:nowrap;gap:6px;
    margin:0 -12px 16px;padding:0 12px 4px;
    scrollbar-width:none;
  }
  .admin-nav::-webkit-scrollbar{display:none}
  .admin-nav a{white-space:nowrap}

  /* Der Dialog füllt den Bildschirm, die Knöpfe stehen untereinander und
     reichen von Rand zu Rand — am Telefon trifft man sonst daneben. */
  .modal{padding:0;place-items:stretch}
  .dlg{max-width:none;width:100%;max-height:100vh;border-radius:0;height:100%}
  .dlg-h{padding:14px 16px}
  .dlg-b{padding:6px 16px 14px}
  .dlg-f{flex-direction:column;align-items:stretch;gap:10px;padding:14px 16px}
  .dlg-f > div{display:flex;gap:10px}
  .dlg-f .btn{flex:1}

  /* Die Kalkulation steht unter der Tabelle und darf dort Platz haben. */
  .srow.total b{font-size:19px}
  .actions .btn{min-height:42px}

  .auth{padding:28px 14px;min-height:100dvh}
  .auth .box{padding:22px 18px}
  .ansicht-frei{top:10px;right:10px}

  .unverbindlich{font-size:12px;padding:9px 12px;gap:9px}
  .unverbindlich.unten{margin:20px 12px 24px;max-width:none}

  /* Ein Kasten mit fester Breite im Fließtext bricht die Seite auf. */
  .urlbox{max-width:100%;overflow-wrap:anywhere}
  .tablewrap table.grid td,.tablewrap table.grid th{padding:8px}
}

/* Wo es keinen Mauszeiger gibt, hilft kein Schwebezustand — dafür stören die
   Bewegungen beim Antippen. */
@media (hover:none){
  .kachel:hover{transform:none}
}

/* --------------------------------------------------------------------------
   Der Fuß jeder Seite und das Blatt, das sich darüberlegt.

   Impressum und Datenschutz gehören auf jede Seite — aber nicht als Weg aus der
   Anwendung hinaus: Wer den Kalkulator verlässt, um das Impressum zu lesen,
   kommt zurück und wartet erst einmal auf seine Kalkulation. Deshalb legt sich
   der Text als Blatt darüber, und darunter steht alles, wie es stand.
   -------------------------------------------------------------------------- */
.seitenfuss{
  display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  margin-top:auto;padding:16px 22px;
  border-top:1px solid var(--line);
  font-size:12px;color:var(--muted);
}
.seitenfuss .fusslinks{display:flex;align-items:center;gap:10px}
.seitenfuss .linkbtn{font-size:12px;color:var(--ink-2)}
.seitenfuss .linkbtn:hover{color:var(--accent-2)}

.rechtsblatt{
  position:fixed;inset:0;z-index:80;
  background:rgba(4,9,11,.72);
  display:grid;place-items:center;padding:28px 16px;
}
:root[data-theme="hell"] .rechtsblatt{background:rgba(11,31,46,.38)}
.rechtsblatt[hidden]{display:none}
.rechtsblatt-innen{
  width:100%;max-width:820px;max-height:88vh;display:flex;flex-direction:column;
  background:var(--panel);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 18px 48px rgba(0,0,0,.4);
}
.rechtsblatt-kopf{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:16px 22px;border-bottom:1px solid var(--line);
}
.rechtsblatt-kopf h2{margin:0;font-size:17px;font-weight:600}
.rechtsblatt-kopf .x{
  background:none;border:0;color:var(--muted);font-size:26px;line-height:1;
  cursor:pointer;padding:0 6px;
}
.rechtsblatt-kopf .x:hover{color:var(--ink)}
.rechtsblatt-text{
  padding:8px 22px 26px;overflow-y:auto;
  font-size:13.5px;line-height:1.7;color:var(--ink-2);
}
.rechtsblatt-text h3{
  margin:22px 0 6px;font-size:13px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink);
}
.rechtsblatt-text h3:first-child{margin-top:14px}
.rechtsblatt-text p{margin:0 0 12px}

/* Dieselben Texte als eigene Seite — wenn jemand die Adresse unmittelbar aufruft. */
main.rechtsseite{max-width:780px;margin:0 auto;padding:48px 24px 70px}
main.rechtsseite h1{font-size:24px;font-weight:650;margin:0 0 20px}
.rechtstext{font-size:14px;line-height:1.75;color:var(--ink-2)}
.rechtstext h3{
  margin:26px 0 7px;font-size:13px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink);
}
.rechtstext p{margin:0 0 13px}

@media (max-width:640px){
  .seitenfuss{padding:14px 12px;gap:8px}
  .rechtsblatt{padding:0}
  .rechtsblatt-innen{max-width:none;max-height:100vh;height:100%;border-radius:0;border:0}
}

/* --------------------------------------------------------------------------
   Der Einkauf des Hauses.

   Steht nur auf Bildschirmen, an denen jemand aus dem Haus sitzt. Damit das auch
   so aussieht — und niemand die Zahl versehentlich vorliest, während ein Kunde
   danebensteht —, ist der Block abgesetzt und in der Warnfarbe gehalten: dasselbe
   Gelb, das in dieser Anwendung „aufpassen" bedeutet.
   -------------------------------------------------------------------------- */
.ek-block{
  margin-top:12px;padding:11px 0 0;
  border-top:1px dashed rgba(232,180,74,.5);
}
.srow.ek{color:var(--warn)}
.srow.ek span{color:var(--warn);opacity:.85}
.srow.ek b{color:var(--warn)}
.srow.ek small{font-weight:400;opacity:.75;margin-left:5px}
.srow.ek.dim,.srow.ek.dim b,.srow.ek.dim span{opacity:.7;font-size:12px}
.srow.ek.marge{margin-top:5px;padding-top:6px;border-top:1px solid rgba(232,180,74,.28)}
.srow.ek.marge b{font-size:15px;font-weight:700}
.ek-hinweis{
  margin:9px 0 0;font-size:10.5px;line-height:1.45;color:var(--warn);opacity:.72;
}
/* Je Position, unter der Zeile — in derselben Farbe, damit der Blick sie als
   zusammengehörig liest. */
.zeile-ek{
  grid-column:1/-1;display:flex;justify-content:space-between;gap:10px;
  margin-top:4px;font-family:var(--fm);font-size:11.5px;color:var(--warn);opacity:.85;
}
.zeile-ek span:first-child{min-width:0}
.zeile-ek span:last-child{flex:0 0 auto;white-space:nowrap}

/* Der Schalter für den Einkaufspreis in der Kopfzeile der Kalkulation. */
.ek-schalter{
  display:inline-flex;align-items:center;gap:6px;cursor:pointer;
  font-size:11px;letter-spacing:.08em;color:var(--warn);
  padding:2px 8px 2px 6px;border:1px solid rgba(232,180,74,.45);border-radius:999px;
}
.ek-schalter input{accent-color:var(--warn);margin:0;width:13px;height:13px}
.ek-schalter:hover{border-color:var(--warn)}

/* Die Leiste darunter: was der Kunde sehen soll.

   Sie steht zwischen Kopf und Positionen und nicht im Kopf selbst — dort wäre sie
   die vierte Bedienung in einer Zeile, die auf einem schmalen Schirm ohnehin schon
   umbricht. Zurückhaltend gehalten: Es sind Ansichtsschalter, keine Preisangaben. */
.anzeigeleiste{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;
  padding:8px 15px;border-bottom:1px solid var(--line);background:var(--panel-2);
  font-size:11.5px;color:var(--ink-2);
}
.anzeigeleiste .al-titel{
  font-size:10px;letter-spacing:.09em;text-transform:uppercase;color:var(--muted);font-weight:600;
}
.anzeigeleiste label{display:inline-flex;align-items:center;gap:6px;cursor:pointer}
.anzeigeleiste input{accent-color:var(--accent);margin:0;width:13px;height:13px}
.anzeigeleiste label:hover{color:var(--ink)}
.anzeigeleiste .al-fuss{margin-left:auto;font-size:10.5px;color:var(--muted)}
@media (max-width:520px){ .anzeigeleiste .al-fuss{margin-left:0} }

/* Stehen die Positionen zum Listenpreis, passen sie nicht zur Summe darunter — der
   Satz dazu gehört zwischen beide, nicht in eine Fußnote am Seitenende. */
.zeilenhinweis{
  margin:0;padding:8px 15px;font-size:11px;line-height:1.45;color:var(--muted);
  border-top:1px dashed var(--line);
}

/* Trägt ein Modul ein Wortzeichen statt eines gezeichneten Sinnbilds, wächst sein
   Feld in die Breite mit. Ein Schriftzug in einem Quadrat wird sonst so klein, dass
   er nicht mehr zu lesen ist — und ein unleserliches Logo ist schlechter als keines.

   Die Klasse „breit" setzt die Ansicht (Module::hatZeichen), nicht das Stylesheet
   über :has(). Der Unterschied zählt: Hängt die Breite des Feldes an einer
   Fähigkeit des Browsers, steht das Zeichen dort, wo sie fehlt, über den Rand
   hinaus — und genau so sah es aus. */
/* Das display steht hier und nicht im style-Attribut des Bildes: sonst schlüge es
   die Regel, die von heller und dunkler Fassung die unpassende ausblendet. */
img.modicon{display:block;max-width:100%}
.kachel-icon.breit,
.kachel-icon:has(img.modicon){
  /* Nicht quadratisch, sondern so breit wie das Zeichen es braucht — und keinen
     Punkt breiter als die Kachel selbst. */
  width:-moz-fit-content;width:fit-content;
  min-width:72px;max-width:100%;padding:0 18px;overflow:hidden;
}
.kacheln.klein .kachel-icon.breit,
.kacheln.klein .kachel-icon:has(img.modicon){
  /* Die Breite muss hier noch einmal stehen: .kacheln.klein .kachel-icon setzt sie
     auf 46px und ist spezifischer als .kachel-icon.breit. Ohne diese Zeile bliebe
     der Kasten schmal und das Zeichen ragte darüber hinaus — genau der Fehler, den
     diese Regeln beheben sollen. */
  width:-moz-fit-content;width:fit-content;
  min-width:56px;max-width:100%;padding:0 13px;
}
/* In der Kopfzeile steht das Zeichen neben dem Titel und braucht etwas Luft. */
.appbar a.modlink img.modicon{margin-right:2px}

/* Der Hinweis, wenn kein Einkaufsrabatt hinterlegt ist. Er steht an derselben
   Stelle wie sonst die Zahlen — wer den Schalter umlegt, bekommt eine Antwort,
   auch wenn die Antwort „dafür fehlt eine Angabe" lautet. */
.ek-fehlt{
  font-size:11.5px;line-height:1.55;color:var(--warn);
}
.ek-fehlt a{color:var(--warn);text-decoration:underline;text-underline-offset:2px}
