/*
 * Structural admin CSS — the parts of the panel layout that are the same
 * whichever theme is active.
 *
 * Themes live in css/themes/*.css and own colour, type and shape. Anything that
 * would have to be copied into all five of them belongs here instead: five
 * copies of one rule is five chances for four of them to fall behind.
 *
 * Loaded by AppServiceProvider immediately before the active theme, so a theme
 * can still override anything here.
 */

/* --------------------------------------------------------------------------
 * "Per page", moved from under the table into the table's own toolbar.
 *
 * It used to sit in the footer beside "Showing 1 result", which is below the
 * last row — so on a full page an admin had to scroll past everything to change
 * how much they were looking at. It now sits at the start of the toolbar, in
 * the same row as search and the filter buttons: one row that holds every
 * control over what the table shows.
 *
 * The toolbar is `justify-content: space-between`, so being the first child is
 * what puts this on the left. The footer control is hidden rather than removed
 * — it is Filament's own markup, and hiding it keeps the relocation to CSS plus
 * one render hook, with nothing patched in vendor.
 * -------------------------------------------------------------------------- */

.fi-ta-records-per-page {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    white-space: nowrap;
}

.fi-ta-records-per-page-label {
    font-size: 0.875rem;
    line-height: 1.25rem;
    color: var(--gray-500);
}

/* The select sizes to its content — "10" in a full-width field would eat the
   whole left half of the toolbar. */
.fi-ta-records-per-page .fi-input-wrp {
    width: auto;
}

.fi-ta-records-per-page select {
    padding-inline-end: 2rem;
}

/* Filament's own copy, at the bottom. One control in two places is two controls
   as far as anyone reading the screen is concerned. */
.fi-pagination-records-per-page-select-ctn {
    display: none;
}

/* --------------------------------------------------------------------------
 * The Nawy import card on the dashboard.
 *
 * Plain CSS rather than Tailwind utilities in the Blade file. The panel is
 * served by Filament's own compiled stylesheet, which contains only the classes
 * Filament's own views use — there is no theme build here scanning app views,
 * so a `flex gap-4` written in a widget silently does nothing. That is exactly
 * how this card first shipped: every element stacked, the button adrift under
 * the text.
 *
 * Colours come from the theme's variables, so the card follows whichever theme
 * is active instead of pinning its own greys.
 * -------------------------------------------------------------------------- */

.nawy-import-card__row {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* Side by side once there is room for the text to stay readable. */
@media (min-width: 40rem) {
    .nawy-import-card__row {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }
}

.nawy-import-card__text {
    min-width: 0;
}

.nawy-import-card__heading {
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.5rem;
    color: var(--gray-950);
}

.nawy-import-card__body {
    margin-top: 0.25rem;
    font-size: 0.875rem;
    line-height: 1.375rem;
    color: var(--gray-500);
    max-width: 65ch;
}

.nawy-import-card__status {
    margin-top: 0.5rem;
    font-size: 0.875rem;
    color: var(--gray-500);
}

.nawy-import-card__status--busy {
    font-weight: 500;
    color: var(--warning-600);
}

.nawy-import-card__status--failed {
    font-weight: 500;
    color: var(--danger-600);
}

/* The button must not be squeezed by a long description beside it. */
.nawy-import-card__actions {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    gap: 0.75rem;
}

:where(.fi-theme-dark) .nawy-import-card__heading {
    color: var(--gray-50);
}

:where(.fi-theme-dark) .nawy-import-card__body,
:where(.fi-theme-dark) .nawy-import-card__status {
    color: var(--gray-400);
}

/* How much of the external website is imported: the design system's long bar,
   primary fill on a neutral track, always with what it counts above it. */
.nawy-import-progress {
    margin-top: 1.25rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--gray-200);
}

.nawy-import-progress__line {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
}

.nawy-import-progress__label {
    font-size: 0.9375rem;
    color: var(--gray-700);
}

.nawy-import-progress__label strong,
.nawy-import-progress__note strong {
    font-weight: 600;
    color: var(--gray-950);
}

.nawy-import-progress__label,
.nawy-import-progress__percent,
.nawy-import-progress__note {
    font-variant-numeric: tabular-nums;
}

/* The one number to take away, so it is the largest thing in the block. */
.nawy-import-progress__percent {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--primary-600);
}

.nawy-import-progress__track {
    margin-top: 0.625rem;
    height: 0.75rem;
    overflow: hidden;
    border-radius: 9999px;
    background: var(--gray-200);
}

.nawy-import-progress__fill {
    height: 100%;
    border-radius: 9999px;
    background: var(--primary-500);
    transition: width 600ms ease;
}

/* An import is running and the count is climbing: stripes move along the
   filled part, so a bar that grows every few seconds does not read as stuck
   between polls. */
.nawy-import-progress--running .nawy-import-progress__fill {
    background-image: linear-gradient(
        45deg,
        rgb(255 255 255 / 0.22) 25%,
        transparent 25%,
        transparent 50%,
        rgb(255 255 255 / 0.22) 50%,
        rgb(255 255 255 / 0.22) 75%,
        transparent 75%,
        transparent
    );
    background-size: 1rem 1rem;
    animation: nawy-import-progress-stripes 0.8s linear infinite;
}

@keyframes nawy-import-progress-stripes {
    to {
        background-position: 1rem 0;
    }
}

/* Waiting for the first count: the empty track, gently pulsing. */
.nawy-import-progress__track--waiting {
    animation: nawy-import-progress-wait 1.4s ease-in-out infinite;
}

@keyframes nawy-import-progress-wait {
    50% {
        opacity: 0.45;
    }
}

@media (prefers-reduced-motion: reduce) {
    .nawy-import-progress__fill {
        transition: none;
    }

    .nawy-import-progress__track--waiting,
    .nawy-import-progress--running .nawy-import-progress__fill {
        animation: none;
    }
}

.nawy-import-progress__note {
    margin-top: 0.5rem;
    font-size: 0.8125rem;
    color: var(--gray-500);
}

.nawy-import-progress__retry {
    font-weight: 600;
    color: var(--primary-600);
}

.nawy-import-progress__retry:hover {
    text-decoration: underline;
}

:where(.fi-theme-dark) .nawy-import-progress {
    border-top-color: var(--gray-800);
}

:where(.fi-theme-dark) .nawy-import-progress__label,
:where(.fi-theme-dark) .nawy-import-progress__note {
    color: var(--gray-400);
}

:where(.fi-theme-dark) .nawy-import-progress__label strong,
:where(.fi-theme-dark) .nawy-import-progress__note strong {
    color: var(--gray-50);
}

:where(.fi-theme-dark) .nawy-import-progress__percent {
    color: var(--primary-400);
}

:where(.fi-theme-dark) .nawy-import-progress__track {
    background: var(--gray-800);
}

:where(.fi-theme-dark) .nawy-import-progress__fill {
    background: var(--primary-400);
}

:where(.fi-theme-dark) .nawy-import-progress__retry {
    color: var(--primary-400);
}

/* The import run log: one line per compound, and the lines have to survive.
   HTML collapses newlines, which turned a readable list of "+ created / ·
   unchanged / ! failed" into a single paragraph. `pre-wrap` rather than `pre`
   so a long error message folds instead of scrolling the panel sideways. */
pre.import-log {
    margin: 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--gray-700);
}

:where(.fi-theme-dark) pre.import-log {
    color: var(--gray-300);
}

/*
 * The dashboard's inbox row: members, leads, meetings, subscribers and ads.
 *
 * Written here rather than as Tailwind utilities for the reason every other
 * admin style is (CLAUDE.md §4.5): the panel is served by Filament's own
 * compiled stylesheet, and no build in this project scans app views, so
 * `flex gap-4` in a widget view silently does nothing.
 */
.de-inbox__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 0.75rem;
}

.de-inbox__card {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.875rem 1rem;
    border: 1px solid rgb(228 228 231);
    border-radius: 0.75rem;
    background: #fff;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.de-inbox__card:hover {
    border-color: rgb(38 58 153 / 0.35);
    box-shadow: 0 4px 14px rgb(38 58 153 / 0.08);
    transform: translateY(-1px);
}

.de-inbox__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 9999px;
    background: rgb(38 58 153 / 0.08);
    color: rgb(38 58 153);
}

.de-inbox__icon svg {
    width: 1.125rem;
    height: 1.125rem;
}

.de-inbox__body {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.de-inbox__count {
    font-size: 1.375rem;
    font-weight: 700;
    line-height: 1.1;
    /* So a column of counts does not jitter as the poll changes them. */
    font-variant-numeric: tabular-nums;
}

.de-inbox__label {
    font-size: 0.8125rem;
    color: rgb(113 113 122);
}

.de-inbox__waiting {
    margin-top: 0.25rem;
    font-size: 0.6875rem;
    font-weight: 600;
    color: rgb(181 118 31);
}

/* The panel's dark mode is a class on <html>, so the cards follow it. */
.dark .de-inbox__card {
    background: rgb(39 39 42);
    border-color: rgb(63 63 70);
}

.dark .de-inbox__label {
    color: rgb(161 161 170);
}

/*
 * The topbar counters, beside the notifications bell.
 *
 * Written here rather than as Tailwind utilities for the reason every other
 * admin style is (CLAUDE.md §4.5): the panel is served by Filament's own
 * compiled stylesheet, and nothing in this project scans app views for more.
 */
.de-counts {
    display: none;
    align-items: center;
    gap: 0.25rem;
    margin-inline-end: 0.5rem;
}

/* A topbar is not the place to fight for room: below `md` the sidebar badges
   already carry these numbers, so the row simply stands down. */
@media (min-width: 768px) {
    .de-counts {
        display: flex;
    }
}

.de-counts__item {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.375rem 0.625rem;
    border-radius: 9999px;
    text-decoration: none;
    color: rgb(82 82 91);
    transition: background-color 0.15s ease, color 0.15s ease;
}

.de-counts__item:hover {
    background: rgb(38 58 153 / 0.08);
    color: rgb(38 58 153);
}

/* Each counter's number as a small solid bubble on its icon's corner, the
   way a phone marks unread items: grey icons, and every bubble the same soft
   violet with a dark number, as the client chose. */
.de-counts__item[class*="de-counts__item--"] {
    --de-count: oklch(0.7 0.17 283.95 / 0.49);
    --de-count-ink: oklch(0 0 0 / 0.77);
}

.de-counts__item[class*="de-counts__item--"] {
    position: relative;
    padding: 0.5rem;
}

.de-counts__item[class*="de-counts__item--"] .de-counts__icon {
    width: 1.375rem;
    height: 1.375rem;
}

.de-counts__item[class*="de-counts__item--"] .de-counts__value {
    position: absolute;
    top: 0.0625rem;
    inset-inline-end: -0.125rem;
    min-width: 1.125rem;
    height: 1.125rem;
    padding: 0 0.3125rem;
    border-radius: 9999px;
    background: var(--de-count);
    color: var(--de-count-ink);
    font-size: 0.6875rem;
    line-height: 1.125rem;
    text-align: center;
    /* A ring in the bar's own colour, so the bubble sits on the icon rather
       than blurring into it. */
    box-shadow: 0 0 0 2px #fff;
}

:where(.fi-theme-dark, .dark) .de-counts__item[class*="de-counts__item--"] .de-counts__value {
    /* The topbar's own ground: a theme that paints it a different shade sets
       `--de-topbar-ground` on `.fi-topbar` (daylight's dark mode does). */
    box-shadow: 0 0 0 2px var(--de-topbar-ground, var(--gray-900));
}

.de-counts__icon {
    width: 1.125rem;
    height: 1.125rem;
    flex: 0 0 auto;
}

.de-counts__value {
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1;
    /* So the row does not jitter as the poll changes the numbers. */
    font-variant-numeric: tabular-nums;
}

/*
 * The name is never drawn: the icon and the number carry it, and the words
 * made a crowded row of a topbar that already holds a search box, a bell and
 * a user menu. It stays in the markup for a screen reader — and the `title`
 * on each item is what a pointer gets — because "8" on its own names nothing.
 */
.de-counts__label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* The topbar's pills ("Alerts blocked", "Install app"). Words as well as an
   icon, because an icon nobody recognises is a question nobody answers. */
.de-counts__enable {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.375rem 0.75rem;
    border-radius: 9999px;
    background: rgb(38 58 153 / 0.08);
    color: rgb(38 58 153);
    font-size: 0.8125rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.de-counts__enable:hover {
    background: rgb(38 58 153 / 0.14);
}

.dark .de-counts__enable {
    background: rgb(255 255 255 / 0.08);
    color: rgb(244 244 245);
}

/* Blocked: muted and not a button, since only the browser can undo it. The
   pill's title says how. */
.de-counts__enable--blocked {
    background: var(--gray-100);
    color: var(--gray-600);
    cursor: help;
}

.dark .de-counts__enable--blocked {
    background: rgb(255 255 255 / 0.05);
    color: var(--gray-400);
}

/*
 * An unassigned lead on Leads and Expo leads (MeetingsTable::recordClasses):
 * a tint and a bar down its leading edge, so a client nobody will ring yet
 * is the first thing an admin sees. Brand blue, the client's choice
 * (2026-10-25); amber before.
 */
.fi-ta-row.de-row-unassigned > td {
    background: var(--primary-50);
}

.fi-ta-row.de-row-unassigned:hover > td {
    background: var(--primary-100);
}

.fi-ta-row.de-row-unassigned > td:first-child {
    box-shadow: inset 3px 0 0 var(--primary-500);
}

.dark .fi-ta-row.de-row-unassigned > td {
    background: color-mix(in oklab, var(--primary-400) 12%, transparent);
}

.dark .fi-ta-row.de-row-unassigned:hover > td {
    background: color-mix(in oklab, var(--primary-400) 18%, transparent);
}

.dark .fi-ta-row.de-row-unassigned > td:first-child {
    box-shadow: inset 3px 0 0 var(--primary-400);
}

/* A meeting's tag (filament/meetings/tag-badge.blade.php), beside the
   person's name in the Meetings list and in an open meeting's heading: one
   of eight solid colours chosen from its words (MeetingDisplay::tagTone),
   white text. The client's pick of four styles (2026-10-22). Solid, so the
   same colours read on the dark theme as well. */
.de-tag {
    display: inline-flex;
    align-items: center;
    margin-inline-start: 0.5rem;
    padding: 0.0625rem 0.5rem;
    border-radius: 0.375rem;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1.25rem;
    letter-spacing: 0.01em;
    color: #fff;
    vertical-align: middle;
    white-space: nowrap;
}

.de-tag--1 { background: #2563eb; }
.de-tag--2 { background: #15803d; }
.de-tag--3 { background: #b45309; }
.de-tag--4 { background: #dc2626; }
.de-tag--5 { background: #7c3aed; }
.de-tag--6 { background: #0f766e; }
.de-tag--7 { background: #c2410c; }
.de-tag--8 { background: #be185d; }

/* A lead whose sender is blocked (BlockedContact): near-black, which no tag takes. */
.de-tag--blocked { background: #111827; }
.dark .de-tag--blocked { box-shadow: inset 0 0 0 1px #6b7280; }

/*
 * An open meeting's history (filament/meetings/update-history.blade.php),
 * newest first: a line down the side with a dot an event, each event's
 * title and time, who and how long ago, then its rows in a quiet box: what
 * it was, faded, an arrow, and what it became, bold. A timeline by request
 * (2026-10-25), in place of a card an update.
 */
.de-history {
    display: grid;
    margin: 0;
    padding: 0;
    list-style: none;
}

.de-history__event {
    position: relative;
    padding: 0 0 1.25rem;
    padding-inline-start: 1.75rem;
}

.de-history__event:last-child {
    padding-bottom: 0;
}

/* The line, from this event's dot down to the next one's. */
.de-history__event::before {
    content: "";
    position: absolute;
    top: 1.125rem;
    bottom: 0.25rem;
    inset-inline-start: 0.375rem;
    width: 2px;
    border-radius: 1px;
    background: var(--gray-200);
}

.de-history__event:last-child::before {
    display: none;
}

/* The dot: hollow for a change, filled for the request arriving. */
.de-history__event::after {
    content: "";
    position: absolute;
    top: 0.25rem;
    inset-inline-start: 0;
    width: 0.875rem;
    height: 0.875rem;
    box-sizing: border-box;
    border: 2px solid var(--primary-600);
    border-radius: 9999px;
    background: #fff;
}

.de-history__event--received::after {
    background: var(--primary-600);
}

.de-history__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.125rem 0.75rem;
}

.de-history__title {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--gray-950);
}

.de-history__when {
    margin-inline-start: auto;
    font-size: 0.8125rem;
    color: var(--gray-500);
}

.de-history__meta {
    margin: 0.125rem 0 0;
    font-size: 0.75rem;
    color: var(--gray-500);
}

.de-history__changes {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 0.5rem 1.25rem;
    margin: 0.5rem 0 0;
    padding: 0.625rem 0.75rem;
    border-radius: 0.5rem;
    background: var(--gray-50);
    font-size: 0.875rem;
}

.de-history__changes dt {
    color: var(--gray-500);
    font-weight: 500;
}

.de-history__changes dd {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.5rem;
    min-width: 0;
    margin: 0;
    overflow-wrap: anywhere;
}

/* What it was: faded, with no line through it, by request (2026-10-25). */
.de-history__old {
    color: var(--gray-500);
}

.de-history__old .de-tag {
    opacity: 0.5;
}

.de-history__arrow {
    color: var(--gray-400);
}

/* A message: the whole of both, the old above the new, its own line breaks
   kept. */
.de-history__changes dd.de-history__long {
    display: grid;
    justify-items: start;
    gap: 0.25rem;
}

.de-history__long .de-history__text {
    white-space: pre-line;
}

.de-history__new {
    font-weight: 600;
    color: var(--gray-950);
}

.de-history__long .de-history__new {
    font-weight: 500;
}

/* The request as it first arrived: plain, there is nothing to compare. */
.de-history__value {
    color: var(--gray-950);
}

/* "No preference", "None": quiet. */
.de-history__none {
    display: inline-block;
    font-style: italic;
    font-weight: 400;
    color: var(--gray-400);
}

.de-history .de-tag {
    margin-inline-start: 0;
}

.dark .de-history__event::before {
    background: rgb(255 255 255 / 0.1);
}

.dark .de-history__event::after {
    /* Hollow means the card shows through: the card's own ground. */
    background: var(--gray-900);
}

.dark .de-history__event--received::after {
    background: var(--primary-500);
}

.dark .de-history__changes {
    background: rgb(255 255 255 / 0.04);
}

.dark .de-history__title,
.dark .de-history__new,
.dark .de-history__value {
    color: #fff;
}

/*
 * A meeting in the bell (App\Notifications\LeadAssigned): two tags, then the
 * facts an agent rings with, in a quiet card. Filament keeps the classes when
 * it cleans the stored HTML; the client's words in it are escaped first.
 */
.de-lead-note {
    display: grid;
    gap: 0.5rem;
    margin-top: 0.375rem;
}

.de-lead-note__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
}

.de-lead-note__tag {
    display: inline-flex;
    align-items: center;
    padding: 0 0.5rem;
    border-radius: 9999px;
    background: var(--gray-100);
    color: var(--gray-700);
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1.375rem;
}

.de-lead-note__tag--kind {
    background: var(--primary-50);
    color: var(--primary-600);
}

.de-lead-note__facts {
    display: grid;
    gap: 0.25rem;
    margin: 0;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--gray-200);
    border-radius: 10px;
    background: var(--gray-50);
}

.de-lead-note__facts > div {
    display: grid;
    grid-template-columns: 4rem 1fr;
    gap: 0.5rem;
    align-items: baseline;
}

.de-lead-note__facts dt {
    color: var(--gray-500);
    font-size: 0.75rem;
}

.de-lead-note__facts dd {
    margin: 0;
    color: var(--gray-950);
    font-size: 0.8125rem;
    font-weight: 500;
    /* Phone numbers and project names never break mid-word into the label. */
    overflow-wrap: anywhere;
}

.dark .de-lead-note__tag {
    background: rgb(255 255 255 / 0.08);
    color: var(--gray-300);
}

.dark .de-lead-note__tag--kind {
    background: rgb(255 255 255 / 0.1);
    color: var(--primary-300);
}

.dark .de-lead-note__facts {
    border-color: rgb(255 255 255 / 0.1);
    background: rgb(255 255 255 / 0.04);
}

.dark .de-lead-note__facts dd {
    color: rgb(244 244 245);
}

.dark .de-counts__item {
    color: rgb(161 161 170);
}

.dark .de-counts__item:hover {
    background: rgb(255 255 255 / 0.08);
    color: rgb(244 244 245);
}

/*
 * The loading screen (filament/page-loading.blade.php): the brand-yellow bar
 * running across the top, and a plain screen with a large "do" and three
 * yellow dots hopping under it. The client's choice. Every page
 * opens behind it (`is-opening`) until it has loaded and been drawn; after
 * that the script adds `is-loading` (the bar) and `is-slow` (the screen) for a
 * slow click. Solid, so a page half drawn never shows through, and it never
 * takes a click.
 */
.de-page-loading {
    position: fixed;
    inset: 0;
    z-index: 60;
    pointer-events: none;
}

.de-page-loading__bar {
    position: absolute;
    inset: 0 0 auto;
    z-index: 1;
    height: 4px;
    overflow: hidden;
    background: var(--tertiary-100);
    opacity: 0;
    transition: opacity 0.15s ease;
}

/* The running part in the darker brand yellows, as the design system has a
   yellow bar on white: the bright one all but vanishes against the topbar. */
.de-page-loading__bar::after {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 40%;
    border-radius: 9999px;
    background: linear-gradient(90deg, var(--tertiary-600), var(--tertiary-700));
    animation: de-page-loading-run 1.1s ease-in-out infinite;
}

.de-page-loading.is-loading .de-page-loading__bar {
    opacity: 1;
}

.de-page-loading__screen {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    background: #fff;
    opacity: 0;
    transition: opacity 0.25s ease;
}

.de-page-loading.is-slow .de-page-loading__screen {
    opacity: 1;
}

/* A page opening: if the script never runs to take it off, it goes by
   itself, so a broken script can never leave the panel covered. */
.de-page-loading.is-opening .de-page-loading__bar,
.de-page-loading.is-opening .de-page-loading__screen {
    animation: de-page-loading-give-up 0.25s ease 8s forwards;
}

.de-page-loading__mark {
    width: 6.5rem;
    height: auto;
    color: var(--primary-600);
}

/* The logo with three yellow dots under it, hopping in turn: the client's
   choice from six (2026-10-22), after the spinning "o". */
.de-page-loading__stack {
    display: grid;
    justify-items: center;
    gap: 1.25rem;
}

.de-page-loading__dots {
    display: flex;
    gap: 0.5rem;
}

.de-page-loading__dots i {
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 9999px;
    background: var(--tertiary-600);
    animation: de-page-loading-hop 0.9s ease-in-out infinite;
}

.de-page-loading__dots i:nth-child(2) {
    animation-delay: 0.15s;
}

.de-page-loading__dots i:nth-child(3) {
    animation-delay: 0.3s;
}

.dark .de-page-loading__bar {
    background: rgb(255 255 255 / 0.08);
}

.dark .de-page-loading__screen {
    /* The page's own night ground, so the screen lifting off is not a flash
       from one black to another. */
    background: var(--gray-950);
}

.dark .de-page-loading__mark {
    color: #fff;
}

@keyframes de-page-loading-run {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(250%); }
}

@keyframes de-page-loading-hop {
    0%, 60%, 100% { transform: translateY(0); opacity: 0.55; }
    30% { transform: translateY(-70%); opacity: 1; }
}

@keyframes de-page-loading-give-up {
    to { opacity: 0; visibility: hidden; }
}

/* Still there for someone who has asked for less motion, just not moving. */
@media (prefers-reduced-motion: reduce) {
    .de-page-loading__bar::after {
        width: 100%;
        animation: none;
    }

    .de-page-loading__dots i {
        animation: none;
    }
}

/* --------------------------------------------------------------------------
 * The dashboard: its header, and the cards under it.
 *
 * Its own block here rather than Tailwind in the Blade files, for the reason
 * at the top of this sheet: the panel is served by Filament's own compiled
 * stylesheet, which holds only the classes Filament's own views use, and
 * nothing in this project scans app views. `flex gap-4` in those templates
 * does nothing at all, silently.
 *
 * **Short by default.** The page is a run of answers, most important first:
 * who got in touch, what was opened, how people searched. Anything that is
 * detail — rows six to a hundred of a ranking, the chart behind each search
 * filter — is one press away and closed until then. Before this the same
 * numbers were three screens of cards, all open.
 *
 * Colours come from the panel's own ramps (`--primary-*`, `--gray-*`) so the
 * cards follow whichever theme is active rather than pinning brand blue and
 * then looking wrong in four of the five. They are named once, below, so dark
 * mode is one block of overrides and not a second copy of every rule.
 * -------------------------------------------------------------------------- */

.de-dash,
.de-dash-head {
    --de-ink: var(--gray-950);
    --de-text: var(--gray-700);
    --de-muted: var(--gray-500);
    --de-faint: var(--gray-400);
    --de-line: var(--gray-200);
    --de-rule: var(--gray-300);
    --de-soft: var(--gray-100);
    --de-hover: var(--gray-50);
    --de-surface: #fff;
    --de-tint: var(--primary-50);
    --de-tint-ink: var(--primary-700);

    /* The data colours: one hue at three strengths. `accent` is the main
       series and the thing to look at first; `accent-2` the middle of a
       stack; `accent-3` its pale end and every bar that is "the rest". */
    --de-accent: var(--primary-600);
    --de-accent-2: var(--primary-400);
    --de-accent-3: var(--primary-200);
    --de-accent-hover: var(--primary-300);

    /* A chosen tab or switch, the one solid thing in its row. */
    --de-pill: var(--primary-600);
    --de-pill-hover: var(--primary-700);
    --de-pill-ink: #fff;

    --de-up: var(--success-600);
    --de-down: var(--danger-600);

    /* Cards lift off a white page by a shadow rather than a heavier border. */
    --de-card-shadow: 0 1px 2px rgb(15 23 42 / 0.04), 0 8px 24px -12px rgb(15 23 42 / 0.12);
}

.dark .de-dash,
.dark .de-dash-head {
    --de-ink: #fff;
    --de-text: var(--gray-200);
    --de-muted: var(--gray-400);
    --de-faint: var(--gray-500);
    --de-line: rgb(255 255 255 / 0.08);
    --de-rule: rgb(255 255 255 / 0.16);
    --de-soft: rgb(255 255 255 / 0.06);
    --de-hover: rgb(255 255 255 / 0.04);
    --de-surface: var(--gray-900);
    --de-tint: color-mix(in srgb, var(--primary-400) 18%, transparent);
    --de-tint-ink: var(--primary-200);

    /* On a dark card the deep blue that leads in daylight all but vanishes,
       so the order turns over: the lightest blue is the strongest mark, and
       the parts of a stack fade toward the card instead of toward white. */
    --de-accent: var(--primary-300);
    --de-accent-2: color-mix(in srgb, var(--primary-300) 58%, transparent);
    --de-accent-3: color-mix(in srgb, var(--primary-300) 28%, transparent);
    --de-accent-hover: color-mix(in srgb, var(--primary-300) 44%, transparent);

    --de-pill: var(--primary-500);
    --de-pill-hover: var(--primary-600);

    --de-up: var(--success-400);
    --de-down: var(--danger-400);

    --de-card-shadow: 0 1px 0 rgb(255 255 255 / 0.03) inset;
}

/* Every card on the dashboard: the design system's card radius, and a soft
   lift instead of the flat ring alone. */
.de-dash .fi-section:not(.fi-section-not-contained) {
    border-radius: 1.25rem;
    box-shadow: var(--de-card-shadow), 0 0 0 1px var(--de-line);
}

/* A card's icon sits in a tinted tile, so the headings line up as a column of
   marks down the page and read as one family of card. */
.de-dash .fi-section-header > .fi-icon {
    box-sizing: content-box;
    padding: 0.4375rem;
    border-radius: 0.75rem;
    background: var(--de-tint);
    color: var(--de-tint-ink);
}

.de-dash .fi-section-header-heading {
    letter-spacing: -0.01em;
}

/* A heading with no description under it: centred on its icon, and the
   header no taller than the two need. */
.de-dash .fi-section-header {
    align-items: center;
    padding-block: 0.875rem;
}

/* Cards in one widget sit as far apart as Filament sets two widgets. */
.de-dash {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

/* The two rankings side by side. Each keeps its own height: one showing
   twenty rows must not stretch the other's five into an empty card. */
.de-dash__pair {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
    gap: 1.5rem;
}

.de-empty {
    margin: 0;
    max-width: 62ch;
    font-size: 0.875rem;
    line-height: 1.6;
    color: var(--de-muted);
}

/* ------------------------------------------------------------ the header
 *
 * The title on one side and the two controls on the other. They are two
 * controls because they are two questions: which days, and what one bar is.
 */

.de-dash-head {
    display: flex;
    flex-flow: row wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem 1.5rem;
}

/* What every percentage on the page is measured against, said once. */
.de-dash-head__against {
    color: var(--de-faint);
}

.de-dash-head__controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
}

.de-dash-head .de-dash-head__busy {
    width: 1.125rem;
    height: 1.125rem;
    color: var(--de-faint);
}

/* ------------------------------------------------------- the date menu */

.de-range__trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    height: 2.25rem;
    padding: 0 0.75rem;
    border: 1px solid var(--de-line);
    border-radius: 0.625rem;
    background: var(--de-surface);
    box-shadow: 0 1px 2px rgb(0 0 0 / 0.04);
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--de-ink);
    white-space: nowrap;
    cursor: pointer;
    transition: border-color 0.12s ease;
}

.de-range__trigger:hover {
    border-color: var(--de-rule);
}

.de-range__trigger:focus-visible,
.de-range__option:focus-visible,
.de-range__button:focus-visible,
.de-range__field input:focus-visible,
.de-switch__option:focus-visible,
.de-select:focus-visible,
.de-tabs__tab:focus-visible {
    outline: 2px solid var(--primary-500);
    outline-offset: 1px;
}

.de-range__trigger .de-range__icon,
.de-range__trigger .de-range__chevron {
    width: 1rem;
    height: 1rem;
    flex: none;
}

.de-range__trigger .de-range__icon {
    color: var(--de-accent);
}

.de-range__trigger .de-range__chevron {
    color: var(--de-faint);
}

.de-range__options {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 0.375rem;
}

.de-range__option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.45rem 0.625rem;
    border: 0;
    border-radius: 0.5rem;
    background: none;
    font: inherit;
    font-size: 0.8125rem;
    color: var(--de-text);
    text-align: start;
    cursor: pointer;
}

.de-range__option:hover {
    background: var(--de-hover);
    color: var(--de-ink);
}

/* Ticked as well as tinted, so the chosen range reads without colour. */
.de-range__option--on {
    background: var(--de-tint);
    color: var(--de-tint-ink);
    font-weight: 600;
}

.de-range__option--on::after {
    content: "✓";
    font-size: 0.75rem;
}

.de-range__custom {
    display: grid;
    gap: 0.625rem;
    padding: 0.75rem;
    border-top: 1px solid var(--de-line);
}

.de-range__field {
    display: grid;
    gap: 0.25rem;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--de-muted);
}

.de-range__field input {
    width: 100%;
    height: 2.125rem;
    padding: 0 0.5rem;
    border: 1px solid var(--de-rule);
    border-radius: 0.5rem;
    background: var(--de-surface);
    font: inherit;
    font-size: 0.8125rem;
    color: var(--de-ink);
}

.de-range__actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    padding-top: 0.125rem;
}

.de-range__button {
    height: 2rem;
    padding: 0 0.875rem;
    border: 1px solid var(--de-rule);
    border-radius: 9999px;
    background: var(--de-surface);
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--de-ink);
    cursor: pointer;
}

.de-range__button--apply {
    border-color: var(--de-pill);
    background: var(--de-pill);
    color: var(--de-pill-ink);
}

.de-range__button--apply:hover {
    border-color: var(--de-pill-hover);
    background: var(--de-pill-hover);
}

.de-range__button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ------------------------------------------------ the bar-size switch
 *
 * Says what it sets ("One bar is a") because "Day | Week | Month" beside a
 * date menu otherwise reads as a second way to pick the dates.
 */

.de-switch {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    height: 2.25rem;
    padding: 3px;
    border-radius: 0.625rem;
    background: var(--de-soft);
}

.de-switch__label {
    padding: 0 0.375rem 0 0.5rem;
    font-size: 0.75rem;
    color: var(--de-muted);
    white-space: nowrap;
}

.de-switch__option {
    height: 100%;
    padding: 0 0.75rem;
    border: 0;
    border-radius: 0.5rem;
    background: none;
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--de-text);
    cursor: pointer;
    transition: background-color 0.12s ease, color 0.12s ease;
}

.de-switch__option:hover:not(:disabled):not(.de-switch__option--on) {
    color: var(--de-ink);
    background: var(--de-surface);
}

/* A filled blue pill, not a colour change on the word alone: the chosen one
   is the only solid thing in the row. */
.de-switch__option--on {
    background: var(--de-pill);
    color: var(--de-pill-ink);
    font-weight: 600;
    box-shadow: 0 1px 2px rgb(0 0 0 / 0.12);
}

.de-switch__option:disabled {
    color: var(--de-faint);
    opacity: 0.6;
    cursor: not-allowed;
}

/* --------------------------------------------------- figures and chart
 *
 * Side by side, not stacked. A number above a wide graph reads as two
 * unrelated things with a gap between them; beside it they read as one
 * statement — here is the total, here is how it arrived.
 */

.de-panel {
    display: grid;
    grid-template-columns: minmax(13rem, 17rem) minmax(0, 1fr);
    align-items: start;
    gap: 1.25rem 2.5rem;
}

.de-panel__figures {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-width: 0;
}

.de-panel__chart {
    min-width: 0;
}

/* The one number the card is about, and nothing else its size. Its change
   sits beside it on the same line, as on the tiles; the label is under both.
   Placed by grid so the words still read figure, label, change in order. */
.de-kpi {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 0.125rem 0.5rem;
}

.de-kpi > .de-kpi__value {
    grid-row: 1;
    grid-column: 1;
}

.de-kpi > .de-kpi__label {
    grid-row: 2;
    grid-column: 1 / -1;
}

.de-kpi > .de-kpi__trend {
    grid-row: 1;
    grid-column: 2;
    justify-self: start;
    margin-top: 0;
}

.de-kpi__value {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.02em;
    color: var(--de-ink);
    font-variant-numeric: tabular-nums;
}

.de-kpi__label {
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--de-text);
}

.de-kpi__trend {
    margin-top: 0.25rem;
    font-size: 0.8125rem;
    color: var(--de-muted);
}

.de-change {
    font-weight: 600;
    color: var(--de-muted);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.de-change--up {
    color: var(--de-up);
}

.de-change--down {
    color: var(--de-down);
}

/* Under a headline figure the change is a small pill, tinted the way it
   went, so it reads as a verdict on the number above it. The sign is still
   written, for print and for anyone who does not see the colour. */
.de-kpi__trend .de-change,
.de-total__row .de-change {
    display: inline-block;
    padding: 0.0625rem 0.4375rem;
    border-radius: 9999px;
    background: var(--de-soft);
    font-size: 0.75rem;
}

.de-kpi__trend .de-change--up,
.de-total__row .de-change--up {
    background: color-mix(in srgb, var(--de-up) 13%, transparent);
}

.de-kpi__trend .de-change--down,
.de-total__row .de-change--down {
    background: color-mix(in srgb, var(--de-down) 13%, transparent);
}

/* ------------------------------------------------------- the five totals
 *
 * Visits, pages opened, searches, projects opened, properties opened: five
 * across on a wide screen, then three, then two.
 */

.de-totals {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 1rem;
}

.de-total {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.de-total__head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.de-total__chip {
    display: grid;
    flex: none;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border-radius: 0.625rem;
    background: var(--de-tint);
    color: var(--de-tint-ink);
}

.de-total .de-total__icon {
    width: 1.125rem;
    height: 1.125rem;
}

.de-totals__tile {
    transition: transform 0.15s ease;
}

/* Every tile the height of the tallest in its row, with the line pinned to
   the bottom, so five sparklines sit on one level however many lines the
   words above them took. */
.de-totals__tile,
.de-totals__tile > .fi-section-content-ctn,
.de-totals__tile .fi-section-content {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}

.de-totals__tile .de-total {
    flex: 1 1 auto;
}

.de-total .de-kpi__trend {
    font-size: 0.75rem;
}

.de-totals__tile:hover {
    transform: translateY(-1px);
}

/* The line under each total: how the figure arrived over the dates, in the
   main series colour, with a wash fading to the card under it. The same
   height whether drawn or not, so the row of tiles stays level. */
.de-spark {
    display: block;
    width: 100%;
    height: 2.25rem;
    margin-top: auto;
    padding-top: 0.625rem;
    box-sizing: content-box;
    color: var(--de-accent);
    overflow: visible;
}

.de-spark--none {
    height: 2.25rem;
}

.de-total__label {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--de-text);
}

/* A tile's figure with its change beside it, on one line. */
.de-total__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.5rem;
    margin-top: 0.5rem;
}

.de-total__hint {
    font-size: 0.8125rem;
    line-height: 1.4;
    color: var(--de-muted);
}

.de-total .de-kpi__trend {
    margin-top: 0;
}

@media (max-width: 80rem) {
    .de-totals {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 48rem) {
    .de-totals {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* The parts of the total, which are also the chart's key: each name carries
   the shade of its own part of a bar, which is what removes a separate legend
   repeating the same three words. Digits line up down the column and between
   one month and the next. */
.de-keys {
    display: grid;
    margin: 0;
    padding: 0.625rem 0 0;
    border-top: 1px solid var(--de-line);
    list-style: none;
}

.de-keys__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto 3.25rem;
    align-items: baseline;
    gap: 0.75rem;
    padding: 0.3rem 0;
    font-size: 0.8125rem;
}

.de-keys__name {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    color: var(--de-text);
}

/* Every name has the swatch's room, filled or not, so a figure that is not on
   the chart ("Booked") lines up under the ones that are and is told apart by
   having no colour. */
.de-keys__name::before {
    content: "";
    flex: none;
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 3px;
}

.de-keys__row--sub .de-keys__name {
    color: var(--de-muted);
}

.de-keys__value {
    text-align: end;
    font-weight: 600;
    color: var(--de-ink);
    font-variant-numeric: tabular-nums;
}

.de-keys__change {
    text-align: end;
    font-size: 0.75rem;
}

/*
 * One hue, three shades, darkest at the base of the stack. Blue against grey
 * read as "counted" against "not counted yet", and a second hue made one card
 * carry two unrelated colour systems; shades of the brand blue keep a big
 * filled area calm and the parts of a bar still obviously parts.
 *
 * Colour is never the only signal: each swatch sits against its own written
 * name, and every bar's tooltip names every number.
 */
.de-chart__seg--whatsapp,
.de-chart__seg--visits,
.de-keys__name--whatsapp::before,
.de-tip__name--whatsapp::before,
.de-tip__name--visits::before {
    background: var(--de-accent);
}

.de-chart__seg--hotline,
.de-keys__name--hotline::before,
.de-tip__name--hotline::before {
    background: var(--de-accent-2);
}

.de-chart__seg--meeting,
.de-keys__name--meeting::before,
.de-tip__name--meeting::before {
    background: var(--de-accent-3);
}

/* ---------------------------------------------------------------- the chart
 *
 * One bar a day (or a week, or a month), split into the things it counts.
 * Plain elements, not SVG: thirty bars is thirty divs, they take a radius and
 * a hover for nothing, and there is no stretched viewBox to fight.
 *
 * Compact on purpose. The chart is the evidence for the figure beside it, not
 * the headline, and at this height three of them fit on one screen.
 */

.de-chart {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 0.5rem;
    padding-top: 0.375rem;
}

/* Three labels against three lines: the top of the scale, half of it, nought. */
.de-chart__axis {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    height: 7.5rem;
    font-size: 0.6875rem;
    line-height: 1;
    color: var(--de-faint);
    text-align: end;
    font-variant-numeric: tabular-nums;
}

.de-chart__axis span:first-child {
    transform: translateY(-50%);
}

.de-chart__axis span:last-child {
    transform: translateY(50%);
}

.de-chart__bars {
    position: relative;
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 7.5rem;
    /* The baseline the bars stand on, and two faint lines above it. */
    border-bottom: 1px solid var(--de-rule);
    background-image: linear-gradient(to bottom, var(--de-soft) 1px, transparent 1px);
    background-size: 100% 50%;
}

.de-chart__bar {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    flex: 1 1 0;
    min-width: 0;
    height: 100%;
    border-radius: 4px 4px 0 0;
    /* A quiet day is still a day: the column lights up under the pointer even
       where nothing happened, so the tooltip is reachable for every one. */
    transition: background-color 0.12s ease;
}

.de-chart__bar:hover {
    background: var(--de-soft);
}

/* A week of bars would otherwise be seven slabs a hand wide: the column takes
   the room and the bar inside it stops at a sensible width. */
.de-chart__seg {
    display: block;
    width: 100%;
    max-width: 2.75rem;
    /* One press on a busy scale is a sliver; without this it rounds to nothing
       and reads as none. */
    min-height: 2px;
    transition: filter 0.12s ease;
}

.de-chart__seg--cap {
    border-radius: 3px 3px 0 0;
}

.de-chart__bar:hover .de-chart__seg {
    filter: brightness(0.9);
}

.dark .de-chart__bar:hover .de-chart__seg {
    filter: brightness(1.25);
}

.de-chart__dates {
    grid-column: 2;
    position: relative;
    height: 1rem;
    margin-top: 0.4rem;
    font-size: 0.6875rem;
    color: var(--de-muted);
    font-variant-numeric: tabular-nums;
}

.de-chart__date {
    position: absolute;
    top: 0;
    white-space: nowrap;
}

.de-chart__date--first {
    inset-inline-start: 0;
}

.de-chart__date--last {
    inset-inline-end: 0;
}

.de-chart__date--between {
    transform: translateX(-50%);
}

.de-chart__none {
    margin: 0;
    padding: 0.25rem 0;
    max-width: 44ch;
    font-size: 0.8125rem;
    line-height: 1.6;
    color: var(--de-muted);
}

/* ------------------------------------------------------------ the tooltip
 *
 * Inside its own bar and shown by `:hover`, so there is no script. It sits
 * just above the bar it describes (the `bottom` is set on the element), and
 * opens inwards near either edge of the chart so it never hangs off the card.
 */

.de-tip {
    position: absolute;
    left: 50%;
    z-index: 20;
    display: grid;
    gap: 0.2rem;
    min-width: 10rem;
    padding: 0.5rem 0.65rem;
    border: 1px solid var(--de-line);
    border-radius: 0.625rem;
    background: var(--de-surface);
    box-shadow: 0 8px 20px rgb(0 0 0 / 0.1);
    font-size: 0.75rem;
    white-space: nowrap;
    transform: translateX(-50%);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.1s ease;
}

.de-chart__bar:hover .de-tip {
    opacity: 1;
    visibility: visible;
}

.de-chart__bar--start .de-tip {
    left: 0;
    transform: none;
}

.de-chart__bar--end .de-tip {
    left: auto;
    right: 0;
    transform: none;
}

.de-tip__when {
    margin-bottom: 0.1rem;
    font-weight: 600;
    color: var(--de-ink);
}

.de-tip__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.de-tip__name {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--de-text);
}

.de-tip__name::before {
    content: "";
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 2px;
}

.de-tip__value {
    font-weight: 600;
    color: var(--de-ink);
    font-variant-numeric: tabular-nums;
}

.de-tip__row--total {
    margin-top: 0.15rem;
    padding-top: 0.3rem;
    border-top: 1px solid var(--de-line);
}

/* ------------------------------------------------------ most opened lists */

/* "Top 5", in the corner of its own card. A plain select: it is a list of
   four, the browser already knows how to draw one on a phone, and it works
   before a line of script has loaded. */
.de-select {
    height: 2rem;
    padding: 0 1.75rem 0 0.625rem;
    border: 1px solid var(--de-line);
    border-radius: 0.5rem;
    background: var(--de-surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%239ca3af'%3E%3Cpath fill-rule='evenodd' d='M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z' clip-rule='evenodd'/%3E%3C/svg%3E") no-repeat right 0.4rem center / 1rem;
    font: inherit;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--de-ink);
    cursor: pointer;
    appearance: none;
}

.de-select:hover {
    border-color: var(--de-rule);
}

.de-rank {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
    /* The rank is drawn from the list's own numbering rather than written into
       each row: it is what an ordered list already means. */
    counter-reset: de-rank;
    /* One height for every row, two lines or one, so five rows is a length
       the scrolling list can be cut to. */
    --de-rank-row: 2.875rem;
}

/* More than five rows scroll inside the card, which stays five rows tall:
   asking for the top twenty must not push the searches twenty rows down the
   page, or leave this card three times the height of the one beside it. */
.de-rank--long {
    max-height: calc(5 * var(--de-rank-row));
    /* Room for the rows' own overhang (their hover fill runs a little past
       the text on both sides), and for the scrollbar not to sit on a number. */
    padding-inline: 0.4rem 0.5rem;
    margin-inline-start: -0.4rem;
    overflow-y: auto;
    /* The scroll stays in the list: reaching its end does not start moving
       the page under the pointer. */
    overscroll-behavior: contain;
}

.de-rank__row {
    /* The name takes the room, not the bar: a compound is identified by its
       name and only compared by its length, and a truncated name cannot be
       identified at all. The bar is a fixed, modest width. */
    display: grid;
    grid-template-columns: 1.5rem minmax(0, 1fr) minmax(3rem, 6.5rem) 2.75rem 3rem;
    align-items: center;
    gap: 0.75rem;
    /* Never squeezed to fit: a list cut to five rows scrolls, it does not
       shrink ten rows into the space. */
    flex: none;
    min-height: var(--de-rank-row);
    padding: 0.4rem;
    margin-inline: -0.4rem;
    border-radius: 0.5rem;
    font-size: 0.8125rem;
    counter-increment: de-rank;
}

/* A row is a thing you can open; hovering says so. */
.de-rank__row:hover {
    background: var(--de-hover);
}

.de-rank__row::before {
    content: counter(de-rank);
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--de-faint);
    text-align: end;
    font-variant-numeric: tabular-nums;
}

/* The top three carry the weight the ranking gives them. */
.de-rank__row:nth-child(-n + 3)::before {
    color: var(--de-accent);
}

.de-rank__label {
    /* A column, because the compound belongs under the unit's name rather
       than after it: "Apartment, Vallis" is the name and "Badya" is a second
       fact about it, and on one line the two ran together. */
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
    min-width: 0;
    font-weight: 500;
    color: var(--de-ink);
    line-height: 1.3;
}

.de-rank__label > a,
.de-rank__label > span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.de-rank__label a {
    color: inherit;
    text-decoration: none;
}

.de-rank__label a:hover {
    text-decoration: underline;
}

/* Where it is — the missing half of a name like "Apartment". Smaller and
   quieter than the name above it, so the row reads as one thing with a note
   rather than as two competing lines. */
.de-rank__context {
    font-size: 0.6875rem;
    font-weight: 400;
    color: var(--de-muted);
}

.de-rank__track,
.de-bars__track,
.de-acc__meter {
    display: block;
    border-radius: 9999px;
    background: var(--de-soft);
}

.de-rank__track {
    height: 0.5rem;
}

.de-rank__fill {
    display: block;
    height: 100%;
    border-radius: 9999px;
    background: var(--de-accent);
}

/* The value sits at the end of its own bar, so the eye never has to travel
   to an axis. */
.de-rank__value {
    text-align: end;
    font-weight: 600;
    color: var(--de-ink);
    font-variant-numeric: tabular-nums;
}

.de-rank__change {
    text-align: end;
    font-size: 0.75rem;
}

.de-rank__note {
    margin: 0.75rem 0 0;
    font-size: 0.75rem;
    color: var(--de-muted);
}

/* ------------------------------------------------------------------------
 * How people search (SearchActivityWidget)
 *
 * Tabs for the three places, then one place's figures beside its bars — the
 * contact card's own shape. Under that, the insights: a row for every filter
 * people used, which opens into the chart of what they chose.
 * -------------------------------------------------------------------------- */

.de-search {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

/* The finding, said before the charts that support it. */
.de-search__finding {
    margin: 0;
    padding-top: 0.75rem;
    border-top: 1px solid var(--de-line);
    font-size: 0.8125rem;
    font-weight: 500;
    line-height: 1.5;
    color: var(--de-text);
}

/* The three places. The same filled blue as the bar-size switch, because it
   is the same kind of choice: one of a few, always exactly one. Each tab
   carries its own visits, so the three can be compared without opening them. */
.de-tabs {
    display: inline-flex;
    /* As wide as its three tabs, not as the card it sits in. */
    align-self: flex-start;
    gap: 2px;
    max-width: 100%;
    padding: 3px;
    border-radius: 0.625rem;
    background: var(--de-soft);
    overflow-x: auto;
}

.de-tabs__tab {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex: none;
    height: 2rem;
    padding: 0 0.875rem;
    border: 0;
    border-radius: 0.5rem;
    background: none;
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--de-text);
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.12s ease, color 0.12s ease;
}

.de-tabs__tab:hover:not(.de-tabs__tab--on) {
    background: var(--de-surface);
    color: var(--de-ink);
}

.de-tabs__tab--on {
    background: var(--de-pill);
    color: var(--de-pill-ink);
    font-weight: 600;
    box-shadow: 0 1px 2px rgb(0 0 0 / 0.12);
}

.de-tabs__count {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--de-muted);
    font-variant-numeric: tabular-nums;
}

.de-tabs__tab--on .de-tabs__count {
    color: rgb(255 255 255 / 0.8);
}

.dark .de-tip {
    box-shadow: 0 12px 28px rgb(0 0 0 / 0.45);
}

/* ---------------------------------------------------------- the insights
 *
 * One row a filter, closed. The closed row is already an answer — what was
 * chosen most, and how often the filter was used beside the others — and the
 * chart behind it opens underneath, one at a time.
 *
 * The opening is a grid row going from 0fr to 1fr, which is the one way to
 * animate to a height nobody has measured: no script reads the content, and
 * nothing below jumps.
 */

.de-acc {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--de-line);
    border-radius: 0.75rem;
    overflow: hidden;
}

.de-acc__item + .de-acc__item {
    border-top: 1px solid var(--de-line);
}

.de-acc__heading {
    margin: 0;
}

.de-acc__toggle {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) minmax(4rem, 11rem) 2.75rem auto;
    align-items: center;
    gap: 0.875rem;
    width: 100%;
    padding: 0.625rem 0.875rem;
    border: 0;
    background: none;
    font: inherit;
    text-align: start;
    cursor: pointer;
    transition: background-color 0.12s ease;
}

.de-acc__toggle:hover,
.de-acc__item--open .de-acc__toggle {
    background: var(--de-hover);
}

.de-acc__toggle:focus-visible {
    outline: 2px solid var(--primary-500);
    outline-offset: -2px;
}

.de-acc__icon {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border-radius: 0.5rem;
    background: var(--de-tint);
    color: var(--de-tint-ink);
}

.de-acc__icon svg {
    width: 1.125rem;
    height: 1.125rem;
}

.de-acc__text {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
    min-width: 0;
}

.de-acc__title {
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--de-ink);
}

.de-acc__summary {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.75rem;
    color: var(--de-muted);
}

/* How much this filter is used beside the others. The closed list is itself
   the chart of which filters people reach for. */
.de-acc__meter {
    height: 0.375rem;
}

.de-acc__meter span {
    display: block;
    height: 100%;
    border-radius: 9999px;
    background: var(--de-accent-hover);
}

.de-acc__item--open .de-acc__meter span {
    background: var(--de-accent);
}

.de-acc__count {
    text-align: end;
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--de-ink);
    font-variant-numeric: tabular-nums;
}

.de-acc__toggle .de-acc__chevron {
    width: 1.125rem;
    height: 1.125rem;
    color: var(--de-faint);
    transition: transform 0.24s ease;
}

.de-acc__item--open .de-acc__chevron {
    transform: rotate(180deg);
}

/* Hidden as well as shut, so nothing inside a closed row can be tabbed to or
   read out; the visibility waits for the row to finish closing. */
.de-acc__panel {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    visibility: hidden;
    transition: grid-template-rows 0.24s ease, opacity 0.18s ease, visibility 0s linear 0.24s;
}

.de-acc__item--open .de-acc__panel {
    grid-template-rows: 1fr;
    opacity: 1;
    visibility: visible;
    transition: grid-template-rows 0.24s ease, opacity 0.24s ease 0.06s, visibility 0s;
}

.de-acc__clip {
    min-height: 0;
    overflow: hidden;
}

/* Lined up under the row's name, past the icon, and no wider than a chart is
   readable at: a bar across a whole desktop is a stripe. */
.de-acc__body {
    max-width: 46rem;
    padding: 0.5rem 0.875rem 1.125rem 3.75rem;
}

.de-acc__line {
    margin: 0 0 0.75rem;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--de-muted);
}

.de-acc__line:last-child {
    margin-bottom: 0;
}

.de-acc__line strong {
    font-weight: 600;
    color: var(--de-ink);
}

.de-acc__unused {
    margin: 0.875rem 0 0;
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--de-muted);
}

/* ------------------------------------------------------------- columns
 *
 * For values with an order of their own: budgets, sizes, bedrooms. Drawn left
 * to right in that order, the most chosen in the full blue and the rest in a
 * pale tint of it, so each chart has one thing to look at first.
 */

.de-cols {
    display: flex;
    align-items: stretch;
    gap: 0.375rem;
    max-width: 38rem;
}

.de-cols__col {
    display: flex;
    flex-direction: column;
    flex: 1 1 0;
    min-width: 0;
}

/* The count sits on top of its own column, so the eye never travels to an
   axis. The padding is the room the tallest column's count stands in. */
.de-cols__plot {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    box-sizing: border-box;
    height: 7.5rem;
    padding-top: 1.1rem;
    border-bottom: 1px solid var(--de-rule);
}

.de-cols__value {
    margin-bottom: 0.2rem;
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--de-text);
    font-variant-numeric: tabular-nums;
}

.de-cols__value--zero {
    color: var(--de-faint);
    font-weight: 500;
}

.de-cols__bar {
    display: block;
    width: 100%;
    max-width: 2.75rem;
    border-radius: 4px 4px 0 0;
    background: var(--de-accent-3);
    transition: background-color 0.12s ease;
}

.de-cols__bar--top {
    background: var(--de-accent);
}

.de-cols__col:hover .de-cols__bar:not(.de-cols__bar--top) {
    background: var(--de-accent-hover);
}

.de-cols__col--top .de-cols__value {
    color: var(--de-ink);
}

.de-cols__label {
    margin-top: 0.35rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: center;
    font-size: 0.6875rem;
    color: var(--de-muted);
    font-variant-numeric: tabular-nums;
}

.de-cols__col--top .de-cols__label {
    font-weight: 600;
    color: var(--de-ink);
}

/* What the axis is counted in, once, under its right-hand end. */
.de-cols__unit {
    max-width: 38rem;
    margin: 0.2rem 0 0;
    text-align: end;
    font-size: 0.6875rem;
    color: var(--de-faint);
}

/* ---------------------------------------------------------------- bars
 *
 * For names ranked by how often they were chosen: areas, types, developers.
 * The name takes the room and the bar a fixed share of what is left, so a
 * long area name is cut at the same place on every row and the numbers line
 * up down the right-hand edge.
 */

.de-bars {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.de-bars__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(5rem, 16rem) 2.75rem;
    align-items: center;
    gap: 0.75rem;
    font-size: 0.8125rem;
}

.de-bars__label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--de-text);
}

.de-bars__track {
    height: 0.5rem;
}

.de-bars__fill {
    display: block;
    height: 100%;
    border-radius: 9999px;
    background: var(--de-accent-3);
}

.de-bars__row--top .de-bars__fill {
    background: var(--de-accent);
}

.de-bars__row--top .de-bars__label {
    font-weight: 600;
    color: var(--de-ink);
}

.de-bars__value {
    text-align: end;
    font-weight: 600;
    color: var(--de-ink);
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------- what stands out
 *
 * Up to four findings, a sentence each with its numbers underneath. The tone
 * tints only the icon's tile: green for up, red for down, the brand's own
 * tint for news that is neither. The sentence always says which way in words.
 */

.de-hl {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0.75rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.de-hl__item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
    padding: 0.75rem 0.875rem;
    border-radius: 1rem;
    /* No card around the four, so each stands on the page the way the tiles
       above it do: the same ground, ring and lift. */
    background: var(--de-surface);
    box-shadow: var(--de-card-shadow), 0 0 0 1px var(--de-line);
}

.de-hl__icon {
    display: grid;
    flex: none;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 0.75rem;
    background: var(--de-tint);
    color: var(--de-tint-ink);
}

.de-hl__icon svg {
    width: 1.125rem;
    height: 1.125rem;
}

.de-hl__item--up .de-hl__icon {
    background: color-mix(in srgb, var(--de-up) 14%, transparent);
    color: var(--de-up);
}

.de-hl__item--down .de-hl__icon {
    background: color-mix(in srgb, var(--de-down) 14%, transparent);
    color: var(--de-down);
}

.de-hl__text {
    display: flex;
    flex-direction: column;
    gap: 0.0625rem;
    min-width: 0;
}

.de-hl__title,
.de-hl__detail {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.de-hl__title {
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.35;
    color: var(--de-ink);
}

.de-hl__title a {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: var(--de-rule);
    text-underline-offset: 3px;
}

.de-hl__title a:hover {
    text-decoration-color: currentColor;
}

.de-hl__detail {
    font-size: 0.75rem;
    line-height: 1.4;
    color: var(--de-muted);
}

/* ------------------------------------------------------------ the map card
 *
 * The contact card's shape. Its keys carry no swatches, because nothing on
 * this card is a part of a stack: a total, and the three buttons under it,
 * set in a step.
 */

.de-keys--plain .de-keys__name::before {
    display: none;
}

.de-keys__row--total .de-keys__name {
    font-weight: 600;
    color: var(--de-ink);
}

.de-keys__row--indent .de-keys__name {
    padding-inline-start: 0.875rem;
}

/* Three small figures in a row under the headline one: what the visits led
   to, without a line of words each. */
.de-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(4.5rem, 1fr));
    gap: 0.5rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--de-line);
}

.de-stats__item {
    display: flex;
    flex-direction: column;
    gap: 0.0625rem;
    min-width: 0;
}

.de-stats__value {
    font-size: 1.125rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--de-ink);
    font-variant-numeric: tabular-nums;
}

.de-stats__label {
    font-size: 0.75rem;
    color: var(--de-muted);
}

/* Short facts as chips: a share, and what was searched for. */
.de-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.de-facts__item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.7rem;
    border-radius: 9999px;
    background: var(--de-soft);
    font-size: 0.75rem;
    line-height: 1.3;
    color: var(--de-text);
}

.de-facts__item svg {
    width: 0.9375rem;
    height: 0.9375rem;
    flex: none;
    color: var(--de-tint-ink);
}

.de-facts__item strong {
    font-weight: 700;
    color: var(--de-ink);
}

/* The question a chart answers, over it, in the card's quiet voice. */
.de-panel__title {
    margin: 0 0 0.75rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--de-text);
}

/* A chart's question on the left, its one-word answer on the right. */
.de-panel__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.25rem 1rem;
    margin-bottom: 0.75rem;
}

.de-panel__head .de-panel__title {
    margin: 0;
}

.de-panel__aside {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--de-accent);
}

/* The filters of the chosen search page, under its visits in the same card. */
.de-search__filters {
    padding-top: 1.25rem;
    border-top: 1px solid var(--de-line);
}

/* The hours of a day across the whole chart side, not the 38rem a filter's
   columns stop at: eight columns, each a hand wide. */
.de-cols.de-cols--wide,
.de-cols__unit.de-cols--wide {
    max-width: none;
}

/* ------------------------------------------------------------ narrower */

@media (max-width: 64rem) {
    .de-dash__pair {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 56rem) {
    /* The figures go above their chart, across the card rather than down it. */
    .de-panel {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 40rem) {
    /* The date menu is the full width of the screen, and the switch under it. */
    .de-dash-head__controls,
    .de-range {
        width: 100%;
    }

    .de-range__trigger {
        width: 100%;
    }

    .de-range__trigger .de-range__label {
        flex: 1 1 auto;
        text-align: start;
    }

    .de-switch {
        width: 100%;
    }

    .de-switch__option {
        flex: 1 1 0;
    }

    .de-tabs {
        width: 100%;
    }

    /* The three share the row, so all of them are on screen; on a screen too
       narrow even for that they scroll sideways, without a scrollbar drawn
       under them. */
    .de-tabs {
        scrollbar-width: none;
    }

    .de-tabs__tab {
        flex: 1 0 auto;
        justify-content: center;
        gap: 0.35rem;
        padding: 0 0.5rem;
    }

    /* Five dates do not fit under a phone's chart; the two ends do. */
    .de-chart__date--between {
        display: none;
    }

    /* On a narrow panel a track costs more width than it earns, and the place
       is what makes a repeated name readable — so the bar goes and the second
       line stays. */
    .de-rank__row {
        grid-template-columns: 1.5rem minmax(0, 1fr) auto 3rem;
    }

    .de-rank__track,
    .de-acc__meter {
        display: none;
    }

    .de-acc__toggle {
        grid-template-columns: auto minmax(0, 1fr) auto auto;
        gap: 0.625rem;
    }

    .de-acc__body {
        padding-inline-start: 0.875rem;
    }

    .de-bars__row {
        grid-template-columns: minmax(0, 1fr) minmax(3rem, 5rem) 2.5rem;
    }
}

/* Nothing here moves for anybody who has asked for things not to. */
@media (prefers-reduced-motion: reduce) {
    .de-acc__panel,
    .de-acc__item--open .de-acc__panel,
    .de-acc__toggle .de-acc__chevron,
    .de-tip {
        transition: none;
    }
}
