html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    width: 100%;
    height: 100%;
    margin: 0;
    overflow: hidden;
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: #0071c1;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.loading-progress {
    position: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 20vh auto 1rem auto;
}

    .loading-progress circle {
        fill: none;
        stroke: #e0e0e0;
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: #1b6ec2;
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

code {
    color: #c02d76;
}

/* Designer Mode Styles */
.designer-hotspot {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 150px;
    height: 150px;
    z-index: 9998;
    /* Invisible but interactive */
    background: transparent;
    cursor: default;
}

.designer-button {
    position: fixed;
    bottom: 20px;
    left: 20px;
    z-index: 9999;
    background: rgba(0, 0, 0, 0.8);
    padding: 10px 20px;
    border-radius: 8px;
    transition: opacity 0.3s ease;
}

.designer-button button {
    background: #ffcc00;
    border: none;
    padding: 10px 20px;
    border-radius: 4px;
    font-weight: bold;
    cursor: pointer;
    color: #000;
    font-size: 14px;
}

.designer-button button:hover {
    background: #ffdd33;
}

.designer-active .display-item {
    cursor: pointer;
}

.display-item.designer-draggable:hover {
    outline: 2px dashed rgba(255, 204, 0, 0.5);
    outline-offset: 2px;
}

.display-item.designer-selected {
    outline: 3px solid #ffcc00;
    outline-offset: 2px;
    cursor: move;
}

.designer-panel {
    position: fixed;
    top: 0;
    right: 0;
    width: 350px;
    height: 100vh;
    background: rgba(0, 0, 0, 0.95);
    color: white;
    z-index: 10000;
    overflow-y: auto;
    box-shadow: -2px 0 10px rgba(0, 0, 0, 0.5);
}

.designer-panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px 20px;
    background: #1a1a1a;
    border-bottom: 2px solid #ffcc00;
}

.designer-panel-header strong {
    font-size: 18px;
    color: #ffcc00;
}

.designer-panel-header button {
    background: transparent;
    border: none;
    color: white;
    font-size: 20px;
    cursor: pointer;
    padding: 5px 10px;
}

.designer-panel-header button:hover {
    color: #ffcc00;
}

.designer-panel-body {
    padding: 20px;
}

.property-group {
    margin-bottom: 25px;
    padding-bottom: 20px;
    border-bottom: 1px solid #333;
}

.property-group:last-child {
    border-bottom: none;
}

.property-group > label {
    display: block;
    font-weight: bold;
    margin-bottom: 12px;
    color: #ffcc00;
    font-size: 14px;
    text-transform: uppercase;
    letter-spacing: 1px;
}

.property-row {
    display: grid;
    grid-template-columns: 100px 1fr;
    gap: 10px;
    align-items: center;
    margin-bottom: 10px;
}

.property-row span {
    font-size: 13px;
    color: #ccc;
}

.property-row input[type="number"],
.property-row input[type="color"],
.property-row input[type="text"],
.property-row select {
    width: 100%;
    padding: 6px 10px;
    background: #2a2a2a;
    border: 1px solid #444;
    border-radius: 4px;
    color: white;
    font-size: 13px;
}

.property-row input[type="color"] {
    height: 35px;
    padding: 2px;
    cursor: pointer;
}

.property-row input[type="checkbox"] {
    width: 20px;
    height: 20px;
    cursor: pointer;
}

.property-row input:focus,
.property-row select:focus {
    outline: none;
    border-color: #ffcc00;
}

.designer-panel-actions {
    margin-top: 30px;
    padding-top: 20px;
    border-top: 1px solid #333;
}

.designer-panel-actions button {
    width: 100%;
    padding: 12px 20px;
    background: #ffcc00;
    border: none;
    border-radius: 4px;
    font-weight: bold;
    font-size: 14px;
    cursor: pointer;
    color: #000;
    text-transform: uppercase;
    letter-spacing: 1px;
}

.designer-panel-actions button:hover {
    background: #ffdd33;
}

.designer-panel-actions button:active {
    transform: translateY(1px);
}

.designer-panel-actions .btn-danger {
    background: #dc3545;
    color: white;
    margin-bottom: 10px;
}

.designer-panel-actions .btn-danger:hover {
    background: #c82333;
}

.designer-toolbar {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: 9999;
    background: rgba(0, 0, 0, 0.8);
    padding: 10px 20px;
    border-radius: 8px;
}

.designer-toolbar button {
    background: #28a745;
    border: none;
    padding: 10px 20px;
    border-radius: 4px;
    font-weight: bold;
    cursor: pointer;
    color: white;
    font-size: 14px;
}

.designer-toolbar button:hover {
    background: #218838;
}

.designer-toolbar .btn-info {
    background: #17a2b8;
}

.designer-toolbar .btn-info:hover {
    background: #138496;
}

.undo-redo-toolbar {
    position: fixed;
    top: 20px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 9999;
    background: rgba(0, 0, 0, 0.9);
    padding: 10px;
    border-radius: 8px;
    display: flex;
    gap: 10px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
}

.undo-redo-toolbar button {
    background: #6c757d;
    border: none;
    padding: 10px 20px;
    border-radius: 4px;
    font-weight: bold;
    cursor: pointer;
    color: white;
    font-size: 14px;
    display: flex;
    align-items: center;
    gap: 5px;
    transition: all 0.2s ease;
}

.undo-redo-toolbar button:hover:not(:disabled) {
    background: #5a6268;
    transform: translateY(-2px);
}

.undo-redo-toolbar button:disabled {
    background: #343a40;
    color: #6c757d;
    cursor: not-allowed;
    opacity: 0.5;
}

.undo-redo-toolbar .btn-undo:not(:disabled) {
    background: #007bff;
}

.undo-redo-toolbar .btn-undo:not(:disabled):hover {
    background: #0056b3;
}

.undo-redo-toolbar .btn-redo:not(:disabled) {
    background: #17a2b8;
}

.undo-redo-toolbar .btn-redo:not(:disabled):hover {
    background: #138496;
}

/* ============================================
   Display Setup Dialog Styles
   ============================================ */
.setup-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    z-index: 10000;
    padding: 16px;
    overflow: auto;
}

.setup-dialog {
    background: white;
    border-radius: 12px;
    padding: 40px;
    max-width: 600px;
    width: 90%;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    margin: auto;
}

.setup-dialog h2 {
    margin: 0 0 10px 0;
    color: #333;
    font-size: 28px;
}

.setup-subtitle {
    color: #666;
    margin: 0 0 30px 0;
    font-size: 14px;
}

.setup-loading {
    text-align: center;
    padding: 40px;
}

.spinner {
    border: 4px solid #f3f3f3;
    border-top: 4px solid #667eea;
    border-radius: 50%;
    width: 50px;
    height: 50px;
    animation: spin 1s linear infinite;
    margin: 0 auto 20px;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

.setup-success {
    text-align: center;
    padding: 40px;
}

.success-icon {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: #4caf50;
    color: white;
    font-size: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 20px;
}

.setup-form {
    display: flex;
    flex-direction: column;
    gap: 25px;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.form-group label {
    font-weight: 600;
    color: #333;
    font-size: 14px;
}

.form-group small {
    color: #999;
    font-size: 12px;
    margin-top: -5px;
}

.hub-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 200px;
    overflow-y: auto;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 10px;
}

.hub-empty {
    text-align: center;
    padding: 30px;
    color: #999;
}

.hub-item {
    display: flex;
    align-items: center;
    gap: 15px;
    padding: 15px;
    border: 2px solid #e0e0e0;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s;
}

.hub-item:hover {
    border-color: #667eea;
    background: #f8f9ff;
}

.hub-item.selected {
    border-color: #667eea;
    background: #f0f3ff;
}

.hub-icon {
    font-size: 32px;
}

.hub-info {
    flex: 1;
}

.hub-name {
    font-weight: 600;
    color: #333;
    margin-bottom: 4px;
}

.hub-address {
    font-size: 12px;
    color: #666;
    font-family: 'Courier New', monospace;
}

.hub-check {
    font-size: 24px;
    color: #667eea;
}

.manual-hub {
    display: flex;
    gap: 10px;
    margin-top: 10px;
}

.hub-input {
    flex: 1;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 6px;
    font-size: 14px;
}

.hub-input:focus {
    outline: none;
    border-color: #667eea;
}

.text-input {
    padding: 12px;
    border: 1px solid #ddd;
    border-radius: 6px;
    font-size: 14px;
    width: 100%;
}

.text-input:focus {
    outline: none;
    border-color: #667eea;
}

.select-input {
    padding: 12px;
    border: 1px solid #ddd;
    border-radius: 6px;
    font-size: 14px;
    width: 100%;
    background: white;
    cursor: pointer;
}

.select-input:focus {
    outline: none;
    border-color: #667eea;
}

.btn-primary {
    padding: 14px 28px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
}

.btn-primary:hover:not(:disabled) {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}

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

.btn-secondary {
    padding: 10px 20px;
    background: white;
    color: #667eea;
    border: 2px solid #667eea;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
}

.btn-secondary:hover {
    background: #667eea;
    color: white;
}

.btn-link {
    background: none;
    border: none;
    color: #667eea;
    font-size: 14px;
    cursor: pointer;
    text-decoration: underline;
    padding: 5px;
}

.btn-link:hover {
    color: #764ba2;
}

.button-group {
    display: flex;
    justify-content: space-between;
    margin-top: 10px;
    padding-top: 12px;
    border-top: 1px solid rgba(0, 0, 0, 0.08);
}

.error-message {
    background: #fee;
    border: 1px solid #fcc;
    color: #c33;
    padding: 12px;
    border-radius: 6px;
    font-size: 14px;
}

/* Page Transition Animations */
.page-fade-out {
    animation: fadeOut var(--transition-duration, 300ms) ease-in-out forwards;
}

.page-fade-in {
    animation: fadeIn var(--transition-duration, 300ms) ease-in-out forwards;
}

.page-slide-out {
    animation: slideOut var(--transition-duration, 300ms) ease-in-out forwards;
}

.page-slide-in {
    animation: slideIn var(--transition-duration, 300ms) ease-in-out forwards;
}

@keyframes fadeOut {
    from { opacity: 1; }
    to { opacity: 0; }
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes slideOut {
    from { transform: translateX(0); }
    to { transform: translateX(-100%); }
}

@keyframes slideIn {
    from { transform: translateX(100%); }
    to { transform: translateX(0); }
}

/* ============================================================================
   Lauftext (Marquee) fuer zu lange Texte - nur Videoanzeige (VAZ), 07/2026
   Ueberarbeitet 2026-08-01 (v1.5.1.6)
   ----------------------------------------------------------------------------
   Zusammenspiel mit js/marquee.js und DisplayRenderer.razor:
   - .sb-marquee ist die an der Feldbreite clippende Box (overflow-x: clip,
     Inline-Style aus dem Renderer). Die innere Schiene .sb-marquee-track
     enthaelt den Text zweimal (Kopie 2 mit Luecke als padding-left).
   - Solange marquee.js KEINEN Ueberlauf gemessen hat, fehlt das Attribut
     data-sb-marquee-run: Kopie 2 ist versteckt, nichts bewegt sich - die Optik
     ist identisch zum klassischen Textfeld.
   - Die BEWEGUNG selbst steht seit dem 2026-08-01 nicht mehr hier, sondern
     kommt aus der Web-Animations-API (js/marquee.js, Element.animate).
     Hier bleiben nur noch Sichtbarkeit und Ausrichtung.

   Warum das Aktiv-Merkmal ein ATTRIBUT ist und keine Klasse:
   Die Klasse .sb-marquee-active musste von JS auf ein Element gesetzt werden,
   dessen class-Attribut Blazor rendert (DisplayRenderer.razor:346). Das ging
   bisher nur gut, weil dort ein unveraenderlicher Literal steht und Blazors
   Diff bei gleichem Wert gar nichts schreibt - also aus Zufall, nicht aus
   Konstruktion. Ein Attribut, das im Render-Tree ueberhaupt nicht vorkommt,
   kann Blazor dagegen unter keinen Umstaenden entfernen: RemoveAttribute
   entsteht nur fuer Attribute, die im alten Baum standen.
   ============================================================================ */

/* Grundzustand (Text passt): zweite Kopie unsichtbar, keine Bewegung.
   UMGESTELLT 2026-08-01 auf das Attribut, Begruendung siehe oben.
   ALT: .sb-marquee:not(.sb-marquee-active) .sb-marquee-copy2 { display: none; } */
.sb-marquee:not([data-sb-marquee-run]) .sb-marquee-copy2 {
    display: none;
}

/* Aktiver Lauftext: Der Text startet immer buendig am linken Feldrand
   ("erster Buchstabe am Anfang der Zeile"), egal welche Ausrichtung das Feld
   im statischen Zustand hat (center/right wuerde die Schiene sonst verschieben).
   Das !important schlaegt den normalen Inline-Style aus DisplayRenderer.razor:351
   - genau wie bisher. Dadurch beginnt die Schiene garantiert bei Offset 0 und die
   Animation kann bei translateX(0px) anfangen, ohne einen Startversatz aus der
   Ausrichtung herausrechnen zu muessen.
   ALT: .sb-marquee.sb-marquee-active { justify-content: flex-start !important; } */
.sb-marquee[data-sb-marquee-run] {
    justify-content: flex-start !important;
}

/* will-change haelt die Schiene auf einer eigenen Compositing-Ebene - die
   Bewegung laeuft dadurch am Hauptthread vorbei und ruckelt nicht, wenn Blazor
   gerade rendert. Bleibt also, auch wenn die Animation selbst jetzt aus dem JS kommt. */
.sb-marquee[data-sb-marquee-run] .sb-marquee-track {
    will-change: transform;
}

/* --- ERSETZT am 2026-08-01 (v1.5.1.6): Die Bewegung kommt jetzt aus der
   Web-Animations-API in js/marquee.js. ---

   Grund fuer den Wechsel: Diese Loesung uebergab Strecke, Dauer und Anlaufpause
   als CSS-Variablen im style-Attribut der Schiene. Dieses Attribut gehoert aber
   Blazor (DisplayRenderer.razor:352 - dort stehen Schriftgroesse, Farbe,
   Schriftschnitt und Schriftart). Schreibt Blazor es neu, sind die drei Variablen
   weg, die Strecke faellt auf den Vorgabewert 0px zurueck und das Band bleibt
   stehen. Der Merk-Zustand im JS haette das nie bemerkt und nie repariert.
   Eine Animation aus Element.animate() haengt dagegen am Element-OBJEKT; ein
   setAttribute('style', ...) kann sie weder loeschen noch anhalten.

.sb-marquee.sb-marquee-active .sb-marquee-track {
    animation: sb-marquee-run var(--sb-marquee-duration, 10s) linear var(--sb-marquee-delay, 0ms) infinite;
    will-change: transform;
}

@keyframes sb-marquee-run {
    from { transform: translateX(0); }
    to   { transform: translateX(calc(-1 * var(--sb-marquee-distance, 0px))); }
}
   --- Ende des ersetzten Blocks --- */
