/* ContForm — Anmeldung + Dashboard + Konto (ergänzt app.css) */
/* ---------------------------------------------------------------- Anmeldung */
/* Achtung: /login und /registrieren laden nur base.css + diese Datei — hier
   keine Tokens aus app.css verwenden, sondern eigene setzen.
   Anmeldung und Registrierung teilen sich diese Karte — beide Seiten
   nutzen .auth-page und .auth-card, damit Feinschliff nur an einer
   Seite nicht ungestaltet bleibt. */
body.auth-page {
  /* dieselben Abstufungen wie im App-Chrome (app.css), hier eigenständig
     gesetzt, weil app.css auf diesen Seiten nicht geladen wird */
  --line-light: color-mix(in oklab, var(--line) 45%, var(--card));
  --wash:       color-mix(in oklab, var(--paper) 62%, var(--card));
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(20px, 6vh, 40px) clamp(16px, 5vw, 24px);
}
/* Die eine große Geste dieser Seite: hinter der Karte spannt sich der Bogen
   selbst — ein einzelner Haarstrich im Kreisbogen, weit größer als das Bild.
   Als Farbverlauf gemalt, nicht als Element: er kann darum weder umbrechen
   noch waagerecht überlaufen. Liegt unter der Papierkörnung aus base.css. */
body.auth-page::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-repeat: no-repeat;
  background-image: radial-gradient(
    circle at 50% 128%,
    transparent 0 min(46vmax, 620px),
    var(--line) min(46vmax, 620px) calc(min(46vmax, 620px) + 1px),
    transparent calc(min(46vmax, 620px) + 1px)
  );
}
.auth-card {
  width: 100%;
  max-width: 400px;
  background: var(--card);
  border: 1px solid var(--line);
  border-top-color: var(--line-light);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-card);
  padding: clamp(24px, 6vw, 34px) clamp(19px, 5vw, 30px) clamp(22px, 4vw, 28px);
  position: relative;
  overflow: hidden;
}
/* Bogen-Kante wie beim öffentlichen Formular — von 6 px auf 4 px zurück-
   genommen und mit Tiefe versehen: eine gedruckte Kante, kein Balken. */
.auth-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  background: linear-gradient(90deg, var(--green-deep), var(--green) 46%, var(--green));
}
.auth-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 44px;
  margin: .2rem 0 clamp(.9rem, 3vw, 1.2rem);
  text-decoration: none;
  color: var(--ink);
}
.auth-brand svg {
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  border-radius: 7.5px;   /* deckt sich mit dem rx=7 im 28er-Viewport */
  box-shadow:
    0 1px 2px color-mix(in oklab, var(--green) 28%, transparent),
    0 5px 12px -7px color-mix(in oklab, var(--green) 55%, transparent);
}
.auth-brand span {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: .005em;
}
.auth-card h1 {
  font-size: clamp(1.25rem, 1.1rem + .7vw, 1.4rem);
  text-align: center;
  margin-bottom: clamp(1rem, 3vw, 1.25rem);
}
/* Unterzeile auf /registrieren — bisher ohne jede Regel. */
.auth-sub {
  margin: -.6rem 0 clamp(1rem, 3vw, 1.25rem);
  text-align: center;
  font-size: .92rem;
  line-height: 1.5;
  color: var(--ink-soft);
  text-wrap: balance;
}
.auth-error {
  background: var(--red-tint);
  color: var(--red);
  font-weight: 600;
  font-size: .92rem;
  border-radius: var(--radius-s);
  padding: .65em 1em;
  margin: 0 0 1.1rem;
  overflow-wrap: anywhere;
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--red) 20%, transparent);
}
.auth-card .btn {
  width: 100%;
  margin-top: .5rem;
  min-height: 44px;
  /* dieselbe Tiefe wie im App-Chrome; app.css ist hier nicht geladen */
  box-shadow:
    inset 0 1px 0 color-mix(in oklab, var(--card) 22%, transparent),
    0 1px 2px color-mix(in oklab, var(--green-deep) 30%, transparent),
    0 8px 16px -10px color-mix(in oklab, var(--green-deep) 60%, transparent);
}
.auth-card .btn:hover {
  box-shadow:
    inset 0 1px 0 color-mix(in oklab, var(--card) 22%, transparent),
    0 1px 2px color-mix(in oklab, var(--green-deep) 34%, transparent),
    0 11px 22px -10px color-mix(in oklab, var(--green-deep) 55%, transparent);
}
.auth-card .btn:active {
  box-shadow: inset 0 1px 3px color-mix(in oklab, var(--green-deep) 45%, transparent);
}
/* Der Fuß gehört nicht mehr zum Formular: eine Haarlinie setzt ihn ab. */
.auth-foot {
  margin-top: clamp(1rem, 3vw, 1.3rem);
  margin-bottom: 0;
  padding-top: .4rem;
  border-top: 1px solid var(--line-light);
  text-align: center;
  font-size: .88rem;
  color: var(--ink-soft);
}
.auth-foot a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 .7rem;
  color: var(--ink-soft);
  text-decoration: none;
  transition: color .15s var(--ease);
}
.auth-foot a:hover { color: var(--green); }
/* Der Honigtopf gegen Spam wird von form.css versteckt — die wird auf
   /registrieren nicht geladen. Ohne diese Zeile stünde das Feld sichtbar im
   Formular. */
.auth-card .bform__hp { position: absolute; left: -9999px; top: -9999px; }
@media (max-height: 560px) {
  /* Flaches Querformat: oben beginnen und die Höhe zusammenziehen, damit die
     Karte nicht über den oberen Bildrand hinauswächst. */
  body.auth-page { justify-content: flex-start; padding-block: 18px; }
  .auth-brand { min-height: 40px; margin-bottom: .7rem; }
  .auth-card { padding-block: 22px 20px; }
  .auth-card h1 { margin-bottom: .8rem; }
  .auth-card .field { margin-bottom: .8rem; }
  .auth-sub { margin-bottom: .8rem; }
}
/* ---------------------------------------------------------------- Dashboard */
.tablewrap {
  overflow-x: auto;
  border-radius: var(--radius-m);
}
/* Spaltenrhythmus (nur .table--cards — also Dashboard und Verwaltung; die
   Eingänge in inbox.css brauchen ihre breiten, umbrechenden Spalten).
   Alle Nebenspalten schrumpfen auf ihren Inhalt, der Titel bekommt den ganzen
   Rest. Vorher teilte die automatische Verteilung dem Titel nur gut ein Drittel
   der Breite zu, während Status und Aktionen Luft horteten. */
@media (min-width: 1024px) {
  /* Erst die Untergrenze: der Spaltenname darf nicht umbrechen. Sonst
     schrumpft eine Spalte mit kurzem Wert („Formulare“ über einer 7) bis die
     Überschrift senkrecht steht. Ab 1024 px ist dafür reichlich Platz. */
  .table--cards thead th { white-space: nowrap; }
  /* Das Paar macht die Verteilung: 100 % zieht allen Überschuss in die
     Titelspalte, 1 % + nowrap lässt die übrigen auf ihren Inhalt schrumpfen. */
  .table--cards td.cell-title,
  .table--cards td.cell-main { width: 100%; }
  .table--cards td.cell-status,
  .table--cards td.cell-count,
  .table--cards td.cell-views,
  .table--cards td.cell-updated,
  .table--cards td.cell-actions,
  .table--cards td[data-label],
  .table--cards td.td-actions {
    width: 1%;
    white-space: nowrap;
  }
}
.formtitle {
  display: block;
  font-weight: 650;
  line-height: 1.3;
  color: var(--ink);
  text-decoration: none;
  overflow-wrap: anywhere;
  transition: color .14s var(--ease);
}
.formtitle:hover { color: var(--green); text-decoration: underline; text-underline-offset: 2px; }
.formslug {
  display: inline-flex;
  align-items: center;
  margin-top: .1rem;
  font-family: var(--font-mono);
  font-size: max(.76rem, 12px);
  letter-spacing: .01em;
  color: var(--ink-soft);
  text-decoration: none;
  overflow-wrap: anywhere;
  transition: color .14s var(--ease);
}
.formslug:hover { color: var(--green); text-decoration: underline; text-underline-offset: 2px; }
/* Die Eingangszahl ist ein Link — ein Feld, das mit dem Leuchtmarker
   unterstrichen ist: dieselbe Geste wie .marker in base.css, nur als
   Trefferfläche gebaut. */
.countlink {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 40px;
  padding: 0 .5rem;
  font-weight: 650;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 2px solid var(--marker);
  border-radius: 6px 6px 0 0;
  transition: background-color .14s var(--ease), color .14s var(--ease);
}
.countlink:hover { color: var(--green-deep); background: var(--marker-soft); }
/* ------------------------------------------- Dashboard: Karten statt Tabelle
   Unterhalb von 1024 px wird jede Tabellenzeile zu einer Karte — dieselbe
   Schwelle wie bei den Eingängen (inbox.css), damit sich beide Listen gleich
   verhalten. Eine Karte je Zeile, volle Breite: das liest sich als Liste,
   ohne Zickzack und ohne seitliches Wischen.
   Aufbau der Karte: Titel + Adresse · Status | Kennzahlen | Aktionen —
   getrennt durch zwei feine Linien. */
@media (max-width: 1023px) {
  .card--flush {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  .tablewrap { overflow-x: visible; border-radius: 0; }
  .table--cards thead { display: none; }
  .table--cards,
  .table--cards tbody,
  .table--cards tr,
  .table--cards td { display: block; }
  .table--cards tbody {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--card-gap);
  }
  .table--cards tr {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .5rem 1rem;
    align-content: start;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-card);
    padding: var(--card-pad);
  }
  .table--cards tbody tr:hover { background: var(--card); }
  .table--cards td {
    min-width: 0;
    padding: 0;
    border: 0;
    box-shadow: none;   /* der Merkstreifen aus app.css gilt nur echten Zeilen */
  }
  /* Spaltenname als Beschriftung über dem Wert — zurückhaltend, damit der
     Wert die Karte trägt und nicht die Beschriftung. */
  .table--cards td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-family: var(--font-mono);
    font-size: max(.75rem, 12px);
    font-weight: 400;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--ink-soft);
    margin-bottom: .05rem;
  }
  /* Kopf- und Fußteil der Karte laufen über die volle Breite.
     .cell-main und .td-actions kommen aus der Verwaltung — sie standen bisher
     in keiner dieser Regeln und wurden dadurch in eine halbe Spalte gepresst;
     die Knopfreihe lief aus ihrer Spur heraus. */
  .table--cards .cell-title,
  .table--cards .cell-main,
  .table--cards .cell-status,
  .table--cards .cell-updated,
  .table--cards .cell-actions,
  .table--cards .td-actions { grid-column: 1 / -1; }
  /* Titel und Adresse als ein Block: knapp untereinander, beide antippbar. */
  .table--cards .cell-title .formtitle {
    display: flex;
    align-items: center;
    min-height: 40px;
    font-size: clamp(1.02rem, .96rem + .25vw, 1.15rem);
    line-height: 1.28;
  }
  .table--cards .cell-title .formslug {
    min-height: 40px;      /* Tippziel bleibt 40 px … */
    margin-top: -.3rem;    /* … optisch rückt die Adresse trotzdem an den Titel */
  }
  /* In der Verwaltung sind Name und Adresse Text, keine Links — sie brauchen
     kein Tippmaß, nur denselben Rhythmus. */
  .table--cards .cell-main .formtitle {
    font-size: clamp(1.02rem, .96rem + .25vw, 1.15rem);
    line-height: 1.28;
  }
  .table--cards .cell-main .formslug { margin-top: .1rem; }
  /* Status schließt den Kopfteil ab; die Linie trennt ihn von den Kennzahlen. */
  .table--cards .cell-status {
    margin-top: -.1rem;
    padding-bottom: .7rem;
    border-bottom: 1px solid var(--line);
  }
  /* In der Verwaltung übernimmt der Kopfteil selbst diesen Abschluss —
     dort folgt auf Name/Adresse gleich die Rolle. */
  .table--cards .cell-main {
    padding-bottom: .7rem;
    border-bottom: 1px solid var(--line);
  }
  /* Kennzahlen: Wert kräftig, Beschriftung darüber */
  .table--cards .cell-count,
  .table--cards .cell-views,
  .table--cards .cell-updated {
    align-self: start;
    color: var(--ink);
    font-weight: 600;
  }
  .table--cards .cell-updated {
    font-weight: 500;
    white-space: normal;   /* .nowrap würde die schmale Karte sprengen */
  }
  .table--cards .cell-count .countlink {
    margin-left: -.5rem;
    font-size: 1.05rem;
  }
  .table--cards .cell-actions .row-actions,
  .table--cards .td-actions .row-actions {
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: .5rem;
    border-top: 1px solid var(--line);
    padding-top: .75rem;
    margin-top: .2rem;
  }
  .table--cards .cell-actions .iconbtn { width: 44px; height: 44px; }
}
/* Ab etwa 540 px ist die Karte breit genug für alle drei Kennzahlen
   nebeneinander — das spart eine Zeile und wirkt ruhiger. */
@media (min-width: 540px) and (max-width: 1023px) {
  .table--cards tr { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .table--cards .cell-updated { grid-column: auto; }
}
/* Breite Karten (ab 680 px): die Kennzahlen stehen links so breit, wie sie
   brauchen, die Aktionen rücken an den rechten Rand derselben Zeile. Das füllt
   die Karte, spart eine Zeile und bringt sie auf gut zwei Drittel ihrer Höhe.
   Alle Spuren mit Untergrenze 0 — bei Platznot wird umbrochen, nie überlaufen. */
@media (min-width: 680px) and (max-width: 1023px) {
  .table--cards tr {
    grid-template-columns: repeat(3, minmax(0, max-content)) minmax(0, 1fr);
  }
  .table--cards .cell-actions {
    grid-column: 4;
    justify-self: end;
    align-self: end;
  }
  .table--cards .cell-actions .row-actions {
    justify-content: flex-end;
    border-top: 0;
    padding-top: 0;
    margin-top: 0;
  }
}
/* Auf Tablets im Querformat bleibt die echte Tabelle stehen — dort brauchen
   Titel- und Slug-Link trotzdem eine daumengerechte Höhe. */
@media (pointer: coarse) {
  .formtitle { display: flex; align-items: center; min-height: 40px; }
  .formslug { min-height: 40px; }
}
/* -------------------------------------------------------------- Verwaltung */
/* Die beiden Einstellkarten hatten bisher gar keine eigenen Regeln: sie klebten
   ohne Abstand aneinander und liefen über die volle Inhaltsbreite, sodass ein
   Passwortfeld gut einen Meter breit war. Beides ist eine Frage der Ordnung,
   nicht der Zierde. */
.verw__reg,
.verw__neu {
  max-width: 560px;                       /* dasselbe Maß wie .stack (Konto) */
  margin-bottom: clamp(1rem, 2.5vw, 1.35rem);
}
/* Der Schalter trägt die Karte — er bekommt Luft nach oben zur Bezeichnung. */
.verw__reg .bswitch { margin-top: -.1rem; }
/* base.css setzt .hint nur innerhalb von .field — hier steht sie frei. */
.verw__reg .hint {
  margin: .45rem 0 0;
  font-size: max(.82rem, 12px);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 52ch;
}
/* Adressen im Fließtext als geschlossenes Feld — dieselbe Geste wie im
   Leerzustand (app.css), damit beide dasselbe sagen. */
.verw__reg .hint .mono {
  display: inline-block;
  padding: .08em .45em;
  border-radius: 6px;
  background: var(--green-tint);
  color: var(--green-deep);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--green) 14%, transparent);
}
/* Zwei Spalten, sobald die Karte breit genug ist: Name und Adresse stehen
   nebeneinander, Passwort und Schalter bleiben durchgehend. Untergrenze 0 in
   beiden Spuren — bei Platznot wird umbrochen, nie überlaufen. */
.verw__form { display: grid; gap: 0 1rem; }
.verw__form .btn { justify-self: start; min-height: 44px; }
@media (min-width: 620px) {
  .verw__form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Name und Adresse (die ersten beiden Felder) teilen sich die Zeile; alles
     danach — Passwort, Schalter, Knopf — läuft durch. */
  .verw__form > .field:nth-child(n+3),
  .verw__form > .btn { grid-column: 1 / -1; }
}
@media (max-width: 480px) {
  .verw__form .btn { justify-self: stretch; width: 100%; }
}
/* Die Beschriftung im Icon-Knopf blendet inbox.css aus — die wird auf
   /app/verwaltung aber nicht geladen. Ohne diese Zeile quetscht sich das Wort
   „Rolle" in den 40-px-Knopf und läuft heraus. In der Kartenansicht unten darf
   es dann erscheinen, dort ist Platz dafür. */
.iconbtn__label { display: none; }
@media (max-width: 1023px) {
  /* In der Kartenansicht ist Platz für das Wort — zwei abstrakte Zeichen
     nebeneinander sagen auf dem Handy zu wenig. Umbruch erlaubt, damit auch
     320 px sicher tragen. */
  .card--rows .row-actions { flex-wrap: wrap; justify-content: flex-start; }
  .card--rows .iconbtn {
    width: auto;
    min-width: 44px;
    height: 44px;
    padding: 0 .75rem;
    gap: .4rem;
  }
  .card--rows .iconbtn__label { display: inline; font-size: max(.82rem, 12px); font-weight: 600; }
}
/* -------------------------------------------------------------------- Konto */
.stack {
  display: grid;
  gap: clamp(1rem, 2.5vw, 1.35rem);
  min-width: 0;
  max-width: 560px;
}
.stack h2 {
  font-size: clamp(1.08rem, 1rem + .35vw, 1.18rem);
  margin-bottom: clamp(.8rem, 2vw, 1rem);
}
/* 1 rem = 16 px: kleinere Eingabeschrift lässt iOS beim Fokus hineinzoomen. */
.input-mono {
  font-family: var(--font-mono) !important;
  font-size: 1rem !important;
}
