/* ==========================================================================
   AnisPay Control Panel — shared design system
   ==========================================================================
   Single source of truth for page chrome: headers, toolbars, data grids,
   cards, summary panels and status banners. Feature pages compose these
   classes instead of shipping their own <style> block, so a change here
   reaches every page at once.

   Shipped from this component library as
       _content/AnisPay.ControlPanel.Components/css/design-system.css
   and linked from App/AnisPay.ControlPanel.WebApp/wwwroot/index.html.

   CASCADE NOTE
   The brand theme (wwwroot/css/themes/*.css) is appended to <head> at runtime
   by the bootstrap script in index.html, so it loads *after* this sheet. Rules
   below that must beat a theme rule of equal specificity are qualified with
   the MudBlazor class they compete with (e.g. `.mud-card.app-card`) rather
   than relying on source order.
   ========================================================================== */


/* ── Tokens ───────────────────────────────────────────────────────────────
   Everything visual is expressed through these so a single edit restyles
   every page. --app-accent is the per-element status colour: the default
   lives here, and the .app-accent-* classes below override it locally. */
:root {
    --app-radius-card: 16px;
    --app-radius-control: 10px;
    --app-radius-tile: 12px;

    --app-shadow-card: 0 2px 10px rgba(0, 0, 0, .06);
    --app-shadow-card-hover: 0 16px 34px rgba(0, 0, 0, .17);
    --app-shadow-panel: 0 4px 18px rgba(0, 0, 0, .07);
    --app-shadow-banner: 0 6px 22px rgba(0, 0, 0, .08);

    --app-ease: cubic-bezier(.2, .8, .2, 1);
    --app-duration: .28s;
    --app-duration-enter: .5s;

    --app-grid-font-size: 1.25rem;

    --app-accent: var(--mud-palette-primary);
}

/* ── Typography ──────────────────────────────────────────────────────────
   Font family and size are user preferences. The bootstrap script in
   index.html replays the stored choice onto <html> as inline custom
   properties before the app renders, so there is no flash of the default.
   The values below are what a first-time visitor gets.

   Everything in the panel sizes in rem, so scaling the root font size scales
   the whole UI proportionally — grid cells, cards, nav and MudBlazor's own
   typography all follow. */
:root {
    --app-font-family: 'Inter', 'El Messiri', 'Roboto', sans-serif;
    --app-font-base: 14px;
    --app-font-scale: 1;

    /* MudBlazor never hardcodes a typeface — every font-family it emits reads
       one of these variables. Redirecting them is therefore all it takes to
       restyle the entire component library, including components we never
       enumerate anywhere.

       !important is load-bearing: MudThemeProvider injects its own :root block
       carrying the Roboto default at runtime, and being appended to <head> last
       it beats an equal-specificity declaration. Anything left to those
       variables would silently fall back to Roboto — which is exactly what
       happened to the breadcrumbs. */
    --mud-typography-default-family: var(--app-font-family) !important;
    --mud-typography-h1-family: var(--app-font-family) !important;
    --mud-typography-h2-family: var(--app-font-family) !important;
    --mud-typography-h3-family: var(--app-font-family) !important;
    --mud-typography-h4-family: var(--app-font-family) !important;
    --mud-typography-h5-family: var(--app-font-family) !important;
    --mud-typography-h6-family: var(--app-font-family) !important;
    --mud-typography-button-family: var(--app-font-family) !important;
    --mud-typography-body1-family: var(--app-font-family) !important;
    --mud-typography-body2-family: var(--app-font-family) !important;
    --mud-typography-subtitle1-family: var(--app-font-family) !important;
    --mud-typography-subtitle2-family: var(--app-font-family) !important;
    --mud-typography-caption-family: var(--app-font-family) !important;
    --mud-typography-overline-family: var(--app-font-family) !important;
    --mud-typography-input-family: var(--app-font-family) !important;
}

/* :root outranks the bare `html`/`body` selectors the brand themes use, so
   the scale survives whichever theme is loaded. */
:root,
:root body {
    font-size: calc(var(--app-font-base) * var(--app-font-scale));
}

/* Everything MudBlazor renders is covered by the variables above. This is only
   for what it doesn't own: the browser's own form-control defaults and
   Bootstrap's reset, neither of which inherits from body on its own. */
:root,
:root body,
:root button,
:root input,
:root optgroup,
:root select,
:root textarea {
    font-family: var(--app-font-family) !important;
}


/* Status accents. Put one of these on any .app-card / .app-summary and the
   left rail, icon tile and hover tint all follow it. */
.app-accent-primary {
    --app-accent: var(--mud-palette-primary);
}

.app-accent-approved {
    --app-accent: var(--mud-palette-success);
}

.app-accent-pending {
    --app-accent: var(--mud-palette-warning);
}

.app-accent-rejected {
    --app-accent: var(--mud-palette-error);
}

.app-accent-info {
    --app-accent: var(--mud-palette-info);
}

.app-accent-neutral {
    --app-accent: var(--mud-palette-text-disabled);
}


/* ── Page chrome ─────────────────────────────────────────────────────────
   Replaces the "GlobalTitle + <br /> + MudStack + <br /><br />" sequence
   every page used to repeat by hand. */
.app-page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin-block: 1.5rem 1.75rem;
}

.app-page-header__actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}

/* Filter row above a grid (wallet id, sender wallet, load button…). */
.app-page-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 1.5rem;
}


/* ── Breadcrumb ──────────────────────────────────────────────────────────
   The first crumb doubles as the "back to the list" link, so it is styled
   to read as the primary action rather than as breadcrumb chrome. */
.app-breadcrumb .mud-breadcrumb-item:first-child > a {
    font-size: 1.5rem;
    font-weight: 600;
    letter-spacing: .01em;
    color: var(--mud-palette-primary);
    cursor: pointer;
    border-radius: 8px;
    padding: 2px 8px;
    transition: color .15s ease, background-color .15s ease;
}

.app-breadcrumb .mud-breadcrumb-item:first-child > a:hover {
    text-decoration: underline;
    color: var(--mud-palette-primary-darken);
    background-color: color-mix(in srgb, var(--mud-palette-primary) 10%, transparent);
}


/* ── Data grid ───────────────────────────────────────────────────────────
   Wrap any MudDataGrid in <DataGridPanel> to pick these up. */
.app-grid td {
    font-size: var(--app-grid-font-size) !important;
}

/* When the grid's internal scroll reaches its top/bottom edge, let further
   scrolling chain to the whole page instead of stopping. */
.app-grid .mud-table-container {
    overscroll-behavior: auto;
}

/* Give the sticky header an opaque background so scrolled rows never show
   through it (also covers the sticky first-column header cell). */
.app-grid .mud-table-head th.mud-table-cell {
    background-color: var(--mud-palette-surface) !important;
}

/* Denser variant for grids whose cells hold long-form text. */
.app-grid--compact {
    --app-grid-font-size: 1.05rem;
}

.app-grid--compact td {
    vertical-align: top;
}

/* Long text in a cell: three lines, then ellipsis. Pair with a tooltip
   carrying the full value. */
.app-text-clamp {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 480px;
    line-height: 1.6;
    white-space: pre-wrap;
}


/* ── Summary panel ───────────────────────────────────────────────────────
   The accent-tinted strip that sits above a grid or a card wall and carries
   the headline chips for whatever the page is showing. */
.app-summary {
    padding: 20px 24px;
    margin-bottom: 1.25rem;
    border-radius: var(--app-radius-card);
    background: linear-gradient(135deg, color-mix(in srgb, var(--app-accent) 12%, var(--mud-palette-surface)), var(--mud-palette-surface) 65%);
    border-inline-start: 5px solid var(--app-accent);
    box-shadow: var(--app-shadow-panel);
    animation: app-panel-in var(--app-duration-enter) var(--app-ease) both;
}

.app-summary__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 14px;
    background: color-mix(in srgb, var(--app-accent) 18%, transparent);
}

.app-summary__icon .mud-icon-root {
    color: var(--app-accent);
}


/* ── Status banner ───────────────────────────────────────────────────────
   A single, loud pass/fail statement (policy agreement, verification gate).
   Colour comes from currentColor so the tint, rail and glow stay in sync. */
.app-banner {
    margin-bottom: 1.5rem;
    padding: 22px 26px;
    border-radius: 18px;
    display: flex;
    align-items: center;
    gap: 20px;
    position: relative;
    overflow: hidden;
    box-shadow: var(--app-shadow-banner);
    animation: app-banner-in .55s var(--app-ease) both;
}

.app-banner::after {
    content: "";
    position: absolute;
    inset-inline-end: -40px;
    top: -40px;
    width: 160px;
    height: 160px;
    border-radius: 50%;
    background: currentColor;
    opacity: .06;
    pointer-events: none;
}

.app-banner--success {
    color: var(--mud-palette-success);
    background: linear-gradient(135deg, color-mix(in srgb, var(--mud-palette-success) 20%, var(--mud-palette-surface)), var(--mud-palette-surface) 72%);
    border-inline-start: 6px solid var(--mud-palette-success);
}

.app-banner--danger {
    color: var(--mud-palette-error);
    background: linear-gradient(135deg, color-mix(in srgb, var(--mud-palette-error) 20%, var(--mud-palette-surface)), var(--mud-palette-surface) 72%);
    border-inline-start: 6px solid var(--mud-palette-error);
}

.app-banner__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    border-radius: 20px;
    flex-shrink: 0;
    background: color-mix(in srgb, currentColor 18%, transparent);
}

.app-banner__icon .mud-icon-root {
    font-size: 2.4rem;
    color: currentColor;
}

.app-banner--success .app-banner__icon {
    animation: app-banner-pulse 2.4s ease-in-out infinite;
}

.app-banner--danger .app-banner__icon {
    animation: app-banner-shake 3.2s ease-in-out infinite;
}

.app-banner__body {
    position: relative;
    z-index: 1;
}

.app-banner__title {
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    margin-bottom: 4px;
}

.app-banner__status {
    font-family: var(--app-font-family);
    font-size: 1.7rem;
    font-weight: 600;
    line-height: 1.3;
    color: currentColor;
}

.app-banner__meta {
    margin-top: 10px;
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}


/* ── Card ────────────────────────────────────────────────────────────────
   The accent-railed card the KYC review page is built from. Qualified with
   .mud-card so the radius and shadow survive the brand theme's own
   `.mud-card { border-radius: 12px !important }` rule (see cascade note). */
.mud-card.app-card {
    border-radius: var(--app-radius-card) !important;
    box-shadow: var(--app-shadow-card) !important;
}

.app-card {
    position: relative;
    overflow: hidden;
    height: 100%;
    display: flex;
    flex-direction: column;
    background-color: var(--mud-palette-surface);
    transition: transform var(--app-duration) var(--app-ease), box-shadow var(--app-duration) ease;
    animation: app-card-in var(--app-duration-enter) var(--app-ease) both;
    will-change: transform, opacity;
}

/* Keeps a wall of cards on an even baseline when some of them hold media. */
.app-card--tall {
    min-height: 360px;
}

.app-card::before {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    width: 4px;
    background: var(--app-accent);
    transition: width var(--app-duration) ease;
}

.mud-card.app-card:hover {
    box-shadow: var(--app-shadow-card-hover) !important;
}

.app-card:hover {
    transform: translateY(-5px);
}

.app-card:hover::before {
    width: 6px;
}

/* A pending card breathes, so an operator's eye lands on the work queue. */
.app-accent-pending.app-card::before {
    animation: app-accent-pulse 2.4s ease-in-out infinite;
}

.app-card .mud-card-header {
    padding-block: 16px;
    gap: 8px;
}

.app-card__headline {
    display: flex;
    align-items: center;
    gap: 12px;
}

.app-card__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    border-radius: var(--app-radius-tile);
    background: color-mix(in srgb, var(--app-accent) 16%, transparent);
    transition: transform var(--app-duration) var(--app-ease);
}

.app-card:hover .app-card__icon {
    transform: scale(1.08) rotate(-4deg);
}

.app-card__icon .mud-icon-root {
    color: var(--app-accent);
}

.app-card__title {
    font-weight: 600;
}

.app-card__actions {
    padding: 12px 16px 16px;
}

.app-card__btn {
    border-radius: var(--app-radius-control);
    transition: transform .18s ease, box-shadow .18s ease;
}

.app-card__btn:hover {
    transform: translateY(-2px);
}

.app-card__alert {
    border-radius: var(--app-radius-control);
    animation: app-fade-in .4s ease both;
}


/* ── Media slot ──────────────────────────────────────────────────────────
   Fixed-width column inside a card holding a document scan, a selfie or a
   liveness video — plus whatever sits under it (a score bar), so the two
   stay the same width. */
.app-media {
    display: block;
    width: 240px;
}

.app-media__content {
    display: block;
    width: 100%;
    height: 180px;
    object-fit: contain;
    border-radius: 6px;
    background-color: var(--mud-palette-background-grey);
}


/* ── Field list ──────────────────────────────────────────────────────────
   Label/value pairs inside a card (name parts, city + location). */
.app-field-list {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 6px 12px;
    margin-top: 4px;
}

@media (max-width: 600px) {
    .app-field-list {
        grid-template-columns: 1fr;
    }
}

.app-field-list__item {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 10px 14px;
    border-radius: var(--app-radius-tile);
    border-inline-start: 3px solid transparent;
    transition: background-color .2s ease, border-color .2s ease;
}

.app-field-list__item:hover {
    background-color: color-mix(in srgb, var(--app-accent) 9%, transparent);
    border-inline-start-color: var(--app-accent);
}

/* Modifier: plain read-only field list, no hover tint/rail. */
.app-field-list--static .app-field-list__item:hover {
    background-color: transparent;
    border-inline-start-color: transparent;
}

.app-field-list__label {
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.app-field-list__value {
    font-family: var(--app-font-family);
    font-size: 1.5rem;
    font-weight: 500;
    line-height: 1.45;
    color: var(--mud-palette-text-primary);
}


/* ── Share dialog ────────────────────────────────────────────────────── */
.share-dialog .mud-dialog {
    border-radius: var(--app-radius-tile);
    overflow: hidden;
}

.share-dialog .mud-dialog-content {
    padding: 0;
}

.share-preview .mud-input-slot textarea {
    font-family: var(--app-font-family), monospace;
    white-space: pre-wrap;
}


/* ── Motion ──────────────────────────────────────────────────────────── */
@keyframes app-card-in {
    from {
        opacity: 0;
        transform: translateY(16px) scale(.985);
    }

    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

@keyframes app-panel-in {
    from {
        opacity: 0;
        transform: translateY(10px) scale(.98);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes app-banner-in {
    from {
        opacity: 0;
        transform: translateY(14px) scale(.98);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes app-fade-in {
    from {
        opacity: 0;
        transform: translateY(6px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes app-accent-pulse {
    0%, 100% {
        opacity: 1;
    }

    50% {
        opacity: .4;
    }
}

@keyframes app-banner-pulse {
    0%, 100% {
        transform: scale(1);
        box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 45%, transparent);
    }

    50% {
        transform: scale(1.07);
        box-shadow: 0 0 0 14px transparent;
    }
}

@keyframes app-banner-shake {
    0%, 90%, 100% {
        transform: translateX(0);
    }

    93% {
        transform: translateX(-3px);
    }

    96% {
        transform: translateX(3px);
    }

    98% {
        transform: translateX(-2px);
    }
}

@media (prefers-reduced-motion: reduce) {
    .app-card,
    .app-card__alert,
    .app-summary,
    .app-banner,
    .app-banner__icon,
    .app-accent-pending.app-card::before {
        animation: none !important;
    }

    .app-card,
    .app-card__icon,
    .app-field-list__item {
        transition: none;
    }
}
