/* =========================================================================
   Admin Control Panel — shared widgets
   =========================================================================

   Every rule here was previously declared inside a per-panel Leptos `<style>`
   block, and several were declared in four panels at once with slightly
   different values. That is not only duplication: a `<style>` inside a
   component exists in the DOM *only while that component is mounted*, so a
   panel that used a class it did not itself declare rendered unstyled unless
   some other panel happened to be on screen. The Collections table was hitting
   exactly that — it uses `.precons-table`, which only decks, pods, precons and
   users declared.

   Loaded globally from apps/frontend-admin/index.html, alongside the main app's
   stylesheets, so the ACP inherits the same tokens and button contract as the
   rest of the product.
   ========================================================================= */

/* ── Panel shell ──────────────────────────────────────────────────────── */

.admin-panel {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.admin-panel-header {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    flex-wrap: wrap;
}

.admin-panel-title {
    margin: 0;
    font-size: 1.4rem;
    font-weight: 600;
}

/* ── Section tabs ─────────────────────────────────────────────────────────
   The in-panel tab strip: User Decks / Preconstructed, Accounts / Pod Pass. */

.section-tabs {
    display: flex;
    gap: 0.5rem;
}

.section-tab {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.45rem 0.9rem;
    border-radius: 6px;
    border: 1px solid var(--border-primary);
    background: none;
    color: var(--text-secondary);
    cursor: pointer;
    font-size: 0.9rem;
    transition: all 0.15s;
}

.section-tab:hover {
    color: var(--text-primary);
    border-color: var(--text-secondary);
}

.section-tab.active {
    background: var(--widget-bg);
    color: var(--text-accent);
    border-color: var(--accent-color);
}

/* ── Data tables ──────────────────────────────────────────────────────────
   `.precons-table` is the historical name and is kept so existing markup keeps
   working; `.admin-table` is the name worth using in new panels. They are the
   same rules, not two lookalikes that can drift. */

.admin-table,
.precons-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-primary);
    border-radius: 8px;
    overflow: hidden;
}

.admin-table th,
.admin-table td,
.precons-table th,
.precons-table td {
    padding: 0.75rem 1rem;
    text-align: left;
    border-bottom: 1px solid var(--border-primary);
    font-size: 0.9rem;
}

.admin-table th,
.precons-table th {
    color: var(--text-secondary);
    font-weight: 600;
    background: var(--bg-tertiary);
}

.admin-table tr:last-child td,
.precons-table tr:last-child td {
    border-bottom: none;
}

.admin-table tr:hover td,
.precons-table tr:hover td {
    background: rgba(255, 255, 255, 0.025);
}

.admin-table-wrap,
.precons-table-wrap {
    overflow-x: auto;
}

.col-name {
    font-weight: 500;
}

.col-count {
    text-align: center;
}

/* ── Stacked cells ────────────────────────────────────────────────────────
   Two related values in one column instead of two columns — a name above the
   address it belongs to, a created date above a last-seen date. Saves a lot of
   horizontal room in wide tables and reads better than the pair of columns it
   replaces, because the association is visual rather than positional.

   `.owner-info` / `.owner-name` / `.owner-email` are the original names, kept
   as aliases: they were declared separately in decks, pods and collections and
   had already drifted (only one of the three set a font size on the name). */

.stacked-cell,
.owner-info {
    display: flex;
    flex-direction: column;
    line-height: 1.35;
}

.stacked-cell-primary,
.owner-name {
    font-weight: 600;
    color: var(--text-primary);
    font-size: 0.9rem;
}

.stacked-cell-sub,
.owner-email {
    font-size: 0.78rem;
    color: var(--text-secondary);
}

/* Deck ownership that has been anonymised by the retention job. */
.owner-name.anonymous {
    color: #f97316;
    font-style: italic;
}

/* A stacked value that is absent rather than merely empty ("Never"). */
.stacked-cell-sub.muted,
.muted-cell {
    color: var(--text-muted);
}

/* ── Row actions ──────────────────────────────────────────────────────── */

.row-actions {
    display: flex;
    gap: 0.4rem;
}

/* Colour, border and hover states come from the shared button contract in
   styles/buttons.css. Only sizing lives here. */
.btn-icon {
    padding: 0.35rem 0.55rem;
    border-radius: 5px;
    cursor: pointer;
    font-size: 0.85rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ── Badges ───────────────────────────────────────────────────────────── */

.format-badge {
    display: inline-block;
    padding: 0.2rem 0.45rem;
    border-radius: 4px;
    font-size: 0.78rem;
    background: var(--bg-primary);
    color: var(--text-secondary);
    border: 1px solid var(--border-primary);
}

/* ── Pagination ───────────────────────────────────────────────────────────
   Every list in the ACP pages in groups of ADMIN_PAGE_SIZE, so the control
   looks and behaves the same everywhere. */

.pagination {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    justify-content: center;
    margin-top: 1rem;
}

.page-btn {
    padding: 0.3rem 0.7rem;
    border-radius: 5px;
    cursor: pointer;
}

.page-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.page-info {
    color: var(--text-secondary);
    font-size: 0.9rem;
}

/* ── Empty and loading states ─────────────────────────────────────────── */

.empty-state {
    text-align: center;
    color: var(--text-secondary);
    padding: 3rem 1rem;
    font-size: 0.95rem;
}

/* ── Cards ────────────────────────────────────────────────────────────── */

.admin-data-card {
    background: var(--bg-tertiary);
    border: 1px solid var(--border-primary);
    border-radius: 8px;
    padding: 1rem;
    min-width: 0;
}

.admin-data-card h3 {
    margin: 0 0 0.75rem 0;
    font-size: 1rem;
}

/* ── Card sync widget ─────────────────────────────────────────────────────
   Timestamps the sync job writes, shown beside the switch that governs them.
   Read-only on purpose: they used to appear in the generic settings grid as an
   editable text box and a mislabelled toggle, and editing the first one moved
   the incremental sync's watermark. */

.sync-timestamps {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    margin-top: 0.85rem;
    padding-top: 0.85rem;
    border-top: 1px solid var(--border-primary);
}

.sync-timestamp {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.sync-timestamp-label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.sync-timestamp-value {
    font-size: 0.85rem;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

/* ── Alerts message preview ───────────────────────────────────────────────
   A frame around real `.notification-item` markup from styles/notifications.css.
   Only the surround is styled here — reimplementing the item would defeat the
   purpose, which is that the preview *is* the component users see. */

.notification-preview-frame {
    border: 1px dashed var(--border-primary);
    border-radius: 8px;
    padding: 0.85rem;
    background: var(--bg-primary);
    max-height: 420px;
    overflow-y: auto;
}

/* The real item is click-to-mark-read; here it is inert. */
.notification-preview-frame .notification-item {
    cursor: default;
}
