/* Projektstile für Dashpulse.
   Nur Schriftdateien und projekteigene Ergänzungen; alle Werte kommen aus
   /standard/tokens.css. Fehlt dort ein Bauteil, wird es im Standard
   nachgetragen, nicht hier ausgebaut. */

@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/source-sans-3-latin-400-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/source-sans-3-latin-600-normal.woff2") format("woff2");
}

/* Kennungsschrift des Standards (--font-mono), lokal wie die Textschrift. */
@font-face {
  font-family: "Source Code Pro";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/source-code-pro-latin-400-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Source Code Pro";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/source-code-pro-latin-600-normal.woff2") format("woff2");
}

/* Nachtrag für den Standard: Logo vor dem Anwendungsnamen in der
   Kopfzeile. Das Zeichen füllt im 64er-Raster 54 Einheiten, sichtbar sind bei
   32 px also gut 27 px in der 56 px hohen Kopfzeile. */
.header__logo {
  flex: none;
  width: var(--space-6);
  height: var(--space-6);
}

/* Nachtrag für den Standard: Rückweg unter dem Titel („Geräte · DS-…“).
   Der Standard nennt die Brotkrume, baut sie aber nicht. Sie ist Navigation
   wie die Seitenleiste und wird ständig benutzt; als Fließtext-Verweis wäre
   sie nach dem ersten Besuch für immer violett. Daher Textfarbe der Zeile,
   unterstrichen, ohne „besucht“. */
.page-head__trail a {
  color: inherit;
}

.page-head__trail a:hover {
  color: var(--color-text);
}

/* Der Einklapp-Knopf hat auf dem Handy nichts zu tun: dort ist die
   Sidebar ein Overlay hinter dem Burger. Gleicher Umbruchpunkt wie in
   components.css. */
@media (max-width: 700px) {
  [data-sidebar-toggle] {
    display: none;
  }
}

/* Nachtrag für den Standard: Anmeldeseite. Der Standard beschreibt das
   Anmeldeformular (patterns.html, „Alle Felder Pflicht“), aber keinen
   Rahmen dafür. Ein schmales Panel in der Mitte, ohne Sidebar und
   Kopfzeile: vor der Anmeldung gibt es nichts zu navigieren. */
.signin {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  min-height: 100vh;
  padding: var(--space-8) var(--space-4);
  background: var(--color-bg);
}

.signin__brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.signin .panel {
  width: 100%;
  max-width: 440px;
}

.signin .panel__body > * + * {
  margin-top: var(--space-4);
}

/* Nachtrag für den Standard: Angaben als Begriff und Wert, etwa in der
   Übersicht eines Datensatzes. Zweispaltig ab Tabletbreite, auf dem Handy
   untereinander. */
.facts {
  display: grid;
  grid-template-columns: minmax(10rem, max-content) 1fr;
  gap: var(--space-2) var(--space-5);
  margin: 0;
}

.facts dt {
  color: var(--color-text-muted);
}

.facts dd {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}

@media (max-width: 700px) {
  .facts {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .facts dd + dt {
    margin-top: var(--space-3);
  }
}

/* QR-Code zum Einrichten des zweiten Faktors. Weißer Grund auch im
   Dunkelmodus, sonst lesen manche Kameras ihn nicht. */
.qr {
  display: block;
  width: 200px;
  height: 200px;
  margin-inline: auto;
}

/* Nachtrag für den Standard: Datensatzliste als Tabelle am Desktop und als
   Karten auf dem Handy (SKILL.md, „Auf dem Handy“). Beide stehen im
   Markup, das Stilblatt zeigt je Breite eines. */
.card-list--phone {
  display: none;
}

@media (max-width: 700px) {
  .table--phone-cards {
    display: none;
  }

  .card-list--phone {
    display: flex;
  }
}

/* Nachtrag für den Standard: Eine Fußzeile mit mehreren Knöpfen (Befehle
   im Gerät, vier Stück) bricht auf dem Handy um, statt über den Rand zu
   laufen. Gemessen bei 390 Pixel Breite: vier Knöpfe brauchen 522 Pixel,
   die Fußzeile hat 356. */
.panel__footer {
  flex-wrap: wrap;
}

/* Nachtrag für den Standard: Anzeigezeiten (Konzept E21). Gruppen mit
   wiederholbaren Zeilen, Wochentage zum Ankreuzen. Die Tage sind
   Kontrollkästchen, damit Tastatur und Vorleseprogramm sie kennen; das Kürzel
   steht sichtbar, der volle Name für Vorleseprogramme. */
.schedule-group {
  border: 0;
  margin: 0 0 var(--space-6);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}

.schedule-group__title {
  padding: 0;
  margin: 0;
  font-size: var(--font-base);
  font-weight: var(--weight-bold);
}

.schedule-rows {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.schedule-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.schedule-row--date {
  flex-direction: column;
  align-items: stretch;
  gap: 0;
}

.schedule-row--date .form-row {
  align-items: flex-end;
  margin-bottom: var(--space-3);
}

.schedule-row--date .form-row:last-of-type {
  margin-bottom: 0;
}

.schedule-row__error {
  flex-basis: 100%;
}

.schedule-row__remove,
.schedule-row__yearly {
  margin-bottom: var(--space-1);
}

.daypicker {
  border: 0;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  min-width: 0;
}

.daypicker > legend {
  float: left;
  width: 100%;
  margin-bottom: var(--space-1);
}

.daypicker__day {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--touch-target);
  min-height: var(--touch-target);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  font-size: var(--font-sm);
  cursor: pointer;
}

/* Das Kästchen bleibt im Tabulatorlauf, nur unsichtbar. */
.daypicker__day input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.daypicker__day:has(input:checked) {
  background: var(--color-primary-soft);
  border-color: var(--color-primary);
  color: var(--color-primary);
  font-weight: var(--weight-bold);
}

.daypicker__day:has(input:focus-visible) {
  box-shadow: var(--focus-ring);
}

.schedule-group > .btn {
  align-self: flex-start;
}

/* Auf dem Handy stapelt der Standard die Felder einer .form-row; dort
   gilt wieder volle Breite statt Ausrichtung an der Unterkante. */
@media (max-width: 700px) {
  .schedule-row--date .form-row {
    align-items: stretch;
  }
}

/* Nachtrag für den Standard: Screenshots der Bildschirme (E12) hängen am
   Befehl. Der Knopf in der Befehlszeile klappt eine Zeile darunter auf,
   erst dann lädt der Browser die Bilder; ein Klick öffnet eines groß. */
.shots__toggle {
  margin-top: var(--space-1);
  /* Text bündig mit der Zeile darüber; der Hintergrund beim Überfahren
     ragt dafür in den Zellenrand. */
  margin-inline-start: calc(-1 * var(--space-3));
}

.table .shots-row > td {
  height: auto;
  padding-block: var(--space-3) var(--space-4);
}

.shots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
  gap: var(--space-4);
}

/* Jedes Bild steht in einem Rahmen, damit ein heller oder dunkler
   Bildschirminhalt nicht in die Seite übergeht: Fläche mit Rand ums Ganze,
   dazu eine kräftige Kante direkt am Bild. */
.shots__item {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-2);
  background: var(--color-bg-subtle);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.shots__image {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}

/* Vorschau des Sichtschutz-Bilds (E31) im selben Rahmen wie die
   Bildschirmfotos, so breit wie eines davon in der Liste. */
.cover-preview {
  max-width: 28rem;
  margin-block: var(--space-3) var(--space-4);
}

/* Nachtrag für den Standard: kleines Formular in einer Tabellenzelle
   (Rolle eines Kontos: Auswahl und Knopf nebeneinander). Bricht in der
   Handyansicht um, statt die Zelle zu sprengen. */
.cell-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.cell-form .field__input {
  width: auto;
}

/* Nachtrag für den Standard: Passwortfeld. Breite wie E-Mail-Adresse;
   über die volle Zeile gezogen sieht es aus, als erwarte es einen Absatz. */
.field--password {
  flex: 3 1 0;
  min-width: 18ch;
  max-width: 40ch;
}

/* Nachtrag für den Standard: Karte mit Handgriffen (Konten auf dem Handy).
   Der Text nimmt die erste Zeile, Auswahl und Knöpfe stehen darunter. */
.card--stacked {
  flex-wrap: wrap;
}

.card--stacked > :first-child {
  flex: 1 1 100%;
}

/* Nachtrag für den Standard: Bildkacheln (Medien, Konzept 17.10). Raster
   wie die Bildschirmfotos, jede Kachel ein Rahmen mit Vorschau, Name und
   einer Zeile Angaben. Als Verweis zur Bearbeitung oder, mit Kästchen, zur
   Auswahl beim Hinzufügen in eine Playlist; dann ist die Kachel das Label. */
.thumbs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 9rem), 1fr));
  gap: var(--space-3);
}

.thumbs__item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
  padding: var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  text-decoration: none;
}

a.thumbs__item:hover,
label.thumbs__item:hover {
  border-color: var(--color-border-strong);
}

.thumbs__item:has(input:checked) {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}

.thumbs__item:has(input:focus-visible) {
  box-shadow: var(--focus-ring);
}

/* Kästchen oben links auf dem Bild, mit voller Trefferfläche. */
.thumbs__check {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  width: var(--touch-target);
  height: var(--touch-target);
  margin: 0;
}

.thumbs__image {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  background: var(--color-bg-subtle);
  border-radius: var(--radius-sm);
}

.thumbs__name {
  font-weight: var(--weight-bold);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.thumbs__meta {
  font-size: var(--font-xs);
  color: var(--color-text-muted);
}

/* Vorschau in einer Tabellenzeile (Bilder einer Playlist): passt in die
   zweizeilige Zeile, Seitenverhältnis bleibt. */
.cell-thumb {
  display: block;
  height: calc(var(--row-height-2) - var(--space-3));
  aspect-ratio: 4 / 3;
  object-fit: contain;
  background: var(--color-bg-subtle);
  border-radius: var(--radius-sm);
}

/* Dauer einer Folie: Zahl und Einheit nebeneinander, schmal. */
.duration {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.duration .field__input {
  width: 9ch;
}

/* Auswahl als Kachelraster: das Fieldset trägt nur die Gruppe. */
fieldset.thumbs {
  margin: 0;
  padding: 0;
  border: 0;
  min-inline-size: 0;
}

/* Nachtrag für den Standard: Spalten der Bilderliste einer Playlist.
   Drei Knöpfe am Zeilenende (hoch, runter, heraus); der Standard kennt
   nur eine und zwei. */
.table .col-actions--3 {
  width: calc(3 * var(--touch-target) + 2 * var(--space-3));
}


/* Bilderliste einer Playlist (Positionstabelle des Standards): Vorschau
   und Name in einer Zelle, damit am Telefon das Bild die Karte anführt. */
.cell-media {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.cell-media__text {
  min-width: 0;
}

@media (max-width: 700px) {
  /* Das Bild nimmt die ganze erste Zeile; Dauer und die drei Knöpfe
     stehen darunter nebeneinander. */
  .table--slides tbody td:first-child {
    flex-basis: 100%;
  }

  .table--slides tbody td.col-actions {
    order: 1;
    flex: 0 0 auto;
    width: auto;
  }
}

/* Die Dauer ist eine kurze Zahl; die Spalte muss nicht die halbe Zeile füllen. */
.table--slides .num {
  width: 12rem;
}
