/*
 * BlackWall interface layer
 *
 * Sits on top of vendor/tabler/tabler.min.css and css/theme.css and carries
 * only what BlackWall adds to the theme: the brand lockup, the admin shell,
 * softened status colours for the badges the templates already emit, and the
 * error pages. Colours come from the theme's --ns-* tokens — never redefine a
 * palette here, extend the theme instead.
 */

:root {
    --bw-mono: "JetBrains Mono", ui-monospace, "SF Mono", "Fira Code", monospace;
    /* Single source of truth for the horizontal inset of card content, so
       body copy, headers, footers and table columns all line up. */
    --bw-card-inset: 1.5rem;
}

/* ── Page backdrop ───────────────────────────────────────────────
   The theme paints a radial wash behind the page. Pinning it to the viewport
   keeps it still while content scrolls, instead of the gradient sliding up and
   leaving the flat page colour behind on long admin pages. */

body.app-page,
.auth-layout {
    background-attachment: fixed;
}

/* ── Density ─────────────────────────────────────────────────────
   Tabler's defaults are tighter than BlackWall's dense admin pages want:
   cards inset content by 1.25rem but table cells by only 0.75rem, and most
   admin pages put a table in a `card-body p-0`, so that 0.75rem was the only
   thing keeping data off the card edge. Widen both and align them. */

.app-page {
    --tblr-card-spacer-y: 1.25rem;
    --tblr-card-spacer-x: var(--bw-card-inset);
    --tblr-card-cap-padding-y: 1rem;
    --tblr-card-cap-padding-x: var(--bw-card-inset);
}

.app-page .table > :not(caption) > * > * {
    padding: 0.85rem 1rem;
}

/* The outermost columns align with the card's own inset rather than sitting
   nearer the edge than the surrounding prose. */
.app-page .card .table > :not(caption) > * > *:first-child {
    padding-left: var(--bw-card-inset);
}

.app-page .card .table > :not(caption) > * > *:last-child {
    padding-right: var(--bw-card-inset);
}

.app-page .list-group-item {
    padding: 0.85rem var(--bw-card-inset);
}

@media (max-width: 575.98px) {
    /* Reclaim horizontal space on small screens. */
    .app-page {
        --bw-card-inset: 1rem;
    }

    .app-page .table > :not(caption) > * > * {
        padding: 0.75rem 0.65rem;
    }
}

/* ── Brand lockup ─────────────────────────────────────────────────
   The theme ships a synthetic three-bar mark. BlackWall replaces it with the
   real logo. blackwall.svg is filled with the theme's brand navy directly, so
   it needs no filter to sit on the light header — the previous dark theme
   inverted a grey logo to white, which this replaces. */

.brand-mark--logo {
    display: inline-flex;
    width: auto;
    height: 30px;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    padding: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
}

.brand-mark--logo img,
.brand-mark--logo svg {
    display: block;
    width: auto;
    height: 100%;
}

.brand-link__name {
    font-size: 1.05rem;
}

/* ── Admin shell ─────────────────────────────────────────────────── */

.admin-main {
    max-width: 1600px;
    margin: 0 auto;
    padding: 0 1.5rem 3rem;
}

.admin-role-badge {
    padding: 0.35rem 0.65rem;
    border: 1px solid var(--ns-color-border);
    border-radius: 8px;
    background: var(--ns-color-surface-subtle);
    color: #54718b;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.admin-footer {
    max-width: 1600px;
    margin: 0 auto;
    padding: 1rem 1.5rem 2.5rem;
}

.admin-footer-shell {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem var(--bw-card-inset);
    border: 1px solid var(--ns-color-border);
    border-radius: var(--ns-radius-card);
    background: var(--ns-color-surface);
    box-shadow: var(--ns-shadow-card);
    color: var(--ns-color-text-muted);
}

.admin-footer-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1.25rem;
    font-size: 0.78rem;
}

.admin-footer-meta strong {
    margin-right: 0.4rem;
    color: #54718b;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.11em;
    text-transform: uppercase;
}

/* Impersonation sits above the sticky header so it can never be scrolled
   out of sight while a switched identity is active. */
.impersonation-bar {
    position: relative;
    z-index: 1030;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 1.5rem;
    border-bottom: 1px solid rgba(245, 159, 0, 0.35);
    background: #fff8e6;
    color: #8a5a00;
    font-size: 0.83rem;
}

/* ── Authentication screens ──────────────────────────────────────
   Shared by the admin, portal and OAuth sign-in pages plus enrolment and
   organisation signup. The theme supplies .auth-layout, .auth-panel and
   .auth-intro__accent; these add the brand lockup and the wider two-column
   arrangement the admin login needs for its build metadata. */

.auth-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    margin-bottom: 1.25rem;
    color: var(--ns-color-brand);
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    text-decoration: none;
}

.auth-brand img {
    display: block;
    height: 38px;
    width: auto;
}

/* Wider than .auth-panel: an information column beside the sign-in card. */
.auth-shell {
    position: relative;
    z-index: 1;
    display: grid;
    width: min(980px, calc(100% - 2rem));
    grid-template-columns: 1.1fr 0.9fr;
    gap: 1.25rem;
    margin: 2rem auto;
    align-items: start;
}

.auth-shell > .card {
    margin: 0;
}

.auth-kicker {
    color: var(--ns-color-action);
    font-size: 0.69rem;
    font-weight: 700;
    letter-spacing: 0.13em;
    text-transform: uppercase;
}

/* Build/version metadata table on the admin sign-in page. */
.build-info {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
}

.build-info th,
.build-info td {
    padding: 0.45rem 0;
    border-bottom: 1px solid var(--ns-color-border);
    vertical-align: top;
}

.build-info tr:last-child th,
.build-info tr:last-child td {
    border-bottom: 0;
}

.build-info th {
    width: 8rem;
    color: #54718b;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.11em;
    text-transform: uppercase;
}

.build-info td {
    color: var(--ns-color-text);
    font-family: var(--bw-mono);
    word-break: break-word;
}

@media (max-width: 991.98px) {
    .auth-shell {
        grid-template-columns: 1fr;
    }
}

/* ── OAuth consent ───────────────────────────────────────────────
   The consent screen keeps its bespoke structure — a lockup pairing BlackWall
   with the requesting client, then one row per fact being consented to —
   restyled onto the theme's surfaces. */

.consent-connection {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
}

.consent-logo {
    display: flex;
    width: 48px;
    height: 48px;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--ns-color-border);
    border-radius: 12px;
    background: var(--ns-color-surface);
}

.consent-logo img.consent-logo__brand {
    height: 26px;
    width: auto;
}

.consent-logo img.consent-logo__client {
    width: 30px;
    height: 30px;
    border-radius: 6px;
    object-fit: contain;
}

.consent-logo .consent-logo__initial {
    color: var(--ns-color-action);
    font-size: 1.25rem;
    font-weight: 700;
}

.consent-dots {
    display: flex;
    max-width: 80px;
    flex: 1;
    align-items: center;
    gap: 4px;
}

.consent-dots span {
    position: relative;
    height: 2px;
    flex: 1;
    overflow: hidden;
    border-radius: 1px;
    background: var(--ns-color-border);
}

.consent-dots span::after {
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, var(--ns-color-action), transparent);
    animation: consent-slide 2s linear infinite;
    content: "";
}

@keyframes consent-slide {
    from { transform: translateX(-100%); }
    to { transform: translateX(100%); }
}

.consent-detail {
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
    padding: 0.875rem 1rem;
    border: 1px solid var(--ns-color-border);
    border-radius: 10px;
    background: var(--ns-color-surface-subtle);
}

.consent-detail + .consent-detail {
    margin-top: 0.75rem;
}

.consent-detail__icon {
    display: flex;
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    background: #eaf5fd;
    box-shadow: inset 0 0 0 1px rgba(12, 120, 201, 0.18);
}

.consent-detail__icon svg {
    width: 16px;
    height: 16px;
    stroke: var(--ns-color-action);
}

.consent-detail__body {
    min-width: 0;
    flex: 1;
}

.consent-detail__label {
    margin-bottom: 0.2rem;
    color: #54718b;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.consent-detail__value {
    color: var(--ns-color-text);
    font-size: 0.94rem;
    font-weight: 600;
}

.consent-detail__sub {
    margin-top: 0.15rem;
    color: var(--ns-color-text-muted);
    font-family: var(--bw-mono);
    font-size: 0.74rem;
    word-break: break-all;
}

.consent-privilege {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25em 0.75em;
    border-radius: 999px;
    background: #eaf5fd;
    box-shadow: inset 0 0 0 1px rgba(12, 120, 201, 0.25);
    color: #0a5f9e;
    font-size: 0.81rem;
    font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
    .consent-dots span::after { animation: none; }
}

/* ── Page headings ───────────────────────────────────────────────
   Admin pages emit `<div class="page-header"><h2>Title</h2></div>` followed by
   a muted paragraph. Map that onto the theme's page-title / page-intro pair so
   every page picks up the theme's typography without being edited. */

.page-header {
    padding: 2rem 0 0;
    margin-bottom: 0.35rem;
}

.page-header h2 {
    margin: 0;
    color: var(--ns-color-brand);
    font-size: clamp(1.55rem, 3vw, 1.9rem);
    font-weight: 700;
    letter-spacing: -0.035em;
}

.page-header + p {
    max-width: 72ch;
    margin-bottom: 0;
    color: var(--ns-color-text-muted);
}

/* Rows that follow a heading block shouldn't double up on top margin. */
.page-header ~ .row.mt-4:first-of-type {
    margin-top: 1.25rem !important;
}

/* ── Tables ──────────────────────────────────────────────────────
   Applies the theme's records-table header treatment to every admin table. */

.app-page .table thead th {
    color: #54718b;
    font-size: 0.69rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
}

.app-page .table tbody tr:hover {
    background: #f7fbfe;
}

.app-page .table-responsive {
    border-radius: var(--ns-radius-card);
}

/* ── Soft status colours ─────────────────────────────────────────
   Templates emit Bootstrap's solid contextual classes. The theme's visual
   language is soft-tinted, so restyle the badge forms in place rather than
   rewriting every call site. Scoped to .badge so alerts, buttons and
   background utilities are left to Tabler. */

.badge {
    font-weight: 600;
    font-size: 0.7rem;
    letter-spacing: 0.04em;
}

.badge.bg-success  { background: #ebfaed !important; color: #1c7c2b !important; box-shadow: inset 0 0 0 1px rgba(47, 179, 68, 0.28); }
.badge.bg-danger   { background: #fdeded !important; color: #b02a2a !important; box-shadow: inset 0 0 0 1px rgba(214, 57, 57, 0.28); }
.badge.bg-warning  { background: #fff6e5 !important; color: #8a5a00 !important; box-shadow: inset 0 0 0 1px rgba(245, 159, 0, 0.3); }
.badge.bg-info     { background: #eaf5fd !important; color: #0a5f9e !important; box-shadow: inset 0 0 0 1px rgba(12, 120, 201, 0.25); }
.badge.bg-primary  { background: #eaf5fd !important; color: #0a5f9e !important; box-shadow: inset 0 0 0 1px rgba(12, 120, 201, 0.25); }
.badge.bg-secondary,
.badge.text-bg-secondary { background: var(--ns-color-surface-subtle) !important; color: #54718b !important; box-shadow: inset 0 0 0 1px var(--ns-color-border); }
.badge.bg-light    { background: var(--ns-color-surface-subtle) !important; color: #54718b !important; box-shadow: inset 0 0 0 1px var(--ns-color-border); }

/* ── Code ────────────────────────────────────────────────────────── */

code,
pre,
.font-monospace {
    font-family: var(--bw-mono);
}

code {
    padding: 0.12em 0.42em;
    border: 1px solid rgba(12, 120, 201, 0.16);
    border-radius: 5px;
    background: #f2f7fc;
    color: #0a5f9e;
    font-size: 0.84em;
}

pre {
    overflow-x: auto;
    padding: 0.85rem 1rem;
    border: 1px solid var(--ns-color-border);
    border-radius: 10px;
    background: var(--ns-color-surface-subtle);
    color: var(--ns-color-text);
    font-size: 0.82rem;
}

pre code {
    padding: 0;
    border: none;
    background: none;
    color: inherit;
    font-size: inherit;
}

/* ── Definition lists ───────────────────────────────────────────── */

dl dt {
    color: #54718b;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

dl dd {
    color: var(--ns-color-text);
}

/* ── Dashboard statistics ───────────────────────────────────────── */

.stat-card {
    border-left: 3px solid var(--ns-color-action) !important;
    transition: transform 180ms ease, box-shadow 180ms ease;
}

.stat-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--ns-shadow-card-hover);
}

.stat-card--green  { border-left-color: var(--ns-color-success) !important; }
.stat-card--amber  { border-left-color: var(--ns-color-warning) !important; }
.stat-card--purple { border-left-color: #7c4de0 !important; }
.stat-card--red    { border-left-color: var(--ns-color-danger) !important; }

.stat-card .display-6 {
    color: var(--ns-color-brand);
    font-size: 1.85rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.03em;
}

.stat-icon {
    display: flex;
    width: 42px;
    height: 42px;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
}

.stat-icon svg {
    width: 21px;
    height: 21px;
}

.stat-icon-blue   { background: #eaf5fd; color: #0a5f9e; box-shadow: inset 0 0 0 1px rgba(12, 120, 201, 0.18); }
.stat-icon-green  { background: #ebfaed; color: #1c7c2b; box-shadow: inset 0 0 0 1px rgba(47, 179, 68, 0.2); }
.stat-icon-amber  { background: #fff6e5; color: #8a5a00; box-shadow: inset 0 0 0 1px rgba(245, 159, 0, 0.22); }
.stat-icon-purple { background: #f2eefc; color: #5b3bb0; box-shadow: inset 0 0 0 1px rgba(124, 77, 224, 0.18); }
.stat-icon-red    { background: #fdeded; color: #b02a2a; box-shadow: inset 0 0 0 1px rgba(214, 57, 57, 0.2); }
.stat-icon-grey   { background: var(--ns-color-surface-subtle); color: #54718b; box-shadow: inset 0 0 0 1px var(--ns-color-border); }

/* Live service indicator in the admin footer. */
.status-dot.online {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 0.45rem;
    border-radius: 50%;
    background: var(--ns-color-success);
    box-shadow: 0 0 0 3px rgba(47, 179, 68, 0.16);
    vertical-align: middle;
}

/* ── Documentation ───────────────────────────────────────────────
   The guide's contents card sticks while the prose scrolls. It has to clear
   the sticky header, which Bootstrap's own sticky-top (top: 0) does not, and
   it must be able to scroll internally: the list is longer than the viewport
   on short screens, and a plain sticky card would strand its lower entries. */

.admin-doc-nav {
    position: sticky;
    top: calc(var(--ns-header-height) + 1rem);
    max-height: calc(100vh - var(--ns-header-height) - 2rem);
    max-height: calc(100dvh - var(--ns-header-height) - 2rem);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.admin-doc-nav > .list-group {
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

@media (max-width: 991.98px) {
    /* Stacked single column below lg: sticking would cover the prose. */
    .admin-doc-nav {
        position: static;
        max-height: none;
    }
}

/* ── Documentation prose ────────────────────────────────────────── */

.admin-doc-body > *:last-child {
    margin-bottom: 0;
}

.admin-doc-body h1,
.admin-doc-body h2,
.admin-doc-body h3,
.admin-doc-body h4 {
    margin-top: 1.75rem;
    margin-bottom: 0.75rem;
    color: var(--ns-color-brand);
    letter-spacing: -0.02em;
}

.admin-doc-body h1:first-child,
.admin-doc-body h2:first-child,
.admin-doc-body h3:first-child,
.admin-doc-body h4:first-child {
    margin-top: 0;
}

.admin-doc-body p,
.admin-doc-body ul,
.admin-doc-body ol,
.admin-doc-body pre,
.admin-doc-body table {
    margin-bottom: 1rem;
}

.admin-doc-body li + li {
    margin-top: 0.35rem;
}

/* ── Error pages ────────────────────────────────────────────────── */

.error-page {
    display: flex;
    min-height: 100vh;
    align-items: center;
    justify-content: center;
    padding: 2rem 0;
}

.error-wrap {
    width: 100%;
    max-width: 960px;
}

.error-code {
    color: var(--ns-color-brand);
    font-size: clamp(5rem, 15vw, 13rem);
    font-weight: 800;
    letter-spacing: -0.05em;
    line-height: 0.9;
    opacity: 0.12;
}

.error-headline {
    margin-top: 1rem;
    color: var(--ns-color-brand);
    font-size: clamp(1.6rem, 4vw, 2.75rem);
    font-weight: 700;
    letter-spacing: -0.03em;
}

.error-detail {
    margin-top: 0.75rem;
    color: var(--ns-color-text-muted);
    font-size: clamp(1rem, 2.2vw, 1.35rem);
}

.trace-wrap {
    padding: 1rem;
    border: 1px solid var(--ns-color-border);
    border-radius: 10px;
    background: var(--ns-color-surface-subtle);
}

.error-trace {
    max-height: 300px;
    overflow: auto;
    color: var(--ns-color-text-muted);
    font-family: var(--bw-mono);
    font-size: 0.78rem;
    white-space: pre-wrap;
    word-break: break-all;
}

@media (prefers-reduced-motion: reduce) {
    .stat-card { transition: none; }
    .stat-card:hover { transform: none; }
}

@media (max-width: 991.98px) {
    .admin-main { padding: 0 1rem 2.5rem; }
    .admin-footer { padding: 1rem 1rem 2rem; }

    .admin-footer-shell {
        flex-direction: column;
        align-items: flex-start;
    }
}
