/* =========================================================================
Admin Control Panel — Components
   =========================================================================

Extracted from the Leptos `<style>` blocks that used to sit inside these
components. Those blocks only existed in the DOM while their component was
mounted, which made cross-panel styling depend on what happened to be on
screen, and made the same rule easy to declare twice with different values.

Sources:
     - apps/frontend-admin/src/ui/components/sync_status_banner.rs
   ========================================================================= */

/* ---- sync_status_banner.rs ---- */
         .sync-banner {
             background: var(--bg-tertiary); border: 1px solid var(--border-primary);
             border-radius: 10px; padding: 1rem 1.25rem; margin-bottom: 1.25rem;
             display: flex; flex-direction: column; gap: 0.6rem;
         }
         .sync-banner.running { border-color: var(--accent-color); }
         .sync-banner.completed { border-color: #48c78e; }
         .sync-banner.failed { border-color: var(--danger-color); }
         .sync-banner-head { display: flex; align-items: center; gap: 0.6rem; }
         .sync-banner-phase { font-weight: 600; }
         .sync-banner-count { color: var(--text-secondary); font-size: 0.85rem; margin-left: auto; }
         .sync-banner-bar {
             background: var(--bg-primary); border: 1px solid var(--border-primary);
             border-radius: 5px; height: 0.6rem; overflow: hidden;
         }
         .sync-banner-fill { height: 100%; background: var(--accent-color); transition: width 0.3s; }
         .sync-banner-warnings { font-size: 0.85rem; color: var(--text-secondary); }
         .sync-banner-warnlist {
             margin-top: 0.4rem; max-height: 200px; overflow-y: auto;
             display: flex; flex-direction: column; gap: 0.2rem;
             font-size: 0.8rem; color: var(--danger-color);
             background: var(--bg-primary); border: 1px solid var(--border-primary);
             border-radius: 4px; padding: 0.5rem 0.75rem;
         }
         @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
         .sync-banner .sync-spinner {
             width: 1em; height: 1em; border-radius: 50%;
             border: 2px solid rgba(255,255,255,0.3); border-top-color: var(--accent-color);
             animation: spin 0.75s linear infinite; flex-shrink: 0;
         }
     

/* ---- styles.rs (was const IMPORT_VERIFICATION_STYLES) ---- */
.import-verification-modal {
 max-width: 1100px !important;
 width: 95% !important;
 max-height: 90vh !important;
 display: flex;
 flex-direction: column;
}

.import-stats {
 display: flex;
 gap: 1.5rem;
 font-size: 0.95rem;
 color: var(--text-secondary);
 margin-top: 0.5rem;
 font-weight: 600;
}

.stat.approved { color: var(--success-color); }
.stat.rejected { color: var(--danger-color); }
.stat.remaining { color: var(--text-secondary); opacity: 0.7; }

.modal-body {
 flex: 1;
 overflow-y: auto;
 padding: 2rem;
 min-height: 0; /* Important for flex-basis: auto to allow shrinking */
}

.batch-actions {
 display: flex;
 gap: 1rem;
 margin-bottom: 2rem;
}

.batch-actions button {
 flex: 1;
 display: flex;
 align-items: center;
 justify-content: center;
 gap: 0.75rem;
 padding: 0.85rem;
 border-radius: 10px;
 border: 1px solid var(--border-primary);
 background: var(--bg-tertiary);
 color: var(--text-primary);
 cursor: pointer;
 transition: all 0.2s;
 font-weight: 600;
}

.btn-approve-all:hover { background: var(--success-bg); border-color: var(--success-color); color: var(--success-color); }
.btn-reject-all:hover { background: var(--danger-bg); border-color: var(--danger-color); color: var(--danger-color); }

.verification-list {
 display: flex;
 flex-direction: column;
 gap: 2rem;
 margin-bottom: 2rem;
 min-height: 500px;
}

.verification-card {
 display: flex;
 gap: 2.5rem;
 padding: 2rem;
 background: var(--bg-secondary);
 border: 1px solid var(--border-primary);
 border-radius: 16px;
 animation: slideIn 0.35s cubic-bezier(0.4, 0, 0.2, 1);
 box-shadow: 0 8px 32px rgba(0,0,0,0.2);
}

@keyframes slideIn {
 from { opacity: 0; transform: translateY(20px); }
 to { opacity: 1; transform: translateY(0); }
}

.card-image-preview {
 width: 160px;
 flex-shrink: 0;
 position: relative;
 z-index: 10;
 pointer-events: auto;
}

.card-image-preview .card-item {
 width: 100%;
 height: auto;
 border-radius: 10px;
 box-shadow: 0 4px 24px rgba(0,0,0,0.5);
 transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.card-image-preview:hover .card-item {
 transform: scale(1.75);
 z-index: 100;
 box-shadow: 0 12px 48px rgba(0,0,0,0.8);
}

.verification-info {
 flex: 1;
 display: flex;
 flex-direction: column;
 gap: 1.5rem;
}

.card-name {
 font-weight: 800;
 font-size: 1.6rem;
 color: var(--text-color);
 border-bottom: 2px solid var(--border-primary);
 padding-bottom: 0.75rem;
 letter-spacing: -0.02em;
}

.tags-container {
 display: flex;
 flex-direction: column;
 gap: 1.25rem;
}

.tag-verification-row {
 display: grid;
 grid-template-columns: 220px 1fr;
 gap: 1rem 1.5rem;
 align-items: start;
 padding: 1.25rem;
 background: rgba(var(--bg-tertiary-rgb), 0.4);
 border-radius: 12px;
 border: 1px solid rgba(var(--border-primary-rgb), 0.6);
 transition: background-color 0.2s;
}

.tag-verification-row:hover {
 background: rgba(var(--bg-tertiary-rgb), 0.6);
}

.tag-identity {
 display: flex;
 flex-direction: column;
 gap: 0.6rem;
}

.tag-badge {
 padding: 0.4rem 1rem;
 background: rgba(var(--color-accent-rgb), 0.12);
 color: var(--text-accent);
 border: 1px solid rgba(var(--color-accent-rgb), 0.25);
 border-radius: 6px;
 font-size: 0.95rem;
 font-weight: 700;
 text-align: center;
 box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.tag-category-label {
 color: var(--text-secondary);
 font-size: 0.85rem;
 font-style: italic;
 text-align: center;
 opacity: 0.8;
}

.tag-metadata-editor-dropdowns {
 display: flex;
 flex-direction: column;
 gap: 0.75rem;
}

.metadata-dropdown-row {
 display: flex;
 gap: 0.5rem;
 align-items: center;
}

.tag-metadata-editor-dropdowns select {
 flex: 1;
 background: rgba(0,0,0,0.4);
 border: 1px solid var(--border-primary);
 border-radius: 6px;
 color: var(--text-primary);
 padding: 0.5rem 0.75rem;
 font-size: 0.9rem;
 cursor: pointer;
 transition: border-color 0.2s;
}

.tag-metadata-editor-dropdowns select:focus {
 outline: none;
 border-color: var(--color-accent);
}

.btn-remove-meta {
 background: none;
 border: none;
 color: var(--danger-color);
 cursor: pointer;
 padding: 0.25rem;
 display: flex;
 align-items: center;
 justify-content: center;
 opacity: 0.6;
 transition: opacity 0.2s;
}

.btn-remove-meta:hover {
 opacity: 1;
}

.btn-add-meta {
 align-self: flex-start;
 background: none;
 border: 1px dashed var(--border-primary);
 color: var(--text-secondary);
 font-size: 0.8rem;
 padding: 0.3rem 0.6rem;
 border-radius: 4px;
 cursor: pointer;
 display: flex;
 align-items: center;
 gap: 0.4rem;
 transition: all 0.2s;
}

.btn-add-meta:hover {
 color: var(--text-accent);
 border-color: var(--color-accent);
 background: rgba(var(--color-accent-rgb), 0.05);
}

.tag-actions {
 grid-column: 1 / -1;
 display: flex;
 gap: 1rem;
 justify-content: flex-end;
 border-top: 1px solid rgba(var(--border-primary-rgb), 0.15);
 padding-top: 1rem;
}

.btn-action {
 width: 64px;
 height: 64px;
 display: flex;
 align-items: center;
 justify-content: center;
 border-radius: 12px;
 border: 2px solid var(--border-primary);
 background: var(--bg-tertiary);
 cursor: pointer;
 transition: all 0.2s;
 box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}

.btn-action svg {
 filter: drop-shadow(0 2px 4px rgba(0,0,0,0.4));
}

.btn-action.approve {
 color: var(--success-color);
 border-color: var(--success-bg-hover);
 background: var(--success-bg);
}
.btn-action.approve:hover {
 background: var(--success-bg-hover);
 border-color: var(--success-color);
 transform: scale(1.1);
 box-shadow: 0 0 15px var(--success-border);
}

.btn-action.reject {
 color: var(--danger-color);
 border-color: var(--danger-bg-hover);
 background: var(--danger-bg);
}
.btn-action.reject:hover {
 background: var(--danger-bg-hover);
 border-color: var(--danger-color);
 transform: scale(1.1);
 box-shadow: 0 0 15px var(--danger-border);
}

.pagination {
 display: flex;
 align-items: center;
 justify-content: center;
 gap: 2.5rem;
 color: var(--text-secondary);
 padding: 2rem 0 1rem 0;
 border-top: 1px solid var(--border-primary);
}

.btn-finalize {
 background: var(--color-accent);
 color: #000;
 padding: 1rem 2.5rem;
 border: none;
 border-radius: 10px;
 font-weight: 800;
 font-size: 1.1rem;
 cursor: pointer;
 transition: transform 0.2s, background-color 0.2s, box-shadow 0.2s;
 box-shadow: 0 4px 12px rgba(var(--color-accent-rgb), 0.3);
}

.btn-finalize:hover:not(:disabled) {
 transform: translateY(-2px);
 background: #fff;
 box-shadow: 0 6px 20px rgba(255, 255, 255, 0.4);
}

.btn-finalize:disabled {
 background: var(--bg-tertiary);
 color: var(--text-secondary);
 cursor: not-allowed;
 opacity: 0.4;
 box-shadow: none;
}

.loading-state {
 display: flex;
 flex-direction: column;
 align-items: center;
 justify-content: center;
 padding: 4rem;
 color: var(--text-secondary);
}

.spinner {
 width: 40px;
 height: 40px;
 border: 3px solid rgba(255,255,255,0.1);
 border-radius: 50%;
 border-top-color: var(--accent-primary);
 animation: spin 1s ease-in-out infinite;
 margin-bottom: 1.5rem;
}

@keyframes spin {
 to { transform: rotate(360deg); }
}

@media (max-width: 768px) {
 .import-verification-modal {
     width: 100% !important;
     height: 100% !important;
     max-height: 100vh !important;
     max-width: 100vw !important;
     margin: 0 !important;
     border-radius: 0 !important;
 }

 .modal-header {
     padding: 1rem;
 }

 .modal-header h3 {
     font-size: 1.15rem;
 }

 .import-stats {
     gap: 0.5rem;
     font-size: 0.75rem;
 }

 .modal-body {
     padding: 0.75rem !important;
 }

 .batch-actions {
     flex-direction: column;
     gap: 0.5rem;
     margin-bottom: 1rem;
 }

 .batch-actions button {
     padding: 0.6rem;
     font-size: 0.9rem;
 }

 .verification-list {
     gap: 1rem;
 }

 .verification-card {
     flex-direction: column;
     padding: 1rem;
     gap: 1rem;
     align-items: stretch;
 }

 .card-image-preview {
     width: 120px;
     margin: 0 auto;
 }

 .card-image-preview:hover img {
     transform: scale(1.1);
 }

 .card-name {
     font-size: 1.2rem;
     text-align: center;
     padding-bottom: 0.5rem;
 }

 .tag-verification-row {
     display: flex;
     flex-direction: column;
     grid-template-columns: none;
     gap: 1rem;
     padding: 0.75rem;
 }

 .tag-identity {
     flex-direction: column;
     align-items: flex-start;
     gap: 0.4rem;
 }

 .tag-badge {
     width: 100%;
     max-width: none;
     font-size: 0.85rem;
     padding: 0.3rem;
 }

 .tag-category-label {
     font-size: 0.75rem;
     text-align: left;
 }

 .tag-metadata-editor-dropdowns {
     width: 100%;
 }

 .metadata-dropdown-row {
     flex-wrap: wrap;
     gap: 0.5rem;
 }

 .metadata-dropdown-row select {
     flex: 1 1 120px;
     min-width: 0;
     font-size: 0.85rem;
 }

 .tag-actions {
     display: flex;
     width: 100%;
     gap: 0.75rem;
     justify-content: stretch;
     border-top: 1px solid rgba(var(--border-primary-rgb), 0.2);
     padding-top: 0.75rem;
 }

 .btn-action {
     flex: 1;
     height: 48px;
     width: auto;
 }

 .pagination {
     gap: 1rem;
     padding: 1rem 0;
 }

 .modal-footer {
     flex-direction: column-reverse;
     padding: 1rem;
     gap: 1rem;
 }

 .btn-finalize {
     width: 100%;
     font-size: 1rem;
     padding: 0.85rem;
 }
}

/* =========================================================================
   Alerts panel (Broadcast + Changelog)
   =========================================================================

   This panel used to be written entirely in Tailwind-style utilities —
   `px-4 py-3 text-sm bg-gray-900 flex-1` and so on. The ACP has no Tailwind
   build, so none of those classes existed: the panel was relying on a handful
   of inline `style=` attributes for anything that actually rendered, and the
   rest was inert. Hence the semantic classes here.
   ========================================================================= */

.alerts-panel {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    height: 100%;
}

.alerts-card {
    background: var(--bg-tertiary);
    border: 1px solid var(--border-primary);
    border-radius: 8px;
    padding: 1.5rem;
}

/* The compose form keeps its natural height; the changelog takes the rest and
   scrolls internally, so the page itself never scrolls. */
.alerts-compose {
    flex: none;
}

.alerts-changelog {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.alerts-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
    gap: 1rem;
}

.alerts-card-title {
    margin: 0 0 1rem 0;
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--text-primary);
}

.alerts-card-header .alerts-card-title {
    margin-bottom: 0;
}

/* ── Compose form ─────────────────────────────────────────────────────── */

.alerts-form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.alerts-field {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    width: 100%;
}

.alerts-field-grow {
    flex: 1;
}

.alerts-label {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-secondary);
}

.alerts-input {
    width: 100%;
    padding: 0.75rem;
    border-radius: 6px;
    border: 1px solid var(--border-primary);
    background: var(--bg-primary);
    color: var(--text-primary);
    font-size: 0.9rem;
}

.alerts-input:focus {
    outline: none;
    border-color: var(--accent-color);
}

/* Markdown is written here, so a monospace column that can be dragged taller
   is the point rather than a preference. */
.alerts-textarea {
    min-height: 300px;
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 0.85rem;
    line-height: 1.6;
    resize: vertical;
}

.alerts-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-top: 0.5rem;
}

.alerts-status {
    font-weight: 500;
    font-size: 0.9rem;
}

.alerts-status.error {
    color: var(--danger-color);
}

.alerts-status.success {
    color: var(--success-color);
}

/* ── Changelog table ──────────────────────────────────────────────────── */

.changelog-scroll {
    flex: 1;
    overflow-y: auto;
    padding-right: 0.5rem;
}

/* Sticky header so the columns stay readable while scrolling a long history.
   Needs its own background or rows show through it. */
.changelog-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--bg-tertiary);
    text-transform: uppercase;
    font-size: 0.75rem;
    letter-spacing: 0.05em;
}

.changelog-table td {
    vertical-align: top;
}

.changelog-message-col {
    width: 50%;
}

.changelog-date {
    white-space: nowrap;
    color: var(--text-muted);
}

.changelog-commit {
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 0.78rem;
    color: var(--text-muted);
}

.changelog-author {
    color: var(--text-secondary);
}

.changelog-message-title {
    font-weight: 500;
    color: var(--text-primary);
}

/* Commit bodies are pre-wrapped text and must keep their line breaks. */
.changelog-message-body {
    margin-top: 0.25rem;
    font-size: 0.78rem;
    color: var(--text-muted);
    white-space: pre-wrap;
    line-height: 1.6;
}
