// =============================================================================
//  Dashboard surfaces
//  Replaces the saturated gradient tiles with a calm, consistent card system.
//  Colour is used only to identify a metric, never as a background wash, so the
//  numbers stay the loudest thing on the page. Works in both Bootstrap themes
//  by reading --bs-* custom properties.
// =============================================================================

.stat-card {
    --tone: var(--bs-primary);

    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 1.15rem 1.25rem;
    text-decoration: none;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 12px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;

    // Tone is carried by a hairline at the top edge rather than a full fill
    position: relative;
    overflow: hidden;

    &::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        height: 2px;
        background: var(--tone);
        opacity: 0.85;
    }

    &:hover {
        border-color: rgba(var(--bs-emphasis-color-rgb), 0.18);
        box-shadow: 0 4px 16px rgba(var(--bs-body-color-rgb), 0.07);
    }

    // Only the clickable variant lifts on hover
    &[href]:hover {
        transform: translateY(-1px);
    }

    &--primary  { --tone: #3b82f6; }
    &--success  { --tone: #10b981; }
    &--warning  { --tone: #f59e0b; }
    &--danger   { --tone: #ef4444; }
    &--info     { --tone: #06b6d4; }
    &--neutral  { --tone: #64748b; }
}

.stat-card__top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
}

.stat-card__text {
    min-width: 0;
}

.stat-card__label {
    display: block;
    margin-bottom: 0.35rem;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);
}

.stat-card__value {
    display: block;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.15;
    color: var(--bs-emphasis-color);
    overflow-wrap: anywhere;
}

.stat-card__sub {
    display: block;
    margin-top: 0.3rem;
    font-size: 0.78rem;
    color: var(--bs-secondary-color);
}

.stat-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    font-size: 1.05rem;
    color: var(--tone);
    background: color-mix(in srgb, var(--tone) 12%, transparent);
    border-radius: 9px;
}

.stat-card__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
    margin-top: 0.9rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--bs-border-color);
    font-size: 0.78rem;

    > span {
        display: inline-flex;
        align-items: baseline;
        gap: 0.35rem;
    }

    .k {
        color: var(--bs-secondary-color);
    }

    .v {
        font-weight: 600;
        color: var(--bs-emphasis-color);
    }
}

// -----------------------------------------------------------------------------
//  Page header
// -----------------------------------------------------------------------------

.page-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--bs-border-color);

    h1 {
        margin: 0;
        font-size: 1.4rem;
        font-weight: 700;
        color: var(--bs-emphasis-color);
    }

    .page-header__sub {
        margin: 0.2rem 0 0;
        font-size: 0.875rem;
        color: var(--bs-secondary-color);
    }
}

// -----------------------------------------------------------------------------
//  Section headings between dashboard blocks
// -----------------------------------------------------------------------------

.dash-section-title {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0 0 0.9rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);

    &::after {
        content: '';
        flex: 1;
        height: 1px;
        background: var(--bs-border-color);
    }
}

// -----------------------------------------------------------------------------
//  Panels (charts, router cards)
// -----------------------------------------------------------------------------

.dash-panel {
    height: 100%;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color) !important;
    border-radius: 12px;
    box-shadow: none !important;

    > .card-header,
    > .dash-panel__head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.75rem;
        padding: 0.9rem 1.15rem;
        background: transparent;
        border-bottom: 1px solid var(--bs-border-color);

        h6 {
            margin: 0;
            font-size: 0.875rem;
            font-weight: 600;
            color: var(--bs-emphasis-color);
        }
    }
}

// Router overview cards inherit the same calm treatment
.router-overview-card {
    border: 1px solid var(--bs-border-color) !important;
    border-radius: 12px !important;
    box-shadow: none !important;
}

// -----------------------------------------------------------------------------
//  Brand wordmark
//  Used in the sidenav, topnav and auth marks. Previously `text-success`, which
//  tied the brand to the semantic success colour and fought the product blue.
// -----------------------------------------------------------------------------

.brand-name {
    color: #1668c4;
    font-weight: 700;
    letter-spacing: -0.01em;

    // A tenant's own business name goes here now, and those run long —
    // "Iten Public WiFi" was overflowing the sidebar and being cut mid-word.
    // Shrink to fit, then trail off cleanly rather than spilling.
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: clamp(0.95rem, 1.4vw, 1.25rem);
}

[data-bs-theme='dark'] .brand-name {
    color: #6ba7ea;
}

// -----------------------------------------------------------------------------
//  Brand mark (square icon beside the wordmark in the sidenav / topnav)
//  Sized in CSS rather than a width attribute so it can shrink on phones, where
//  a 40px mark crowded the header.
// -----------------------------------------------------------------------------

.brand-mark {
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    object-fit: contain;
}

@media (max-width: 575.98px) {
    .brand-mark {
        width: 26px;
        height: 26px;
    }

    .navbar-brand .brand-name,
    .brand-name {
        font-size: 1.05rem;
    }
}

// =============================================================================
//  Link a MikroTik wizard
// =============================================================================

.link-steps {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 1.5rem;
    padding: 0 0 1.25rem;
    list-style: none;
    border-bottom: 1px solid var(--bs-border-color);
    overflow-x: auto;
}

.link-steps__item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex: 1;
    min-width: max-content;
    color: var(--bs-secondary-color);

    // Connector line between steps
    &:not(:last-child)::after {
        content: '';
        flex: 1;
        height: 2px;
        min-width: 1.5rem;
        margin-left: 0.5rem;
        background: var(--bs-border-color);
    }

    &.is-complete::after {
        background: var(--bs-success);
    }

    &.is-current,
    &.is-complete {
        color: var(--bs-emphasis-color);
        font-weight: 600;
    }
}

.link-steps__dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    flex: 0 0 auto;
    font-size: 0.8rem;
    font-weight: 700;
    border-radius: 50%;
    border: 2px solid var(--bs-border-color);
    background: var(--bs-body-bg);

    .is-current & {
        color: var(--bs-success);
        border-color: var(--bs-success);
    }

    .is-complete & {
        color: #fff;
        background: var(--bs-success);
        border-color: var(--bs-success);
    }
}

.link-steps__label {
    font-size: 0.9rem;
    white-space: nowrap;
}

// On phones the four labels cannot fit, and a scrolling stepper is worse than
// no labels. Keep the dots and show only the step you are actually on.
@media (max-width: 575.98px) {
    .link-steps {
        gap: 0.35rem;
        overflow-x: visible;
    }

    .link-steps__item:not(.is-current) .link-steps__label {
        display: none;
    }

    .link-steps__item:not(:last-child)::after {
        min-width: 0.75rem;
        margin-left: 0.35rem;
    }
}

// --- Provisioning one-liner --------------------------------------------------

.provision-script {
    position: relative;
    padding: 1rem 1rem 1rem;
    background: var(--bs-tertiary-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 10px;

    code {
        display: block;
        padding-right: 7rem;
        font-size: 0.78rem;
        line-height: 1.6;
        color: var(--bs-emphasis-color);
        word-break: break-all;
        white-space: pre-wrap;
    }
}

.provision-script__copy {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    z-index: 1;
}

// --- Service tiles -----------------------------------------------------------

.service-tile {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    height: 100%;
    padding: 1rem;
    cursor: pointer;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 10px;
    transition: border-color 0.15s ease, background-color 0.15s ease;

    &:hover { border-color: var(--bs-secondary-color); }

    &.is-on {
        border-color: var(--bs-success);
        background: rgba(var(--bs-success-rgb), 0.06);
    }

    // Pushed to the far edge, and it must stay the last child for that to
    // move only itself rather than the whole row.
    input {
        margin-left: auto;
        flex: 0 0 auto;
        width: 1.15rem;
        height: 1.15rem;
        cursor: pointer;
    }
}

.service-tile__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 34px;
    flex: 0 0 auto;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--bs-emphasis-color);
    background: var(--bs-tertiary-bg);
    border-radius: 7px;
}

.service-tile__body {
    display: flex;
    flex-direction: column;

    strong { font-size: 0.95rem; }
    small { color: var(--bs-secondary-color); }
}

// --- Bridge port picker ------------------------------------------------------

.port-list {
    display: grid;
    gap: 0.5rem;
}

.port-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.7rem 0.9rem;
    cursor: pointer;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 9px;
    transition: border-color 0.15s ease, background-color 0.15s ease;

    &:hover { border-color: var(--bs-secondary-color); }

    &.is-on {
        border-color: var(--bs-success);
        background: rgba(var(--bs-success-rgb), 0.06);
    }

    // The WAN port stays selectable but is visually discouraged
    &.is-uplink {
        border-style: dashed;
    }
}

.port-row__name {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--bs-emphasis-color);
}

.port-row__hint {
    margin-left: auto;
    font-size: 0.78rem;
    color: var(--bs-secondary-color);
    text-align: right;
}

// --- Summary + log -----------------------------------------------------------

.summary-list {
    margin: 0;

    > div {
        display: flex;
        justify-content: space-between;
        gap: 1rem;
        padding: 0.65rem 0;
        border-bottom: 1px solid var(--bs-border-color);

        &:last-child { border-bottom: 0; }
    }

    dt {
        font-weight: 500;
        color: var(--bs-secondary-color);
    }

    dd {
        margin: 0;
        font-weight: 600;
        text-align: right;
        color: var(--bs-emphasis-color);
        overflow-wrap: anywhere;
    }
}

.config-log {
    padding: 1rem;
    font-size: 0.78rem;
    line-height: 1.7;
    color: var(--bs-emphasis-color);
    background: var(--bs-tertiary-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 10px;
    max-height: 16rem;
    overflow: auto;
}

// =============================================================================
//  Operational pulse
//  The band at the top of the dashboard: greeting, status chips, the list of
//  things that need a decision, and today's incoming payments.
// =============================================================================

.pulse-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.pulse-shift {
    display: block;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);
}

.pulse-greeting {
    margin: 0.25rem 0 0.15rem;
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--bs-emphasis-color);
}

.pulse-sub {
    margin: 0;
    font-size: 0.875rem;
    color: var(--bs-secondary-color);
}

.pulse-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.pulse-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.7rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--bs-secondary-color);
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 100px;

    &.is-ok {
        color: #0f9d6e;
        border-color: rgba(15, 157, 110, 0.3);
        background: rgba(15, 157, 110, 0.07);
    }

    &.is-warn {
        color: #b26b00;
        border-color: rgba(245, 158, 11, 0.35);
        background: rgba(245, 158, 11, 0.09);
    }

    &.is-bad {
        color: #d92d20;
        border-color: rgba(217, 45, 32, 0.3);
        background: rgba(217, 45, 32, 0.07);
    }
}

// Quiet pulsing dot for the "live" chip
.pulse-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
    animation: pulse-fade 2s ease-in-out infinite;
}

@keyframes pulse-fade {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

@media (prefers-reduced-motion: reduce) {
    .pulse-dot { animation: none; }
}

// --- Action rows -------------------------------------------------------------

.action-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.7rem 0.85rem;
    margin-bottom: 0.5rem;
    text-decoration: none;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-left: 3px solid var(--bs-secondary-color);
    border-radius: 9px;
    transition: border-color 0.13s ease, background-color 0.13s ease;

    &:last-child { margin-bottom: 0; }

    &:hover {
        background: rgba(var(--bs-emphasis-color-rgb), 0.03);
    }

    &--danger { border-left-color: #d92d20; }
    &--warning { border-left-color: #f59e0b; }

    i {
        margin-left: auto;
        color: var(--bs-secondary-color);
        font-size: 0.8rem;
    }
}

.action-row__body {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;

    strong {
        font-size: 0.875rem;
        color: var(--bs-emphasis-color);
    }

    small {
        font-size: 0.78rem;
        color: var(--bs-secondary-color);
    }
}

// --- Activity feed -----------------------------------------------------------

.activity-row {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.6rem 1.15rem;
    border-bottom: 1px solid var(--bs-border-color);

    &:last-child { border-bottom: 0; }
}

.activity-row__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    flex: 0 0 auto;
    font-size: 0.75rem;
    color: #0f9d6e;
    background: rgba(15, 157, 110, 0.1);
    border-radius: 50%;
}

.activity-row__body {
    font-size: 0.85rem;
    color: var(--bs-body-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

    strong { color: var(--bs-emphasis-color); }
}

.activity-row__meta {
    margin-left: auto;
    flex: 0 0 auto;
    font-size: 0.72rem;
    color: var(--bs-secondary-color);
    white-space: nowrap;
}

// --- Renewals table ----------------------------------------------------------

.renewals-table {
    th {
        font-size: 0.68rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        color: var(--bs-secondary-color);
        border-bottom: 1px solid var(--bs-border-color);
    }

    td {
        font-size: 0.85rem;
        vertical-align: middle;
    }
}

// =============================================================================
//  Payments ledger
// =============================================================================



// Search field with a leading icon
.ledger-search {
    position: relative;

    i {
        position: absolute;
        top: 50%;
        left: 0.6rem;
        transform: translateY(-50%);
        font-size: 0.8rem;
        color: var(--bs-secondary-color);
        pointer-events: none;
    }

    input {
        width: 15rem;
        max-width: 100%;
        padding-left: 1.9rem;
    }
}

.ledger-table {
    th {
        font-size: 0.68rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        color: var(--bs-secondary-color);
        white-space: nowrap;
        border-bottom: 1px solid var(--bs-border-color);
    }

    td {
        font-size: 0.85rem;
        vertical-align: middle;
    }
}

// Receipt codes are scanned character by character, so give them a mono face.
.ledger-receipt {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.78rem;
    color: var(--bs-emphasis-color);
}

// =============================================================================
//  Shared page header (x-page-head)
// =============================================================================

.page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.page-head__crumb {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);

    i { font-size: 0.6rem; opacity: 0.6; }
}

.page-head__title {
    margin: 0.3rem 0 0;
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--bs-emphasis-color);
}

.page-head__lead {
    margin: 0.2rem 0 0;
    font-size: 0.875rem;
    color: var(--bs-secondary-color);
}

.page-head__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

// -----------------------------------------------------------------------------
//  Live payments ticker
//
//  Sits between the greeting and the headline numbers. Shows one payment at a
//  time rather than a list: a stack of ten receipts becomes wallpaper, whereas
//  a single line that keeps changing is noticed from across the room.
// -----------------------------------------------------------------------------

.pulse-ticker {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
    padding: 0.7rem 1rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.75rem;
    background: var(--bs-body-bg);
    font-size: 0.86rem;
    // The rotating line must never push the bar wider than the page.
    overflow: hidden;
}

.pulse-ticker__badge {
    flex: none;
    padding: 0.15rem 0.5rem;
    border-radius: 0.35rem;
    background: rgba(25, 135, 84, 0.16);
    color: #198754;
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.pulse-ticker__stage {
    position: relative;
    flex: 1;
    min-width: 0;
    // Holds its height while an item swaps, so the bar does not jump.
    min-height: 1.25rem;
}

.pulse-ticker__item,
.pulse-ticker__idle {
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    line-height: 1.25rem;
}

.pulse-ticker__idle { color: var(--bs-secondary-color); }

.pulse-ticker__item {
    color: var(--bs-body-color);

    b { font-weight: 700; }

    em {
        margin-left: 0.35rem;
        color: var(--bs-secondary-color);
        font-style: normal;
        font-size: 0.8rem;
    }
}

.pulse-ticker__right {
    flex: none;
    font-size: 0.8rem;
    white-space: nowrap;

    &.is-ok { color: #198754; }
    &.is-bad { color: #dc3545; }
}

// Each new payment slides up into place.
.ticker-in { transition: transform 0.35s ease, opacity 0.35s ease; }
.ticker-in-start { opacity: 0; transform: translateY(0.5rem); }
.ticker-in-end { opacity: 1; transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
    .ticker-in { transition: none; }
    .ticker-in-start { opacity: 1; transform: none; }
}

@media (max-width: 575.98px) {
    // The router count is a nice-to-have; the payment is the point.
    .pulse-ticker__right { display: none; }
}

// -----------------------------------------------------------------------------
//  Global search palette (Ctrl+K)
//
//  Uses Bootstrap's theme variables rather than fixed colours so it follows the
//  admin between dark and light without a second set of rules.
// -----------------------------------------------------------------------------

.gsearch-trigger {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    max-width: 460px;
    padding: 0.48rem 0.85rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.6rem;
    background: var(--bs-tertiary-bg);
    color: var(--bs-secondary-color);
    font-size: 0.86rem;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;

    &:hover {
        border-color: var(--bs-primary);
        background: var(--bs-body-bg);
    }
}

.gsearch-trigger__label {
    flex: 1;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.gsearch-kbd,
.gsearch-foot kbd {
    padding: 0.1rem 0.38rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.3rem;
    background: var(--bs-body-bg);
    color: var(--bs-secondary-color);
    font-family: inherit;
    font-size: 0.68rem;
    font-weight: 600;
}

.gsearch-scrim {
    position: fixed;
    inset: 0;
    z-index: 1080;
    display: flex;
    justify-content: center;
    // Sits high rather than centred: the list grows downwards, and a centred
    // box would jump as results arrive.
    padding: 9vh 1rem 1rem;
    background: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(2px);
}

.gsearch-modal {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 640px;
    max-height: 74vh;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.9rem;
    background: var(--bs-body-bg);
    box-shadow: 0 24px 70px rgba(0, 0, 0, 0.45);
    overflow: hidden;
}

.gsearch-head {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.9rem 1.1rem;
    border-bottom: 1px solid var(--bs-border-color);

    > i { color: var(--bs-secondary-color); }
}

.gsearch-input {
    flex: 1;
    min-width: 0;
    border: 0;
    background: transparent;
    color: var(--bs-body-color);
    font-family: inherit;
    font-size: 1.02rem;
    outline: none;

    &::placeholder { color: var(--bs-secondary-color); }
}

.gsearch-x {
    border: 0;
    background: transparent;
    color: var(--bs-secondary-color);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
}

.gsearch-body {
    flex: 1;
    overflow-y: auto;
    padding: 0.5rem 0;
}

.gsearch-hint {
    margin: 0;
    padding: 2.2rem 1.2rem;
    color: var(--bs-secondary-color);
    font-size: 0.88rem;
    text-align: center;
}

.gsearch-group__label {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.55rem 1.1rem 0.3rem;
    color: var(--bs-secondary-color);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.gsearch-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.55rem 1.1rem;
    color: var(--bs-body-color);
    text-decoration: none;

    // Keyboard and mouse share one highlight, so arrowing down and hovering
    // never disagree about what is selected.
    &.is-active {
        background: var(--bs-tertiary-bg);
        box-shadow: inset 3px 0 0 var(--bs-primary);
    }
}

.gsearch-item__body {
    flex: 1;
    min-width: 0;
}

.gsearch-item__title,
.gsearch-item__meta {
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.gsearch-item__title { font-size: 0.9rem; font-weight: 600; }

.gsearch-item__meta {
    color: var(--bs-secondary-color);
    font-size: 0.76rem;
}

.gsearch-item__badge {
    flex: none;
    padding: 0.14rem 0.45rem;
    border-radius: 0.35rem;
    background: var(--bs-tertiary-bg);
    color: var(--bs-secondary-color);
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
}

.gsearch-foot {
    display: flex;
    gap: 1.1rem;
    padding: 0.6rem 1.1rem;
    border-top: 1px solid var(--bs-border-color);
    background: var(--bs-tertiary-bg);
    color: var(--bs-secondary-color);
    font-size: 0.74rem;

    span { display: inline-flex; align-items: center; gap: 0.35rem; }
}

// -----------------------------------------------------------------------------
//  Portal designer
//
//  The preview deliberately re-declares the portal's look in miniature rather
//  than embedding the real stylesheet: the portal's CSS assumes it owns the
//  whole page (fixed backdrop, full-height body) and would fight the admin
//  shell. Both read the same --hp-* variables, so colours stay truthful.
// -----------------------------------------------------------------------------

// --- Workspace ---------------------------------------------------------------
//  Two columns, not a Bootstrap .row of .cards. The dashboard card class sets
//  height:100% so a tile fills its grid cell; stacking several of them in one
//  column made each stretch to the height of the tallest thing in the row —
//  which here is the phone preview — leaving a screen of empty panel between
//  every heading.
.pd-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    align-items: start;

    @media (min-width: 1200px) {
        grid-template-columns: minmax(0, 1fr) 22rem;
    }
}

.pd-work {
    min-width: 0;
    border: 1px solid var(--bs-border-color);
    border-radius: 12px;
    background: var(--bs-body-bg);
    overflow: hidden;
}

.pd-sec {
    border-bottom: 1px solid var(--bs-border-color);

    &:last-child { border-bottom: 0; }
}

.pd-sec__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.85rem 1.15rem;
    background: var(--bs-tertiary-bg);
    border-bottom: 1px solid var(--bs-border-color);

    h6 {
        margin: 0;
        font-size: 0.8rem;
        font-weight: 600;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        color: var(--bs-emphasis-color);
    }

    > span {
        color: var(--bs-secondary-color);
        font-size: 0.76rem;
        text-align: right;
    }
}

.pd-sec__body { padding: 1.15rem; }

// --- Palettes ----------------------------------------------------------------
.pd-presets {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
    gap: 0.6rem;
    padding: 1.15rem;
}

.pd-preset {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.6rem;
    background: var(--bs-body-bg);
    color: inherit;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;

    &:hover { border-color: var(--bs-secondary-color); }

    &.is-on {
        border-color: var(--bs-primary);
        box-shadow: 0 0 0 1px var(--bs-primary) inset;
    }
}

// Three dots on the palette's own background, so a scheme is judged the way it
// will actually be seen rather than as swatches on the admin's background.
.pd-preset__chips {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: none;
    padding: 5px 6px;
    border-radius: 0.4rem;

    i {
        display: block;
        width: 9px;
        height: 9px;
        border-radius: 50%;
    }
}

.pd-preset__name {
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

// --- Fields ------------------------------------------------------------------
.pd-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11.5rem, 1fr));
    gap: 0.9rem 1rem;
    padding: 1.15rem;
}

.pd-field {
    min-width: 0;

    &--full { grid-column: 1 / -1; }
}

.pd-field__label {
    display: block;
    margin-bottom: 0.35rem;
    font-size: 0.82rem;
    font-weight: 600;

    // What the colour actually controls. Six hex fields named only "Accent" and
    // "Tertiary" gave no way to tell which one you wanted without trying it.
    span {
        display: block;
        margin-top: 0.1rem;
        color: var(--bs-secondary-color);
        font-size: 0.72rem;
        font-weight: 400;
        line-height: 1.35;
    }
}

.pd-toggles { padding: 0.25rem 1.15rem 0.9rem; }

.pd-preview__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.75rem;

    h6 {
        margin: 0;
        font-size: 0.8rem;
        font-weight: 600;
        letter-spacing: 0.04em;
        text-transform: uppercase;
    }

    span {
        color: var(--bs-secondary-color);
        font-size: 0.76rem;
    }
}

.pd-preview__note {
    margin: 0.85rem 0 0;
    color: var(--bs-secondary-color);
    font-size: 0.76rem;
    line-height: 1.45;
    text-align: center;
}

.pd-colour {
    display: flex;
    align-items: center;
    gap: 0.4rem;

    input[type="color"] {
        flex: none;
        width: 38px;
        height: 32px;
        padding: 2px;
        border: 1px solid var(--bs-border-color);
        border-radius: 0.4rem;
        background: var(--bs-body-bg);
        cursor: pointer;
    }
}

.pd-toggle {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    padding: 0.65rem 0;
    border-bottom: 1px solid var(--bs-border-color);
    cursor: pointer;

    &:last-child { border-bottom: 0; }

    input {
        flex: none;
        width: 1.05rem;
        height: 1.05rem;
        margin-top: 0.1rem;
        accent-color: var(--bs-primary);
        cursor: pointer;
    }
}

.pd-toggle__label { display: block; font-size: 0.88rem; font-weight: 600; }

.pd-toggle__hint {
    display: block;
    margin-top: 0.1rem;
    color: var(--bs-secondary-color);
    font-size: 0.78rem;
    line-height: 1.4;
}

.pd-log {
    margin: 0;
    padding: 0.7rem 0.9rem;
    border-radius: 0.5rem;
    background: var(--bs-tertiary-bg);
    list-style: none;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.78rem;
    line-height: 1.8;
}

// --- Preview -----------------------------------------------------------------
// align-items:start on the grid shrinks this column to its content, which
// leaves a sticky child nothing to travel inside — the preview scrolled away
// the moment you reached the colour pickers, on the one page where seeing the
// result while you edit is the whole point. Stretch it, and clear the fixed
// top bar.
.pd-side { align-self: stretch; }

.pd-preview-wrap {
    position: sticky;
    top: 5.25rem;
}

.pd-phone {
    max-width: 340px;
    margin: 0 auto;
    padding: 12px;
    border: 1px solid var(--bs-border-color);
    border-radius: 28px;
    background: var(--bs-tertiary-bg);
}

.pd-phone__screen {
    max-height: 62vh;
    overflow-y: auto;
    padding: 14px 12px;
    border-radius: 20px;
    background: var(--hp-bg);
    color: var(--hp-text);
}

.pd-card {
    padding: 16px 14px;
    border: 1px solid rgba(148, 163, 184, 0.16);
    border-radius: var(--hp-radius);
    background: var(--hp-card);
}

.pd-brand {
    margin-bottom: 6px;
    font-size: 1.25rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    text-align: center;
    word-break: break-word;
    background: var(--hp-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.pd-welcome {
    color: var(--hp-primary);
    font-size: 0.82rem;
    font-weight: 700;
    text-align: center;
}

.pd-tagline {
    margin-bottom: 12px;
    color: #94a3b8;
    font-size: 0.74rem;
    text-align: center;
}

.pd-help {
    margin-bottom: 11px;
    padding: 9px;
    border: 1px solid rgba(148, 163, 184, 0.14);
    border-radius: 10px;
    background: rgba(15, 23, 42, 0.55);
    text-align: center;

    strong {
        display: block;
        color: var(--hp-primary);
        font-size: 0.74rem;
    }

    span {
        color: var(--hp-primary);
        font-size: 0.8rem;
        font-weight: 700;
        text-decoration: underline;
    }
}

.pd-btn {
    padding: 10px;
    border-radius: 10px;
    background: var(--hp-gradient);
    color: #fff;
    font-size: 0.76rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-align: center;
    text-transform: uppercase;
}

.pd-trial {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-top: 10px;
    padding: 9px 10px;
    border: 1px solid rgba(59, 130, 246, 0.35);
    border-radius: 10px;
    background: rgba(15, 23, 42, 0.55);
    font-size: 0.76rem;
    font-weight: 700;
}

.pd-chip {
    padding: 2px 5px;
    border-radius: 4px;
    background: #34d399;
    color: #065f46;
    font-size: 0.55rem;
    font-weight: 800;
    letter-spacing: 0.06em;
}

.pd-rule {
    margin: 14px 0 9px;
    color: #64748b;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-align: center;
    text-transform: uppercase;
}

.pd-plan {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 7px;
    padding: 9px 10px;
    border: 1px solid rgba(244, 63, 94, 0.4);
    border-left: 3px solid var(--hp-tertiary);
    border-radius: 9px;
    background: rgba(15, 23, 42, 0.5);

    b { display: block; font-size: 0.78rem; }
    em { font-style: normal; font-size: 0.7rem; color: var(--hp-primary); font-weight: 800; }
}

.pd-buy {
    flex: none;
    padding: 4px 11px;
    border: 1px solid rgba(96, 165, 250, 0.55);
    border-radius: 7px;
    color: #60a5fa;
    font-size: 0.68rem;
    font-weight: 700;
}

.pd-tile {
    margin-top: 10px;
    padding: 10px;
    border: 1px solid rgba(148, 163, 184, 0.18);
    border-radius: 10px;
    background: rgba(15, 23, 42, 0.5);
    font-size: 0.74rem;
    font-weight: 600;
}

.pd-foot {
    margin-top: 14px;
    color: #475569;
    font-size: 0.65rem;
    text-align: center;
}

/* Subscriber type / detail tabs */
.sub-tabs{display:flex;flex-wrap:wrap;gap:.4rem}
.sub-tab{display:inline-flex;align-items:center;gap:.45rem;padding:.45rem .9rem;border:1px solid var(--bs-border-color);
 border-radius:999px;background:var(--bs-body-bg);color:var(--bs-secondary-color);font:inherit;font-size:.85rem;
 font-weight:600;cursor:pointer;transition:background .15s,color .15s,border-color .15s}
.sub-tab:hover{color:var(--bs-body-color)}
.sub-tab.is-active{background:var(--bs-primary);border-color:var(--bs-primary);color:#fff}
.sub-tab span{padding:.05rem .4rem;border-radius:999px;background:var(--bs-tertiary-bg);
 color:var(--bs-secondary-color);font-size:.72rem;font-weight:700}
.sub-tab.is-active span{background:rgba(255,255,255,.22);color:#fff}

/* Definition list used on the subscriber overview */
.sub-facts{margin:0;font-size:.88rem}
.sub-facts>div{display:flex;justify-content:space-between;gap:1rem;padding:.55rem 0;
 border-bottom:1px solid var(--bs-border-color)}
.sub-facts>div:last-child{border-bottom:0}
.sub-facts dt{margin:0;color:var(--bs-secondary-color);font-weight:500}
.sub-facts dd{margin:0;font-weight:600;text-align:right;word-break:break-all}
