/*
 * Panel chrome overrides. Design System v0.1.
 */

/* --- brand logo -------------------------------------------------------- */

/*
 * .fi-topbar is min-height, not height, so an oversized logo grows the app bar
 * instead of being clipped. The assets are cropped to their artwork, so this
 * cap should never engage -- it exists so the next asset drop cannot resize the
 * chrome. .fi-simple-header .fi-logo (login) is left alone: no surrounding bar.
 */
.fi-topbar .fi-logo,
.fi-sidebar-header .fi-logo {
    max-height: calc(var(--topbar-height) - 1.5rem);
    width: auto;
    max-width: 100%;
    object-fit: contain;
}

/* --- typography -------------------------------------------------------- */

/*
 * Inter Tight at 400 reads light at panel text sizes. 500 is already in the
 * font request Filament hardcodes, so this costs no extra download.
 * --tw-font-weight must be set too: the compiled utilities read it.
 */
.fi-body {
    --tw-font-weight: var(--font-weight-medium);
    font-weight: var(--font-weight-medium);
}

/* --- sidebar ----------------------------------------------------------- */

/*
 * Filament leaves .fi-sidebar transparent on desktop, so the rail is whatever
 * the body is. Hover and active must move with it -- Filament paints both from
 * --gray-100, the shade the rail is being set to, so darkening the rail alone
 * makes every hover state invisible.
 *
 * Light mode only: --gray-100 is a light colour in both themes.
 */
.fi-sidebar:not(:where(.dark, .dark *)),
.fi-sidebar-header:not(:where(.dark, .dark *)) {
    background-color: var(--gray-100);
}

.fi-sidebar-item-btn:not(:where(.dark, .dark *)):hover,
.fi-sidebar-item.fi-active > .fi-sidebar-item-btn:not(:where(.dark, .dark *)),
.fi-sidebar-group-btn:not(:where(.dark, .dark *)):hover,
.fi-sidebar-group-dropdown-trigger-btn:not(:where(.dark, .dark *)):hover {
    background-color: var(--gray-200);
}

/* --- primary buttons --------------------------------------------------- */

/*
 * Repoints --color-* rather than background-color, so Filament's own hover,
 * focus and disabled rules keep working. :not(.fi-outlined) is required:
 * outlined buttons, links and badges are .fi-color-primary too and render text
 * from --color-500, so an unscoped override turns them all black.
 */
.fi-btn:not(.fi-outlined).fi-color-primary {
    --color-600: #000000;
    --color-500: var(--gray-800);
    --color-50: #FFFFFF;
}

/*
 * Inverted in dark mode: black on the gray-900 panel has almost no edge. The
 * fill lands on --gray-50, so the label has to be near-black to read -- 950,
 * not 800, since 800 on a near-white chip is the weakest pairing here.
 *
 * `color` is restated rather than left to --color-50 alone: Filament resolves
 * the label through --dark-text -> var(--color-50), and any component that
 * renders a primary button with an ad-hoc array colour gets those custom
 * properties as an inline style, which no stylesheet rule can outrank.
 */
.fi-btn:not(.fi-outlined).fi-color-primary:where(.dark, .dark *) {
    --color-600: var(--gray-50);
    --color-500: var(--gray-200);
    --color-50: var(--gray-950);

    color: var(--gray-950);
}

.fi-btn:not(.fi-outlined).fi-color-primary:where(.dark, .dark *) > .fi-icon {
    color: var(--gray-950);
}

/* --- environment badge ------------------------------------------------- */

/*
 * Rendered only outside production. Tints are keyed off the APP_ENV value so
 * the markup carries no inline style -- a real CSP is a pending ticket in
 * App\Http\Middleware\SecurityHeaders and would block inline styles.
 */
.fi-env-badge {
    --env-bg: var(--yellow-400);

    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.75rem;
    border-radius: 9999px;
    background-color: var(--env-bg);
    color: var(--gray-800);
    font-size: 0.75rem;
    font-weight: var(--font-weight-bold);
    line-height: 1.25rem;
    letter-spacing: 0.06em;
    white-space: nowrap;
}

.fi-env-badge[data-env="local"],
.fi-env-badge[data-env="development"] {
    --env-bg: var(--info-400);
}

.fi-env-badge[data-env="staging"] {
    --env-bg: var(--warning-400);
}

.fi-env-badge[data-env="testing"] {
    --env-bg: var(--purple-300);
}

.fi-env-badge-debug {
    padding: 0 0.375rem;
    border-radius: 9999px;
    background-color: var(--gray-800);
    color: var(--env-bg);
    font-size: 0.625rem;
    letter-spacing: 0.04em;
}

/* --- analytics page grid ----------------------------------------------- */

/*
 * Cards in a row share one height. Grid items already stretch to the row, but
 * the card is the widget's child, so the widget has to hand its height on:
 * make it a column and let the card take the rest. Layout only -- colours and
 * dark mode stay Filament's -- and scoped to the page class so the Statistics
 * pages and the dashboard keep their natural heights. Below the lg breakpoint
 * the grid is one column and every card simply fills its own row.
 */
.fi-analytics-page .fi-wi-widget {
    display: flex;
    flex-direction: column;
}

.fi-analytics-page .fi-wi-widget > .fi-section {
    flex: 1 1 auto;
}

/*
 * Chart boxes are fixed, as in the metrics reference: 210px, or 250px for the
 * KYC reasons list. Filament's chart frame has no height of its own -- with a
 * max height it only caps the canvas -- so a chart came out shorter than its
 * cap and an empty one taller. The frame is given the height instead and the
 * widgets turn Chart.js's aspect ratio off (ExplainsInTooltip), so the chart
 * fills the box exactly and the empty state occupies the same box.
 *
 * The heights repeat DashboardSections::CHART_HEIGHT and CHART_HEIGHT_TALL.
 * A widget cannot put a class on its own frame, so the taller one is picked
 * out by the max-height it writes on the canvas (or the min-height on its
 * empty frame); a test pins both spellings.
 */
.fi-analytics-page .fi-wi-chart .fi-wi-chart-frame {
    height: 210px;
    overflow: hidden;
}

.fi-analytics-page .fi-wi-chart .fi-wi-chart-frame:has(canvas[style*="max-height: 250px"]),
.fi-analytics-page .fi-wi-chart .fi-wi-chart-frame[style*="min-height: 250px"] {
    height: 250px;
}

/* The reference's card type: a 13.5px title over an 11.5px muted subtitle. */
.fi-analytics-page .fi-wi-widget .fi-section-header-heading {
    font-size: 0.84rem;
    font-weight: 500;
}

.fi-analytics-page .fi-wi-widget .fi-section-header-description {
    font-size: 0.72rem;
}

/* --- journey analytics -------------------------------------------------- */

/* Sections need more air than Filament's default stack gives them here. */
.journey-page {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

/*
 * A funnel runs down, not across: four of the eight stage names are two words,
 * and a horizontal strip either truncates them or scrolls out of sight.
 */
.journey-funnel {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.journey-row {
    /* Overridden per row from the stage's own badge colour, so both agree. */
    --journey-accent: var(--gray-400);
    display: grid;
    grid-template-columns: minmax(10rem, 12rem) 1fr minmax(8rem, auto);
    align-items: center;
    gap: 1.25rem;
    width: 100%;
    padding: 0.875rem 1rem;
    text-align: left;
    cursor: pointer;
    border: 1px solid transparent;
    border-radius: 0.75rem;
    background-color: transparent;
    transition: background-color 150ms, border-color 150ms;
}

.journey-row:hover {
    background-color: var(--gray-100);
}

.journey-row:hover:where(.dark, .dark *) {
    background-color: var(--gray-800);
}

.journey-row--on {
    border-color: var(--journey-accent);
    background-color: var(--gray-100);
}

.journey-row--on:where(.dark, .dark *) {
    background-color: var(--gray-800);
}

.journey-row:focus-visible {
    outline: 2px solid var(--journey-accent);
    outline-offset: 2px;
}

.journey-row__label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.875rem;
    font-weight: var(--font-weight-semibold);
    color: var(--gray-700);
}

.journey-row__label:where(.dark, .dark *) {
    color: var(--gray-200);
}

/* Marks a stage that opens into sub-steps, so a dead click is never a surprise. */
.journey-row__more {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.125rem;
    height: 1.125rem;
    border-radius: 9999px;
    background-color: var(--journey-accent);
    color: var(--gray-50);
    font-size: 0.6875rem;
    line-height: 1;
}

.journey-row__track {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 1rem;
    min-width: 0;
}

/* Width is set inline as a percentage of the 1fr column, so the bars share one scale. */
.journey-row__bar {
    height: 1.625rem;
    min-width: 0.375rem;
    border-radius: 0.375rem;
    background-color: var(--journey-accent);
}

.journey-row__value {
    font-size: 0.9375rem;
    font-weight: var(--font-weight-semibold);
    font-variant-numeric: tabular-nums;
    color: var(--gray-900);
}

.journey-row__value:where(.dark, .dark *) {
    color: var(--gray-50);
}

/* One short phrase now that the durations moved into the connector below. */
.journey-row__meta {
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
    color: var(--gray-500);
    text-align: right;
}

.journey-row__meta:where(.dark, .dark *) {
    color: var(--gray-400);
}

/*
 * The connector between two bars is the move itself, so it carries the share that made it and
 * how long it took. The rule down its left edge is what ties the two bars together.
 */
.journey-move {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.375rem 1rem;
    margin-left: 1.75rem;
    padding: 0.5rem 0 0.5rem 1rem;
    border-left: 2px solid var(--gray-200);
    font-size: 0.75rem;
    color: var(--gray-500);
}

.journey-move:where(.dark, .dark *) {
    border-left-color: var(--gray-700);
}

/* No stage below the last one, so the rule stops rather than pointing at nothing. */
.journey-move--tail {
    border-left-style: dashed;
}

.journey-move__arrow {
    line-height: 1;
}

.journey-move__ratio {
    font-weight: var(--font-weight-semibold);
    font-variant-numeric: tabular-nums;
    color: var(--gray-700);
}

.journey-move__ratio:where(.dark, .dark *) {
    color: var(--gray-300);
}

.journey-move__times {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.875rem;
    font-variant-numeric: tabular-nums;
}

/* The typical case is the headline; the two edges sit back from it. */
.journey-move__median {
    font-weight: var(--font-weight-semibold);
    color: var(--gray-700);
}

.journey-move__median:where(.dark, .dark *) {
    color: var(--gray-300);
}

.journey-move__edge {
    color: var(--gray-400);
}

/* --- skip reasons ------------------------------------------------------- */

.journey-reasons {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.journey-reason {
    display: grid;
    grid-template-columns: minmax(10rem, 14rem) 1fr minmax(6rem, auto);
    align-items: center;
    gap: 1.25rem;
    padding: 0.625rem 1rem;
    border-radius: 0.625rem;
}

.journey-reason:hover {
    background-color: var(--gray-100);
}

.journey-reason:hover:where(.dark, .dark *) {
    background-color: var(--gray-800);
}

.journey-reason__label {
    font-size: 0.8125rem;
    color: var(--gray-700);
}

.journey-reason__label:where(.dark, .dark *) {
    color: var(--gray-200);
}

.journey-reason__track {
    display: block;
    min-width: 0;
}

/* Orange, not brand green: every bar here is something that did not happen. */
.journey-reason__bar {
    display: block;
    height: 1.125rem;
    border-radius: 0.3125rem;
    background-color: var(--warning-400);
}

.journey-reason__count {
    display: flex;
    align-items: baseline;
    justify-content: flex-end;
    gap: 0.5rem;
    font-size: 0.875rem;
    font-weight: var(--font-weight-semibold);
    font-variant-numeric: tabular-nums;
    color: var(--gray-900);
}

.journey-reason__count:where(.dark, .dark *) {
    color: var(--gray-50);
}

.journey-reason__share {
    font-weight: var(--font-weight-medium);
    color: var(--gray-400);
}

/* --- shared ------------------------------------------------------------- */

.journey-empty {
    padding: 2.5rem 1.5rem;
    text-align: center;
}

.journey-empty__title {
    font-size: 0.875rem;
    font-weight: var(--font-weight-semibold);
    color: var(--gray-700);
}

.journey-empty__title:where(.dark, .dark *) {
    color: var(--gray-200);
}

.journey-empty__body {
    margin-top: 0.375rem;
    font-size: 0.8125rem;
    color: var(--gray-500);
}

.journey-note {
    padding: 0 0.25rem;
    font-size: 0.8125rem;
    color: var(--gray-500);
}

.journey-note a {
    color: var(--primary-500);
    text-decoration: underline;
}

/* One column is unreadable at 12rem of label; below sm each row becomes three lines. */
@media (max-width: 640px) {
    .journey-row,
    .journey-reason {
        grid-template-columns: 1fr;
        gap: 0.625rem;
    }
}

/* A stat that opens into its rows; the cards are Filament's, only the affordance is ours. */
.journey-stat {
    cursor: pointer;
    transition: border-color 150ms, box-shadow 150ms;
}

.journey-stat:hover {
    border-color: var(--gray-300);
}

.journey-stat:hover:where(.dark, .dark *) {
    border-color: var(--gray-600);
}

.journey-stat--on {
    border-color: var(--primary-400);
    box-shadow: 0 0 0 1px var(--primary-400);
}

/*
 * The KPI strip is the reference's row of four tiles: a padded card, a small
 * muted label, a 24px figure and one line of change, 11px apart. Filament's stat
 * is roomier, so spacing and type are set here; colours and dark mode stay its.
 */
.fi-analytics-page .fi-wi-stats-overview .fi-section-content {
    gap: 0.7rem;
}

.fi-analytics-page .fi-wi-stats-overview .fi-wi-stats-overview-stat {
    padding: 0.875rem 1rem;
    border-radius: 0.8rem;
}

.fi-analytics-page .fi-wi-stats-overview .fi-wi-stats-overview-stat-content {
    row-gap: 0.45rem;
}

.fi-analytics-page .fi-wi-stats-overview .fi-wi-stats-overview-stat-label {
    font-size: 0.75rem;
    font-weight: 400;
}

.fi-analytics-page .fi-wi-stats-overview .fi-wi-stats-overview-stat-value {
    font-size: 1.5rem;
    line-height: 1;
    letter-spacing: -0.02em;
}

.fi-analytics-page .fi-wi-stats-overview .fi-wi-stats-overview-stat-description {
    font-size: 0.75rem;
}

/*
 * The tile's line is the reference's .delta and .ctx: only the change is
 * coloured, the context after it stays muted. Filament's description would
 * colour the whole line from the stat's colour, so the colours are set on the
 * spans and the description itself is left gray.
 */
.fi-analytics-page .fi-wi-stats-overview .fi-kpi-delta {
    font-weight: 500;
}

.fi-analytics-page .fi-wi-stats-overview .fi-kpi-delta-up {
    color: var(--success-600);
}

.fi-analytics-page .fi-wi-stats-overview .fi-kpi-delta-down {
    color: var(--danger-600);
}

.fi-analytics-page .fi-wi-stats-overview .fi-kpi-delta-up:where(.dark, .dark *) {
    color: var(--success-400);
}

.fi-analytics-page .fi-wi-stats-overview .fi-kpi-delta-down:where(.dark, .dark *) {
    color: var(--danger-400);
}

.fi-analytics-page .fi-wi-stats-overview .fi-kpi-ctx {
    color: var(--gray-500);
}

.fi-analytics-page .fi-wi-stats-overview .fi-kpi-ctx:where(.dark, .dark *) {
    color: var(--gray-400);
}
