/*
 * LSOE Learning admin panel.
 *
 * Education administration is record-keeping: enrolments, certificates,
 * qualification numbers, awarding bodies. The panel stays denser than the
 * learner application, but shares its visual language: the same cool ground,
 * brand blue, Poppins headings, soft ring-edged surfaces and rounded
 * controls, with one signal colour that only ever means "this needs you".
 *
 * Plain CSS on purpose. Filament 3's own theme build expects Tailwind 3 and
 * this application is on Tailwind 4, so rather than run a second, conflicting
 * build for a stylesheet this size, everything here rides on the CSS custom
 * properties Filament already exposes. The palette itself is set in
 * AdminPanelProvider, which is the supported way and covers dark mode for
 * free; this file is typography, surfaces and density only.
 */

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap');

:root {
    /* The learner application's cool ground (tokens.color.surface.base), a
       shade off white so long sessions are easier than pure #fff. Dark mode
       keeps Filament's own surfaces. */
    --fm-paper: #f4f6fb;
    --fm-paper-raised: #ffffff;
    --fm-rule: rgb(5 11 39 / 0.08);
    --fm-ring: 0 0 0 1px rgb(5 11 39 / 0.05);
    --fm-display: 'Poppins', ui-sans-serif, system-ui, sans-serif;
    --fm-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
}

/* ── Surfaces ──────────────────────────────────────────────────────────── */

html:not(.dark) .fi-body,
html:not(.dark) .fi-main-ctn {
    background-color: var(--fm-paper);
}

html:not(.dark) .fi-sidebar,
html:not(.dark) .fi-topbar > nav {
    background-color: var(--fm-paper-raised);
    border-color: var(--fm-rule);
}

/* ── Headings ──────────────────────────────────────────────────────────── */

/*
 * Poppins is the brand heading face across the product, so moving between the
 * learner application and the panel does not change voice.
 */
.fi-header-heading,
.fi-simple-header-heading,
.fi-section-header-heading,
.fi-wi-stats-overview-stat-label,
.fi-modal-heading,
.fi-fo-section-header-heading,
.fm-brand-name {
    font-family: var(--fm-display);
    letter-spacing: -0.02em;
}

.fi-header-heading {
    font-weight: 600;
    font-size: 1.6rem;
}

.fi-section-header-heading,
.fi-fo-section-header-heading {
    font-weight: 600;
    letter-spacing: -0.01em;
}

/* Stat labels are small caps rather than a shrunken heading: they are labels
   for a number, not titles. */
.fi-wi-stats-overview-stat-label {
    font-family: inherit;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.6875rem;
    font-weight: 700;
    opacity: 0.72;
}

/* ── Figures and identifiers ───────────────────────────────────────────── */

/*
 * Money, counts and dates line up in columns, so they get tabular figures.
 * Without this, a column of prices is ragged and genuinely harder to scan.
 */
.fi-ta-text,
.fi-ta-record-content,
.fi-wi-stats-overview-stat-value,
.fi-in-text {
    font-variant-numeric: tabular-nums;
}

.fi-wi-stats-overview-stat-value {
    font-feature-settings: 'tnum' 1;
    letter-spacing: -0.02em;
}

/*
 * Identifiers — certificate numbers, qualification numbers, order references —
 * are strings a person compares character by character against a document or
 * an email. Monospace makes that possible; it is not decoration.
 */
.fm-identifier,
.fi-ta-text-item-label:has(> .fm-identifier) {
    font-family: var(--fm-mono);
    font-size: 0.8125rem;
    letter-spacing: -0.01em;
}

/* ── Density ───────────────────────────────────────────────────────────── */

/* Filament's default row padding is generous for forms and wasteful for a
   catalogue of 200 courses. A little tighter, still comfortably clickable. */
.fi-ta-row .fi-ta-cell {
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
}

.fi-ta-header-cell {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.6875rem;
}

/* ── Navigation ────────────────────────────────────────────────────────── */

.fi-sidebar-group-label {
    text-transform: uppercase;
    letter-spacing: 0.09em;
    font-size: 0.6875rem;
    font-weight: 700;
    opacity: 0.6;
}

/* Same active state as the learner sidebar: a soft brand tint with a rule. */
.fi-sidebar-item-button {
    border-radius: 0.625rem;
}

html:not(.dark) .fi-sidebar-item-active .fi-sidebar-item-button {
    background-color: rgb(var(--primary-600) / 0.08);
    box-shadow: inset 3px 0 0 0 rgb(var(--primary-600));
}

/* ── Motion ────────────────────────────────────────────────────────────── */

/* One considered transition rather than movement everywhere. */
.fi-sidebar-item-button,
.fi-btn {
    transition: background-color 140ms ease, box-shadow 140ms ease, color 140ms ease;
}

@media (prefers-reduced-motion: reduce) {
    .fi-sidebar-item-button,
    .fi-btn {
        transition: none;
    }
}


/* ── Brand lockup ──────────────────────────────────────────────────────── */

.fm-brand {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
}

.fm-brand-mark {
    height: 1.75rem;
    width: auto;
    flex-shrink: 0;
}

/* One mark per theme, so the monogram keeps its contrast either way. */
.fm-brand-mark--dark { display: none; }
.dark .fm-brand-mark--light { display: none; }
.dark .fm-brand-mark--dark { display: inline; }

.fm-brand-name {
    font-family: var(--fm-display);
    font-weight: 600;
    font-size: 1.0625rem;
    letter-spacing: -0.015em;
    white-space: nowrap;
    color: rgb(var(--gray-950));
}

.dark .fm-brand-name {
    color: #fff;
}


/* ── Focus ─────────────────────────────────────────────────────────────── */

/*
 * Keyboard focus has to be obvious against the warm ground, and only for
 * keyboard users: a ring that follows the mouse reads as a rendering fault.
 * Two rings — ink inside, paper outside — so the indicator survives whichever
 * surface it lands on, including inside a filled button.
 */
:where(a, button, [role='button'], input, select, textarea, summary):focus-visible {
    outline: 2px solid rgb(var(--primary-600));
    outline-offset: 2px;
    border-radius: 0.375rem;
}

.dark :where(a, button, [role='button'], input, select, textarea, summary):focus-visible {
    outline-color: rgb(var(--primary-400));
}

/* ── Empty states ──────────────────────────────────────────────────────── */

/*
 * The panel spends its first weeks mostly empty, so an empty table is a normal
 * state rather than an error, and it is given the same quiet treatment as
 * everything else rather than a large grey void.
 */
.fi-ta-empty-state-heading {
    font-family: var(--fm-display);
    font-weight: 600;
}

.fi-ta-empty-state-description {
    max-width: 32rem;
    margin-inline: auto;
}

/* ── Signal ────────────────────────────────────────────────────────────── */

/*
 * Amber means work is waiting and nothing else uses it. Never set it as bare
 * text on the content ground: the brand amber measures 2.6:1 there. Filament
 * renders it at the 700 shade inside a tinted pill, which the panel's
 * configured amber clears — see AdminPaletteContrastTest.
 */

/* ── Operational surfaces ──────────────────────────────────────────────── */

/* Ring-edged white surfaces with the learner application's 18px corners. */
.fi-section {
    border-radius: 1.125rem !important;
    border: 0 !important;
    box-shadow: var(--fm-ring) !important;
}

.fi-wi-stats-overview-stat {
    border-radius: 1rem !important;
    border: 0 !important;
    box-shadow: var(--fm-ring) !important;
}

.dark .fi-section,
.dark .fi-wi-stats-overview-stat {
    border: 1px solid rgba(255, 255, 255, 0.09) !important;
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.25) !important;
}

.fi-btn {
    border-radius: 0.75rem;
}

.fi-wi-stats-overview-stat {
    transition: box-shadow 140ms ease;
}

.fi-wi-stats-overview-stat:hover {
    box-shadow: 0 0 0 1px rgb(var(--primary-600) / 0.25), 0 6px 16px -8px rgb(5 11 39 / 0.18) !important;
}

@media (prefers-reduced-motion: reduce) {
    .fi-wi-stats-overview-stat {
        transition: none;
    }
}


/* ── Dark mode for the dashboard widgets ───────────────────────────────── */

/*
 * The widget views use Tailwind dark: utilities that Filament's compiled panel
 * stylesheet does not contain (it only ships the classes Filament itself
 * uses), so without these rules the shortcut tiles stay white with near-white
 * text and the platform status labels fall below readable contrast.
 */
.dark .fm-quick-action {
    background-color: rgb(255 255 255 / 0.05);
    border-color: rgb(255 255 255 / 0.12);
}

/*
 * (Doubled with .grid so these outrank the view's own sm:grid-cols-3, which
 * Filament's stylesheet does ship and which loads after this file.)
 *
 * The shortcut grid asks for grid-cols-2 / lg:grid-cols-6, tile padding and a
 * one-line clamp with utilities that are not in Filament's stylesheet, which
 * left phones with no columns and desktops with three. Stated here instead:
 * two columns, three from 640px, six from 1280px.
 */
.grid.fm-quick-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
}

@media (min-width: 640px) {
    .grid.fm-quick-actions { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 1280px) {
    .grid.fm-quick-actions { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

.fm-quick-action {
    padding: 0.875rem;
    min-width: 0;
}

.fm-quick-action > div {
    min-width: 0;
    max-width: 100%;
}

.fm-quick-action-title,
.fm-quick-action-desc {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The view asks for 11px with an arbitrary-value class Filament's stylesheet does
   not ship, so the description fell back to body size and outweighed its title. */
.fm-quick-action-desc {
    font-size: 0.6875rem;
    line-height: 1.35;
    /* Up to two lines, so a narrow tile keeps most of its description. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    white-space: normal;
}

.dark .fm-quick-action:hover {
    border-color: rgb(var(--primary-400));
}

.dark .fm-quick-action-icon {
    background-color: rgb(255 255 255 / 0.07);
}

.dark .fm-quick-action-title {
    color: rgb(var(--gray-100));
}

.dark .fm-quick-action-desc {
    color: rgb(var(--gray-400));
}

.dark .fm-health-label {
    color: rgb(var(--gray-300));
}

/* A long status note (for example the upload limits) wraps inside its card
   rather than running past the edge. */
.fm-health-row {
    flex-wrap: wrap;
}

/* Doubled with the row so they outrank the view's own shrink-0 utility. */
.fm-health-row .fm-health-value {
    flex-shrink: 1;
    min-width: 0;
}

.fm-health-row .fm-health-text {
    overflow-wrap: anywhere;
}

.dark .fm-health-text.text-emerald-700 {
    color: rgb(52 211 153);
}

.dark .fm-health-text.text-amber-700 {
    color: rgb(251 191 36);
}
