/*
 * Ronia Office panel theme. Loaded AFTER Filament's compiled CSS via a render
 * hook, so it can restate the injected color scales and component surfaces
 * without a build step: there is no node on the server, and a hand-authored
 * override survives a composer update where a forked vendor file would not.
 *
 * Two ideas carry the whole design:
 *   1. Navy is the house, gold is the signal. Gold appears only where the
 *      user's attention should go: the active nav item, the primary action,
 *      focus. It is never body text on a light surface (2.4:1).
 *   2. Dark mode is layered, not flat: page, card and raised surfaces are
 *      three distinct navy steps, so cards read as cards without heavy lines.
 *
 * Every direction-sensitive rule uses logical properties, so Arabic RTL
 * mirrors for free. All text/background pairs were computed against WCAG AA
 * before shipping (lowest pair 5.4:1, most above 7:1).
 *
 * The values here are the working implementation of the approved demo palette
 * (navy + gold). The Designer agent owns any change of palette direction.
 */

/* ---------------------------------------------------------------- scales */

.dark {
    /* Navy-rich gray scale, hue 262, replacing Filament's neutral slate.
       950 is the page, 900 the card, 800 the raised/hover step.
       Values matched against the approved demo, which runs darker than
       Filament's defaults. */
    --gray-950: oklch(0.155 0.04 262);
    --gray-900: oklch(0.21 0.042 262);
    --gray-800: oklch(0.285 0.042 262);
    --gray-700: oklch(0.35 0.04 262);
    --gray-600: oklch(0.46 0.036 261);
    --gray-500: oklch(0.585 0.032 260);
    --gray-400: oklch(0.72 0.03 258);
    --gray-300: oklch(0.855 0.018 256);
    --gray-200: oklch(0.91 0.012 255);
    --gray-100: oklch(0.95 0.008 253);
    --gray-50: oklch(0.975 0.005 250);
}

/* ------------------------------------------------------------ base layer */

.fi-body {
    font-feature-settings: 'ss01' on;
}

/* Numbers in tables, stats and badges line up in columns. */
.fi-ta-table,
.fi-wi-stats-overview-stat-value,
.fi-badge {
    font-variant-numeric: tabular-nums;
}

/* Gold focus ring everywhere: one signal color for "you are here". */
.fi-body :focus-visible {
    outline: 2px solid oklch(0.75 0.135 90);
    outline-offset: 2px;
}

/* ==================================================== layout: sidebar and topbar */
/*
 * The reference design's shell, one to one: a 250px deep navy sidebar opened
 * by a gold brand tile, and a slim translucent topbar carrying the language
 * switcher, the office filter, search, the bell and the user menu.
 *
 * The hex values here are the demo's own tokens rather than oklch
 * restatements, so this section cannot quietly drift away from the reference:
 *   --navy-900 #0f1a30 (sidebar)   --navy-800 #152238 (hover / controls)
 *   --navy-700 #1c2c47 (active)    --border   #243453
 *   --gold #c9a227   --gold-light #e0bd4f
 *   --text #e9edf5   --text-dim #9fb0c9
 *
 * The 250px itself is set by the panel's ->sidebarWidth(): Filament writes
 * --sidebar-width as an inline style on <html>, which no stylesheet can beat.
 *
 * Trap worth remembering: the sidebar element carries BOTH .fi-sidebar and
 * .fi-main-sidebar. Never make .fi-main-sidebar transparent - it zeroes the
 * navy set below.
 *
 * Every direction sensitive rule is a logical property, so Arabic RTL mirrors
 * without a second stylesheet.
 */

:root {
    --ronia-topbar-height: 3.25rem;
}

/* --------------------------------------------------------- shell geometry */

/*
 * The reference puts the sidebar in the top left corner: it owns the full
 * height of the window, brand block included, and the topbar spans only the
 * width left over. Filament stacks them the other way - a full width topbar
 * across the top with .fi-layout (sidebar + content) beneath it - so on
 * desktop the two are re-seated here.
 *
 * The topbar is moved off the sidebar's column, the layout row is pulled up
 * underneath it, and the content column gets that height back as padding.
 * Below the sidebar breakpoint none of this applies: there the sidebar is a
 * fixed overlay and the topbar has to keep the whole width.
 */
@media (min-width: 1024px) {
    .fi-body-has-navigation .fi-topbar-ctn {
        margin-inline-start: var(--sidebar-width);
    }

    .fi-body-has-navigation .fi-layout {
        margin-block-start: calc(-1 * var(--ronia-topbar-height));
    }

    .fi-body-has-navigation .fi-main-ctn {
        padding-block-start: var(--ronia-topbar-height);
    }

    .fi-body-has-topbar .fi-sidebar {
        top: 0;
        height: 100dvh;
    }
}

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

.dark .fi-sidebar {
    background-color: #0f1a30;
    border-inline-end: 1px solid #243453;
}

/*
 * Light mode keeps a LIGHT sidebar. The navy-in-daylight version was reviewed
 * and rejected; it must not come back.
 */
:root:not(.dark) .fi-sidebar {
    background-color: #fff;
    border-inline-end: 1px solid oklch(0.9 0.01 262);
}

.fi-sidebar-nav {
    padding-inline: 1rem;
    padding-block: 0.25rem 1.25rem;
    row-gap: 0.25rem;
}

.fi-sidebar-nav-groups,
.fi-sidebar-group {
    row-gap: 0.25rem;
}

/* ------------------------------------------------------ sidebar brand block */

/*
 * Filament prints the brand twice down the sidebar: once as the text logo in
 * the header, once as the tenant name in the switcher under it. The reference
 * has a single brand block, so the header goes and the switcher becomes it -
 * gold tile, name, tagline - while staying the tenant switcher it was.
 */
.fi-sidebar-header-ctn {
    display: none;
}

.fi-sidebar .fi-tenant-menu {
    /* Filament indents this block with its own margins; the brand block is
       aligned to the nav below it instead, so padding does the whole job. */
    margin: 0;
    padding-inline: 1rem;
    padding-block: 1.125rem 0.75rem;
}

.fi-sidebar .fi-tenant-menu-trigger {
    justify-content: flex-start;
    column-gap: 0.625rem;
    padding: 0.375rem;
    text-align: start;
}

.dark .fi-tenant-menu-trigger:hover,
.dark .fi-tenant-menu-trigger:focus-visible {
    background-color: #152238;
}

.fi-sidebar .fi-tenant-avatar {
    width: 2.375rem;
    height: 2.375rem;
    border-radius: 0.625rem;
    flex-shrink: 0;
}

/*
 * Filament renders the tenant label above the tenant name. The design wants
 * the name first with the tagline beneath, so the column is reversed here
 * rather than the vendor template being forked for one line of markup.
 */
.fi-tenant-menu-trigger-text {
    display: flex;
    flex-direction: column-reverse;
    align-items: flex-start;
    row-gap: 0.0625rem;
    min-width: 0;
}

.fi-tenant-menu-trigger-tenant-name {
    font-size: 0.875rem;
    font-weight: 800;
    line-height: 1.2;
    /* Agency names are longer than the demo's two words and are written in
       three scripts; wrapping beats an ellipsis that hides which agency you
       are looking at. */
    white-space: normal;
    overflow-wrap: anywhere;
}

.dark .fi-tenant-menu-trigger-tenant-name {
    color: #e9edf5;
}

.fi-tenant-menu-trigger-current-tenant-label {
    font-size: 0.6875rem;
    font-weight: 500;
    line-height: 1.35;
}

.dark .fi-tenant-menu-trigger-current-tenant-label {
    color: #9fb0c9;
}

:root:not(.dark) .fi-tenant-menu-trigger-current-tenant-label {
    color: oklch(0.55 0.02 260);
}

.fi-tenant-menu-trigger > .fi-icon {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
    margin-inline-start: auto;
}

.dark .fi-tenant-menu-trigger > .fi-icon {
    color: #9fb0c9;
}

/* -------------------------------------------------------- sidebar nav items */

.fi-sidebar-item-btn {
    justify-content: flex-start;
    column-gap: 0.625rem;
    border-radius: 0.625rem;
    padding: 0.6875rem 0.75rem;
}

.fi-sidebar-item-label {
    font-size: 0.875rem;
    font-weight: 600;
}

.fi-sidebar-item-icon {
    width: 1.1875rem;
    height: 1.1875rem;
    flex-shrink: 0;
}

.dark .fi-sidebar-item-label,
.dark .fi-sidebar-item-icon {
    color: #9fb0c9;
}

:root:not(.dark) .fi-sidebar-item-label {
    color: oklch(0.42 0.02 260);
}

:root:not(.dark) .fi-sidebar-item-icon {
    color: oklch(0.55 0.02 260);
}

.dark .fi-sidebar-item:not(.fi-active) > .fi-sidebar-item-btn:hover {
    background-color: #152238;
}

.dark .fi-sidebar-item:not(.fi-active) > .fi-sidebar-item-btn:hover .fi-sidebar-item-label,
.dark .fi-sidebar-item:not(.fi-active) > .fi-sidebar-item-btn:hover .fi-sidebar-item-icon {
    color: #e9edf5;
}

:root:not(.dark) .fi-sidebar-item:not(.fi-active) > .fi-sidebar-item-btn:hover {
    background-color: oklch(0.965 0.004 260);
}

/*
 * Active item: a lighter navy plate with a gold label and a gold icon. Gold
 * marks where you are and nothing else - no bar, no border, no outline, the
 * way the reference draws it.
 */
.dark .fi-sidebar-item.fi-active > .fi-sidebar-item-btn {
    background-color: #1c2c47;
}

.dark .fi-sidebar-item.fi-active .fi-sidebar-item-label {
    color: #e0bd4f !important;
}

.dark .fi-sidebar-item.fi-active .fi-sidebar-item-icon {
    color: #c9a227 !important;
}

/*
 * Light mode: same structure, light surfaces. Bright gold on white is 2.4:1,
 * so the active label and icon take a deeper bronze of the same hue (5.1:1 on
 * the warm wash behind them).
 */
:root:not(.dark) .fi-sidebar-item.fi-active > .fi-sidebar-item-btn {
    background-color: oklch(0.955 0.032 92);
}

:root:not(.dark) .fi-sidebar-item.fi-active .fi-sidebar-item-label,
:root:not(.dark) .fi-sidebar-item.fi-active .fi-sidebar-item-icon {
    color: oklch(0.5 0.11 88) !important;
}

/* ------------------------------------------------------------------ topbar */

/*
 * Slim and translucent: 52px instead of Filament's 64, no drop shadow, a hair
 * line instead of the default ring, and blur behind it so content scrolling
 * under it stays legible.
 */
.fi-topbar {
    min-height: 3.25rem;
    padding-inline: 1.25rem;
    column-gap: 0.75rem;
    box-shadow: none;
    --tw-ring-shadow: 0 0 #0000;
}

.dark .fi-topbar {
    background-color: color-mix(in oklab, #0f1a30 92%, transparent);
    backdrop-filter: blur(8px);
    border-block-end: 1px solid #243453;
}

:root:not(.dark) .fi-topbar {
    background-color: color-mix(in oklab, #fff 88%, transparent);
    backdrop-filter: blur(8px);
    border-block-end: 1px solid oklch(0.91 0.008 255);
}

/*
 * On desktop the sidebar carries the brand, so the topbar's copy of the logo
 * is a second answer to a question nobody asked. Below the sidebar breakpoint
 * it comes back, because there it is the only brand on screen.
 */
@media (min-width: 1024px) {
    .fi-topbar-start {
        display: none;
    }
}

/* Our own controls sit after the logo slot; the end block stays last. */
.ronia-topbar-controls {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
    order: 1;
}

.fi-topbar-end {
    order: 2;
    column-gap: 0.75rem;
}

/* ------------------------------------------------------- language switcher */

.ronia-lang-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.125rem;
    padding: 3px;
    border-radius: 999px;
    border: 1px solid transparent;
}

.dark .ronia-lang-switch {
    background-color: #152238;
    border-color: #243453;
}

:root:not(.dark) .ronia-lang-switch {
    background-color: oklch(0.965 0.004 260);
    border-color: oklch(0.9 0.008 260);
}

.ronia-lang-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.25rem;
    padding: 0.3125rem 0.6875rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.dark .ronia-lang-btn {
    color: #9fb0c9;
}

:root:not(.dark) .ronia-lang-btn {
    color: oklch(0.45 0.02 260);
}

.dark .ronia-lang-btn:hover {
    color: #e9edf5;
}

:root:not(.dark) .ronia-lang-btn:hover {
    color: oklch(0.28 0.02 260);
}

/* Placed last on purpose: the gold plate has to survive the hover rules. */
.dark .ronia-lang-btn-active,
.dark .ronia-lang-btn-active:hover,
:root:not(.dark) .ronia-lang-btn-active,
:root:not(.dark) .ronia-lang-btn-active:hover {
    background-image: linear-gradient(135deg, #e0bd4f, #c9a227);
    color: #171208;
}

/* ------------------------------------------------------------ office filter */

.ronia-office-filter {
    display: inline-flex;
    min-width: 0;
}

.ronia-office-select {
    /* Without a floor it is the first thing a crowded topbar squeezes to
       nothing, which reads as "the filter disappeared". */
    min-width: 7rem;
    max-width: 14rem;
    border-radius: 0.625rem;
    border: 1px solid transparent;
    padding: 0.4375rem 0.625rem;
    font-family: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1.25;
}

.dark .ronia-office-select {
    background-color: #152238;
    border-color: #243453;
    color: #e9edf5;
    /* Makes the native option list dark too, instead of a white flash. */
    color-scheme: dark;
}

:root:not(.dark) .ronia-office-select {
    background-color: #fff;
    border-color: oklch(0.9 0.008 260);
    color: oklch(0.28 0.02 260);
    color-scheme: light;
}

/*
 * Below the sidebar breakpoint the topbar has to hold the menu button, search,
 * the bell, the avatar and these two controls in one row, which is one row too
 * many. It wraps instead, the way the reference stacks its topbar on a phone,
 * so nothing is squeezed out of existence.
 */
@media (max-width: 1023px) {
    .fi-topbar {
        flex-wrap: wrap;
        row-gap: 0.5rem;
        padding-block: 0.5rem;
    }

    .ronia-topbar-controls {
        order: 3;
        width: 100%;
    }

    .ronia-office-select {
        max-width: 10rem;
    }
}

/* ------------------------------------------- global search and the bell */

/* Both stay, both get quieter: a pill on the topbar surface rather than a
   full input with its own ring. */
.fi-topbar .fi-global-search-field .fi-input-wrp {
    border-radius: 999px;
    border: 1px solid transparent;
    box-shadow: none;
    --tw-ring-shadow: 0 0 #0000;
}

.dark .fi-topbar .fi-global-search-field .fi-input-wrp {
    background-color: #152238;
    border-color: #243453;
}

:root:not(.dark) .fi-topbar .fi-global-search-field .fi-input-wrp {
    background-color: oklch(0.965 0.004 260);
    border-color: oklch(0.9 0.008 260);
}

.fi-topbar .fi-global-search-field .fi-input {
    font-size: 0.8125rem;
    padding-block: 0.375rem;
}

.dark .fi-topbar-database-notifications-btn .fi-icon {
    color: #9fb0c9;
}

:root:not(.dark) .fi-topbar-database-notifications-btn .fi-icon {
    color: oklch(0.5 0.02 260);
}

/* ------------------------------------------------------- cards and panels */

.fi-section,
.fi-wi-widget .fi-section,
.fi-ta-ctn {
    border-radius: 0.9rem;
}

.dark .fi-section:not(.fi-section-not-contained),
.dark .fi-ta-ctn,
.dark .fi-wi-stats-overview-stat {
    /* Round 2 after real-screen feedback: the whisper borders of round 1
       vanished on Bas's monitor. Edges are now explicit - a solid visible
       border plus a gold accent on the top edge, the same treatment as the
       login card, so every box declares itself. Filament's own dark ring is
       white/10 (a harsh light wire on navy) and is re-tinted to match.

       fi-section-not-contained is excluded on purpose: Filament uses it as an
       INVISIBLE layout wrapper (the stats grid sits inside one), and boxing
       it drew a second frame around the row of stat tiles - the "double
       square" Bas reported. A wrapper is not a card.

       No gold on card edges: in the reference demo the boxes are drawn by a
       steel-blue border and a lighter surface, and gold is reserved for the
       active nav item, the heading dots and the data itself. The gold top
       edge from the earlier round read as decoration the demo never had. */
    background-color: oklch(0.21 0.042 262);
    --tw-ring-color: oklch(0.34 0.05 262);
    border: 1px solid oklch(0.34 0.05 262);
    box-shadow: 0 1px 2px rgb(0 0 0 / 0.3), 0 10px 28px -12px rgb(0 0 0 / 0.45);
}

.dark .fi-section-not-contained {
    background-color: transparent;
    border: none;
    box-shadow: none;
    --tw-ring-color: transparent;
}

:root:not(.dark) .fi-section:not(.fi-section-not-contained),
:root:not(.dark) .fi-ta-ctn,
:root:not(.dark) .fi-wi-stats-overview-stat {
    border: 1px solid oklch(0.88 0.012 262);
    box-shadow: 0 1px 2px rgb(15 27 45 / 0.05), 0 8px 20px -14px rgb(15 27 45 / 0.12);
}

:root:not(.dark) .fi-section-not-contained {
    background-color: transparent;
    border: none;
    box-shadow: none;
    --tw-ring-color: transparent;
}

/* ------------------------------------------------------------- stat tiles */

.fi-wi-stats-overview-stat {
    border-radius: 0.9rem;
    transition: transform 120ms ease, box-shadow 120ms ease;
}

.fi-wi-stats-overview-stat:hover {
    transform: translateY(-1px);
}

.fi-wi-stats-overview-stat-label {
    font-size: 0.78rem;
    letter-spacing: 0.02em;
    color: oklch(0.55 0.03 260);
}

.dark .fi-wi-stats-overview-stat-label {
    color: oklch(0.72 0.03 258);
}

.fi-wi-stats-overview-stat-value {
    font-weight: 700;
    letter-spacing: -0.01em;
}

/* Stat cards rebuilt to the demo's anatomy: colored icon chip on top, the
   big number under it, the muted label at the bottom.

   The markup renders label and icon together inside label-ctn with the value
   after them, so label-ctn is dissolved with display:contents and the three
   pieces are reordered with flex order. */
.fi-wi-stats-overview-stat {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.6rem;
}

.fi-wi-stats-overview-stat-label-ctn {
    display: contents;
}

.fi-wi-stats-overview-stat .fi-wi-stats-overview-stat-label-ctn > .fi-icon {
    order: 1;
    box-sizing: content-box;
    width: 1.3rem;
    height: 1.3rem;
    padding: 0.5rem;
    border-radius: 0.65rem;
}

.fi-wi-stats-overview-stat-value {
    order: 2;
    font-size: 2rem;
    line-height: 1.1;
}

.fi-wi-stats-overview-stat-label {
    order: 3;
}

.fi-wi-stats-overview-stat-description {
    order: 4;
}

/* One chip color per stat, like the demo's green/blue/gold/red cards.
   Position, not meaning, keys the color: the stats render in a fixed order
   (cases, clients, appointments, expiring, pending, open tasks), and these
   are identity accents, not status signals. */
.fi-wi-stats-overview .fi-grid-col:nth-child(6n + 1) .fi-wi-stats-overview-stat .fi-icon {
    color: oklch(0.75 0.12 250);
    background-color: color-mix(in oklab, oklch(0.65 0.15 250) 16%, transparent);
}

.fi-wi-stats-overview .fi-grid-col:nth-child(6n + 2) .fi-wi-stats-overview-stat .fi-icon {
    color: oklch(0.78 0.14 155);
    background-color: color-mix(in oklab, oklch(0.68 0.16 155) 16%, transparent);
}

.fi-wi-stats-overview .fi-grid-col:nth-child(6n + 3) .fi-wi-stats-overview-stat .fi-icon {
    color: oklch(0.78 0.13 90);
    background-color: color-mix(in oklab, oklch(0.72 0.135 90) 16%, transparent);
}

.fi-wi-stats-overview .fi-grid-col:nth-child(6n + 4) .fi-wi-stats-overview-stat .fi-icon {
    color: oklch(0.72 0.16 25);
    background-color: color-mix(in oklab, oklch(0.64 0.19 25) 16%, transparent);
}

.fi-wi-stats-overview .fi-grid-col:nth-child(6n + 5) .fi-wi-stats-overview-stat .fi-icon {
    color: oklch(0.74 0.12 300);
    background-color: color-mix(in oklab, oklch(0.65 0.15 300) 16%, transparent);
}

.fi-wi-stats-overview .fi-grid-col:nth-child(6n + 6) .fi-wi-stats-overview-stat .fi-icon {
    color: oklch(0.76 0.11 185);
    background-color: color-mix(in oklab, oklch(0.68 0.13 185) 16%, transparent);
}

/* Section and widget headings carry the demo's gold dot marker, one shared
   visual cue that says "a box starts here" in both modes and both directions. */
.fi-section-header-heading::before,
.fi-ta-header-heading::before {
    content: '';
    display: inline-block;
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 9999px;
    background-color: oklch(0.72 0.135 90);
    margin-inline-end: 0.5rem;
    vertical-align: 0.12em;
}

/* ----------------------------------------------------------------- tables */

/* Table headers stay normal case and quiet, as in the demo. Uppercase was
   tried and dropped: it fights Arabic, which has no case at all. */
.fi-ta-header-cell {
    font-size: 0.78rem;
}

.dark .fi-ta-row:hover {
    background-color: color-mix(in oklab, oklch(0.285 0.042 262) 55%, transparent);
}

:root:not(.dark) .fi-ta-row:hover {
    background-color: oklch(0.975 0.006 262);
}

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

.fi-btn {
    transition: filter 120ms ease, box-shadow 120ms ease;
}

.fi-btn:hover {
    filter: brightness(1.05);
}

/* Primary buttons carry a faint gold glow so the page's one main action
   reads first. Filament already puts dark text on the gold fill. */
.fi-btn.fi-color-primary {
    box-shadow: 0 1px 2px rgb(0 0 0 / 0.1), 0 4px 14px -6px oklch(0.68 0.17 90 / 0.5);
}

/* ------------------------------------------------------------- login page */

.fi-simple-layout {
    background:
        radial-gradient(60rem 32rem at 15% -10%, oklch(0.32 0.06 262 / 0.5), transparent 60%),
        radial-gradient(50rem 30rem at 110% 110%, oklch(0.62 0.12 90 / 0.14), transparent 55%),
        oklch(0.96 0.005 255);
}

.dark .fi-simple-layout {
    background:
        radial-gradient(60rem 32rem at 15% -10%, oklch(0.30 0.06 262 / 0.6), transparent 60%),
        radial-gradient(50rem 30rem at 110% 110%, oklch(0.62 0.12 90 / 0.10), transparent 55%),
        oklch(0.14 0.04 262);
}

.fi-simple-main {
    border-block-start: 3px solid oklch(0.75 0.135 90);
    border-start-start-radius: 0.9rem;
    border-start-end-radius: 0.9rem;
    box-shadow: 0 1px 3px rgb(15 27 45 / 0.08), 0 24px 48px -24px rgb(15 27 45 / 0.35);
}

.fi-simple-header-heading {
    font-weight: 700;
}

/* ------------------------------------------------------------- scrollbars */

.dark ::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

.dark ::-webkit-scrollbar-thumb {
    background-color: oklch(0.32 0.04 262);
    border-radius: 5px;
    border: 2px solid oklch(0.17 0.042 262);
}

.dark ::-webkit-scrollbar-track {
    background-color: transparent;
}

/* ====================================================== client files module

   The client list and the client file page, rebuilt to the approved demo:
   dark navy surfaces, steel-blue edges, and gold used for exactly four things
   - the active filter chip, completed stage segments, the primary button, and
   data accents. Everything else is text and quiet borders.

   Both modes are real: the custom properties below are the light values and
   are restated once under .dark. Every direction-sensitive rule uses logical
   properties, so Arabic mirrors without a second stylesheet.
   ------------------------------------------------------------------------ */

.ronia-cards,
.ronia-file,
.ronia-settings-launcher,
.ronia-settings-overlay {
    --ronia-surface: #fff;
    --ronia-raised: oklch(0.975 0.006 262);
    --ronia-border: oklch(0.88 0.012 262);
    --ronia-text: oklch(0.28 0.03 262);
    --ronia-dim: oklch(0.52 0.025 262);
    /* Bright gold is 2.4:1 on white, so light mode says gold in bronze. */
    --ronia-gold-text: oklch(0.5 0.11 88);
    --ronia-gold: oklch(0.72 0.135 90);
    --ronia-amber: oklch(0.68 0.15 75);
    --ronia-green: oklch(0.52 0.13 155);
    --ronia-red: oklch(0.53 0.19 25);
    --ronia-blue: oklch(0.5 0.15 250);
    --ronia-track: oklch(0.91 0.01 262);
    --ronia-radius: 0.9rem;
}

.dark .ronia-cards,
.dark .ronia-file,
.dark .ronia-settings-launcher,
.dark .ronia-settings-overlay {
    --ronia-surface: oklch(0.21 0.042 262);
    --ronia-raised: oklch(0.255 0.042 262);
    --ronia-border: oklch(0.34 0.05 262);
    --ronia-text: oklch(0.93 0.012 258);
    --ronia-dim: oklch(0.72 0.03 258);
    --ronia-gold-text: oklch(0.8 0.12 90);
    --ronia-gold: oklch(0.75 0.135 90);
    --ronia-amber: oklch(0.78 0.14 78);
    --ronia-green: oklch(0.78 0.14 155);
    --ronia-red: oklch(0.7 0.16 25);
    --ronia-blue: oklch(0.7 0.13 250);
    --ronia-track: oklch(0.3 0.045 262);
}

/* ------------------------------------------------------------- the pills */

.ronia-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.1rem 0.55rem;
    border-radius: 9999px;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.5;
    white-space: nowrap;
}

.ronia-pill-blue {
    color: var(--ronia-blue);
    background-color: color-mix(in oklab, var(--ronia-blue) 15%, transparent);
}

.ronia-pill-gray {
    color: var(--ronia-dim);
    background-color: color-mix(in oklab, var(--ronia-dim) 15%, transparent);
}

.ronia-pill-green {
    color: var(--ronia-green);
    background-color: color-mix(in oklab, var(--ronia-green) 15%, transparent);
}

.ronia-pill-amber {
    color: var(--ronia-amber);
    background-color: color-mix(in oklab, var(--ronia-amber) 15%, transparent);
}

.ronia-pill-red {
    color: var(--ronia-red);
    background-color: color-mix(in oklab, var(--ronia-red) 15%, transparent);
}

/* ---------------------------------------------------------- the card list */

.ronia-cards {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    color: var(--ronia-text);
}

.ronia-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--ronia-border);
    border-radius: var(--ronia-radius);
    background-color: var(--ronia-surface);
    transition: border-color 120ms ease, transform 120ms ease;
}

.ronia-card:hover {
    border-color: var(--ronia-gold);
    transform: translateY(-1px);
}

/* The whole card opens the file. An overlay link rather than a wrapping
   anchor, so the Show/Hide button inside stays a real button and its click
   never navigates. */
.ronia-card-hit {
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: var(--ronia-radius);
}

.ronia-card > *:not(.ronia-card-hit) {
    position: relative;
    z-index: 2;
    pointer-events: none;
}

.ronia-card a,
.ronia-card button {
    pointer-events: auto;
}

.ronia-card-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
}

.ronia-card-identity {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    min-width: 0;
}

.ronia-card-name-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.ronia-card-name {
    font-size: 0.925rem;
    font-weight: 800;
}

.ronia-card-passport,
.ronia-field-payment {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.ronia-passport-value {
    font-size: 0.8rem;
    color: var(--ronia-dim);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
}

.ronia-reveal {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    padding: 0.1rem 0.5rem;
    border: 1px solid var(--ronia-border);
    border-radius: 9999px;
    background-color: var(--ronia-raised);
    color: var(--ronia-gold-text);
    font-size: 0.7rem;
    font-weight: 700;
    cursor: pointer;
}

.ronia-reveal:hover {
    border-color: var(--ronia-gold);
}

.ronia-reveal-icon {
    inline-size: 0.8rem;
    block-size: 0.8rem;
}

.ronia-card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    font-size: 0.75rem;
    color: var(--ronia-dim);
}

/* The card's end-side column at the top: status pill, then the money block,
   level with the identity so the big figure spends height the name and
   passport rows already paid for (Bas, 2026-09-05: the number stays big and
   stays on top). Logical properties mirror it to the left in Arabic from
   this one rule; no [dir='rtl'] override, and none should be added - the day
   one appears, the other one is forgotten. */
.ronia-card-side {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.3rem;
    margin-inline-start: auto;
    text-align: end;
    flex: none;
}

/* The money under the pill.

   Every colour is a --ronia-* token, and those are declared twice already
   (.ronia-cards / .ronia-file, then again under .dark), so this block is
   correct in both modes without restating either prefix - unlike an override
   of the .fi-ta-ctn card treatment, which must repeat both. */
.ronia-card-money {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    text-align: end;
    gap: 0.05rem;
    line-height: 1.2;
}

/* The figure the office acts on. Big enough to read across a desk, which is
   the whole point of keeping it out of the meta line. */
.ronia-money-lead {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
}

.ronia-money-lead-label {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--ronia-dim);
    text-transform: none;
}

.ronia-money-lead-value {
    font-size: 1.35rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
}

/* Red while money is owed, green once nothing is. Both are statements of
   fact rather than decoration: the red is the office's to-do list. */
.ronia-money-due {
    color: var(--ronia-red);
}

.ronia-money-settled {
    color: var(--ronia-green);
}

/* Paid and Total: the context around the number, deliberately quiet. */
.ronia-money-rest {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: baseline;
    gap: 0.1rem 0.4rem;
    font-size: 0.72rem;
    color: var(--ronia-dim);
}

.ronia-money-part {
    display: inline-flex;
    align-items: baseline;
    gap: 0.25rem;
    white-space: nowrap;
}

.ronia-money-label {
    color: var(--ronia-dim);
}

.ronia-money-value {
    color: var(--ronia-text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Kept for the Payments block in the client file, which still colours its
   Paid and Remaining figures. The card no longer uses these two. */
.ronia-money-paid {
    color: var(--ronia-green);
}

.ronia-money-remaining {
    color: var(--ronia-red);
}

/* Visible enough to separate the two small figures, quiet enough not to be
   read as a third one. --ronia-border is too faint here; this is the dim ink
   held back instead. */
.ronia-money-sep {
    color: var(--ronia-dim);
    opacity: 0.65;
}

/* Segmented progress: gold behind, amber where the file is now, dim ahead. */
.ronia-stepper-mini {
    display: flex;
    gap: 4px;
}

.ronia-seg {
    flex: 1;
    block-size: 5px;
    border-radius: 9999px;
    background-color: var(--ronia-track);
}

.ronia-seg-done {
    background-color: var(--ronia-gold);
}

.ronia-seg-current {
    background-color: var(--ronia-amber);
}

.ronia-card-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.35rem 1rem;
    padding-block-start: 0.55rem;
    border-block-start: 1px solid var(--ronia-border);
    font-size: 0.72rem;
    color: var(--ronia-dim);
}

.ronia-foot-docs {
    font-weight: 700;
}

.ronia-danger {
    color: var(--ronia-red);
}

.ronia-success {
    color: var(--ronia-green);
}

/* Filter chips: the list page's tabs, rounded, gold only when active. */
.fi-resource-clients.fi-resource-list-records-page .fi-tabs {
    flex-wrap: wrap;
    gap: 0.5rem;
    border: 0;
    box-shadow: none;
}

.fi-resource-clients.fi-resource-list-records-page .fi-tabs-item {
    border: 1px solid oklch(0.88 0.012 262);
    border-radius: 9999px;
    padding-inline: 0.9rem;
}

.dark .fi-resource-clients.fi-resource-list-records-page .fi-tabs-item {
    border-color: oklch(0.34 0.05 262);
}

.fi-resource-clients.fi-resource-list-records-page .fi-tabs-item.fi-active {
    background-color: oklch(0.75 0.135 90);
    border-color: oklch(0.75 0.135 90);
}

.fi-resource-clients.fi-resource-list-records-page .fi-tabs-item.fi-active .fi-tabs-item-label {
    color: oklch(0.2 0.03 262);
    font-weight: 700;
}

/* ------------------------------------------------------- the file page */

.ronia-file {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    color: var(--ronia-text);
}

.ronia-file-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.ronia-file-head-tags {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.ronia-back {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--ronia-dim);
}

.ronia-back:hover {
    color: var(--ronia-gold-text);
}

/* The chevron points at the reading edge, so it flips with the document. */
.ronia-back-icon {
    inline-size: 1rem;
    block-size: 1rem;
}

[dir='rtl'] .ronia-back-icon {
    transform: scaleX(-1);
}

.ronia-highlights {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.75rem;
}

.ronia-highlight {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.85rem 1rem;
    border-radius: var(--ronia-radius);
    border: 1px solid var(--ronia-border);
    background-color: var(--ronia-surface);
}

.ronia-highlight-blue {
    border-color: color-mix(in oklab, var(--ronia-blue) 35%, transparent);
    background-color: color-mix(in oklab, var(--ronia-blue) 10%, var(--ronia-surface));
}

.ronia-highlight-gold {
    border-color: color-mix(in oklab, var(--ronia-gold) 35%, transparent);
    background-color: color-mix(in oklab, var(--ronia-gold) 10%, var(--ronia-surface));
}

.ronia-highlight-icon {
    inline-size: 1.25rem;
    block-size: 1.25rem;
    color: var(--ronia-dim);
}

.ronia-highlight-blue .ronia-highlight-icon {
    color: var(--ronia-blue);
}

.ronia-highlight-gold .ronia-highlight-icon {
    color: var(--ronia-gold-text);
}

.ronia-highlight-label,
.ronia-field-label {
    font-size: 0.72rem;
    color: var(--ronia-dim);
}

.ronia-highlight-value {
    font-size: 0.95rem;
    font-weight: 800;
}

.ronia-highlight-note {
    font-size: 0.7rem;
    color: var(--ronia-dim);
}

.ronia-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 0.6rem;
}

.ronia-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 0.65rem 0.8rem;
    border-radius: 0.7rem;
    border: 1px solid var(--ronia-border);
    background-color: var(--ronia-raised);
}

.ronia-field-value {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    font-size: 0.85rem;
    font-weight: 700;
}

.ronia-amount {
    font-variant-numeric: tabular-nums;
    color: var(--ronia-gold-text);
}

.ronia-block {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1rem 1.1rem;
    border: 1px solid var(--ronia-border);
    border-radius: var(--ronia-radius);
    background-color: var(--ronia-surface);
}

/* The same gold dot the panel's section headings carry, so a block on this
   page reads as the same kind of box as everywhere else. */
.ronia-block-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.9rem;
    font-weight: 700;
}

.ronia-block-title::before {
    content: '';
    inline-size: 0.45rem;
    block-size: 0.45rem;
    border-radius: 9999px;
    background-color: var(--ronia-gold);
}

.ronia-block-action {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.ronia-muted {
    font-size: 0.8rem;
    color: var(--ronia-dim);
}

/* ----------------------------------------------------------- payments

   The block on the client file: one summary per case, then that case's
   receipts. Same tokens as the rest of the file, so it inherits both modes
   from the .ronia-file / .dark .ronia-file declarations at the top; and
   every box uses logical properties, so Arabic mirrors it without a rule
   of its own. .ronia-money-paid / -remaining are shared with the card line
   above, deliberately: one definition of "green means money came in". */

.ronia-pay-case {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

/* Two cases in one block need air between them, and a line to say where one
   quote stops and the next begins. */
.ronia-pay-case + .ronia-pay-case {
    padding-block-start: 0.9rem;
    margin-block-start: 0.3rem;
    border-block-start: 1px solid var(--ronia-border);
}

.ronia-pay-case-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.2rem 0.6rem;
    font-size: 0.78rem;
}

.ronia-pay-case-ref {
    font-weight: 700;
    color: var(--ronia-text);
}

.ronia-pay-case-service {
    color: var(--ronia-dim);
}

.ronia-pay-summary {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
}

.ronia-pay-figure {
    flex: 1 1 7rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--ronia-border);
    border-radius: 0.6rem;
    background-color: var(--ronia-raised);
}

.ronia-pay-figure dt {
    font-size: 0.7rem;
    color: var(--ronia-dim);
}

.ronia-pay-figure dd {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--ronia-text);
    font-variant-numeric: tabular-nums;
}

/* The element selector above is (0,1,1) and .ronia-money-paid is (0,1,0), so
   the shared card classes lose here on their own. Restated at the same
   specificity rather than with !important: green and red have to mean the
   same thing in the block as they do on the card. */
.ronia-pay-figure dd.ronia-money-paid {
    color: var(--ronia-green);
}

.ronia-pay-figure dd.ronia-money-remaining {
    color: var(--ronia-red);
}

/* The history is a real table so a screen reader gets the header row, but it
   sits inside a card and must not draw a second frame around itself. */
.ronia-pay-history {
    overflow-x: auto;
}

.ronia-pay-table {
    inline-size: 100%;
    border-collapse: collapse;
    font-size: 0.78rem;
}

.ronia-pay-caption {
    text-align: start;
    padding-block-end: 0.35rem;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--ronia-dim);
}

.ronia-pay-table th {
    text-align: start;
    font-weight: 700;
    color: var(--ronia-dim);
    padding: 0.35rem 0.5rem;
    border-block-end: 1px solid var(--ronia-border);
    white-space: nowrap;
}

.ronia-pay-table td {
    padding: 0.4rem 0.5rem;
    border-block-end: 1px solid var(--ronia-border);
    color: var(--ronia-text);
    vertical-align: top;
}

.ronia-pay-table tr:last-child td {
    border-block-end: 0;
}

.ronia-pay-amount {
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.ronia-pay-note {
    color: var(--ronia-dim);
}

/* ------------------------------------------------------- stage stepper */

.ronia-stepper {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ronia-step {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    flex: 1 1 5rem;
    min-inline-size: 5rem;
    text-align: center;
}

.ronia-step-dot {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 1.6rem;
    block-size: 1.6rem;
    border-radius: 9999px;
    background-color: var(--ronia-track);
    color: var(--ronia-dim);
    font-size: 0.75rem;
    font-weight: 700;
}

.ronia-step-done .ronia-step-dot {
    background-color: var(--ronia-gold);
    color: oklch(0.2 0.03 262);
}

.ronia-step-current .ronia-step-dot {
    background-color: var(--ronia-amber);
    color: oklch(0.2 0.03 262);
}

.ronia-step-check {
    inline-size: 0.9rem;
    block-size: 0.9rem;
}

.ronia-step-label {
    font-size: 0.65rem;
    color: var(--ronia-dim);
    line-height: 1.3;
}

.ronia-step-done .ronia-step-label,
.ronia-step-current .ronia-step-label {
    color: var(--ronia-text);
    font-weight: 700;
}

/* --------------------------------------------------- post-arrival steps */

.ronia-checklist,
.ronia-doc-checklist,
.ronia-notes,
.ronia-timeline {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ronia-check {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    text-align: start;
}

.ronia-check[disabled] {
    cursor: default;
    opacity: 0.7;
}

.ronia-check-box {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 1.05rem;
    block-size: 1.05rem;
    border-radius: 0.35rem;
    border: 1px solid var(--ronia-border);
    background-color: var(--ronia-raised);
}

.ronia-check-box-on {
    background-color: var(--ronia-gold);
    border-color: var(--ronia-gold);
    color: oklch(0.2 0.03 262);
}

.ronia-check-icon {
    inline-size: 0.75rem;
    block-size: 0.75rem;
}

.ronia-check-label {
    font-size: 0.82rem;
    color: var(--ronia-dim);
}

.ronia-check-label-on {
    color: var(--ronia-text);
    font-weight: 600;
}

/* ----------------------------------------------------------- documents */

.ronia-progress {
    inline-size: 100%;
    block-size: 7px;
    border-radius: 9999px;
    background-color: var(--ronia-track);
    overflow: hidden;
}

.ronia-progress-fill {
    display: block;
    block-size: 100%;
    border-radius: 9999px;
    background-image: linear-gradient(90deg, var(--ronia-gold), oklch(0.82 0.12 92));
}

[dir='rtl'] .ronia-progress-fill {
    background-image: linear-gradient(270deg, var(--ronia-gold), oklch(0.82 0.12 92));
}

.ronia-doc-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding-block: 0.35rem;
}

.ronia-doc-name {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.82rem;
    color: var(--ronia-dim);
}

.ronia-doc-name-done {
    color: var(--ronia-text);
}

.ronia-doc-check {
    inline-size: 1rem;
    block-size: 1rem;
    color: var(--ronia-green);
}

.ronia-doc-missing {
    inline-size: 1rem;
    block-size: 1rem;
    color: var(--ronia-dim);
}

.ronia-doc-action {
    margin-inline-start: auto;
}

.ronia-attach,
.ronia-link {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--ronia-gold-text);
    padding: 0.1rem 0.5rem;
    border-radius: 9999px;
    background-color: color-mix(in oklab, var(--ronia-gold) 12%, transparent);
}

.ronia-attach-icon,
.ronia-link-icon {
    inline-size: 0.85rem;
    block-size: 0.85rem;
}

.ronia-doc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 0.75rem;
}

.ronia-doc-card {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.6rem;
    border: 1px solid var(--ronia-border);
    border-radius: 0.7rem;
    background-color: var(--ronia-raised);
}

.ronia-doc-thumb {
    display: flex;
    align-items: center;
    justify-content: center;
    block-size: 7rem;
    border-radius: 0.5rem;
    background-color: var(--ronia-track);
    overflow: hidden;
}

.ronia-doc-thumb img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
}

.ronia-doc-thumb-icon {
    inline-size: 2rem;
    block-size: 2rem;
    color: var(--ronia-dim);
}

.ronia-doc-type {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--ronia-gold-text);
}

.ronia-doc-file {
    font-size: 0.8rem;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.ronia-doc-sub {
    font-size: 0.68rem;
    color: var(--ronia-dim);
}

.ronia-doc-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    padding-block-start: 0.3rem;
}

/* ------------------------------------------------------ log and notes */

.ronia-timeline-item {
    padding-inline-start: 0.7rem;
    border-inline-start: 2px solid var(--ronia-gold);
}

.ronia-timeline-date,
.ronia-note-date {
    font-size: 0.68rem;
    color: var(--ronia-dim);
    font-variant-numeric: tabular-nums;
}

.ronia-timeline-text {
    font-size: 0.8rem;
}

.ronia-timeline-causer,
.ronia-note-author {
    font-size: 0.7rem;
    color: var(--ronia-dim);
}

.ronia-note {
    padding-block-end: 0.5rem;
    border-block-end: 1px solid var(--ronia-border);
}

.ronia-note-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.ronia-note-body {
    font-size: 0.82rem;
    margin: 0.2rem 0 0;
    white-space: pre-line;
}

.ronia-note-form {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.ronia-textarea {
    inline-size: 100%;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--ronia-border);
    border-radius: 0.6rem;
    background-color: var(--ronia-raised);
    color: var(--ronia-text);
    font: inherit;
    font-size: 0.85rem;
    resize: vertical;
}

.ronia-textarea:focus {
    outline: 2px solid var(--ronia-gold);
    outline-offset: 1px;
}

.ronia-button {
    align-self: flex-start;
    padding: 0.4rem 0.9rem;
    border: 1px solid var(--ronia-border);
    border-radius: 0.55rem;
    background-color: var(--ronia-raised);
    color: var(--ronia-text);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
}

.ronia-button:hover {
    border-color: var(--ronia-gold);
}

.ronia-button-primary {
    background-color: var(--ronia-gold);
    border-color: var(--ronia-gold);
    color: oklch(0.2 0.03 262);
}

/* Snackbar: every flash notification surfaces through ONE toast at the
   bottom center (Bas, 2026-09-05). Position comes from the panel config
   (Notifications::alignment / verticalAlignment in AppServiceProvider);
   these rules add the one-at-a-time cap, the slide-up entrance, and keep
   the toast off the very edge of the screen. Scoped to .fi-no so the
   database-notifications slide-over is untouched. */
.fi-no {
    padding-bottom: 1.5rem;
}

.fi-no > *:not(:last-child) {
    display: none;
}

.fi-no .fi-no-notification {
    animation: ronia-snackbar-in 0.25s ease-out;
    box-shadow: 0 10px 30px rgb(0 0 0 / 0.35);
    max-width: min(28rem, calc(100vw - 2rem));
}

@keyframes ronia-snackbar-in {
    from {
        opacity: 0;
        transform: translateY(0.75rem);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

/* ------------------------------------------------- the file in a slide-over

   Clicking a card opens the client file in a Filament slide-over instead of
   navigating to the full page. The file's own blocks are unchanged; the three
   rules below only account for the two things a modal changes - there is no
   page backdrop behind the blocks any more, and the click that opens the panel
   costs a round trip that the card should admit to.

   Filament decides which edge the panel comes from, so nothing here names a
   side. Every offset is a logical property, as everywhere above.
   ------------------------------------------------------------------------ */

.ronia-card-busy {
    opacity: 0.6;
}

/* White blocks on a white modal read as one sheet; a step of tint plus the
   border they already have keeps them reading as blocks. */
.ronia-file-panel {
    --ronia-surface: oklch(0.985 0.005 262);
}

.dark .ronia-file-panel {
    --ronia-surface: oklch(0.235 0.042 262);
}

/* In the panel this link is the only way out to Edit and Merge, so it is a
   target rather than a footnote. */
.ronia-file-panel .ronia-back {
    padding-block: 0.3rem;
    padding-inline: 0.7rem;
    border: 1px solid var(--ronia-border);
    border-radius: 9999px;
}
/* ==========================================================================
   Appointments and reminders

   The day sheet from the approved demo: a date picker under the Daily/Weekly
   tabs, the window's appointments on one side and the reminders those same
   appointments own on the other.

   Same navy + gold vocabulary as the client files module, and the same rule
   about gold: it is the primary button and a hover edge, nothing else. Status
   is said in amber / blue / green / red through the shared ronia-pill classes.

   Every direction-sensitive rule uses logical properties, so Arabic mirrors
   without a second stylesheet.
   ========================================================================== */

/* The token set is restated here rather than shared with .ronia-cards: this
   module is appended to the theme, and a rule that reached back up into the
   card list's selector would break the moment either moved. */
.ronia-appts {
    --ronia-surface: #fff;
    --ronia-raised: oklch(0.975 0.006 262);
    --ronia-border: oklch(0.88 0.012 262);
    --ronia-text: oklch(0.28 0.03 262);
    --ronia-dim: oklch(0.52 0.025 262);
    --ronia-gold-text: oklch(0.5 0.11 88);
    --ronia-gold: oklch(0.72 0.135 90);
    --ronia-amber: oklch(0.68 0.15 75);
    --ronia-green: oklch(0.52 0.13 155);
    --ronia-red: oklch(0.53 0.19 25);
    --ronia-blue: oklch(0.5 0.15 250);
    --ronia-track: oklch(0.91 0.01 262);
    --ronia-radius: 0.9rem;

    display: flex;
    flex-direction: column;
    gap: 1rem;
    color: var(--ronia-text);
}

.dark .ronia-appts {
    --ronia-surface: oklch(0.21 0.042 262);
    --ronia-raised: oklch(0.255 0.042 262);
    --ronia-border: oklch(0.34 0.05 262);
    --ronia-text: oklch(0.93 0.012 258);
    --ronia-dim: oklch(0.72 0.03 258);
    --ronia-gold-text: oklch(0.8 0.12 90);
    --ronia-gold: oklch(0.75 0.135 90);
    --ronia-amber: oklch(0.78 0.14 78);
    --ronia-green: oklch(0.78 0.14 155);
    --ronia-red: oklch(0.7 0.16 25);
    --ronia-blue: oklch(0.7 0.13 250);
    --ronia-track: oklch(0.3 0.045 262);
}

/* ------------------------------------------------------- the date picker */

.ronia-appts-controls {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
}

.ronia-appts-date {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-inline-size: 12rem;
}

.ronia-appts-date-label {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--ronia-dim);
}

.ronia-appts-date-input {
    padding-block: 0.4rem;
    padding-inline: 0.65rem;
    border: 1px solid var(--ronia-border);
    border-radius: 0.6rem;
    background-color: var(--ronia-surface);
    color: var(--ronia-text);
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
}

.ronia-appts-date-input:focus-visible {
    outline: 2px solid var(--ronia-gold);
    outline-offset: 1px;
}

/* The native date popup paints itself from the colour scheme, not from our
   variables; without this it arrives white on a navy page. */
.dark .ronia-appts-date-input {
    color-scheme: dark;
}

/* ------------------------------------------------------------ the layout */

.ronia-appts-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

/* One column below the tablet break: the reminders card is a companion to the
   day sheet, not a sidebar, and it reads better under it than beside it. */
@media (max-width: 1023px) {
    .ronia-appts-layout {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ------------------------------------------------------- the day heading */

.ronia-appts-day {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    padding-block-start: 0.35rem;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--ronia-text);
}

.ronia-appts-day:not(:first-of-type) {
    margin-block-start: 0.35rem;
    padding-block-start: 0.7rem;
    border-block-start: 1px solid var(--ronia-border);
}

/* ---------------------------------------------------------- the appointment */

.ronia-appt-row,
.ronia-appt-reminder {
    position: relative;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    padding-block: 0.65rem;
    padding-inline: 0.8rem;
    border: 1px solid var(--ronia-border);
    border-radius: 0.75rem;
    background-color: var(--ronia-raised);
}

.ronia-appt-row {
    transition: border-color 120ms ease;
}

.ronia-appt-row:hover {
    border-color: var(--ronia-gold);
}

/* An appointment that is over, cancelled or missed is still on the sheet -
   a gap with no explanation is how the missed one gets found too late - but it
   is not what the eye should land on. */
.ronia-appt-row-closed {
    opacity: 0.72;
}

/* The whole row opens the client's file. An overlay link rather than a
   wrapping anchor, so the Done / Did not attend buttons inside stay real
   buttons and their click never navigates. */
.ronia-appt-row > *:not(.ronia-card-hit) {
    position: relative;
    z-index: 2;
    pointer-events: none;
}

.ronia-appt-row a,
.ronia-appt-row button {
    pointer-events: auto;
}

.ronia-appt-main {
    min-inline-size: 0;
}

.ronia-appt-line {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.3rem;
    font-size: 0.85rem;
    font-weight: 700;
    line-height: 1.5;
}

.ronia-appt-time {
    font-variant-numeric: tabular-nums;
}

.ronia-appt-who {
    overflow-wrap: anywhere;
}

.ronia-appt-sub {
    margin-block-start: 0.15rem;
    font-size: 0.72rem;
    line-height: 1.6;
    color: var(--ronia-dim);
    overflow-wrap: anywhere;
}

/* align-items on a column flex box works along the inline axis, so flex-end
   is the end of the reading direction and mirrors in Arabic on its own. */
.ronia-appt-side {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.4rem;
    flex-shrink: 0;
}

.ronia-appt-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.3rem;
}

/* ------------------------------------------------------- the empty states */

.ronia-appts-empty {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding-block: 1.5rem;
    padding-inline: 0.5rem;
    text-align: center;
}

.ronia-appts-empty-title {
    font-size: 0.85rem;
    font-weight: 700;
}

/* --------------------------------------------------------- the reminders */

.ronia-appts-note {
    padding-block-start: 0.6rem;
    border-block-start: 1px solid var(--ronia-border);
}
/* ============================================================ tasks module

   The task board: three columns of cards on a navy surface, gold used only
   for the section dot and the hover edge, exactly as in the client files
   module. The custom properties, the pill classes and .ronia-block-title are
   already defined by that module's block in ronia-theme.css; the board
   restates the palette for itself so it never depends on being nested inside
   a .ronia-cards subtree.

   Every direction-sensitive rule uses logical properties, so Arabic mirrors
   without a second stylesheet. The one exception is the advance arrow, which
   is flipped rather than repositioned - there is no logical way to mirror a
   glyph.
   ------------------------------------------------------------------------ */

.ronia-kanban {
    --ronia-surface: #fff;
    --ronia-raised: oklch(0.975 0.006 262);
    --ronia-border: oklch(0.88 0.012 262);
    --ronia-text: oklch(0.28 0.03 262);
    --ronia-dim: oklch(0.52 0.025 262);
    --ronia-gold: oklch(0.72 0.135 90);
    --ronia-gold-text: oklch(0.5 0.11 88);
    --ronia-amber: oklch(0.68 0.15 75);
    --ronia-green: oklch(0.52 0.13 155);
    --ronia-red: oklch(0.53 0.19 25);
    --ronia-blue: oklch(0.5 0.15 250);
    --ronia-radius: 0.9rem;

    display: grid;
    grid-template-columns: 1fr;
    gap: 0.875rem;
    color: var(--ronia-text);
}

.dark .ronia-kanban {
    --ronia-surface: oklch(0.21 0.042 262);
    --ronia-raised: oklch(0.255 0.042 262);
    --ronia-border: oklch(0.34 0.05 262);
    --ronia-text: oklch(0.93 0.012 258);
    --ronia-dim: oklch(0.72 0.03 258);
    --ronia-gold: oklch(0.75 0.135 90);
    --ronia-gold-text: oklch(0.8 0.12 90);
    --ronia-amber: oklch(0.78 0.14 78);
    --ronia-green: oklch(0.78 0.14 155);
    --ronia-red: oklch(0.7 0.16 25);
    --ronia-blue: oklch(0.7 0.13 250);
}

/* The demo's own breakpoint: three columns side by side from 768px, stacked
   below it, because three columns on a phone are three unreadable strips. */
@media (min-width: 768px) {
    .ronia-kanban {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        align-items: start;
    }
}

/* -------------------------------------------------------------- a column */

.ronia-kanban-col {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.75rem;
    border: 1px solid var(--ronia-border);
    border-radius: var(--ronia-radius);
    background-color: var(--ronia-raised);
    min-block-size: 7.5rem;
}

.ronia-kanban-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* .ronia-block-title carries the gold dot; here it is a heading, so the
   browser default margins have to go. */
.ronia-kanban-head .ronia-block-title {
    margin: 0;
}

.ronia-kanban-count {
    padding-block: 0.1rem;
    padding-inline: 0.5rem;
    border-radius: 9999px;
    background-color: color-mix(in oklab, var(--ronia-dim) 16%, transparent);
    color: var(--ronia-dim);
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.5;
}

.ronia-kanban-empty {
    padding-block: 1.75rem;
    text-align: center;
    color: var(--ronia-dim);
    font-size: 0.8rem;
}

.ronia-kanban-note {
    margin-block-start: auto;
    color: var(--ronia-dim);
    font-size: 0.7rem;
}

/* ---------------------------------------------------------------- a card */

.ronia-task-card {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    padding: 0.7rem 0.8rem;
    border: 1px solid var(--ronia-border);
    border-radius: 0.7rem;
    background-color: var(--ronia-surface);
    transition: border-color 120ms ease, transform 120ms ease;
}

.ronia-task-card:hover {
    border-color: var(--ronia-gold);
    transform: translateY(-1px);
}

.ronia-task-title {
    font-size: 0.825rem;
    font-weight: 700;
    line-height: 1.5;
}

.ronia-task-title a {
    color: inherit;
    text-decoration: none;
}

.ronia-task-title a:hover {
    color: var(--ronia-gold-text);
}

.ronia-task-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    flex-wrap: wrap;
    color: var(--ronia-dim);
    font-size: 0.72rem;
}

/* An overdue deadline is the one thing on the card that has to shout. */
.ronia-task-due.ronia-danger {
    color: var(--ronia-red);
    font-weight: 700;
}

.ronia-task-file {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    font-size: 0.72rem;
    color: var(--ronia-dim);
}

.ronia-task-file a {
    color: var(--ronia-blue);
    text-decoration: none;
}

.ronia-task-file a:hover {
    text-decoration: underline;
}

.ronia-task-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.ronia-task-actions {
    display: flex;
    align-items: center;
    gap: 0.3rem;
}

.ronia-task-advance,
.ronia-task-revert {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding-block: 0.2rem;
    padding-inline: 0.5rem;
    border: 1px solid var(--ronia-border);
    border-radius: 9999px;
    background-color: transparent;
    color: var(--ronia-dim);
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.5;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color 120ms ease, color 120ms ease;
}

.ronia-task-advance:hover,
.ronia-task-revert:hover {
    border-color: var(--ronia-gold);
    color: var(--ronia-gold-text);
}

.ronia-task-advance[disabled],
.ronia-task-revert[disabled] {
    opacity: 0.5;
    cursor: wait;
}

.ronia-task-icon {
    inline-size: 0.8rem;
    block-size: 0.8rem;
}

/* The arrow points along the reading direction, so it turns around in Arabic.
   Mirroring a glyph has no logical-property equivalent. */
[dir='rtl'] .ronia-task-arrow {
    transform: scaleX(-1);
}
/* ==========================================================================
   DASHBOARD
   Appended to ronia-theme.css by the deploy. Everything here is scoped to the
   dashboard's own widgets: .ronia-dash on the custom widget roots, and a
   handful of overrides on Filament's stat tiles.

   Logical properties only - this screen is read right-to-left half the time.
   ========================================================================== */

/* The palette tokens the ronia-* components (pills, links) are written
   against. They are declared on .ronia-cards and .ronia-file for the client
   files module; the dashboard needs the same set on its own root, with the
   same values, so a pill looks identical on both screens. */
.ronia-dash {
    --ronia-surface: #fff;
    --ronia-raised: oklch(0.975 0.006 262);
    --ronia-border: oklch(0.88 0.012 262);
    --ronia-text: oklch(0.28 0.03 262);
    --ronia-dim: oklch(0.52 0.025 262);
    --ronia-gold-text: oklch(0.5 0.11 88);
    --ronia-gold: oklch(0.72 0.135 90);
    --ronia-amber: oklch(0.68 0.15 75);
    --ronia-green: oklch(0.52 0.13 155);
    --ronia-red: oklch(0.53 0.19 25);
    --ronia-blue: oklch(0.5 0.15 250);
    --ronia-track: oklch(0.91 0.01 262);
    --ronia-radius: 0.9rem;

    color: var(--ronia-text);
}

.dark .ronia-dash {
    --ronia-surface: oklch(0.21 0.042 262);
    --ronia-raised: oklch(0.255 0.042 262);
    --ronia-border: oklch(0.34 0.05 262);
    --ronia-text: oklch(0.93 0.012 258);
    --ronia-dim: oklch(0.72 0.03 258);
    --ronia-gold-text: oklch(0.8 0.12 90);
    --ronia-gold: oklch(0.75 0.135 90);
    --ronia-amber: oklch(0.78 0.14 78);
    --ronia-green: oklch(0.78 0.14 155);
    --ronia-red: oklch(0.7 0.16 25);
    --ronia-blue: oklch(0.7 0.13 250);
    --ronia-track: oklch(0.3 0.045 262);
}

/* ------------------------------------------------------------ alert banner */

/* One red line, and only when something has earned it. The red lives in the
   inline-start edge and a faint wash, not in a solid block: a full red card at
   the top of every load is noise, and this has to still read as an exception
   the twentieth time it appears. */
.ronia-alert {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.65rem;
    padding: 0.75rem 1rem;
    border: 1px solid color-mix(in oklab, var(--ronia-red) 35%, var(--ronia-border));
    border-inline-start: 3px solid var(--ronia-red);
    border-radius: var(--ronia-radius);
    background-color: color-mix(in oklab, var(--ronia-red) 8%, var(--ronia-surface));
    text-decoration: none;
    color: inherit;
    transition: border-color 120ms ease, transform 120ms ease;
}

.ronia-alert:hover {
    transform: translateY(-1px);
    border-color: var(--ronia-red);
}

.ronia-alert-icon {
    display: inline-flex;
    color: var(--ronia-red);
}

.ronia-alert-icon .fi-icon {
    inline-size: 1.25rem;
    block-size: 1.25rem;
}

.ronia-alert-body {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 1 1 16rem;
    min-inline-size: 0;
}

.ronia-alert-text {
    font-size: 0.82rem;
    font-weight: 700;
}

.ronia-alert-go {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--ronia-gold-text);
    white-space: nowrap;
}

.ronia-alert-go-icon {
    inline-size: 1rem;
    block-size: 1rem;
}

/* The arrow points the way the reader is going, so it turns around in Arabic.
   Heroicons ship one direction only; the flip has to happen here. */
[dir='rtl'] .ronia-alert-go-icon {
    transform: scaleX(-1);
}

/* -------------------------------------------------------------- the cards */

.ronia-dash-card {
    display: flex;
    flex-direction: column;
    padding: 1rem;
    border: 1px solid var(--ronia-border);
    border-radius: var(--ronia-radius);
    background-color: var(--ronia-surface);
    block-size: 100%;
}

/* Late today is the only card that carries the danger accent. */
.ronia-dash-card-danger {
    border-inline-start: 3px solid var(--ronia-red);
}

.ronia-dash-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 0.75rem;
    font-size: 0.9rem;
    font-weight: 800;
}

/* The same gold dot the panel's section headings carry, drawn by hand here
   because these headings are ours, not Filament's. */
.ronia-dash-dot {
    inline-size: 0.4rem;
    block-size: 0.4rem;
    border-radius: 9999px;
    background-color: var(--ronia-gold);
    flex: none;
}

.ronia-dash-subtitle {
    margin: 0.85rem 0 0.15rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--ronia-dim);
}

.ronia-dash-subtitle:first-of-type {
    margin-block-start: 0;
}

.ronia-dash-note {
    margin: -0.4rem 0 0.75rem;
    font-size: 0.72rem;
    color: var(--ronia-dim);
}

.ronia-dash-empty {
    padding: 1.5rem 0.5rem;
    text-align: center;
    font-size: 0.8rem;
    color: var(--ronia-dim);
}

/* ------------------------------------------------------- office comparison */

.ronia-dash-table-wrap {
    overflow-x: auto;
}

.ronia-dash-table {
    inline-size: 100%;
    border-collapse: collapse;
    font-size: 0.8rem;
}

.ronia-dash-table th {
    padding: 0.4rem 0.4rem;
    text-align: start;
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--ronia-dim);
    white-space: nowrap;
    border-block-end: 1px solid var(--ronia-border);
}

.ronia-dash-table td {
    padding: 0.55rem 0.4rem;
    vertical-align: middle;
    border-block-end: 1px solid var(--ronia-border);
}

.ronia-dash-table tr:last-child td {
    border-block-end: none;
}

/* Counts are read down the column, so they line up on the far edge and use
   the same digits in both scripts - Arabic-Indic digits in one column and
   Western in the next would be unreadable. */
.ronia-dash-num {
    text-align: end;
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum';
}

.ronia-dash-table td.ronia-dash-num {
    font-weight: 700;
}

/* The header has to be restated: `.ronia-dash-table th` sets text-align:start
   and outranks the bare `.ronia-dash-num` class, so without this the column
   heading sits on the left while its own numbers sit on the right, and every
   count reads as if it belonged to the next column along. */
.ronia-dash-table th.ronia-dash-num {
    text-align: end;
}

.ronia-dash-office {
    font-weight: 700;
    margin-inline-end: 0.35rem;
}

.ronia-dash-tz {
    margin-inline-start: 0.35rem;
    font-size: 0.68rem;
    color: var(--ronia-dim);
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------- late today / urgent rows */

.ronia-dash-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.65rem;
    padding: 0.6rem 0;
    border-block-end: 1px solid var(--ronia-border);
}

.ronia-dash-row:last-child {
    border-block-end: none;
}

.ronia-dash-row-main {
    min-inline-size: 0;
}

.ronia-dash-row-title {
    font-size: 0.82rem;
    font-weight: 700;
    margin-block-end: 0.15rem;
}

/* A late row is named after the person who has to answer for it; the meta line
   is where that name lives, so it stays legible rather than whispering. */
.ronia-dash-row-meta {
    font-size: 0.72rem;
    color: var(--ronia-dim);
}

.ronia-dash-row-late .ronia-dash-row-title {
    color: var(--ronia-red);
}

.ronia-dash-sep {
    margin-inline: 0.3rem;
    color: var(--ronia-dim);
}

.ronia-dash-link {
    color: inherit;
    text-decoration: none;
}

.ronia-dash-link:hover {
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

/* ----------------------------------------------------- stat tiles as links */

/* The tiles are anchors now: each one opens the list it counts. The vertical
   tile anatomy and the chip colors already exist above; this only adds the
   affordance the demo gives a clickable card - it lifts and its edge turns
   gold. */
a.fi-wi-stats-overview-stat {
    text-decoration: none;
    color: inherit;
    cursor: pointer;
}

a.fi-wi-stats-overview-stat:hover {
    border-color: oklch(0.72 0.135 90);
}

a.fi-wi-stats-overview-stat:focus-visible {
    outline: 2px solid oklch(0.72 0.135 90);
    outline-offset: 2px;
}

/* Two tiles are not identity accents but warnings, so position stops deciding
   their color: "late or unconfirmed" is red because it is danger, and the two
   document tiles are amber because they are a deadline, not a failure yet.

   The nth-child rules above are five class-level selectors deep; these have to
   match that depth to override them, hence the redundant-looking :nth-child(n). */
.fi-wi-stats-overview .fi-grid-col:nth-child(n) .fi-wi-stats-overview-stat.ronia-stat-danger .fi-icon {
    color: oklch(0.72 0.16 25);
    background-color: color-mix(in oklab, oklch(0.64 0.19 25) 16%, transparent);
}

.fi-wi-stats-overview .fi-grid-col:nth-child(n) .fi-wi-stats-overview-stat.ronia-stat-warning .fi-icon {
    color: oklch(0.78 0.13 90);
    background-color: color-mix(in oklab, oklch(0.72 0.135 90) 16%, transparent);
}

/* ------------------------------------------------------------------ layout */

/* Late today and Top 3 sit side by side on a wide screen and stack under each
   other on a narrow one; the dashboard's own two-column grid does that, and
   the cards' block-size:100% above makes the pair share a bottom edge. */
@media (max-width: 40rem) {
    .ronia-alert {
        align-items: flex-start;
    }

    .ronia-dash-card {
        padding: 0.85rem;
    }
}
/* ==========================================================================
   Document archive

   The vault screen from the approved reference design: four stat cards (which
   are the shared Filament stat tiles and are styled nowhere here), the
   Documents / Archived files tabs, and below them either a wall of document
   cards or the list of finished client files.

   The document card itself is deliberately NOT restyled: .ronia-doc-grid,
   .ronia-doc-card, .ronia-doc-thumb, .ronia-doc-type, .ronia-doc-file,
   .ronia-doc-sub, .ronia-doc-actions and .ronia-link all come from the client
   file module, and a document should look the same wherever it is met. Only the
   tokens those rules read have to be restated on this screen's own root, which
   is what the block below does.

   Same navy + gold vocabulary as the rest of the app, and the same rule about
   gold: primary and active accents only. Every direction-sensitive rule uses
   logical properties, so Arabic mirrors without a second stylesheet.
   ========================================================================== */

/* The token set is restated here rather than shared with .ronia-cards or
   .ronia-file: this module is appended to the theme, and a rule that reached
   back up into another module's selector would break the moment either moved.
   The values are that module's values, unchanged. */
.ronia-arch {
    --ronia-surface: #fff;
    --ronia-raised: oklch(0.975 0.006 262);
    --ronia-border: oklch(0.88 0.012 262);
    --ronia-text: oklch(0.28 0.03 262);
    --ronia-dim: oklch(0.52 0.025 262);
    /* Bright gold is 2.4:1 on white, so light mode says gold in bronze. */
    --ronia-gold-text: oklch(0.5 0.11 88);
    --ronia-gold: oklch(0.72 0.135 90);
    --ronia-amber: oklch(0.68 0.15 75);
    --ronia-green: oklch(0.52 0.13 155);
    --ronia-red: oklch(0.53 0.19 25);
    --ronia-blue: oklch(0.5 0.15 250);
    --ronia-track: oklch(0.91 0.01 262);
    --ronia-radius: 0.9rem;

    display: flex;
    flex-direction: column;
    gap: 1rem;
    color: var(--ronia-text);
}

.dark .ronia-arch {
    --ronia-surface: oklch(0.21 0.042 262);
    --ronia-raised: oklch(0.255 0.042 262);
    --ronia-border: oklch(0.34 0.05 262);
    --ronia-text: oklch(0.93 0.012 258);
    --ronia-dim: oklch(0.72 0.03 258);
    --ronia-gold-text: oklch(0.8 0.12 90);
    --ronia-gold: oklch(0.78 0.13 90);
    --ronia-amber: oklch(0.78 0.15 75);
    --ronia-green: oklch(0.72 0.14 155);
    --ronia-red: oklch(0.68 0.18 25);
    --ronia-blue: oklch(0.68 0.14 250);
    --ronia-track: oklch(0.3 0.045 262);
}

/* A sentence above a list, saying what the list is a list of. */
.ronia-arch-note {
    font-size: 0.78rem;
    color: var(--ronia-dim);
}

/* ------------------------------------------------- the archived files list */

.ronia-arch-files {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.ronia-arch-file {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.9rem;
    padding: 0.75rem 1rem;
    border: 1px solid var(--ronia-border);
    border-radius: var(--ronia-radius);
    background-color: var(--ronia-surface);
    transition: border-color 120ms ease;
}

.ronia-arch-file:hover {
    border-color: var(--ronia-gold);
}

/* Takes the slack so the date and the link sit at the reading end. */
.ronia-arch-file-main {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    flex: 1 1 16rem;
    min-inline-size: 0;
}

.ronia-arch-file-name {
    font-size: 0.9rem;
    font-weight: 700;
}

.ronia-arch-file-meta {
    font-size: 0.75rem;
    color: var(--ronia-dim);
}

.ronia-arch-file-date {
    font-size: 0.75rem;
    color: var(--ronia-dim);
    white-space: nowrap;
}

.ronia-arch-file-open {
    white-space: nowrap;
}

/* --------------------------------------------------------- the empty state */

.ronia-arch-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    padding: 2.5rem 1rem;
    text-align: center;
    border: 1px dashed var(--ronia-border);
    border-radius: var(--ronia-radius);
    background-color: var(--ronia-surface);
}

.ronia-arch-empty-icon {
    inline-size: 2rem;
    block-size: 2rem;
    color: var(--ronia-dim);
}

.ronia-arch-empty-title {
    font-size: 0.9rem;
    font-weight: 700;
}

.ronia-arch-empty-help {
    font-size: 0.78rem;
    color: var(--ronia-dim);
    max-inline-size: 32rem;
}

/* Floating client cards (Bas, 2026-09-05): the client files list used to sit
   inside the table container's own box, which drew a frame around the whole
   list down to the pagination and clipped each card's gold hover border.
   The cards ARE the boxes; the container disappears. Scoped with :has() to
   pages whose table content renders ronia cards, so ordinary tables
   (Settings, Activity log) keep their frame.

   The mode-prefixed selectors are not decoration: the card treatment above is
   written as `:root:not(.dark) .fi-ta-ctn` / `.dark .fi-ta-ctn`, so a bare
   `.fi-ta-ctn:has(...)` loses to it on specificity in light mode and the
   frame comes back (it did - Bas saw it). These must always outrank both. */
.fi-ta-ctn:has(.ronia-card),
.fi-ta-ctn:has(.ronia-doc-grid),
.dark .fi-ta-ctn:has(.ronia-card),
.dark .fi-ta-ctn:has(.ronia-doc-grid),
:root:not(.dark) .fi-ta-ctn:has(.ronia-card),
:root:not(.dark) .fi-ta-ctn:has(.ronia-doc-grid) {
    background: transparent;
    border: none;
    box-shadow: none;
    --tw-ring-color: transparent;
    --tw-ring-shadow: 0 0 #0000;
    overflow: visible;
}

/* The toolbar and filters hang outside .ronia-cards, so the palette scoped
   there does not reach them; restate the two tokens they use on the ctn. */
.fi-ta-ctn:has(.ronia-card),
.fi-ta-ctn:has(.ronia-doc-grid) {
    --ronia-surface: #fff;
    --ronia-border: oklch(0.88 0.012 262);
}

.dark .fi-ta-ctn:has(.ronia-card),
.dark .fi-ta-ctn:has(.ronia-doc-grid) {
    --ronia-surface: oklch(0.21 0.042 262);
    --ronia-border: oklch(0.34 0.05 262);
}

.fi-ta-ctn:has(.ronia-card) .fi-ta-content,
.fi-ta-ctn:has(.ronia-doc-grid) .fi-ta-content {
    overflow: visible;
}

/* The filter panel becomes a floating card of its own, the same footing as
   the client cards it sits above. */
.fi-ta-ctn:has(.ronia-card) .fi-ta-filters-above-content-ctn,
.fi-ta-ctn:has(.ronia-doc-grid) .fi-ta-filters-above-content-ctn {
    background: var(--ronia-surface);
    border: 1px solid var(--ronia-border);
    border-radius: 0.9rem;
    padding: 1rem 1.25rem;
    margin-block-end: 1rem;
    box-shadow: 0 1px 2px rgb(15 27 45 / 0.05);
}

/* The search row floats bare: the input draws its own pill, and one more
   framed strip here would restart the boxes-inside-boxes Bas flagged. */
.fi-ta-ctn:has(.ronia-card) .fi-ta-header-toolbar,
.fi-ta-ctn:has(.ronia-doc-grid) .fi-ta-header-toolbar {
    background: transparent;
    border: none;
    padding-inline: 0;
    margin-block-end: 0.25rem;
}

.fi-ta-ctn:has(.ronia-card) .fi-ta-footer,
.fi-ta-ctn:has(.ronia-doc-grid) .fi-ta-footer {
    border-top: none;
    margin-block-start: 0.5rem;
}
/* ==========================================================================
   Account switcher: the "you are not yourself right now" bar

   One rule for this module: it must be impossible to miss and impossible to
   mistake for part of the page. So it is the only navy-and-gold bar that is
   fixed to the viewport, it says the same thing in both themes, and it never
   scrolls away - an administrator who has forgotten they are viewing as an
   employee is the failure this bar exists to prevent.

   Rendered by resources/views/filament/impersonation/banner.blade.php from
   PanelsRenderHook::BODY_START, so it is the first element inside <body>.

   THE GEOMETRY TRAP

   Filament's topbar is `position: sticky; top: 0` and its sidebar is
   `position: fixed`, and the theme's shell puts the sidebar in the top left
   corner at full height. A bar laid out in the normal flow would therefore be
   overlapped by the sidebar and slid over by the topbar on the first scroll.

   So the bar is fixed, and the three things that assume they own the top of
   the viewport are moved down by its height:

     - the body gets top padding, which pushes the topbar and the layout down;
     - the sticky topbar's own `top` is moved off zero, or it would re-stick
       underneath the bar the moment the page scrolls;
     - the fixed sidebar is moved down and shortened by the same amount.

   All three hang off :has() on the bar itself, so nothing is shifted unless
   the bar is actually on the page - there is no state to keep in sync, and a
   browser without :has() degrades to a bar overlapping the topbar rather than
   to a broken layout.

   Every direction sensitive rule is a logical property, so Arabic mirrors
   without a second stylesheet.
   ========================================================================== */

.fi-body:has(.ronia-impersonation-bar) {
    --ronia-imp-height: 2.75rem;

    padding-block-start: var(--ronia-imp-height);
}

.fi-body:has(.ronia-impersonation-bar) .fi-topbar-ctn {
    top: var(--ronia-imp-height);
}

/* Beats the theme's own `.fi-body-has-topbar .fi-sidebar { top: 0 }`, which is
   inside a desktop media query: this file is appended after it and the :has()
   argument adds the class needed to win on specificity as well as on order. */
.fi-body:has(.ronia-impersonation-bar) .fi-sidebar {
    inset-block-start: var(--ronia-imp-height);
    height: calc(100dvh - var(--ronia-imp-height));
}

/* ------------------------------------------------------------------ the bar */

.ronia-impersonation-bar {
    --ronia-imp-height: 2.75rem;

    position: fixed;
    inset-block-start: 0;
    inset-inline: 0;
    /* Above the topbar and the sidebar, which are both z-index 30. Below
       Filament's notifications, which have to stay reachable. */
    z-index: 40;

    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-height: var(--ronia-imp-height);
    padding-block: 0.375rem;
    padding-inline: 1rem;

    background-color: #0f1a30;
    border-block-end: 2px solid #c9a227;
    color: #e9edf5;
    font-size: 0.8125rem;
    line-height: 1.25;
}

/* The bar is a system-level warning, not page content, so it keeps the same
   navy in both themes. A bar that changed colour with the theme would read as
   part of the design instead of as a state the reader has to act on. */

.ronia-impersonation-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    inline-size: 1.5rem;
    block-size: 1.5rem;
    border-radius: 999px;
    background-color: color-mix(in oklab, #c9a227 22%, transparent);
    color: #e0bd4f;
}

.ronia-impersonation-icon svg {
    inline-size: 1rem;
    block-size: 1rem;
}

.ronia-impersonation-text {
    font-weight: 600;
    color: #fff;
    min-width: 0;
}

.ronia-impersonation-who {
    color: #9fb0c9;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The way back is pushed to the far end and given the only gold fill on the
   bar, because it is the only thing on it that can be clicked. */
.ronia-impersonation-form {
    margin-inline-start: auto;
    flex: none;
    display: flex;
}

.ronia-impersonation-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding-block: 0.3125rem;
    padding-inline: 0.75rem;
    border: 1px solid #c9a227;
    border-radius: 999px;
    background-color: #c9a227;
    color: #0f1a30;
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.ronia-impersonation-btn:hover {
    background-color: #e0bd4f;
    border-color: #e0bd4f;
}

.ronia-impersonation-btn:focus-visible {
    outline: 2px solid #e0bd4f;
    outline-offset: 2px;
}

/* On a phone the bar has to stay one line tall, so the secondary sentence -
   whose account you actually are - is the part that goes. The warning and the
   way out both survive. */
@media (max-width: 640px) {
    .ronia-impersonation-who {
        display: none;
    }

    .ronia-impersonation-bar {
        gap: 0.5rem;
        padding-inline: 0.75rem;
    }

    .ronia-impersonation-text {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}
/*
 * Notifications and PWA.
 *
 * One control: the enable-notifications button in the sidebar footer. It is
 * deliberately quiet - it is plumbing the reader touches once per device, not
 * a feature that should compete with the navigation above it.
 *
 * Merged into public/css/ronia-theme.css by the orchestrator.
 */

.ronia-push-toggle {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    width: 100%;
    padding: 0.5rem 0.75rem;
    margin: 0.25rem 0.5rem 0.75rem;
    box-sizing: border-box;
    width: calc(100% - 1rem);

    font: inherit;
    font-size: 0.8125rem;
    font-weight: 500;
    line-height: 1.25;
    text-align: start;
    color: rgb(148 163 184);

    background: transparent;
    border: 1px solid rgb(148 163 184 / 0.22);
    border-radius: 0.5rem;
    cursor: pointer;

    transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
}

/*
 * Not optional. `display: flex` on a class beats the user agent's
 * `[hidden] { display: none }`, which is an attribute selector of lower
 * specificity - without this rule the button ships visible on browsers that
 * cannot do push at all, and push.js setting .hidden = true does nothing.
 */
.ronia-push-toggle[hidden] {
    display: none;
}

.ronia-push-toggle:hover:not([disabled]) {
    color: #c9a227;
    border-color: rgb(201 162 39 / 0.5);
    background: rgb(201 162 39 / 0.08);
}

.ronia-push-toggle:focus-visible {
    outline: 2px solid #c9a227;
    outline-offset: 2px;
}

.ronia-push-icon {
    flex: 0 0 auto;
    width: 1.125rem;
    height: 1.125rem;
}

/*
 * Already on: still visible, because the reader needs a way back off, but no
 * longer soliciting a click.
 */
.ronia-push-toggle[data-ronia-push-state='enabled'] {
    color: rgb(134 172 118);
    border-color: rgb(134 172 118 / 0.3);
}

/*
 * Blocked at OS or browser level. Nothing this application does can undo that -
 * only the browser's own site settings can - so the button stops pretending to
 * be actionable and says why.
 */
.ronia-push-toggle[disabled] {
    color: rgb(148 163 184 / 0.6);
    border-style: dashed;
    cursor: not-allowed;
}

/*
 * Collapsed sidebar: the label goes, the bell stays, so the control does not
 * blow the rail open.
 */
.fi-sidebar:not(.fi-sidebar-open) .ronia-push-toggle {
    justify-content: center;
    padding-inline: 0.5rem;
}

.fi-sidebar:not(.fi-sidebar-open) .ronia-push-toggle > [data-ronia-push-label] {
    display: none;
}

/*
 * Standalone (installed) mode: iOS draws the status bar over the top of the
 * viewport, so the panel shell has to keep out of its way. Harmless in a
 * normal tab, where the safe-area insets are zero.
 */
@media all and (display-mode: standalone) {
    .fi-topbar {
        padding-top: env(safe-area-inset-top, 0);
    }

    .fi-sidebar {
        padding-bottom: env(safe-area-inset-bottom, 0);
    }
}

/* ------------------------------------------------- the settings launcher */
/* One button at the end of the sidebar, and the floating window it opens,
   replacing the five-link Settings group (Bas, 2026-09-14).

   .ronia-settings-launcher is listed with the module roots above, not left
   to :root: the --ronia-* tokens are declared per module, so anything drawn
   outside one of those wrappers keeps its spacing and silently loses every
   colour. The overlay is nested inside the launcher, so it inherits them
   even though it is position:fixed. */

.ronia-settings-launcher {
    padding: 0.25rem 0.5rem 0.5rem;
}

.ronia-settings-button {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    width: 100%;
    padding: 0.5rem 0.625rem;
    border: 1px solid var(--ronia-border);
    border-radius: 0.6rem;
    background-color: transparent;
    color: var(--ronia-text);
    font-size: 0.875rem;
    font-weight: 500;
    text-align: start;
    cursor: pointer;
    transition: background-color 120ms, border-color 120ms;
}

.ronia-settings-button:hover {
    border-color: var(--ronia-gold);
    background-color: var(--ronia-raised);
}

.ronia-settings-button-icon {
    width: 1.25rem;
    height: 1.25rem;
    flex: none;
    color: var(--ronia-gold-text);
}

.ronia-settings-overlay {
    position: fixed;
    inset: 0;
    /* Above Filament's sidebar (z-20) and topbar (z-30), below its own
       notifications, so a toast fired from inside the window is still read. */
    z-index: 40;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background-color: oklch(0.21 0.042 262 / 0.55);
    backdrop-filter: blur(2px);
}

.ronia-settings-window {
    width: min(34rem, 100%);
    max-height: 90vh;
    overflow-y: auto;
    padding: 1.25rem;
    border: 1px solid var(--ronia-border);
    border-radius: var(--ronia-radius);
    background-color: var(--ronia-surface);
    color: var(--ronia-text);
    box-shadow: 0 24px 48px oklch(0.21 0.042 262 / 0.28);
}

.ronia-settings-window-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.ronia-settings-window-title {
    font-size: 1.05rem;
    font-weight: 600;
}

.ronia-settings-window-note {
    margin-top: 0.25rem;
    color: var(--ronia-dim);
    font-size: 0.8125rem;
    line-height: 1.5;
}

.ronia-settings-close {
    flex: none;
    padding: 0.25rem;
    border-radius: 0.5rem;
    color: var(--ronia-dim);
    cursor: pointer;
}

.ronia-settings-close:hover {
    background-color: var(--ronia-raised);
    color: var(--ronia-text);
}

.ronia-settings-close-icon {
    width: 1.25rem;
    height: 1.25rem;
}

.ronia-settings-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.625rem;
    margin-top: 1rem;
}

/* One column on a phone: two 8rem tiles side by side wrap their labels to
   three lines and stop being readable. */
@media (max-width: 30rem) {
    .ronia-settings-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

.ronia-settings-item {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.75rem;
    border: 1px solid var(--ronia-border);
    border-radius: 0.7rem;
    background-color: var(--ronia-raised);
    color: var(--ronia-text);
    font-size: 0.875rem;
    font-weight: 500;
    transition: border-color 120ms, background-color 120ms;
}

.ronia-settings-item:hover {
    border-color: var(--ronia-gold);
    background-color: var(--ronia-surface);
}

.ronia-settings-item-icon {
    width: 1.25rem;
    height: 1.25rem;
    flex: none;
    color: var(--ronia-gold-text);
}

/* --------------------------------------- the stat tiles on a big screen */
/* Mulham, 22/09/2026, after the phone strips: the desktop cards had the same
   problem the phone did, 156px tall for one word and one number, with the
   count floating in the middle of an empty card. Same shape as the phone -
   label on one side, number on the other - just roomier, so the six cards read
   as one band instead of six posters. Three per row is unchanged. */
@media (min-width: 40.0625rem) {
    .fi-wi-stats-overview .fi-wi-stats-overview-stat {
        padding: 0.9rem 1.1rem;
    }

    .fi-wi-stats-overview .fi-wi-stats-overview-stat-content {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: 1rem;
    }

    .fi-wi-stats-overview .fi-wi-stats-overview-stat-label-ctn {
        min-width: 0;
        flex: 1 1 auto;
    }

    .fi-wi-stats-overview .fi-wi-stats-overview-stat-value {
        flex: none;
        line-height: 1.1;
    }
}

/* ------------------------------------------- the stat tiles on a phone */
/* Mulham, 22/09/2026: on a narrow screen the six tiles came out one per row at
   full desktop size, so the dashboard opened with two numbers on screen and
   everything else below the fold. Two small squares side by side fixed the
   scrolling but kept a band of dead space under every number, so on a phone
   the tile stops being a card and becomes a strip: icon and label on one side,
   the count on the other, six of them stacked.

   The track count is in StatsOverview::getColumns() - Filament writes it into
   an inline custom property no selector can outrank. Everything below is the
   shape. The breakpoint is the same 40rem the widget switches at.

   The value is padding-free rather than margin-free on purpose: these stats
   carry no description, so the strip is genuinely one line of content and the
   vertical rhythm can come from the strip itself. */
@media (max-width: 40rem) {
    /* The gap between the strips, tightened with them. Scoped to the stats
       widget's own grid so it cannot reach a section grid elsewhere. */
    .fi-wi-stats-overview .fi-grid {
        gap: 0.5rem;
    }

    .fi-wi-stats-overview .fi-wi-stats-overview-stat {
        padding: 0.5rem 0.75rem;
        border-radius: 0.6rem;
    }

    /* The row lives on the inner content wrapper, not on the tile: the tile's
       only child is this div, so a flex-row on the tile would lay out one box
       and change nothing. */
    .fi-wi-stats-overview .fi-wi-stats-overview-stat-content {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: 0.75rem;
    }

    .fi-wi-stats-overview .fi-wi-stats-overview-stat-label-ctn {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        min-width: 0;
        flex: 1 1 auto;
    }

    .fi-wi-stats-overview .fi-wi-stats-overview-stat-label-ctn > .fi-icon {
        width: 0.95rem;
        height: 0.95rem;
        padding: 0.3rem;
        border-radius: 0.45rem;
        flex: none;
    }

    .fi-wi-stats-overview .fi-wi-stats-overview-stat-label {
        font-size: 0.78rem;
        line-height: 1.25;
    }

    .fi-wi-stats-overview .fi-wi-stats-overview-stat-value {
        font-size: 1.15rem;
        line-height: 1.2;
        flex: none;
    }
}

/* Book by voice (Mulham, 25/09/2026). */
.ronia-voice { display: grid; gap: 1rem; }
.ronia-voice__mic-row { display: flex; align-items: center; gap: 1rem; margin-bottom: 0.75rem; }
.ronia-voice__mic {
    flex: none; width: 4rem; height: 4rem; border-radius: 9999px;
    display: grid; place-items: center;
    background: #c9a227; color: #0f1b33; border: 0; cursor: pointer;
    box-shadow: 0 0 0 0 rgba(201, 162, 39, 0.5);
}
.ronia-voice__mic.is-listening { background: #dc2626; color: #fff; animation: ronia-voice-pulse 1.4s infinite; }
.ronia-voice__mic-icon { width: 1.75rem; height: 1.75rem; }
@keyframes ronia-voice-pulse {
    0% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.55); }
    100% { box-shadow: 0 0 0 1rem rgba(220, 38, 38, 0); }
}
.ronia-voice__hint { display: grid; gap: 0.25rem; font-size: 0.875rem; opacity: 0.9; }
.ronia-voice__warn { color: #f59e0b; font-size: 0.85rem; }
.ronia-voice__note { font-size: 0.85rem; opacity: 0.8; margin-top: 0.5rem; }
.ronia-voice__box {
    width: 100%; border-radius: 0.6rem; padding: 0.75rem; font-size: 1rem;
    background: transparent; color: inherit;
    border: 1px solid rgba(148, 163, 184, 0.35);
}
.ronia-voice__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
.ronia-voice__draft { display: grid; grid-template-columns: max-content 1fr; gap: 0.5rem 1rem; }
.ronia-voice__draft dt { opacity: 0.7; }
.ronia-voice__draft dd { font-weight: 600; margin: 0; }
.ronia-voice__draft dd.is-missing { color: #f59e0b; font-weight: 400; }
.ronia-voice__status { font-size: 0.85rem; color: #c9a227; }
.ronia-voice__meter { display: block; width: 12rem; max-width: 100%; height: 0.4rem; border-radius: 9999px; background: rgba(148, 163, 184, 0.25); overflow: hidden; }
.ronia-voice__meter > span { display: block; height: 100%; background: #22c55e; transition: width 60ms linear; }

/* Ringing reminder card (public/js/push.js ring()). Sits above everything,
   including Filament modals, and stays until the reader presses a button. */
.ronia-ring {
    position: fixed;
    inset: 0;
    z-index: 2147483000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgb(11 17 32 / 0.72);
}

.ronia-ring__box {
    width: min(26rem, 100%);
    padding: 1.5rem;
    border-radius: 1rem;
    border: 2px solid #c9a227;
    background: #0b1120;
    color: #fff;
    text-align: center;
    box-shadow: 0 0 0 0 rgb(201 162 39 / 0.6);
    animation: ronia-ring-pulse 1.25s ease-out infinite;
}

.ronia-ring__title {
    display: block;
    font-size: 1.25rem;
    color: #e6c65c;
}

.ronia-ring__body {
    margin: 0.75rem 0 1.25rem;
    line-height: 1.6;
}

.ronia-ring__actions {
    display: flex;
    gap: 0.75rem;
    justify-content: center;
    flex-wrap: wrap;
}

.ronia-ring__open,
.ronia-ring__dismiss {
    padding: 0.6rem 1.2rem;
    border-radius: 0.6rem;
    font-weight: 600;
    cursor: pointer;
}

.ronia-ring__open {
    background: #c9a227;
    color: #0b1120;
}

.ronia-ring__dismiss {
    border: 1px solid rgb(255 255 255 / 0.4);
    background: transparent;
    color: #fff;
}

@keyframes ronia-ring-pulse {
    0% { box-shadow: 0 0 0 0 rgb(201 162 39 / 0.6); }
    100% { box-shadow: 0 0 0 1.5rem rgb(201 162 39 / 0); }
}

@media (prefers-reduced-motion: reduce) {
    .ronia-ring__box { animation: none; }
}

/* Appointment importance (2026-10-08). The pill on every row says the level;
   the two that must not slip also get a bar on the reading edge, so a busy
   day can be scanned for them without reading a word. inset-inline-start
   flips to the right edge in Arabic on its own. */
.ronia-pill-priority {
    font-weight: 800;
}

.ronia-appt-prio-urgent,
.ronia-appt-prio-high {
    position: relative;
}

.ronia-appt-prio-urgent::before,
.ronia-appt-prio-high::before {
    content: "";
    position: absolute;
    inset-block: 0.55rem;
    inset-inline-start: 0;
    inline-size: 4px;
    border-radius: 4px;
    z-index: 3;
    pointer-events: none;
}

.ronia-appt-prio-urgent::before {
    background-color: var(--ronia-red);
}

.ronia-appt-prio-high::before {
    background-color: var(--ronia-amber);
}

/*
 * Old mobile browsers (Chromium < 104, e.g. Samsung Internet 18 on the doctor's
 * phone) ignore the CSS `translate` property that Filament uses to slide the
 * sidebar away, so the closed sidebar stayed on screen over every page.
 * Same slide done with `transform`, only where `translate` is unsupported.
 */
@supports not (translate: 0) {
    @media (max-width: 63.999rem) {
        .fi-sidebar:not(.fi-sidebar-open) {
            transform: translateX(-100%);
        }

        [dir="rtl"] .fi-sidebar:not(.fi-sidebar-open) {
            transform: translateX(100%);
        }

        .fi-sidebar.fi-sidebar-open {
            transform: none;
            width: 20rem;
            max-width: 85vw;
        }

        .fi-sidebar-close-overlay {
            background-color: rgba(3, 7, 18, 0.5);
        }
    }
}
