/*
 * Admin console theme.
 *
 * Tokens are the mobile app's dark palette (lib/theme/app_palette.dart), so the console and the app
 * read as one product and a colour changed in one place has an obvious counterpart in the other.
 * Names mirror the Dart ones deliberately — `--ad-text-secondary` is `textSecondary` — so the two can
 * be diffed by eye.
 *
 * Written by hand rather than on a framework: the designs are a specific dark console, and adapting
 * Bootstrap to them costs more than the handful of layout primitives actually needed.
 */

:root {
    --ad-page: #0A1628;
    --ad-surface: #0D1520;
    --ad-surface-raised: #131C2C;
    --ad-text-primary: #FFFFFF;
    --ad-text-secondary: #8B9AB0;
    --ad-accent: #4A9EFF;
    --ad-divider: #1E2A3A;
    --ad-card-border: #3F5E7E;
    --ad-error: #F44336;
    --ad-verified: #3ECF8E;
    --ad-warning: #E07B00;
    --ad-record: #E8B33A;
    --ad-button-secondary: #2A3545;

    --ad-radius: 12px;
    --ad-radius-sm: 8px;

    --ad-sidebar-width: 232px;
    --ad-sidebar-width-collapsed: 68px;

    --ad-font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
}

body {
    background: var(--ad-page);
    color: var(--ad-text-primary);
    font-family: var(--ad-font);
    font-size: 14px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

a {
    color: var(--ad-accent);
    text-decoration: none;
}

h1, h2, h3 {
    margin: 0;
    font-weight: 600;
}

/* ---- Pre-boot splash ------------------------------------------------------------------------
   Shown while the WebAssembly runtime downloads. Styled rather than left blank so the first paint
   is the console's own dark surface instead of a white page that then flips. */

.ad-splash {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    gap: 6px;
}

.ad-splash__mark {
    font-size: 22px;
    font-weight: 600;
    letter-spacing: 0.2px;
}

.ad-splash__sub {
    font-size: 11px;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    color: var(--ad-text-secondary);
}

.ad-splash__bar {
    margin-top: 18px;
    width: 160px;
    height: 2px;
    background: var(--ad-divider);
    overflow: hidden;
    border-radius: 2px;
}

.ad-splash__bar span {
    display: block;
    width: 40%;
    height: 100%;
    background: var(--ad-accent);
    animation: ad-indeterminate 1.1s ease-in-out infinite;
}

@keyframes ad-indeterminate {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(350%); }
}

/* ---- App frame ----------------------------------------------------------------------------- */

.ad-shell {
    display: flex;
    height: 100vh;
    overflow: hidden;
}

.ad-main {
    flex: 1;
    min-width: 0;
    overflow-y: auto;
    padding: 24px 28px 28px;
    /* A column, so a page can claim the height its header leaves behind by asking for `flex: 1`
       instead of subtracting a guess from 100vh. Ordinary stacked pages are unaffected — block
       children in a stretch-aligned column lay out exactly as they did. */
    display: flex;
    flex-direction: column;
}

/* ---- Sidebar ------------------------------------------------------------------------------- */

.ad-sidebar {
    width: var(--ad-sidebar-width);
    flex-shrink: 0;
    background: var(--ad-surface);
    border-right: 1px solid var(--ad-divider);
    display: flex;
    flex-direction: column;
    transition: width 140ms ease;
}

.ad-sidebar--collapsed {
    width: var(--ad-sidebar-width-collapsed);
}

.ad-sidebar__brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 18px 16px;
    white-space: nowrap;
    overflow: hidden;
}

.ad-sidebar__logo {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 8px;
    background: linear-gradient(135deg, var(--ad-accent), #2B6FD1);
    display: grid;
    place-items: center;
    font-weight: 700;
    font-size: 14px;
}

.ad-sidebar__name {
    font-size: 15px;
    font-weight: 600;
    line-height: 1.15;
}

.ad-sidebar__tagline {
    font-size: 9px;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--ad-text-secondary);
}

.ad-nav {
    flex: 1;
    overflow-y: auto;
    padding: 6px 10px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.ad-nav__item {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 11px;
    border-radius: var(--ad-radius-sm);
    color: var(--ad-text-secondary);
    font-size: 13.5px;
    white-space: nowrap;
    overflow: hidden;
    cursor: pointer;
}

.ad-nav__item:hover {
    background: var(--ad-surface-raised);
    color: var(--ad-text-primary);
}

.ad-nav__item.active {
    background: var(--ad-accent);
    color: #FFFFFF;
    font-weight: 500;
}

.ad-nav__icon {
    width: 18px;
    flex-shrink: 0;
    text-align: center;
}

.ad-sidebar__footer {
    border-top: 1px solid var(--ad-divider);
    padding: 10px;
}

.ad-userchip {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px;
    border-radius: var(--ad-radius-sm);
    width: 100%;
    background: none;
    border: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    overflow: hidden;
}

.ad-userchip:hover {
    background: var(--ad-surface-raised);
}

.ad-userchip__avatar {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--ad-button-secondary);
    display: grid;
    place-items: center;
    font-size: 12px;
    font-weight: 600;
}

.ad-userchip__name {
    font-size: 13px;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ad-userchip__role {
    font-size: 11px;
    color: var(--ad-text-secondary);
}

.ad-collapse {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    margin-top: 4px;
    padding: 9px 11px;
    background: none;
    border: none;
    border-radius: var(--ad-radius-sm);
    color: var(--ad-text-secondary);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
}

.ad-collapse:hover {
    background: var(--ad-surface-raised);
    color: var(--ad-text-primary);
}

/* ---- Page header --------------------------------------------------------------------------- */

.ad-pagehead {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 20px;
}

.ad-pagehead__title {
    font-size: 24px;
    font-weight: 600;
}

.ad-pagehead__subtitle {
    color: var(--ad-text-secondary);
    font-size: 13.5px;
    margin-top: 2px;
}

.ad-pagehead__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

/* ---- Surfaces ------------------------------------------------------------------------------ */

.ad-card {
    background: var(--ad-surface);
    border: 1px solid var(--ad-divider);
    border-radius: var(--ad-radius);
    padding: 16px 18px;
}

.ad-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 56px 24px;
    text-align: center;
    color: var(--ad-text-secondary);
}

.ad-empty__title {
    font-size: 15px;
    font-weight: 600;
    color: var(--ad-text-primary);
}

/* ---- Controls ------------------------------------------------------------------------------ */

.ad-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 9px 15px;
    border: 1px solid transparent;
    border-radius: var(--ad-radius-sm);
    font: inherit;
    font-size: 13.5px;
    font-weight: 500;
    cursor: pointer;
}

.ad-btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.ad-btn--primary {
    background: var(--ad-accent);
    color: #FFFFFF;
}

.ad-btn--secondary {
    background: var(--ad-button-secondary);
    color: var(--ad-text-primary);
}

.ad-btn--ghost {
    background: transparent;
    border-color: var(--ad-divider);
    color: var(--ad-text-secondary);
}

.ad-btn--ghost:hover {
    color: var(--ad-text-primary);
}

.ad-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 14px;
}

.ad-field label {
    font-size: 12.5px;
    color: var(--ad-text-secondary);
}

.ad-input {
    padding: 10px 12px;
    background: var(--ad-page);
    border: 1px solid var(--ad-divider);
    border-radius: var(--ad-radius-sm);
    color: var(--ad-text-primary);
    font: inherit;
    font-size: 14px;
}

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

/* A textarea sizes itself from its `cols` attribute unless told otherwise, so one outside .ad-field's
   stretching column comes out at its 20-column default. Half the panel by default, still draggable,
   and floored so a narrow pane does not shrink it to a slot. */
.ad-input--half {
    width: 50%;
    min-width: 260px;
    max-width: 100%;
}

.ad-alert {
    padding: 10px 12px;
    border-radius: var(--ad-radius-sm);
    font-size: 13px;
    margin-bottom: 14px;
}

.ad-alert--error {
    background: rgba(244, 67, 54, 0.12);
    border: 1px solid rgba(244, 67, 54, 0.4);
    color: #FFB4AE;
}

.ad-alert--info {
    background: rgba(74, 158, 255, 0.1);
    border: 1px solid rgba(74, 158, 255, 0.35);
    color: #BBD9FF;
}

/* ---- Tabs ---------------------------------------------------------------------------------- */

.ad-tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--ad-divider);
    margin-bottom: 12px;
}

.ad-tabs__tab {
    padding: 10px 14px;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    color: var(--ad-text-secondary);
    font: inherit;
    font-size: 13.5px;
    cursor: pointer;
    white-space: nowrap;
}

.ad-tabs__tab:hover {
    color: var(--ad-text-primary);
}

.ad-tabs__tab.active {
    color: var(--ad-accent);
    border-bottom-color: var(--ad-accent);
    font-weight: 500;
}

/* The backlog lives here rather than in a tile row above the split — the tab is where you look to
   decide where to work, and the tiles cost the photo 100px. */
.ad-tabs__count {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--ad-button-secondary);
    color: var(--ad-text-secondary);
    font-size: 11.5px;
    font-weight: 600;
}

.ad-tabs__tab.active .ad-tabs__count {
    background: var(--ad-accent);
    color: #FFFFFF;
}

/* ---- Badges -------------------------------------------------------------------------------- */

.ad-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 500;
    white-space: nowrap;
    background: var(--ad-button-secondary);
    color: var(--ad-text-secondary);
}

/* Header-sized. The base badge is tuned for list rows, where dozens sit in a column and a small pill
   is right; on a detail header it is the one status on the screen and reads as an afterthought.
   Matches .ad-btn's padding and size so it balances the buttons below it. */
.ad-badge--lg {
    padding: 9px 15px;
    font-size: 13.5px;
    font-weight: 600;
}

.ad-badge--pending {
    background: rgba(224, 123, 0, 0.15);
    color: #F0A94C;
}

.ad-badge--verified {
    background: rgba(62, 207, 142, 0.14);
    color: var(--ad-verified);
}

.ad-badge--rejected {
    background: rgba(244, 67, 54, 0.14);
    color: #FF8A80;
}

/* Gold, and the only gold on the console. A record is the one thing in the review queue that is not
   routine, and a reviewer working a column of catches reads the colour before the words. */
.ad-badge--record {
    background: rgba(232, 179, 58, 0.18);
    color: var(--ad-record);
    font-weight: 600;
}

/* ---- Stat tiles ---------------------------------------------------------------------------
   auto-fit rather than a fixed four columns: the row reflows to two-up on a narrow window instead
   of squeezing four unreadable tiles or forcing the page to scroll sideways. */

.ad-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px;
    margin-bottom: 16px;
}

.ad-tile {
    background: var(--ad-surface);
    border: 1px solid var(--ad-divider);
    border-radius: var(--ad-radius);
    padding: 14px 16px;
}

.ad-tile__label {
    color: var(--ad-text-secondary);
    font-size: 12.5px;
}

.ad-tile__value {
    font-size: 26px;
    font-weight: 600;
    line-height: 1.25;
    margin-top: 2px;
}

/* Not every tile has one — see AdminAppUserEndpoints.GetAppUserStats for which counters can
   honestly be compared against a week ago and which cannot. Reserves no space when absent. */
.ad-tile__delta {
    display: flex;
    align-items: baseline;
    gap: 6px;
    margin-top: 6px;
    font-size: 12px;
    color: var(--ad-text-secondary);
}

.ad-tile__trend--up {
    color: var(--ad-verified);
    font-weight: 600;
}

.ad-tile__trend--down {
    color: #FF8A80;
    font-weight: 600;
}

/* Says how far back a counter can actually see, when that is less far than its label implies. */
.ad-tile__caveat {
    margin-top: 6px;
    font-size: 11.5px;
    color: var(--ad-warning);
}

/* ---- Pager --------------------------------------------------------------------------------- */

.ad-pager {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 10px 12px;
    border-top: 1px solid var(--ad-divider);
}

.ad-pager__count {
    flex: 1;
    min-width: 0;
    color: var(--ad-text-secondary);
    font-size: 12px;
}

.ad-pager__page {
    min-width: 30px;
    padding: 5px 9px;
    background: transparent;
    border: 1px solid var(--ad-divider);
    border-radius: var(--ad-radius-sm);
    color: var(--ad-text-secondary);
    font: inherit;
    font-size: 12.5px;
    cursor: pointer;
}

.ad-pager__page:hover:not(:disabled) {
    color: var(--ad-text-primary);
    border-color: var(--ad-accent);
}

.ad-pager__page:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.ad-pager__page.active {
    background: var(--ad-accent);
    border-color: var(--ad-accent);
    color: #FFFFFF;
    font-weight: 600;
}

/* The gap in 1 … 7 8 9 … 154. Not a button; nothing to click. */
.ad-pager__gap {
    color: var(--ad-text-secondary);
    font-size: 12.5px;
    padding: 0 2px;
}

/* ---- Avatars ------------------------------------------------------------------------------- */

.ad-avatar {
    width: 28px;
    height: 28px;
    flex-shrink: 0;
    border-radius: 50%;
    object-fit: cover;
    background: var(--ad-button-secondary);
    display: grid;
    place-items: center;
    font-size: 11px;
    font-weight: 600;
    color: var(--ad-text-secondary);
}

.ad-avatar--lg {
    width: 46px;
    height: 46px;
    font-size: 16px;
}

.ad-user {
    display: flex;
    align-items: center;
    gap: 9px;
    min-width: 0;
}

/* ---- Master/detail: panes scroll independently; page does not. --------------------------- */

.ad-split {
    display: grid;
    /* --ad-split-left from JS splitter; browser reflows without Blazor. */
    grid-template-columns: var(--ad-split-left, 40%) 14px minmax(0, 1fr);
    /* flex:1 (not 100vh calc) so only panes scroll under the page header. */
    flex: 1;
    /* Floor so a short window can scroll the page rather than crush panes. */
    min-height: 360px;
}

@media (max-width: 1100px) {
    /* Stack when side-by-side is too narrow for the photo. */
    .ad-split {
        grid-template-columns: minmax(0, 1fr);
        flex: none;
    }

    .ad-split__handle {
        display: none;
    }
}

.ad-split__handle {
    cursor: col-resize;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Wide hit target; thin visual line via ::before. */
    touch-action: none;
}

.ad-split__handle::before {
    content: "";
    width: 2px;
    height: 34px;
    border-radius: 2px;
    background: var(--ad-divider);
}

.ad-split__handle:hover::before {
    background: var(--ad-accent);
    height: 60px;
}

.ad-split__pane {
    background: var(--ad-surface);
    border: 1px solid var(--ad-divider);
    border-radius: var(--ad-radius);
    overflow-y: auto;
    min-height: 0;
}

/* Visible focus ring — list owns j/k. */
.ad-split__pane:focus-visible {
    outline: none;
    border-color: var(--ad-accent);
}

/* A pane with a fixed header over a scrolling body — so the filters stay put and the table's own
   sticky header still works inside what actually scrolls. */
.ad-split__pane--list {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 0;
}

.ad-pane__head {
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 10px 12px;
    border-bottom: 1px solid var(--ad-divider);
}

.ad-pane__head select.ad-input {
    padding: 6px 9px;
    font-size: 13px;
}

.ad-pane__body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

/* ---- List ---------------------------------------------------------------------------------- */

.ad-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.ad-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--ad-surface);
    border-bottom: 1px solid var(--ad-divider);
    padding: 10px 12px;
    text-align: left;
    font-weight: 500;
    font-size: 11.5px;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    color: var(--ad-text-secondary);
    white-space: nowrap;
}

.ad-table tbody td {
    padding: 9px 12px;
    border-bottom: 1px solid var(--ad-divider);
    vertical-align: middle;
}

.ad-table tbody tr {
    cursor: pointer;
}

.ad-table tbody tr:hover {
    background: var(--ad-surface-raised);
}

.ad-table tbody tr.selected {
    background: rgba(74, 158, 255, 0.14);
}

/* Selected marker survives list blur (detail focus). */
.ad-table tbody tr.selected td:first-child {
    box-shadow: inset 3px 0 0 var(--ad-accent);
}

/* Sortable header. Cursor and hover are the whole affordance — a permanent arrow on every column
   competes with the one marking the column actually in force. */
.ad-table thead th.ad-sortable {
    cursor: pointer;
    user-select: none;
}

.ad-table thead th.ad-sortable:hover {
    color: var(--ad-text-primary);
}

.ad-table__thumb {
    width: 40px;
    height: 32px;
    object-fit: cover;
    border-radius: 4px;
    background: var(--ad-button-secondary);
    display: block;
}

.ad-table__muted {
    color: var(--ad-text-secondary);
    font-size: 12px;
}

/* ---- Detail pane: fixed head/photo; facts scroll. ------------------------------------------ */

.ad-split__pane--flush {
    overflow: hidden;
    padding: 0;
}

.ad-detail {
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 16px 18px;
    /* Queried below, so the layout follows the pane's own width — which the reviewer sets by
       dragging the divider, and which the viewport therefore cannot describe. */
    container-type: inline-size;
}

/* Stacked by default; side by side once there is room. A portrait photo in a full-width row can
   only fill a narrow middle strip, and the rest of the row sits empty — putting the facts in that
   space costs nothing and gives the photo the whole height instead of half of it. */
.ad-detail__main {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.ad-detail__media {
    flex: 0 1 50%;
    min-height: 120px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

@container (min-width: 780px) {
    .ad-detail__main {
        flex-direction: row;
    }

    .ad-detail__media {
        /* Height is no longer the constraint, so the cap goes: the photo takes the column. */
        flex: 1 1 58%;
        min-width: 0;
    }

    .ad-detail__scroll {
        flex: 1 1 42%;
        min-width: 0;
    }
}

.ad-detail__head {
    flex: none;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
}

/* Cap photo at ~50% pane height (flex-basis, not viewport max-height). */
.ad-detail__photo {
    flex: 1 1 auto;
    min-height: 0;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--ad-page);
    border-radius: var(--ad-radius-sm);
}

.ad-detail__scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.ad-detail__angler {
    display: flex;
    align-items: center;
    gap: 11px;
}

.ad-detail__name {
    font-size: 15px;
    font-weight: 600;
}

.ad-photo {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: var(--ad-radius-sm);
    display: block;
    cursor: zoom-in;
}

.ad-detail__expand {
    position: absolute;
    right: 8px;
    bottom: 8px;
    padding: 5px 10px;
    border: 1px solid var(--ad-divider);
    border-radius: var(--ad-radius-sm);
    background: rgba(10, 22, 40, 0.82);
    color: var(--ad-text-primary);
    font: inherit;
    font-size: 12px;
    cursor: pointer;
}

.ad-detail__expand:hover {
    border-color: var(--ad-accent);
}

.ad-thumbs {
    flex: none;
    display: flex;
    gap: 8px;
    overflow-x: auto;
    padding-bottom: 4px;
}

.ad-thumbs__item {
    width: 74px;
    height: 56px;
    flex-shrink: 0;
    object-fit: cover;
    border-radius: var(--ad-radius-sm);
    border: 2px solid transparent;
    background: var(--ad-button-secondary);
    cursor: pointer;
}

.ad-thumbs__item.active {
    border-color: var(--ad-accent);
}

.ad-facts {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 7px 14px;
    align-items: baseline;
    font-size: 13px;
}

.ad-facts dt {
    color: var(--ad-text-secondary);
    white-space: nowrap;
}

.ad-facts dd {
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Side-by-side fact panels; auto-fit collapses when narrow. */
.ad-detail__panels {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 12px;
    align-items: start;
}

/* Equal-height columns. Opt-in rather than the default for .ad-detail__panels, whose panels are
   independent cards on the moderation screen and are meant to end where their content does. */
.ad-detail__panels--stretch {
    align-items: stretch;
}

/* One grid after another: the rule below strips the top margin from panels inside a grid, so two
   stacked grids would meet flush. Only this adjacency needs it — a grid followed by a standalone
   panel already gets the gap from that panel's own margin. */
.ad-detail__panels + .ad-detail__panels {
    margin-top: 12px;
}

.ad-panel {
    background: var(--ad-surface-raised);
    border-radius: var(--ad-radius-sm);
    padding: 12px 14px;
    margin-top: 12px;
}

.ad-detail__panels .ad-panel {
    margin-top: 0;
}

.ad-panel__title {
    font-size: 11.5px;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    color: var(--ad-text-secondary);
    margin-bottom: 9px;
}

.ad-hint {
    color: var(--ad-text-secondary);
    font-size: 12px;
}

/* Verification panel pinned under facts (not scrolled away). */

.ad-verify {
    flex: none;
    border-top: 1px solid var(--ad-divider);
    padding-top: 12px;
}

/* Species on the left: it is the ruling on most catches, and it decides the outcome. The
   measurement card stays beside it even when nothing was recorded, so the two jobs do not
   appear and disappear between catches. */
.ad-verify__pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-bottom: 10px;
}

.ad-verify__card {
    background: var(--ad-surface-raised);
    border: 1px solid var(--ad-divider);
    border-radius: var(--ad-radius-sm);
    padding: 12px 14px;
    min-width: 0;
}

/* A species that cannot be named makes the measurements moot. Dimmed, and its controls are disabled. */
.ad-verify__card--moot {
    opacity: 0.45;
}

.ad-verify__card-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    font-size: 17px;
    margin-bottom: 2px;
}

.ad-verify__card-icon {
    width: 22px;
    height: 22px;
    flex: none;
}

.ad-verify__row-icon {
    width: 16px;
    height: 16px;
    flex: none;
}

/* Picture sits in the empty corner beside the heading, so it does not add a row. */
.ad-verify__card--species {
    position: relative;
}

.ad-verify__card--species .ad-verify__card-title,
.ad-verify__card--species .ad-verify__question {
    padding-right: 168px;
}

.ad-verify__species-img {
    position: absolute;
    top: 12px;
    right: 14px;
    display: flex;
    width: 156px;
    height: 78px;
    object-fit: contain;
    margin: 0;
}

.ad-verify__match-img,
.ad-verify__match-slot {
    width: 64px;
    height: 32px;
    min-width: 64px;
    max-width: 64px;
    overflow: hidden;
}

.ad-verify__match-img {
    object-fit: contain;
}

/* Same fish as the heading. Muted grey so a missing picture still holds the name in place;
   white on the highlighted row, which is already blue. */
.ad-verify__fish-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ad-text-secondary);
}

.ad-verify__fish-placeholder svg {
    width: 36px;
    height: 22px;
    display: block;
}

.ad-verify__species-img.ad-verify__fish-placeholder svg {
    width: 88px;
    height: 54px;
}

.ad-typeahead__item:hover .ad-verify__fish-placeholder {
    color: #FFFFFF;
}

.ad-verify__question {
    margin: 0 0 10px;
    color: var(--ad-text-secondary);
    font-size: 12.5px;
}

.ad-verify__value {
    font-size: 13px;
    font-weight: 600;
}

@media (max-width: 1100px) {
    .ad-verify__pair {
        grid-template-columns: 1fr;
    }
}

.ad-verify__row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
    flex-wrap: wrap;
}

/* Name and search box are the whole row, centred on each other. The picture is the next line. */
.ad-verify__row.ad-verify__row--species {
    align-items: center;
    margin-bottom: 0;
}

.ad-verify__label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 118px;
    font-size: 13px;
}

.ad-verify__actions {
    display: flex;
    gap: 8px;
    margin-top: 12px;
    flex-wrap: wrap;
    align-items: center;
}

/* Pushed to the trailing edge: actions here belong to a different decision from the ruling buttons
   beside them, and one of them unpublishes. Separation is the affordance. */
.ad-verify__actions-trailing {
    margin-left: auto;
    display: flex;
    gap: 8px;
    align-items: center;
}

/* Centred dialog. Distinct from .ad-lightbox, which is a fullscreen stage for one image. */
.ad-modal {
    position: fixed;
    inset: 0;
    z-index: 950;
    background: rgba(4, 10, 20, 0.72);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.ad-modal__card {
    background: var(--ad-surface-raised);
    border-radius: var(--ad-radius-sm);
    padding: 18px 20px;
    width: min(520px, 100%);
    max-height: calc(100vh - 48px);
    overflow-y: auto;
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.5);
}

.ad-modal__title {
    font-weight: 600;
    margin-bottom: 10px;
}

.ad-modal__actions {
    display: flex;
    gap: 8px;
    margin-top: 14px;
    justify-content: flex-end;
    flex-wrap: wrap;
    align-items: center;
}

/* Tri-state: neither side selected = undecided. */
.ad-segmented {
    display: inline-flex;
    border: 1px solid var(--ad-divider);
    border-radius: var(--ad-radius-sm);
    overflow: hidden;
}

.ad-segmented button {
    padding: 6px 14px;
    background: transparent;
    border: none;
    color: var(--ad-text-secondary);
    font: inherit;
    font-size: 12.5px;
    cursor: pointer;
}

.ad-segmented button + button {
    border-left: 1px solid var(--ad-divider);
}

.ad-segmented button:hover {
    background: var(--ad-surface-raised);
    color: var(--ad-text-primary);
}

.ad-segmented button.on-verify {
    background: rgba(62, 207, 142, 0.18);
    color: var(--ad-verified);
    font-weight: 600;
}

.ad-segmented button.on-reject {
    background: rgba(244, 67, 54, 0.18);
    color: #FF8A80;
    font-weight: 600;
}

.ad-verify__gate {
    color: var(--ad-warning);
    font-size: 12px;
}

/* Record confirmation, above the ruling buttons so it is on the way to the one being pressed rather
   than off in a corner. A <label>, so the whole strip toggles the box — the badge and the two
   lengths are the reason to tick it, and they should be part of the target. */
.ad-verify__record {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
    padding: 8px 12px;
    border: 1px solid rgba(232, 179, 58, 0.45);
    border-radius: var(--ad-radius-sm);
    background: rgba(232, 179, 58, 0.10);
    cursor: pointer;
}

.ad-verify__record input {
    width: 16px;
    height: 16px;
    margin: 0;
    flex: none;
    accent-color: var(--ad-record);
    cursor: pointer;
}

.ad-verify__record-text {
    font-size: 13px;
}

.ad-btn--danger {
    background: var(--ad-error);
    color: #FFFFFF;
}

/* Destructive, but only opens a confirmation — the solid fill is reserved for the button that
   actually does it. Recedes at rest so a rarely-used action does not compete with the ruling
   buttons beside it, and arms on hover.

   The dimmed red matches a disabled .ad-btn--danger (same token at the 0.55 disabled opacity), which
   is the weight this reads best at. The label sits a little stronger than the border: at 0.55 the
   text is legible but thin against the dark surface, and this button says four words. */
.ad-btn--danger-outline {
    background: transparent;
    border-color: rgba(244, 67, 54, 0.55);
    color: rgba(244, 67, 54, 0.78);
}

.ad-btn--danger-outline:hover {
    background: var(--ad-error);
    color: #FFFFFF;
}

/* The restorative counterpart, dimmed to the same weights as the danger outline so the pair reads
   as one family: on a decided catch, outline means "undo something", and only the colour says which
   direction. Both recede until hovered. */
.ad-btn--verify-outline {
    background: transparent;
    border-color: rgba(62, 207, 142, 0.55);
    color: rgba(62, 207, 142, 0.78);
}

.ad-btn--verify-outline:hover {
    background: var(--ad-verified);
    color: #06231A;
}

/* Third of the family: restrictive but not destructive — it changes how the next catch is handled,
   it does not remove anything. Same dimmed weights as the pair above. */
.ad-btn--warning-outline {
    background: transparent;
    border-color: rgba(224, 123, 0, 0.55);
    color: rgba(224, 123, 0, 0.9);
}

.ad-btn--warning-outline:hover {
    background: var(--ad-warning);
    color: #1A1000;
}

/* Secondary action that is neither destructive nor an undo — it just reveals something. Text at full
   strength rather than the 0.78 the family above uses: that dimming reads as caution next to a
   danger button, and beside a solid primary it reads as disabled. */
.ad-btn--accent-outline {
    background: transparent;
    border-color: rgba(74, 158, 255, 0.55);
    color: var(--ad-accent);
}

.ad-btn--accent-outline:hover {
    background: var(--ad-accent);
    color: #FFFFFF;
}

.ad-btn--verify {
    background: var(--ad-verified);
    color: #06231A;
}

/* Status line for a state worth reading before acting on it. */
.ad-status {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 10px;
}

.ad-status__icon {
    flex: none;
    line-height: 1;
    font-size: 18px;
}

.ad-status__label {
    font-weight: 600;
}

.ad-status__detail {
    color: var(--ad-text-secondary);
    font-size: 12.5px;
    margin-top: 2px;
}

.ad-input--sm {
    padding: 6px 9px;
    font-size: 13px;
    width: 96px;
}

.ad-verify textarea.ad-input {
    width: 100%;
    resize: vertical;
    min-height: 46px;
}

/* Both notes on one line. They are usually left empty — the common ruling is Clear then Verify —
   so two stacked multi-line boxes spent ~190px of the photo on fields nobody filled in. Still
   drag-resizable when there is something long to say. */
.ad-verify__notes {
    display: flex;
    gap: 10px;
    margin-bottom: 8px;
    align-items: flex-start;
}

.ad-verify__notes > * {
    flex: 1 1 0;
    min-width: 0;
}

.ad-verify__notes textarea.ad-input {
    min-height: 38px;
}

/* Narrow windows: the pair would leave neither box wide enough to read a sentence in. */
@media (max-width: 1100px) {
    .ad-verify__notes {
        flex-direction: column;
    }
}

/* Overlay results so the action buttons do not shift. */
.ad-typeahead {
    position: relative;
    flex: 1;
    min-width: 160px;
}

.ad-typeahead__list {
    position: absolute;
    bottom: calc(100% + 4px);
    left: 0;
    right: 0;
    max-height: 210px;
    overflow-y: auto;
    z-index: 20;
    background: var(--ad-surface-raised);
    border: 1px solid var(--ad-card-border);
    border-radius: var(--ad-radius-sm);
}

.ad-typeahead__item {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr);
    align-items: center;
    column-gap: 8px;
    width: 100%;
    padding: 7px 11px;
    background: none;
    border: none;
    color: inherit;
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}

.ad-typeahead__item:hover {
    background: var(--ad-accent);
    color: #FFFFFF;
}

.ad-typeahead__sub {
    color: var(--ad-text-secondary);
    font-size: 11.5px;
    font-style: italic;
}

.ad-typeahead__item:hover .ad-typeahead__sub {
    color: rgba(255, 255, 255, 0.75);
}

/* ---- Photo lightbox ------------------------------------------------------------------------ */

.ad-lightbox {
    position: fixed;
    inset: 0;
    z-index: 900;
    background: rgba(4, 10, 20, 0.93);
    display: flex;
    flex-direction: column;
}

.ad-lightbox__bar {
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--ad-divider);
}

.ad-lightbox__title {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    color: var(--ad-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ad-lightbox__stage {
    flex: 1;
    min-height: 0;
    overflow: auto;
    display: grid;
    /* safe center: fit small images; overflow still scrollable when zoomed. */
    place-content: safe center;
    cursor: grab;
    touch-action: none;
}

.ad-lightbox__stage.is-grabbing {
    cursor: grabbing;
}

.ad-lightbox__stage img {
    display: block;
    /* No max when zoomed — overflow is what enables pan. */
    max-width: none;
}

.ad-lightbox__stage--fit img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    object-fit: contain;
}

/* ---- Centred single-card pages (sign-in, no-access) ---------------------------------------- */

.ad-centred {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 24px;
}

.ad-centred__card {
    width: 100%;
    max-width: 380px;
    background: var(--ad-surface);
    border: 1px solid var(--ad-divider);
    border-radius: var(--ad-radius);
    padding: 28px;
}

.ad-centred__title {
    font-size: 19px;
    font-weight: 600;
    margin-bottom: 4px;
}

.ad-centred__subtitle {
    color: var(--ad-text-secondary);
    font-size: 13.5px;
    margin-bottom: 20px;
}

/* ---- Blazor's error bar -------------------------------------------------------------------- */

#blazor-error-ui {
    background: #2A1A16;
    color: #FFD9D4;
    border-top: 1px solid var(--ad-error);
    bottom: 0;
    display: none;
    left: 0;
    padding: 10px 14px;
    position: fixed;
    width: 100%;
    z-index: 1000;
    font-size: 13px;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 14px;
    top: 9px;
}
