/*
 * Vorlage V2: Void-Hintergrund und alle UI-Bausteine.
 *
 * Die Ebenen von unten nach oben:
 *   0  #void-effect   Sternenfeld und Sternbilder (Canvas, siehe void.js)
 *   1  .app-shell     sichtbare UI
 *
 * Alle Farben, Radien und Schatten stehen als Custom Properties oben. Wer die
 * Vorlage umfärben will, ändert nur diese Werte.
 */

:root {
  /* Grundfarbe des Sternenraums. Muss zu voidBaseColor in void.js passen. */
  --template-void: #0a0414;
  --template-bg: #050409;
  --template-bg-soft: #130d1f;
  --template-panel: rgba(13, 10, 19, 0.86);
  --template-panel-strong: rgba(18, 12, 27, 0.98);
  /* 0,4 und nicht 0,28 — wegen der Ecken.
     
     Eine einen Punkt breite Linie kann eine Rundung nicht ganz ausfüllen: Sie
     trifft dort jeden Bildpunkt nur teilweise und wird entsprechend blasser.
     Nachgemessen an der Eingabezeile: 83 Prozent der geraden Kante bei
     hundertprozentiger Bildschirmskalierung — und nur 47 Prozent bei
     hundertfünfzig, weil dort ein CSS-Punkt auf anderthalb Bildpunkte fällt.
     Mit 0,28 verschwand die Ecke dabei, die Umrandung sah an den Rundungen
     schwarz aus. Dagegen hilft nur ein kräftigerer oder ein dickerer Strich.
     
     Dieselbe Zahl steht in `VoidColors.kt`. */
  --template-line: rgba(190, 94, 255, 0.4);
  --template-line-strong: rgba(199, 120, 255, 0.62);
  --template-purple: #9d1cff;
  --template-purple-hover: #b94dff;
  --template-text: #fbf8ff;
  --template-muted: rgba(251, 248, 255, 0.62);
  --template-danger: #ff4d6d;
  --template-success: #4dff9a;
  --template-radius: 8px;
  --template-shadow: 0 18px 44px rgba(5, 4, 9, 0.38);
  color-scheme: dark;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

* {
  box-sizing: border-box;
  user-select: none;
}

input,
textarea,
[contenteditable="true"] {
  user-select: text;
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
}

/* Die Grundfarbe liegt auch im CSS, damit die Seite ohne JavaScript nicht
   weiß aufblitzt, bevor der Sternenraum das erste Bild zeichnet. */
body {
  min-height: 100vh;
  color: var(--template-text);
  background-color: var(--template-void);
}

#void-effect {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
}

.app-shell {
  position: relative;
  z-index: 1;
  display: grid;
  min-height: 100vh;
  place-items: center;
  padding: 24px;
}

.template-panel {
  width: min(900px, calc(100vw - 48px));
}

.template-card {
  padding: 22px;
  color: var(--template-text);
  border: 1.5px solid var(--template-line);
  border-radius: var(--template-radius);
  background: var(--template-panel);
  box-shadow: var(--template-shadow);
  backdrop-filter: blur(12px);
}

.template-title {
  margin: 0 0 12px;
  color: var(--template-text);
  font-size: clamp(2rem, 5vw, 4rem);
  line-height: 1;
}

.template-text {
  margin: 0;
  color: var(--template-muted);
  line-height: 1.55;
}

/* `position` und `z-index` sind hier kein Beiwerk, sondern nötig, damit das
   aufgeklappte Auswahlmenü über dem steht, was unter der Zeile folgt.

   Der Grund ist unscheinbar: `backdrop-filter` erzeugt einen eigenen
   Stapelkontext. Das `z-index: 10` des Menüs gilt dadurch nur *innerhalb*
   dieser Zeile — nach außen zählt allein, wo die Zeile selbst im Stapel liegt.
   Ohne Angabe ist das die Reihenfolge im Dokument, und alles, was danach
   kommt, malt darüber. Genau das passiert mit einer Knopfzeile darunter, die
   ebenfalls einen `backdrop-filter` trägt: Das Menü verschwindet dahinter.

   20 statt 1, damit später noch etwas zwischen Zeile und Seiteninhalt passt. */
.template-form-row {
  position: relative;
  z-index: 20;
  display: grid;
  grid-template-columns: minmax(240px, 560px) 116px 148px;
  width: fit-content;
  max-width: calc(100vw - 48px);
  overflow: visible;
  border: 1.5px solid var(--template-line);
  border-radius: var(--template-radius);
  background: var(--template-panel);
  box-shadow: var(--template-shadow);
  backdrop-filter: blur(12px);
}

.template-input,
.template-button,
.template-select-trigger {
  height: 58px;
  color: var(--template-text);
  font: inherit;
  border: 0;
  outline: 0;
}

.template-input {
  min-width: 0;
  padding: 0 20px;
  border-radius: calc(var(--template-radius) - 1px) 0 0 calc(var(--template-radius) - 1px);
  background: transparent;
}

.template-input::placeholder {
  color: rgba(251, 248, 255, 0.44);
}

.template-input:focus {
  box-shadow: inset 0 0 0 1px rgba(199, 120, 255, 0.42);
}

.template-select {
  position: relative;
  min-width: 0;
  height: 58px;
}

.template-select-trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  background: var(--template-panel-strong);
  border-left: 1.5px solid var(--template-line);
  border-right: 1.5px solid var(--template-line);
  cursor: pointer;
}

/* Der Pfeil ist kein Zeichen, sondern ein Winkel aus zwei Rahmenlinien eines
   leeren Quadrats. Das hat einen Grund: Ein Schriftzeichen sähe je nach
   Schriftart anders aus, dieser Winkel überall gleich.

   Das `translateY` gleicht aus, dass der gedrehte Winkel optisch tiefer sitzt,
   als seine Umrandung vermuten lässt. */
/* Nicht mehr in Gebrauch: Der Winkel ist inzwischen ein Vektor im Markup, damit
   er dieselbe Geometrie hat wie in der App. Siehe `app.css`. */
.template-select-trigger::after {
  content: none;
}

/* Aufgeklappt zeigt der Pfeil nach oben.

   Warum -135 und nicht 225 Grad: Beide enden gleich — der Unterschied sind
   volle 360 Grad, das Bild am Ende ist dasselbe. Verschieden ist der *Weg*.
   Von 45 auf 225 zählt der Wert hinauf, die Drehung läuft im Uhrzeigersinn,
   und die Spitze wandert von unten über **links** nach oben. Von 45 auf -135
   zählt er hinunter, und sie nimmt den Weg über **rechts**.

   Die Verschiebung kippt mit ins Positive, sonst hinge der Winkel zu hoch —
   er ist nicht punktsymmetrisch, seine Spitze liegt außerhalb der Mitte. */
.template-select.is-open .template-select-trigger::after {
  transform: translateY(2px) rotate(-135deg);
}

.template-select-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 10;
  /* Immer im Baum und immer ein Raster.
     
     Vorher stand hier `display: none`, umgeschaltet über `is-open`. Eine
     Anzeigeart lässt sich aber nicht weich überblenden — die Liste war
     schlagartig da und schlagartig weg. Jetzt bewegt `dropdown.js` ihre Höhe,
     und `visibility` hält sie dazwischen aus dem Weg: Ohne das blieben die drei
     Rahmenlinien als Strich unter der Zeile stehen, auch bei Höhe null. */
  display: grid;
  visibility: hidden;
  height: 0;
  width: 100%;
  overflow: hidden;
  border-right: 1.5px solid var(--template-line);
  border-bottom: 1.5px solid var(--template-line);
  border-left: 1.5px solid var(--template-line);
  /* Deckend, nicht durchscheinend wie die übrigen Flächen. Ein aufgeklapptes
     Menü liegt über fremdem Inhalt — schon zwei Prozent Durchlässigkeit
     lassen den Text darunter erkennbar durchschimmern, und das liest sich
     nicht als Absicht, sondern als Darstellungsfehler. Der Farbwert ist
     `--template-panel-strong` ohne seine Transparenz. */
  background: #120c1b;
  box-shadow: 0 12px 22px rgba(5, 4, 9, 0.3);
}

.template-select-menu button {
  width: 100%;
  height: 38px;
  padding: 0 16px;
  color: rgba(251, 248, 255, 0.84);
  font: inherit;
  font-weight: 500;
  text-align: left;
  border: 0;
  outline: 0;
  background: transparent;
  cursor: pointer;
}

.template-select-menu button:hover,
.template-select-menu button:focus-visible,
.template-select-menu button[aria-selected="true"] {
  color: var(--template-text);
  background: rgba(157, 28, 255, 0.38);
}

.template-button {
  padding: 0 22px;
  font-weight: 700;
  background: var(--template-purple);
  cursor: pointer;
  transition:
    background 160ms ease,
    color 160ms ease,
    opacity 160ms ease;
}

.template-form-row > .template-button {
  border-radius: 0 calc(var(--template-radius) - 1px) calc(var(--template-radius) - 1px) 0;
}

.template-button:hover,
.template-button:focus-visible {
  background: var(--template-purple-hover);
}

.template-button:disabled,
.template-button.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.template-button-outline {
  height: 42px;
  padding: 0 18px;
  color: var(--template-text);
  font: inherit;
  font-weight: 700;
  border: 1.5px solid var(--template-line-strong);
  border-radius: var(--template-radius);
  outline: 0;
  background: rgba(18, 12, 29, 0.62);
  cursor: pointer;
}

.template-button-outline:hover,
.template-button-outline:focus-visible {
  border-color: var(--template-purple-hover);
  background: rgba(157, 28, 255, 0.16);
}

.template-chip {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  padding: 0 12px;
  color: var(--template-text);
  font-size: 0.86rem;
  font-weight: 700;
  border: 1.5px solid var(--template-line);
  border-radius: 999px;
  background: rgba(18, 12, 29, 0.62);
}

.template-chip.is-success {
  color: var(--template-success);
  border-color: rgba(77, 255, 154, 0.46);
}

.template-chip.is-danger {
  color: var(--template-danger);
  border-color: rgba(255, 77, 109, 0.46);
}

.template-progress {
  width: min(560px, calc(100vw - 72px));
  height: 5px;
  margin-top: 14px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(190, 94, 255, 0.12);
  opacity: 0;
  transition: opacity 180ms ease;
}

.template-progress span {
  display: block;
  width: 34%;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, transparent, #cf7aff, transparent);
  transform: translateX(-120%);
}

.template-progress.is-active {
  opacity: 1;
}

.template-progress.is-active span {
  animation: template-progress-sweep 1.25s ease-in-out infinite alternate;
}

.template-percent {
  min-height: 18px;
  margin: 8px 0 0;
  color: rgba(207, 122, 255, 0.86);
  font-size: 0.82rem;
  font-weight: 700;
  text-align: center;
  opacity: 0;
  transition: opacity 180ms ease;
}

.template-percent.is-active {
  opacity: 1;
}

.template-percent .template-progress-value,
.template-percent .template-progress-count {
  color: rgba(207, 122, 255, 0.86);
}

.template-percent .template-percent-symbol,
.template-percent .template-progress-divider,
.template-percent .template-progress-dot,
.template-percent .template-progress-title {
  color: #ffffff;
}

.template-progress-title {
  display: inline-block;
  max-width: min(360px, calc(100vw - 210px));
  overflow: hidden;
  vertical-align: bottom;
  white-space: nowrap;
}

.template-progress-title span {
  display: inline-block;
  min-width: 100%;
}

.template-progress-title.is-marquee span {
  min-width: max-content;
  animation: template-marquee 8s ease-in-out infinite alternate;
}

.template-status {
  min-height: 22px;
  margin: 6px 0 0;
  color: rgba(251, 248, 255, 0.72);
  font-size: 0.92rem;
  text-align: center;
}

.template-status.is-error {
  color: #ff8bc2;
}

.template-preview {
  display: none;
  width: min(560px, calc(100vw - 72px));
  margin-bottom: 34px;
  text-align: center;
}

.template-preview.is-visible {
  display: block;
}

.template-preview-title {
  position: relative;
  max-width: 560px;
  margin: 0 auto;
  overflow: hidden;
  color: rgba(251, 248, 255, 0.86);
  font-size: 1.06rem;
  font-weight: 700;
  line-height: 1.35;
  white-space: nowrap;
}

.template-preview-title span {
  display: inline-block;
  min-width: 100%;
}

.template-preview-title.is-marquee span {
  min-width: max-content;
  animation: template-marquee 9s ease-in-out infinite alternate;
}

.template-preview-subtitle {
  display: none;
  max-width: 560px;
  margin: 1px auto 0;
  overflow: hidden;
  color: rgba(251, 248, 255, 0.58);
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1.1;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.template-preview-subtitle.is-visible {
  display: block;
}

.template-preview-image {
  display: block;
  width: auto;
  max-width: min(380px, 100%);
  max-height: 380px;
  margin: 10px auto 0;
  object-fit: contain;
  border: 1.5px solid var(--template-line-strong);
  border-radius: var(--template-radius);
  background: transparent;
  box-shadow: 0 0 0 1px rgba(207, 122, 255, 0.18);
}

.template-preview-image.is-video {
  width: min(380px, 100%);
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.template-preview-image.is-square {
  width: min(380px, 100%);
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.template-option-grid {
  display: none;
  grid-template-columns: repeat(auto-fit, minmax(74px, max-content));
  justify-content: center;
  gap: 8px;
  width: min(560px, calc(100vw - 72px));
  margin-top: 12px;
}

.template-option-grid.is-visible {
  display: grid;
}

.template-option-grid button {
  min-width: 74px;
  height: 34px;
  padding: 0 14px;
  color: rgba(251, 248, 255, 0.78);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  border: 1px solid rgba(190, 94, 255, 0.22);
  border-radius: var(--template-radius);
  background: rgba(32, 20, 45, 0.9);
  cursor: pointer;
  transition:
    background 160ms ease,
    border-color 160ms ease,
    color 160ms ease;
}

.template-option-grid button:hover,
.template-option-grid button:focus-visible,
.template-option-grid button.is-selected {
  color: var(--template-text);
  border-color: rgba(207, 122, 255, 0.72);
  outline: 0;
  background: rgba(157, 28, 255, 0.72);
}

.template-track-list {
  display: none;
  --template-row-gap: 4px;
  --template-row-height: 32px;
  --template-list-height: calc(var(--template-row-height) * 5 + var(--template-row-gap) * 4 + 16px);
  width: min(560px, calc(100vw - 72px));
  max-height: var(--template-list-height);
  margin-top: 12px;
  padding: 8px;
  overflow-x: hidden;
  overflow-y: auto;
  border: 1px solid rgba(190, 94, 255, 0.26);
  border-radius: var(--template-radius);
  background: rgba(12, 8, 18, 0.58);
  scrollbar-width: none;
}

.template-track-list.is-visible {
  display: grid;
  grid-auto-rows: var(--template-row-height);
  gap: var(--template-row-gap);
}

.template-track-list.is-scrollable {
  height: var(--template-list-height);
  min-height: var(--template-list-height);
  max-height: var(--template-list-height);
}

.template-track-list::-webkit-scrollbar {
  display: none;
}

.template-track {
  display: grid;
  grid-template-columns: 18px 16px minmax(0, 1fr) 0 0 92px;
  align-items: center;
  column-gap: 6px;
  min-height: 0;
  height: var(--template-row-height);
  padding: 0 8px;
  color: rgba(251, 248, 255, 0.78);
  font-size: 0.86rem;
  border-radius: 6px;
  background: rgba(32, 20, 45, 0.38);
}

.template-track.is-single-digit {
  grid-template-columns: 10px 16px minmax(0, 1fr) 0 0 92px;
}

.template-track.has-status {
  grid-template-columns: 18px 16px minmax(0, 1fr) 42px 26px 92px;
}

.template-track.is-single-digit.has-status {
  grid-template-columns: 10px 16px minmax(0, 1fr) 42px 26px 92px;
}

.template-track input {
  width: 14px;
  height: 14px;
  accent-color: var(--template-purple);
}

.template-track-number {
  color: rgba(207, 122, 255, 0.78);
  font-weight: 700;
  text-align: left;
}

.template-track-title {
  overflow: hidden;
  color: #ffffff;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.template-track-title span {
  display: inline-block;
  min-width: 100%;
  color: #ffffff;
}

.template-track-title.is-marquee {
  text-overflow: clip;
}

.template-track-title.is-marquee span {
  min-width: max-content;
  animation: template-marquee 7s ease-in-out infinite alternate;
}

.template-track-percent {
  min-width: 42px;
  color: rgba(207, 122, 255, 0.78);
  font-size: 0.76rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.template-track-percent .template-percent-symbol {
  color: #ffffff;
}

.template-track-state {
  color: #ff5e9c;
  font-size: 0.88rem;
  text-align: center;
}

.template-track.is-done .template-track-state {
  color: var(--template-success);
}

.template-track.is-error .template-track-state {
  color: #ff5e9c;
}

.template-track.is-active .template-track-state {
  color: #ffffff;
}

.template-track button {
  height: 26px;
  padding: 0 10px;
  color: var(--template-text);
  font: inherit;
  font-size: 0.76rem;
  font-weight: 700;
  border: 1px solid var(--template-purple);
  border-radius: 6px;
  background: var(--template-purple);
  cursor: pointer;
}

.template-track button:hover,
.template-track button:focus-visible {
  border-color: var(--template-purple-hover);
  outline: 0;
  background: var(--template-purple-hover);
}

.template-track button:disabled {
  color: rgba(251, 248, 255, 0.38);
  border-color: rgba(180, 170, 196, 0.16);
  background: rgba(118, 112, 128, 0.26);
  cursor: not-allowed;
}

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

@keyframes template-progress-sweep {
  to {
    transform: translateX(300%);
  }
}

@keyframes template-marquee {
  0%,
  14% {
    transform: translateX(0);
  }

  86%,
  100% {
    transform: translateX(calc(-1 * var(--template-marquee-distance, 0px)));
  }
}

@media (max-width: 760px) {
  .template-form-row {
    grid-template-columns: 1fr;
    width: min(420px, calc(100vw - 32px));
  }

  .template-input,
  .template-select-trigger,
  .template-button {
    border-radius: 0;
  }

  .template-input {
    border-radius: calc(var(--template-radius) - 1px) calc(var(--template-radius) - 1px) 0 0;
  }

  .template-select-trigger {
    border-top: 1.5px solid var(--template-line);
    border-right: 0;
    border-left: 0;
  }

  .template-form-row > .template-button {
    border-radius: 0 0 calc(var(--template-radius) - 1px) calc(var(--template-radius) - 1px);
  }
}

/* Wer wenig Bewegung eingestellt hat, bekommt den Raum still: die Sterne
   schweben nicht mehr (siehe void.js), und Laufschriften sowie Ladebalken
   halten an. Die Sternbilder am Zeiger bleiben. */
@media (prefers-reduced-motion: reduce) {
  /* Der Pfeil klappt weiterhin um, nur ohne den Zwischenweg. */
  .template-select-trigger::after {
    transition: none;
  }

  .template-progress.is-active span,
  .template-progress-title.is-marquee span,
  .template-preview-title.is-marquee span,
  .template-track-title.is-marquee span {
    animation: none;
  }
}
