/* wifi-qr — mobile-first, light/dark via prefers-color-scheme, print styles at the end */

:root {
  color-scheme: light;
  --accent: #0e7490;
  --accent-strong: #155e75;
  --bg: #f1f5f9;
  --panel: #ffffff;
  --text: #0f172a;
  --text-soft: #627188;   /* 4,52 auf --bg (vorher #64748b: 4,34) */
  --border: #e2e8f0;
  --error: #dc2626;
  --card-bg: #ffffff;
  --card-text: #0f172a;
  --card-soft: #64748b;
  --shadow: 0 10px 30px rgba(15, 23, 42, 0.10);
}

/* Dark theme comes in two doors with identical furniture:
   1) system preference (unless the user forced light),
   2) the theme dropdown forcing dark. Keep both in sync! */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --accent: #22d3ee;
    --accent-strong: #67e8f9;
    --bg: #0b1220;
    --panel: #101a2c;
    --text: #e2e8f0;
    --text-soft: #94a3b8;
    --border: #1e293b;
    --error: #f87171;
    --shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
    /* the card itself stays light: it is a preview of a printed object */
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --accent: #22d3ee;
  --accent-strong: #67e8f9;
  --bg: #0b1220;
  --panel: #101a2c;
  --text: #e2e8f0;
  --text-soft: #94a3b8;
  --border: #1e293b;
  --error: #f87171;
  --shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  /* the card itself stays light: it is a preview of a printed object */
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.app-shell {
  max-width: 62rem;
  margin: 0 auto;
  padding: 1rem 1rem 2rem;
}

/* ---------- header ---------- */

.site-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.75rem 1rem;
  padding: 0.5rem 0 1.25rem;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex: 1 1 18rem;
}

.brand-icon { width: 46px; height: 46px; flex: none; }

.brand h1 { margin: 0; font-size: 1.35rem; line-height: 1.2; }

.tagline { margin: 0.15rem 0 0; color: var(--text-soft); font-size: 0.92rem; }

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

.lang-wrap select,
#printMode,
.install-btn {
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 0.45rem 0.6rem;
  font: inherit;
  font-size: 0.9rem;
}

/* Install button: looks like the selects next to it, hidden until the browser offers
   installation (see app.js). On phones it gets a full row of its own. */
.install-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.install-btn[hidden] { display: none; }
.install-btn svg { flex: none; }
.install-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 560px) {
  .header-controls { flex: 1 1 100%; flex-wrap: wrap; }
  .install-btn { flex: 1 1 100%; }
}

/* ---------- layout ---------- */

main {
  display: grid;
  gap: 1.25rem;
  /* minmax(0, 1fr) statt 1fr: Sonst wird die Spalte so breit wie ihr breitester Inhalt, auf Russisch
     schob das bei 320 px das Formular ueber den Rand. */
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

@media (min-width: 760px) {
  main { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 1rem;
  padding: 1.25rem;
}

/* ---------- form ---------- */

.field { margin-bottom: 1rem; }

.field label { display: block; font-weight: 600; font-size: 0.92rem; margin-bottom: 0.35rem; }

.field input[type="text"],
.field input[type="password"],
.field select {
  width: 100%;
  font: inherit;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 0.6rem;
  padding: 0.65rem 0.75rem;
}

.field input:focus-visible,
.field select:focus-visible,
.btn:focus-visible,
.icon-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.password-wrap { position: relative; }

.password-wrap input { padding-right: 2.8rem; }

.icon-btn {
  position: absolute;
  right: 0.3rem;
  top: 50%;
  transform: translateY(-50%);
  border: none;
  background: none;
  color: var(--text-soft);
  padding: 0.45rem;
  cursor: pointer;
  border-radius: 0.5rem;
}

.icon-btn[aria-pressed="true"] { color: var(--accent); }

.checks { display: grid; gap: 0.5rem; }

.check {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.95rem;
  cursor: pointer;
}

.check input { width: 1.1rem; height: 1.1rem; accent-color: var(--accent); }

.error { color: var(--error); font-size: 0.88rem; margin: 0.5rem 0 0; }

.privacy-note {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 1.25rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  color: var(--text-soft);
  font-size: 0.88rem;
}

.privacy-note svg { flex: none; margin-top: 0.15rem; color: var(--accent); }

/* ---------- the card ---------- */

.preview-panel { display: flex; flex-direction: column; align-items: center; }

.wifi-card {
  width: min(100%, 21rem);
  background: var(--card-bg);
  color: var(--card-text);
  border-radius: 1.1rem;
  border: 1px solid #e2e8f0;
  box-shadow: var(--shadow);
  padding: 1.4rem 1.5rem 1rem;
  text-align: center;
  transition: opacity 0.2s;
}

.wifi-card.is-demo { opacity: 0.45; }

.card-head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  color: #0e7490;
  margin-bottom: 0.9rem;
}

.card-wifi-icon { width: 30px; height: 30px; }

.card-title { font-size: 1.3rem; font-weight: 700; letter-spacing: 0.02em; }

.qr-box {
  display: flex;
  justify-content: center;
  margin: 0 auto;
}

.qr-box svg {
  width: min(100%, 13.5rem);
  height: auto;
  display: block;
}

.card-scan {
  margin: 0.7rem 0 0.9rem;
  font-size: 0.85rem;
  color: var(--card-soft);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.card-detail { margin: 0.4rem 0; }

.card-label {
  display: block;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--card-soft);
}

.card-value {
  display: block;
  font-weight: 700;
  font-size: 1.05rem;
  overflow-wrap: anywhere;
}

.card-value.mono { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-weight: 600; }

.card-footer {
  margin: 1rem 0 0;
  padding-top: 0.6rem;
  border-top: 1px dashed #e2e8f0;
  font-size: 0.68rem;
  color: #69788c;   /* 4,50 auf der weißen Karte (vorher #94a3b8: 2,56) */
}

/* ---------- actions ---------- */

.actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 1.1rem;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 0.6rem;
  padding: 0.55rem 0.85rem;
  cursor: pointer;
}

.btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent-strong); }

.btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn.primary { color: #0b1220; }
}
:root[data-theme="dark"] .btn.primary { color: #0b1220; }

.btn.primary:hover:not(:disabled) { background: var(--accent-strong); color: #fff; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn.primary:hover:not(:disabled) { color: #0b1220; }
}
:root[data-theme="dark"] .btn.primary:hover:not(:disabled) { color: #0b1220; }

.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.print-group { display: inline-flex; gap: 0.35rem; }

.toast {
  margin: 0.8rem 0 0;
  font-size: 0.9rem;
  color: var(--accent-strong);
  font-weight: 600;
}

/* ---------- footer ---------- */

.site-footer {
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  color: var(--text-soft);
  font-size: 0.85rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  text-align: center;
}

.site-footer a {
  color: inherit;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.site-footer a:hover { color: var(--accent-strong); }

/* ---------- print ---------- */

#printArea { display: none; }

@media print {
  .app-shell { display: none !important; }

  body { background: #fff; }

  #printArea { display: block; }

  #printArea .wifi-card {
    width: 85mm;
    margin: 8mm auto;
    box-shadow: none;
    border: 1px solid #cbd5e1;
    opacity: 1;
    page-break-inside: avoid;
  }

  /* table tent: two mirrored halves, fold between them */
  #printArea.tent .tent-half {
    height: 128mm;
    display: flex;
    align-items: center;
    justify-content: center;
    page-break-inside: avoid;
  }

  #printArea.tent .tent-half .wifi-card { margin: 0; }

  #printArea.tent .tent-half.flip { transform: rotate(180deg); }

  #printArea.tent .fold-line {
    border-top: 1px dashed #94a3b8;
    height: 0;
  }
}

/* ---------- Sehhilfen: Hoher Kontrast, Farbenblind, Umgekehrte Farben ----------
   (31.10.2026) Eine Wahl für die ganze Werkstatt: localStorage
   „werkstatt.darstellung“, alle Werkzeuge liegen auf einem Ursprung. Das
   Kopf-Skript setzt data-theme (light/dark, wie bisher) und data-vision
   (contrast, cvd, invert). Die beiden Farbblöcke oben bleiben, wie sie sind. */

/* Hoher Kontrast dunkel: Schwarz, Schrift #E0E0E0 (15,91:1), jede Farbe 7:1 */
:root[data-vision="contrast"][data-theme="dark"] {
  --bg: #000000;
  --panel: #000000;
  --text: #E0E0E0;
  --text-soft: #C4C4C4;   /* 12,04 */
  --border: #A0A0A0;      /* 8,03 */
  --shadow: none;
}

/* Hoher Kontrast hell: Weiß, Schrift Schwarz, gleiche Farbtöne nachgedunkelt */
:root[data-vision="contrast"][data-theme="light"] {
  --accent: #005F78;      /* 7,22, auch Weiß auf dem Knopf */
  --accent-strong: #155E75;
  --bg: #FFFFFF;
  --panel: #FFFFFF;
  --text: #000000;
  --text-soft: #2B2B2B;   /* 14,16 */
  --border: #585757;      /* 7,20 */
  --error: #B2000F;       /* 7,24 */
  --shadow: none;
}

/* Die Karte bleibt weiß, sie ist die Druckvorschau. Im Hohen Kontrast werden
   ihre leisen Grautöne (bis 2,56:1 in der Fußzeile) auf 7:1 nachgedunkelt. */
:root[data-vision="contrast"] {
  --card-soft: #49586E;   /* 7,23 */
}
:root[data-vision="contrast"] .card-head { color: #005F78; }
:root[data-vision="contrast"] .card-footer { color: #4B586B; border-top-color: #585757; }
:root[data-vision="contrast"] .wifi-card { border: 2px solid #585757; }
/* Das Beispiel vor der ersten Eingabe ist sonst nur blasser (45 %), das reißt
   jeden Kontrast. Hier steht es voll da und trägt einen gestrichelten Rahmen. */
:root[data-vision="contrast"] .wifi-card.is-demo { opacity: 1; border-style: dashed; }
:root[data-vision="contrast"] :is(.panel, .btn, .field input, .field select, .lang-wrap select, #printMode, .install-btn) { border-width: 2px; }
:root[data-vision="contrast"] :focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* Am Handy teilen sich Darstellung und Sprache eine Zeile. Ein Auswahlfeld ist
   so breit wie sein längster Eintrag, und das ist seit den acht Darstellungen
   „Hoher Kontrast dunkel“ (ru „Для дальтоников, светлая“). Ohne diese Regel
   rutschten die Felder bei 320 px in zwei Zeilen; die Darstellung bekommt den
   größeren Teil, ein zu langer Eintrag wird im Feld gekappt. */
@media (max-width: 560px) {
  .header-controls .lang-wrap { flex: 1 1 0; min-width: 0; }
  .header-controls .lang-wrap:has(#themeSelect) { flex-grow: 1.6; }
  .header-controls .lang-wrap select { width: 100%; min-width: 0; }
}
:root[data-vision="contrast"] .site-footer a { text-decoration: underline; }

/* Farbenblind: Fehler in Zinnober (Okabe-Ito) statt Rot, bleibt bei Rot- und
   Grünschwäche sichtbar. Die Fehlermeldung steht ohnehin als Text da. */
:root[data-vision="cvd"][data-theme="light"] { --error: #B75000; }  /* 4,61 */
:root[data-vision="cvd"][data-theme="dark"] { --error: #D76004; }   /* 4,61 */

/* Umgekehrte Farben wie der Farbfilter von Windows. Die Karte samt QR-Code
   ist der Inhalt: sie wird ein zweites Mal umgedreht und bleibt so echt
   (data-echt), damit der Code scannt und aussieht wie gedruckt. */
:root[data-vision="invert"] { filter: invert(1); }
:root[data-vision="invert"] :is(img:not([src*=".svg"]), video, [data-echt]):not([data-echt] *) { filter: invert(1); }
/* Umdrehen erhält den WCAG-Kontrast nicht. Im Dunkeln kämen Akzent und
   Fehler umgedreht auf 3,79 und 3,19; leicht angehoben halten sie 4,6. */
@media (prefers-color-scheme: dark) {
  :root[data-vision="invert"] {
    --accent: #38DEF9;
    --error: #FF8E8B;
  }
}
/* Gedruckt wird nie umgedreht */
@media print {
  :root[data-vision="invert"],
  :root[data-vision="invert"] :is(img:not([src*=".svg"]), video, [data-echt]):not([data-echt] *) { filter: none; }
}
