{% extends "basis.html" %}{% block weich %} data-weich{% endblock %}{% block inhalt %}{% from "schalter.html" import schalter, wahl %}{% from "unterseiten.html" import konto_zeilen, zurueck with context %} {# Weiche Navigation (23.10.2026): Konto wechselt weich wie Library & Co. – alle Skripte mit data-seite, kein Inline-Skript (CSP). konto.js leitet alte Anker weiter (#speicher nach /quellen, #analysen nach /analysen) und steht deshalb vorn. #} {% set ks = t.kontoseite.sicherheit %}{% set tb = t.kontoseite.benachrichtigung %} {# Handy schlank, Phase 3c (07.11.2026): am Handy zuerst die Liste der Bereiche (Name + Zustand), Tipp öffnet den Bereich als Unterseite (static/unterseiten.js schaltet über Anker und Verlauf: data-ut nennt die Unterseite eines Abschnitts, data-ut-teil Teile des Formulars „Erscheinungsbild“, die nur unter „Mein Mixer“ stehen). Breit und ohne Skript bleibt die lange Seite wie bisher. #}
{{ zurueck("/einstellungen") }}

{{ t.konto }}

{% if fehler %}{% endif %} {# Konto und Sicherheit (23.10.2026): große Karte ganz oben, nur im Ory-Modus. Drei Blöcke: Schutz-Stufe · Anmeldewege · Geräte und Adresse, darunter drei Knöpfe. Kratos nicht erreichbar: ehrlicher Hinweis statt Fehler. #} {% if sicherheit %}

{{ ks.titel }}

{% if not sicherheit.erreichbar %}

{{ ks.nicht_erreichbar }}

{% else %}

{{ ks.stufe.replace("{n}", sicherheit.stufe | string) }}

    {% for ok in sicherheit.stufen %}
  1. {{ ks.stufen[loop.index0] }} – {{ ks.erledigt if ok else ks.offen }}
  2. {% endfor %}

{{ ks.streng_an if sicherheit.schutz_an else ks.streng_aus }}

{{ ks.wege_titel }}

{% set w = sicherheit.wege %}
  • {{ ks.passkeys_keine if not w.passkey else (ks.passkeys_eins if w.passkey == 1 else ks.passkeys.replace("{n}", w.passkey | string)) }}{% if sicherheit.passkey_zuletzt %}{{ ks.passkey_zuletzt.replace("{name}", sicherheit.passkey_zuletzt) }}{% endif %}
  • {{ ks.app_ja if w.totp else ks.app_nein }}
  • {{ ks.codes_ja if w.lookup_secret else ks.codes_nein }}
  • {{ ks.mail_code }}
{% if sicherheit.namen_verborgen %}

{{ ks.namen_mit_faktor }}

{% endif %}

{{ ks.geraete_titel }}

{% if sicherheit.sitzungen is none %}{{ ks.sitzungen_unbekannt }}{% elif sicherheit.sitzungen == 1 %}{{ ks.sitzungen_eins }}{% else %}{{ ks.sitzungen.replace("{n}", sicherheit.sitzungen | zahl(sprache)) }}{% endif %}

{{ ks.adresse }}
{{ sicherheit.adresse }} · {{ ks.adresse_aendern }}

{{ ks.oeffnen }} {{ ks.passkey_neu }} {% if not sicherheit.schutz_an %}{{ ks.streng }}{% endif %}
{% endif %}
{% endif %} {# Benachrichtigungen (23.10.2026): Häkchen je Art; Sicherheit immer an (kein Häkchen). Ohne Spalte in der Datenbank (Code vor der Einmal-Datei) gibt es die Karte nicht. #} {% if bn.bereit %}

{{ tb.titel }}

{{ tb.intro }}

{% if bn_gespeichert %}

{{ tb.gespeichert }}

{% endif %} {% if not bn.bestaetigt %}

{{ tb.unbestaetigt }}

{% elif not bn.versand %}

{{ tb.versand_aus }}

{% else %}

{{ tb.an_adresse.replace("{adresse}", bn.adresse) }}

{% endif %}

{% endif %} {# Zustimmung „Plattensuche bei MusicBrainz“ (12.11.2026): Zustand mit Datum und EIN Knopf (zustimmen bzw. zurücknehmen), ohne Skript. Nur mit Plattenregal, nie in Store-Fassungen, Live-Demo, Offline-Paket (app._platten_zustimmung_konto). Zum Zustimmen steht der ganze Text der Fassung da; Fassung, Sprache und Prüfwert reisen mit (timbre_api/platten_zustimmung.py). #} {% set pz = platten_zustimmung_konto() %}{% if pz %}

{{ pz.titel }}

{{ pz.zeile }}

{{ pz.text.titel }}
{% for kopf, satz in pz.text.punkte %}
{{ kopf }}
{{ satz }}
{% endfor %}

{{ pz.text.nachweis }}

{% if not pz.gueltig %}{% endif %}

{{ pz.zum_regal }}

{{ pz.folge }}

{% endif %}

{{ t.kontingent }}

{# Mitgliedschaft (11.11.2026, TP2 0529): für JEDES Konto, in jeder Fassung – ein Name, kein Datum, kein Abzeichen. Darunter das Kontingent mit dem echten Zählwert des Kontos. #}

{{ t.earlybird.mitglied }}: {{ t.earlybird.name }}

{{ t.earlybird.mitglied_unter }}

{{ t.kontingent_satz.replace("{g}", k.genutzt | zahl(sprache)).replace("{n}", k.grenze | zahl(sprache)).replace("{f}", k.frei | zahl(sprache)) }}

{{ t.kontingent_regel }}

{% if k.frei <= 0 %}

{% if store_app %}{{ t.earlybird.kontingent_leer }}{% elif earlybird and nutzer.get('kontingent_grenze') is not none %}{{ t.earlybird.kontingent_voll_web | replace("{n}", k.grenze | zahl(sprache)) }}{% else %}{{ t.kontingent_leer }}{% endif %}

{% endif %} {# Der Hinweis verspricht die höhere Vorgabe – mit eigener Grenze des Kontos (kontingent_grenze) stimmte er nicht. Einen Knopf „Mail neu senden“ gibt es nicht: Dafür hat Timbre keinen Weg, der Text nennt den Support. #} {% if not nutzer.email_bestaetigt and nutzer.get('kontingent_grenze') is none %}

{{ t.email_hinweis.replace("{b}", vorgabe_bestaetigt | zahl(sprache)).replace("{u}", vorgabe_unbestaetigt | zahl(sprache)) }}

{% endif %}
{# Onlinespeicher und Analysen-Verlauf stehen seit UX-Paket 1 unter „Quellen“. Alte Lesezeichen auf /konto#speicher und /konto#analysen leitet static/konto.js dorthin (der Anker kommt nie beim Server an); ohne Skript bleibt dieser Hinweis. #} {% if beta %}{% set bp = t.tspeicher.platz %}

{{ bp.konto_titel }}

{{ bp.zeile.replace("{b}", beta.belegt | gb(sprache)).replace("{k}", beta.kontingent | gb(sprache)).replace("{f}", beta.frei | gb(sprache)) }}

{% if beta.voll %}

{{ bp.voll }}

{% elif beta.prozent >= 80 %}

{{ bp.fast_voll.replace("{f}", beta.frei | gb(sprache)) }}

{% endif %}

{{ bp.zum_upload }}

{% endif %}

{{ t.quellen.konto_hinweis }} {{ t.quellen.konto_link }}.

{# Rekordbox-Import (23.10.2026): Löschen steht unter Quellen (Karte „Rekordbox“, geht ohne JavaScript) #}

{{ t.rekordbox.konto.hinweis }} {{ t.rekordbox.konto.link }}

{{ t.erscheinungsbild }}

{# DJ-Schalter (24.10.2026): Design, Modus und Mixer als Segment (eine Taste je Wahl, LED an der gewählten), die Häkchen darunter als Schalter – das Formular und „Speichern“ bleiben, wie sie waren (templates/schalter.html) #}
{{ t.design }}
{# Neonlila (28.10.2026): freischaltbare Designs nur, wenn die Verwaltung sie diesem Konto freigeschaltet hat (design.designs_fuer) #} {% for wert in designs_fuer(eb) %} {{ wahl("design", wert, t.designs.namen[wert], an=(eb.design == wert)) }} {% endfor %}
{% for wert in designs_frei(eb) %}

{{ t.designs.namen[wert] }} · {{ t.designs.frei_hinweis }}. {{ t.designs.beschreibung.get(wert, "") }}

{% endfor %}
{{ t.modus }}
{# 24.10.2026: Dunkel · Hell · Nach Tageszeit · Wie dein Gerät (Standard zuerst); die Wahl wirkt als Vorschau sofort #} {% for wert in modi_folge %} {{ wahl("modus", wert, t["modus_" ~ wert], an=(eb.modus == wert), beschrieben=("modus-tageszeit-hilfe" if wert == "tageszeit" else none)) }} {% endfor %}

{{ t.modus_tageszeit_hilfe }}

{# Band-Wellenform (17.10.2026): Mein Mixer – 3er-Block, Trennfrequenzen des gewählten Satzes darunter (erscheinungsbild.js folgt der Wahl) #}
{{ t.mixer }}
{% for wert in ("djm3","xone4","v10") %} {{ wahl("mixer", wert, t.mixer_namen[wert], an=(eb.mixer == wert), beschrieben="mixer-hilfe", daten={"grenzen": t.mixer_grenzen[wert]}) }} {% endfor %}

{{ t.mixer_hilfe }} {{ t.mixer_grenzen[eb.mixer] }}

{# Tonart-Schreibweise (07.11.2026, Leitlinie Maintainer: kognitiver Load minimal): drei große Tasten am echten Wert aus der eigenen Library („12m“ · „7A“ · „Dm“, Vorgabe Open Key zuerst) mit Mini-Unterzeile; ein Tipp wirkt sofort und speichert (static/konto.js, PATCH /api/v1/konto), ohne Skript über „Speichern“. Ohne eigene Wahl ist die automatische Vorgabe markiert; `tonart_auto` hält fest, dass nichts gewählt wurde (Speichern ohne Änderung lässt sie automatisch). #} {% set tsw = t.tonart_sw %}{% set tw = eb | tonart_wirksam %}{% set tbsp = tonart_beispiel(nutzer) %}
{{ tsw.titel }}
{% for wert in ("open","alnum","note") %} {% endfor %}

{% if eb | tonart_automatisch %}{% endif %} {# Fly-in anpassbar (30.10.2026, Variante B): eingestellt wird direkt im Fly-in – hier nur der Weg dorthin #} {{ schalter(tasten.lavalampe, t.lavalampe_zeigen, name="lavalampe", an=eb.lavalampe) }} {# H33: Die Einstellung wirkt nur in der Desktop-App – solange keine App öffentlich ist (Beta-Manifest leer), steht sie hier nicht; der gespeicherte Wert bleibt (verborgenes Feld), damit „Speichern“ ihn nicht zurücksetzt. #} {% if app_da %}{{ schalter(tasten.hilfe_einblenden, t.hilfe_einblenden, name="hilfe_einblenden", an=eb.hilfe_einblenden) }}

{{ t.hilfe_einblenden_hilfe }}

{% elif eb.hilfe_einblenden %}{% endif %} {# Paket 2: Kurztasten der Tag List (T, Alt+↑/↓) – wirken nur auf dem Fokus und lassen sich abschalten (WCAG 2.1.4) #} {{ schalter(tasten.kurztasten, t.kurztasten, name="kurztasten", an=eb.kurztasten, hilfe_id="kurztasten-hilfe") }}

{{ t.kurztasten_hilfe }}

{# Tutorial „Kniffe“ (29.10.2026): Kniffe im Kontext abschaltbar wie die Kurztasten; Einstieg und Seite /kniffe bleiben #} {{ schalter(tasten.kniffe, t.kniffe.konto.schalter, name="kniffe", an=(eb.kniffe is not sameas false), hilfe_id="kniffe-hilfe") }}

{{ t.kniffe.konto.hilfe }} {{ t.kniffe.ui.alle }} →

{# Stufe 0 „Now Playing“: seit 07.11.2026 immer an, ohne Schalter (BPM · Tonart · Energie in `album` der Media Session, player.js) #} {{ schalter(tasten.farben_eigen, t.lavafarben_eigen, name="farben_eigen", id="farben_eigen", an=eb.lavafarben) }}
{% for i in range(4) %} {# Konto-Kontrast (24.10.2026): Bandname als eigenes Textstück über dem Farbfeld – sein Kontrast gilt gegen die Karte, nicht gegen die Farbfläche darunter (vorher maß die Prüfung den ganzen Block samt Farbfeld) #} {% endfor %}
{% for wert, name, hell, dunkel in lavafarben_designs(eb) %} {% endfor %}

{{ t.lavafarben_hilfe }}

{{ schalter(tasten.teilen, t.teilen, name="teilen", an=nutzer.teilen) }}

{{ t.teilen_hilfe }}

{# 08.11.2026 (Zweig konto-patch): Mit Skript speichert jedes Feld sich selbst (static/konto.js, PATCH /api/v1/konto – auch im App-Fenster, wo dieses POST nicht ankommt), mit Stand je Feld; „Speichern“ ist dann verborgen (Klasse ut-sofort-an). Ohne Skript geht alles wie bisher über POST /konto. #}
{# Musikordner (bis 25.10.2026 hier): steht seit 25.10. unter Quellen → Rekordbox – dort, wo die Rekordbox-XML eingelesen wird und Timbre den Ordner aus der XML vorschlagen kann. Kein Verweis hier: das Konto trägt nur, was auf dem Server liegt, der Ordner ist eine Angabe über das Gerät. Alte Links /konto#musikordner-h leitet static/konto.js nach /quellen#rk-ordner. #} {# Handy (3c): Überschrift der Unterseite „Konto und Sicherheit“ über Datenexport und Löschen – breit verborgen (wie bisher ohne) #}

{{ t.home.ut_daten }}

{{ t.export }}

{{ t.loeschen }}

{% endblock %}