/*
    Admin console styles - ONLY what the Sales stylesheets have no equivalent for.

    The shell, buttons, grids, forms, chips, dialogs and search boxes all come from
    Styles/Sales/Sales.css and Styles/Sales/Components.css, which the build copies in from
    Clients/Sales/Styles (see TradieOnTheMove.Api.csproj's CopySalesStylesToAdmin target). Colours
    here use the tokens those sheets define (--surface, --border, --danger, ...) so the two apps
    stay in step.
*/

:root {
    /* Status colours. Sales carries these as literals on its lead-status chips; named here because
       this app uses them for more than one thing each. They convey meaning, not chrome. */
    --success: #2E7D32;
    --warning: #B26A00;
    --info: #1565C0;

    /* Filter matches in the log viewer: every match, and the one Prev/Next is on. Translucent so
       a match keeps its line's level colour; the current one solid, to find at a glance. */
    --log-match-bg: rgba(255, 200, 0, 0.35);
    --log-match-current-bg: #FF9800;
    --log-match-current-text: #000000;
}

/* ── Login ─────────────────────────────────────────────────────────────────── */

/* The Sales sheet styles the login button as input[type="button"], but the control is a real
   type="submit" (so the browser's password manager sees a genuine submit). */
input.LoginFormElementControl[type="submit"] {
    background: var(--brand);
    color: var(--text-on-brand);
    border: none;
    cursor: pointer;
    font-weight: 600;
}

input.LoginFormElementControl[type="submit"]:hover {
    background: var(--brand-hover);
}

input.LoginFormElementControl[type="submit"]:disabled {
    opacity: 0.6;
    cursor: default;
}

/* ── Buttons ───────────────────────────────────────────────────────────────── */

.SalesButton:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.SalesButton:disabled:hover {
    background: var(--surface);
}

.SalesButton.Primary:disabled:hover {
    background: var(--brand);
}

/* Anchors styled as buttons (Edit, Cancel, New Tenant) sit beside real <button>s, so they need
   the same box - Components.css only does this inside .SalesFormButtons. */
a.SalesButton {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    line-height: normal;
}

/* An action that takes something away: deactivating a tenant, dropping a connection, blocking an
   address, deleting a cached transaction. Outlined rather than filled, so a row of them does not
   turn the grid red. */
.SalesButton.Danger {
    color: var(--danger);
    border-color: var(--danger);
}

.SalesButton.Danger:hover {
    background: var(--danger);
    color: #fff;
}

.SalesButton.Danger:disabled:hover {
    background: var(--surface);
    color: var(--danger);
}

.SalesButton.AdminIconButton {
    padding: 2px 8px;
    min-width: 28px;
}

/* ── Toolbars ──────────────────────────────────────────────────────────────── */

.AdminToolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 12px;
}

.AdminToolbar h3 {
    margin: 0;
}

/* Pushes whatever follows it to the right-hand end of a toolbar or a detail header. */
.AdminToolbarSpacer {
    flex: 1 1 auto;
}

/* A toolbar that is a thing in its own right (the connector update bar, the block-an-address
   form) rather than a row of filters above a grid. */
.AdminToolbarCard {
    padding: 10px 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.AdminSelect,
.AdminInput {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font-family: inherit;
    font-size: 14px;
    max-width: 100%;
}

.AdminSelect {
    max-width: 320px;
}

.AdminInput {
    width: 180px;
}

.AdminInput.AdminInputWide {
    width: 320px;
}

.AdminSelect:focus,
.AdminInput:focus {
    outline: none;
    border-color: var(--brand);
}

/* .SalesDetailSubheading pulls itself up under a heading with a negative margin; under a toolbar
   there is no heading to tuck beneath. */
.AdminCountLabel {
    margin-top: 0;
    margin-bottom: 8px;
}

.AdminSectionHeading {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin: 28px 0 8px;
}

.AdminSectionHeading h3 {
    margin: 0;
}

.AdminSectionHeading a {
    font-size: 13px;
}

.AdminCachedTransactions,
.AdminTenantStorage,
.AdminTenantSize,
.AdminClearData {
    margin-top: 28px;
}

/* The tenant screen's Clear Data panel (Data-Housekeeping-Plan.md section 3): a tick box per kind
   of data, its label over a muted line of how much there is. */
.AdminClearDataList {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 8px 0 12px;
    max-width: 720px;
}

.AdminClearDataRow {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 8px 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    cursor: pointer;
}

.AdminClearDataRow input {
    margin-top: 3px;
}

.AdminClearDataText {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.AdminClearDataLabel {
    font-weight: 600;
    color: var(--text);
}

.AdminClearDataDetail {
    font-size: 13px;
    color: var(--text-muted);
}

/* Tenant size (Tenant-Size-Design.md): the figures in a row, wrapping on a narrow screen, each a
   label / value / note stack lined up from the top so every label and value sits on one line
   whatever the notes say. The trend line is in the brand colour through currentColor so it
   follows the theme. */
.AdminSizeSummary {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 12px 32px;
    margin: 8px 0 16px;
}

.AdminSizeFigure {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 88px;
}

.AdminSizeValue {
    font-size: 20px;
    font-weight: 600;
    line-height: 1.2;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

/* Kept one line tall even when empty, so a figure without a note is the same height as one with. */
.AdminSizeNote {
    min-height: 1.4em;
}

/* "Measured"/"Estimated" - sized to its words so it is never pushed off the right edge. */
.SalesLeadsTable th.AdminSizeHow,
.SalesLeadsTable td.AdminSizeHow {
    width: 1%;
    white-space: nowrap;
    padding-right: 16px;
}

/* Deleted tenants' leftovers, under the Tenants list's size line. */
.AdminSizeUnassigned {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    margin-top: 4px;
}

/* A rule between the sizes and the growth figures after them. */
.AdminSizeFigure.GrowthStart {
    border-left: 1px solid var(--border);
    padding-left: 32px;
}

.AdminSizeSparkWrap {
    color: var(--brand);
    max-width: 100%;
    align-self: center;
}

.AdminSizeSparkWrap svg {
    display: block;
    max-width: 100%;
    height: auto;
}

/* ── Storage screen (View.StorageOverview.js) ──────────────────────────────── */

/* The graph's series fills - identity only; text never wears them. Validated as a pair (and the
   leftovers band is a neutral grey, so it reads as "not a tenant's") against the white card. */
:root {
    --chart-db: #2a78d6;
    --chart-s3: #eb6834;
    --chart-leftover: #b4b8bf;
}

.AdminStorageChartCard,
.AdminDiskCard {
    padding: 12px 16px 8px;
    margin-bottom: 20px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.AdminStorageChartCard h4,
.AdminDiskCard h4 {
    margin: 0;
}

.AdminSegmented {
    display: inline-flex;
}

.AdminSegmented .SalesButton,
.SalesButton.AdminStorageBack {
    padding: 4px 12px;
    font-size: 13px;
    border-radius: 0;
}

.AdminSegmented .SalesButton:first-child {
    border-radius: var(--radius) 0 0 var(--radius);
}

.AdminSegmented .SalesButton:last-child {
    border-radius: 0 var(--radius) var(--radius) 0;
    border-left: none;
}

.AdminSegmented .SalesButton.Active {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--text-on-brand);
}

.AdminChartLegend {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 16px;
    margin-bottom: 4px;
    font-size: 12px;
    color: var(--text-muted);
}

.AdminChartLegendItem {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.AdminChartSwatch {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 2px;
    flex: none;
}

.AdminChartSwatch.Db,
.AdminChartBand.Db {
    background: var(--chart-db);
    fill: var(--chart-db);
}

.AdminChartSwatch.S3,
.AdminChartBand.S3 {
    background: var(--chart-s3);
    fill: var(--chart-s3);
}

.AdminChartSwatch.Leftover,
.AdminChartBand.Leftover {
    background: var(--chart-leftover);
    fill: var(--chart-leftover);
}

/* ── Tenant Activity graph (View.TenantActivity.js) ────────────────────────── */

/* The Storage graph's validated pair again: blue for people, the neutral grey for web hooks -
   grey because they are the ERP talking to us, not anybody using the system. */
.AdminChartSwatch.People,
.AdminChartBand.People {
    background: var(--chart-db);
    fill: var(--chart-db);
}

.AdminChartSwatch.WebHooks,
.AdminChartBand.WebHooks {
    background: var(--chart-leftover);
    fill: var(--chart-leftover);
}

.AdminTenantActivity {
    margin-top: 20px;
}

.AdminTenantActivity h3 {
    margin: 0;
}

.AdminActivitySummary {
    margin: 4px 0 8px;
}

/* The hovered day's column, behind its bar. */
.AdminActivityHover {
    fill: var(--surface-2);
    pointer-events: none;
}

.AdminActivityTypes {
    border-top: 1px solid var(--border);
    margin-top: 4px;
    padding-top: 4px;
}

.AdminActivityTypes .AdminChartTooltipRow {
    font-size: 11px;
}

.SalesLeadsTable td.AdminLastActiveCell {
    white-space: nowrap;
}

.AdminStorageChart {
    position: relative;
    width: 100%;
}

.AdminStorageChart svg {
    display: block;
    max-width: 100%;
    height: auto;
    outline: none;
}

.AdminStorageChart svg:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}

.AdminChartBandEdge {
    fill: none;
    stroke: var(--surface);
    stroke-width: 2;
    stroke-linejoin: round;
}

.AdminChartGrid {
    stroke: var(--border);
    stroke-width: 1;
    stroke-dasharray: 2 3;
}

.AdminChartBaseline {
    stroke: var(--text-muted);
    stroke-width: 1;
}

.AdminChartAxisText {
    fill: var(--text-muted);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.AdminChartCrosshair {
    stroke: var(--text);
    stroke-width: 1;
    pointer-events: none;
}

.AdminChartTooltip {
    position: absolute;
    min-width: 200px;
    padding: 8px 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    font-size: 12px;
    color: var(--text);
    pointer-events: none;
    z-index: 2;
}

.AdminChartTooltipTitle {
    font-weight: 600;
    margin-bottom: 4px;
}

.AdminChartTooltipRow {
    display: grid;
    grid-template-columns: 10px 1fr auto;
    align-items: center;
    gap: 6px;
    line-height: 1.6;
}

.AdminChartTooltipRow.Total {
    border-top: 1px solid var(--border);
    margin-top: 2px;
    padding-top: 2px;
    font-weight: 600;
}

.AdminChartTooltipValue {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.SalesLeadsTable tr.AdminStorageTenantRow {
    cursor: pointer;
}

.SalesLeadsTable tr.AdminStorageTenantRow.Selected td {
    background: var(--surface-2);
    box-shadow: inset 0 -1px 0 var(--brand);
}

.SalesLeadsTable tr.AdminStorageTenantRow.Selected td:first-child {
    box-shadow: inset 3px -1px 0 var(--brand);
}

.SalesLeadsTable td.AdminStorageTotalCell {
    font-weight: 600;
}

.AdminStorageInactive {
    font-size: 11px;
}

.SalesLeadsTable td.AdminStorageShare {
    white-space: nowrap;
    min-width: 96px;
}

.AdminStorageShareBar {
    display: block;
    height: 4px;
    margin-top: 3px;
    border-radius: 2px;
    background: var(--surface-2);
    overflow: hidden;
}

.AdminStorageShareBar > span {
    display: block;
    height: 100%;
    background: var(--brand);
    border-radius: 2px;
}

.SalesLeadsTable td.AdminStorageTrendCell {
    color: var(--brand);
    width: 1%;
    padding-top: 4px;
    padding-bottom: 4px;
}

.AdminStorageTrend {
    display: block;
}

.AdminStorageTrend polyline {
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}

/* Whole system: tables and folders that belong to no tenant. Neutral, not a status colour - the
   chip's words carry it, and the dashed edge tells the two kinds apart at a glance. */
.AdminStorageSystemTable .AdminChip {
    white-space: nowrap;
}

.SalesStatusChip.AdminChip.AdminStorageShared {
    border-style: dashed;
    font-weight: 600;
}

.SalesButton.AdminStorageShowAll {
    margin: 8px 0 16px;
}

/* Whole system: how full the database's disk is. The free part is the bare track. */
.AdminDiskMeter {
    display: flex;
    height: 12px;
    margin: 12px 0 4px;
    border-radius: 6px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    overflow: hidden;
}

.AdminDiskMeterUsed {
    background: var(--chart-db);
    border-radius: 6px 0 0 6px;
}

/* 90% full or more. The Remaining figure beside it says the same in words. */
.AdminDiskMeterUsed.Nearly {
    background: var(--warning);
}

.AdminDiskCard .AdminSizeSummary {
    margin-bottom: 4px;
}

.AdminDiskBreakdown {
    margin-top: 4px;
}

.AdminStorageSystemTable td .AdminStorageDescription {
    font-size: 12px;
}

/* Tenant list headings that order the list when clicked. */
.SalesLeadsTable th.AdminSortable {
    cursor: pointer;
    user-select: none;
}

.SalesLeadsTable th.AdminSortable:hover,
.SalesLeadsTable th.AdminSortable:focus-visible,
.SalesLeadsTable th.AdminSortable.Sorted {
    text-decoration: underline;
}

.AdminStorageDescription {
    font-size: 12px;
    color: var(--text-muted);
}

.SalesLeadsTable tr.AdminStorageTotal td {
    font-weight: 600;
}

.SalesLeadsTable td.AdminStorageExpand,
.AdminStorageTable th:first-child {
    width: 44px;
}

/* The rows an open area grows: its jobs, and under an open job its files. Tinted and indented so
   they read as belonging to the row above rather than as more areas. */
.SalesLeadsTable tr.AdminStorageGroup td,
.SalesLeadsTable tr.AdminStorageDetail td {
    background: var(--surface-2);
}

.SalesLeadsTable tr.AdminStorageGroup td.AdminStorageExpand {
    padding-left: 28px;
    width: 72px;
}

.SalesLeadsTable tr.AdminStorageOther td {
    color: var(--text-muted);
}

.SalesLeadsTable td.AdminStorageFilesCell {
    padding-left: 72px;
    white-space: normal;
}

.AdminStorageThumbnails {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
    gap: 8px;
}

.AdminStorageThumbnail {
    display: block;
    text-decoration: none;
    color: var(--text-muted);
    font-size: 12px;
    text-align: center;
}

.AdminStorageThumbnail img {
    display: block;
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 2px;
}

.AdminStorageThumbnail:hover img {
    border-color: var(--text-muted);
}

.AdminStorageFiles {
    width: 100%;
    border-collapse: collapse;
}

/* Under a grid of thumbnails, when a job has both. */
.AdminStorageThumbnails + .AdminStorageFiles,
.AdminStorageMore {
    margin-top: 10px;
}

.SalesLeadsTable .AdminStorageFiles td {
    padding: 4px 8px 4px 0;
    border: 0;
    background: transparent;
}

/* ── Image viewer ──────────────────────────────────────────────────────────── */

/* View.ImageViewer.js - a job's photos, full screen, one at a time. Dark whatever the page is, as
   photo viewers are: the image is the only thing meant to be looked at. Above the dialogs
   (#GreyOut 200, .ModalDialog 201), with a backdrop of its own. */
#AdminImageViewer {
    position: fixed;
    inset: 0;
    z-index: 250;
    display: flex;
    flex-direction: column;
    background: rgba(0, 0, 0, 0.94);
    color: #FFFFFF;
}

body.AdminImageViewerOpen {
    overflow: hidden;
}

.AdminImageViewerBar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px 8px 16px;
    min-height: 52px;
}

#AdminImageViewerHeading {
    flex: 1;
    min-width: 0;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

#AdminImageViewerPosition {
    font-size: 13px;
    opacity: 0.8;
    white-space: nowrap;
}

.AdminImageViewerButton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: none;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.12);
    color: #FFFFFF;
    font-size: 18px;
    text-decoration: none;
    cursor: pointer;
}

.AdminImageViewerButton:hover:not(:disabled),
.AdminImageViewerButton:focus-visible {
    background: rgba(255, 255, 255, 0.24);
    outline: none;
}

.AdminImageViewerButton:disabled {
    opacity: 0.3;
    cursor: default;
}

.AdminImageViewerStage {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 12px;
}

.AdminImageViewerStep {
    width: 48px;
    height: 48px;
    font-size: 22px;
}

.AdminImageViewerFrame {
    flex: 1;
    min-width: 0;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
}

#AdminImageViewerImage {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

#AdminImageViewerError {
    position: absolute;
    max-width: 420px;
    padding: 16px;
    text-align: center;
    line-height: 1.4;
}

#AdminImageViewerCaption {
    padding: 10px 16px 16px;
    text-align: center;
    font-size: 13px;
    opacity: 0.85;
    overflow-wrap: anywhere;
}

/* A phone's width: the step buttons sit over the image's edges rather than taking room beside it. */
@media (max-width: 600px) {
    .AdminImageViewerStage {
        position: relative;
        padding: 0;
    }

    .AdminImageViewerStep {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        z-index: 1;
    }

    #AdminImageViewerPrevious {
        left: 8px;
    }

    #AdminImageViewerNext {
        right: 8px;
    }
}

/* ── Chips ─────────────────────────────────────────────────────────────────── */

.AdminChip.Success {
    background: var(--success);
    border-color: var(--success);
    color: #fff;
}

.AdminChip.Danger {
    background: var(--danger);
    border-color: var(--danger);
    color: #fff;
}

.AdminChip.Warning {
    background: var(--warning);
    border-color: var(--warning);
    color: #fff;
}

.AdminChip.Info {
    background: var(--info);
    border-color: var(--info);
    color: #fff;
}

/* .AdminChip.Neutral is .SalesStatusChip's own default look - nothing to add. */

/* A chip sitting after text in the same cell ("Acme Ltd  [3 Cached]"). */
.AdminChipInline {
    margin-left: 8px;
}

/* The Connector State chip opens the connections screen. Still reads as status at a glance; the
   hover is what says it can be clicked. */
a.AdminChipLink {
    cursor: pointer;
    text-decoration: none;
}

a.AdminChipLink:hover,
a.AdminChipLink:focus {
    box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.35);
    outline: none;
}

/* ── Grid cells ────────────────────────────────────────────────────────────── */

.AdminRowLink {
    font-weight: 600;
}

.AdminRowLink:hover {
    text-decoration: underline;
}

/* A column of counts: right-aligned so the digits line up, heading included - a right-aligned
   column under a left-aligned heading reads as a misalignment. */
.SalesLeadsTable th.AdminNumberCell,
.SalesLeadsTable td.AdminNumberCell {
    text-align: right;
}

.AdminMono {
    font-family: Consolas, "SFMono-Regular", Menlo, monospace;
    font-size: 12px;
}

/* .SalesLeadsTable cells are nowrap, which is right for names and dates and wrong for free text
   of no fixed length - a reason, a User-Agent, an error message. */
.SalesLeadsTable td.AdminWrapCell {
    white-space: normal;
    word-break: break-word;
    min-width: 180px;
    max-width: 420px;
}

/* Billing: an opened tenant line's users, one row each, indented under it so their transactions
   sit in the tenant's own Transactions column. */
.SalesLeadsTable tr.BillingUsersRow td {
    color: var(--text-muted);
}

.SalesLeadsTable tr.BillingUsersRow td:first-child {
    padding-left: 28px;
}

.SalesLeadsTable td input[type="checkbox"] {
    width: 16px;
    height: 16px;
    cursor: pointer;
}

.SalesLeadsTable td input[type="checkbox"]:disabled {
    cursor: not-allowed;
}

.AdminTextDanger {
    color: var(--danger);
}

.AdminTextSuccess {
    color: var(--success);
}

.AdminBlockMessage {
    margin-bottom: 12px;
}

.AdminPayload {
    margin: 0;
    padding: 10px;
    max-height: 260px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-family: Consolas, "SFMono-Regular", Menlo, monospace;
    font-size: 12px;
    color: var(--text);
}

/* A tick box in a form row: the box beside its own label, with a hint underneath. */
.SalesFormRow.AdminCheckRow label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--text);
    cursor: pointer;
}

.SalesFormRow.AdminCheckRow input[type="checkbox"] {
    width: 16px;
    height: 16px;
    margin: 0;
}

.AdminCheckHint {
    font-size: 12px;
    color: var(--text-muted);
}

/* ── Tenant form ───────────────────────────────────────────────────────────── */

/* Components.css styles text/email/number inputs in a form row; the Accredo password is the one
   password field in the app. */
.SalesFormRow input[type="password"] {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size: 14px;
    font-family: inherit;
    color: var(--text);
    background: var(--surface);
}

/* A write-only secret (Infusion uuids, Accredo password) with its Clear button beside it. The box
   takes the room; min-width:0 lets it shrink in a narrow grid column instead of pushing the button
   out. */
.AdminSecretField {
    display: flex;
    gap: 8px;
    align-items: stretch;
}

.AdminSecretField input {
    flex: 1;
    min-width: 0;
}

.AdminSecretField .AdminSecretClear {
    flex: none;
    padding: 6px 12px;
    font-size: 13px;
}

/* Marked for clearing on save: the locked box says so in the danger colour. */
.AdminSecretField.Clearing input {
    border-color: var(--danger);
    background: var(--surface-2);
}

.AdminSecretField.Clearing input::placeholder {
    color: var(--danger);
}

/* ── Tenant tabs ───────────────────────────────────────────────────────────── */

/* Details | Settings, under a tenant's heading. Underlined tabs rather than the pill buttons used
   for filters: these switch screen, they do not narrow a list. */
.AdminTabs {
    display: flex;
    gap: 4px;
    margin: -8px 0 20px;
    border-bottom: 1px solid var(--border);
}

.AdminTab {
    padding: 8px 14px;
    margin-bottom: -1px;
    color: var(--text-muted);
    border-bottom: 2px solid transparent;
    font-weight: 600;
}

.AdminTab:hover {
    color: var(--text);
}

.AdminTab.Active {
    color: var(--brand);
    border-bottom-color: var(--brand);
}

/* ── Tenant settings ───────────────────────────────────────────────────────── */

/* Sticks under the title bar while there is something unsaved, so Save all is reachable from
   anywhere in a list of well over a hundred rows. */
.AdminPendingBar {
    position: sticky;
    top: calc(var(--header-height) + 8px);
    z-index: 50;
    border-color: var(--warning);
    box-shadow: var(--shadow);
}

body.NotificationBarVisible .AdminPendingBar {
    top: calc(var(--header-height) + var(--notification-height) + 8px);
}

.SalesLeadsTable tr.AdminSettingCategory td {
    background: var(--surface-2);
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
    padding-top: 14px;
}

/* Name and description wrap; the grid's cells are nowrap by default, and a description is a
   sentence or three. */
.SalesLeadsTable td.AdminSettingName {
    white-space: normal;
    width: 55%;
    min-width: 260px;
}

.AdminSettingTitle {
    color: var(--text);
    font-weight: 600;
}

.AdminSettingDescription {
    margin-top: 2px;
    color: var(--text-muted);
    font-size: 12px;
    line-height: 1.4;
}

.SalesLeadsTable td.AdminSettingValue {
    white-space: normal;
    vertical-align: top;
}

.AdminSettingInput {
    width: 280px;
}

.AdminSettingInput[type="number"],
.AdminSettingInput[type="time"] {
    width: 140px;
}

/* A staged, unsaved edit. The left edge is what catches the eye when scrolling the list; the tint
   is what says which row the Save beside it belongs to. */
.SalesLeadsTable tr.AdminSettingDirty td {
    background: #FFF8E6;
}

.SalesLeadsTable tr.AdminSettingDirty td:first-child {
    box-shadow: inset 3px 0 0 var(--warning);
}

/* Reserved even when empty, so the Value column does not jump sideways as buttons come and go. */
.SalesLeadsTable td.AdminSettingActions {
    width: 150px;
    vertical-align: top;
}

.AdminSettingNote {
    margin-top: 4px;
    max-width: 360px;
    color: var(--warning);
    font-size: 12px;
    line-height: 1.4;
}

.AdminChipList {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 6px;
    max-width: 360px;
}

.AdminRemovableChip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: normal;
}

.AdminRemovableChip button {
    border: 0;
    padding: 0 2px;
    background: transparent;
    color: var(--text-muted);
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
}

.AdminRemovableChip button:hover {
    color: var(--danger);
}

.AdminRemovableChip button:disabled {
    cursor: not-allowed;
    opacity: 0.5;
}

/* ── Remote Help ───────────────────────────────────────────────────────────────
   Class names are the ones Clients/CPDashboard used, so the two consoles' markup stays
   recognisably the same thing while both exist. */

/* Which company the screen is helping (View.RemoteHelp's renderTenantPicker). CPDashboard never
   had one - it took the company from the session - hence a name of its own. */
.remote-help-tenant {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}

.remote-help-tenant label {
    font-weight: 600;
}

#RemoteHelpTenantSelect {
    min-width: 260px;
    max-width: 100%;
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    font-family: inherit;
    font-size: 14px;
    color: var(--text);
}

#RemoteHelpTenantSelect:disabled {
    opacity: 0.7;
}

.SalesView p.remote-help-choose {
    color: var(--text-muted);
}

/* "Remote Help" on a company's own header (View.TenantEdit's renderHeader), pushed to the far end
   so it reads as an action on the company rather than one of its tabs. */
.SalesDetailHeader .AdminHeaderAction {
    margin-left: auto;
}

.remote-help-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 12px;
    margin-bottom: 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

#RemoteHelpCodeInput {
    font-size: 20px;
    letter-spacing: 4px;
    width: 140px;
    padding: 6px;
    text-align: center;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-family: inherit;
    color: var(--text);
}

#RemoteHelpCodeInput:focus {
    outline: none;
    border-color: var(--brand);
}

.remote-help-status {
    font-weight: 600;
}

/* Status colours convey meaning - not tokens, and not to be neutralised. */
.remote-help-status-waiting { color: #946200; }
.remote-help-status-live    { color: #1B7F37; }
.remote-help-status-ended   { color: #B3261E; }

.remote-help-meta {
    padding: 4px 2px 10px;
    font-size: 12px;
    color: var(--text-muted);
}

/* The replay renders at the user's own device dimensions rather than reflowing to the desktop,
   so the agent sees the phone layout the user is describing. */
.remote-help-stage {
    position: relative;
    overflow: auto;
    padding: 16px;
    background: #DADDE2;
    border-radius: var(--radius);
    min-height: 620px;
}

#RemoteHelpPlayer {
    width: fit-content;
    margin: 0 auto;
    background: #fff;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}

.remote-help-history {
    margin-top: 28px;
}

/* Control mode. The outline is the agent's cue that clicks now land on somebody else's device -
   worth being unmistakable about. */
.remote-help-control-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    padding: 10px 12px;
    margin-bottom: 8px;
    background: #FFF4E5;
    border: 1px solid #E0B87A;
    border-radius: var(--radius);
    font-size: 14px;
}

.remote-help-field-entry {
    display: flex;
    align-items: center;
    gap: 8px;
}

.remote-help-field-entry input,
.remote-help-field-entry select {
    padding: 5px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    min-width: 200px;
    font-family: inherit;
    font-size: 14px;
}

.remote-help-stage-controllable,
.remote-help-stage.remote-help-stage-controllable {
    /* pointer, not crosshair: crosshair reads as "draw a selection". */
    cursor: pointer;
    outline: 2px solid #E0B87A;
    outline-offset: -2px;
}

/* The replay iframe must not swallow the clicks the stage is there to read and forward. */
.remote-help-stage-controllable iframe {
    pointer-events: none;
}

/* The queue of unanswered requests. */
.remote-help-queue {
    padding: 12px 14px;
    margin-bottom: 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.remote-help-queue-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
}

.remote-help-queue-state {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 2px 8px;
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--text-muted);
}

.remote-help-queue-state.remote-help-queue-live {
    background: #E3F3E6;
    color: #1B7F37;
}

.SalesView p.remote-help-queue-empty {
    margin: 0;
    font-size: 13px;
}

.remote-help-queue-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 8px 10px;
    margin-top: 6px;
    background: #FFF4E5;
    border: 1px solid #E0B87A;
    border-radius: var(--radius);
    font-size: 14px;
}

.remote-help-queue-who {
    font-weight: 700;
    flex: 1 1 auto;
}

.remote-help-queue-app,
.remote-help-queue-age {
    color: var(--text-muted);
    font-size: 12.5px;
    flex: 0 0 auto;
}

/* Full screen. Two layouts in one: inside the real Fullscreen API the element already fills the
   screen, and position:fixed covers the case where the API was refused or is unavailable - the
   flag alone still gives the agent a fills-the-window view, which is most of the value. */
.remote-help-stage.remote-help-stage-fullscreen {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 9999;
    margin: 0;
    border-radius: 0;
    padding: 0;
    background: #1c1c1c;
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* The chrome that rides along inside full screen: the status/exit bar and, when control is
   granted, the control bar. Stacked, full width, and outside the replay itself so neither can
   cover the other. */
.remote-help-fullscreen-chrome {
    width: 100%;
    flex: 0 0 auto;
    cursor: default;
}

.remote-help-fullscreen-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 8px 14px;
    background: #2b2b2b;
    color: #fff;
}

.remote-help-fullscreen-bar .remote-help-status {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The status colours were chosen against a light card; on the dark bar they need lifting. */
.remote-help-fullscreen-bar .remote-help-status-live    { color: #6FD98A; }
.remote-help-fullscreen-bar .remote-help-status-waiting { color: #F0C674; }
.remote-help-fullscreen-bar .remote-help-status-ended   { color: #FF8A80; }

/* The replay renders at the device's own pixel size. Scaling it up to fill a desktop screen
   would blur it, so it is centred in the space instead. */
.remote-help-stage-fullscreen #RemoteHelpPlayer {
    margin: auto;
}

/* Inside full screen the control bar sits on a dark ground, where its amber card would glare. */
.remote-help-stage-fullscreen .remote-help-control-bar {
    margin: 0;
    border-radius: 0;
    border-left: none;
    border-right: none;
    background: #3a331f;
    border-color: #6b5a2e;
    color: #f5e6c8;
}

.remote-help-stage-fullscreen .remote-help-control-bar code {
    color: #ffd98a;
}

.remote-help-stage-fullscreen .remote-help-field-entry input,
.remote-help-stage-fullscreen .remote-help-field-entry select {
    background: #fff;
    color: #222;
}

/* ── Connector logs ────────────────────────────────────────────────────────── */

/* #tenants/{id}/logs - Elite-ConnectorLogs-Design.md section 5. */
.AdminMuted {
    color: var(--text-muted);
    font-size: 13px;
}

.AdminCheckLabel {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text);
    white-space: nowrap;
}

.AdminLogPanel {
    margin-top: 20px;
}

/* The "Current" chip beside a file name in the list (View.LogViewer, on either log screen). */
.AdminLogBrowser td.AdminMono .AdminChip {
    margin-left: 8px;
}

/* A terminal-ish pane: fixed height so a tail scrolls inside it rather than growing the page.
   Wraps, because a horizontal scrollbar on every long stack-trace line is worse than wrapping. */
.AdminLogViewer {
    height: 60vh;
    min-height: 240px;
    overflow: auto;
    padding: 8px 10px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-family: Consolas, "Cascadia Mono", Menlo, monospace;
    font-size: 12px;
    line-height: 1.45;
    color: var(--text);
}

.AdminLogLine {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.AdminLogLine.DEBUG,
.AdminLogLine.TRACE {
    color: var(--text-muted);
}

.AdminLogLine.WARN {
    color: var(--warning);
}

.AdminLogLine.ERROR,
.AdminLogLine.FATAL {
    color: var(--danger);
}

.AdminLogLine mark.AdminLogMatch {
    background: var(--log-match-bg);
    color: inherit;
    border-radius: 2px;
    padding: 0;
}

.AdminLogLine mark.AdminLogMatch.Current {
    background: var(--log-match-current-bg);
    color: var(--log-match-current-text);
    outline: 1px solid var(--log-match-current-bg);
}

/* "3 of 17" beside the Prev/Next buttons - a fixed width so the boxes after it don't shuffle as it counts. */
.AdminMatchCount {
    min-width: 84px;
    white-space: nowrap;
}

.AdminLogLine.Marker {
    color: var(--text-muted);
    font-style: italic;
    text-align: center;
    margin: 4px 0;
}

.AdminLogPanel .SalesSearchWrap {
    flex: 1 1 260px;
    max-width: 420px;
}

@media (max-width: 700px) {
    .AdminLogViewer {
        height: 55vh;
        font-size: 11px;
    }
}

/* ── Ghosting (Admin-Ghost-Design.md 7.1) ─────────────────────────────────────────────────────
   The ghost colour is purple, as in Mobile and the Scheduler, and used for nothing else, so it is
   never read as a status. */
.AdminGhostButton {
    border-color: #6A1B9A;
    color: #6A1B9A;
}

.AdminGhostHistory {
    margin-top: 28px;
}

/* While ghosting, the console's navigation is hidden (View.GhostMode), so the content takes the
   full width rather than leaving the nav's gap. */
body.AdminGhosting #SalesContent {
    margin-left: 0;
}

.AdminGhostPanel {
    max-width: 640px;
    margin: 40px auto;
    padding: 24px 28px;
    border-top: 6px solid #6A1B9A;
    border-radius: 6px;
    background: var(--surface);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
}

    .AdminGhostPanel h2 {
        margin-top: 0;
        color: #6A1B9A;
    }

.AdminGhostSummary {
    font-size: 16px;
}

.AdminGhostButtons {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 20px;
}

/* a.SalesButton is inline-flex, which drops the space in " Open Mobile", so the gap does the
   spacing. A fixed icon width keeps the narrow phone glyph from sitting off-centre. */
.AdminGhostButtons a.SalesButton {
    gap: 8px;
}

    .AdminGhostButtons a.SalesButton .fa {
        width: 1em;
        text-align: center;
    }
/* ── Job hooks ────────────────────────────────────────────────────────────── */

/* #tenants/{id}/hooks - Connector-HookCheck-Design.md section 5. One section per connector machine. */
.AdminHookMachine + .AdminHookMachine {
    border-top: 1px solid var(--border);
    margin-top: 24px;
}

.AdminHookMachine h4 {
    margin: 18px 0 6px;
}

.AdminHookSummary {
    font-size: 15px;
    margin: 8px 0 4px;
}
