/* =========================================================================
   Suitiee — Filament panel theme (shared across admin / provider / partner /
   client / staff). Loaded as a static stylesheet via the STYLES_AFTER render
   hook so it layers on top of Filament's compiled CSS without a per-panel
   Vite build. Saudi-premium "Soft UI Evolution": warm ivory canvas, terracotta
   brand, gold hairline accents, soft layered shadows, rounded cards.
   Dark mode is left to Filament defaults — light-mode rules are scoped with
   :where(html:not(.dark)) so toggling dark stays clean.
   ========================================================================= */

:root {
    --tv-ivory:         #FAF7F0;
    --tv-paper:         #FFFFFF;
    --tv-accent:        #C2703D;
    --tv-accent-deep:   #B05F33;
    --tv-ink:           #2B1D14;
    --tv-amber:         #E0A33D;
    --tv-gold:          #C9A227;
    --tv-accent-wash:   rgba(194,112,61, 0.08);
    --tv-accent-line:   rgba(194,112,61, 0.16);
    --tv-hairline:      rgba(11, 42, 34, 0.08);
    --tv-shadow-sm:     0 1px 2px rgba(11, 42, 34, 0.05);
    --tv-shadow-md:     0 1px 2px rgba(11, 42, 34, 0.04), 0 10px 28px -12px rgba(11, 42, 34, 0.16);
    --tv-shadow-lg:     0 2px 6px rgba(11, 42, 34, 0.05), 0 24px 48px -20px rgba(11, 42, 34, 0.22);
    --tv-radius:        1rem;
    --tv-font:          'Thmanyah Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
}

/* ---- Typography ---------------------------------------------------------- */
.fi-body,
.fi-simple-layout {
    font-family: var(--tv-font);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}
.fi-header-heading,
.fi-section-header-heading,
.fi-simple-header-heading,
.fi-wi-stats-overview-stat-value {
    font-family: var(--tv-font);
    letter-spacing: -0.012em;
    font-weight: 800;
}

/* ---- Canvas (ivory + faint Saudi girih watermark) ----------------------- */
:where(html:not(.dark)) .fi-body {
    background-color: var(--tv-ivory);
    background-image: url('/brand/pattern-girih-faint.svg');
    background-size: 64px;
    background-attachment: fixed;
}
:where(html:not(.dark)) .fi-main-ctn { background-color: transparent; }

/* ---- Sidebar ------------------------------------------------------------- */
:where(html:not(.dark)) .fi-sidebar {
    background-color: var(--tv-paper);
    border-inline-end: 1px solid var(--tv-hairline);
}
.fi-sidebar-item-btn {
    border-radius: 0.7rem;
    font-weight: 600;
    transition: background-color .18s ease, color .18s ease;
}
:where(html:not(.dark)) .fi-sidebar-item:not(.fi-active) .fi-sidebar-item-btn:hover {
    background-color: var(--tv-accent-wash);
}
/* Active item: accent wash pill + a crisp gold leading accent bar */
:where(html:not(.dark)) .fi-sidebar-item.fi-active > .fi-sidebar-item-btn {
    background-color: var(--tv-accent-wash);
    box-shadow: inset 3px 0 0 var(--tv-gold);
    color: var(--tv-accent-deep);
}
:where(html:not(.dark)) .fi-sidebar-item.fi-active .fi-sidebar-item-icon {
    color: var(--tv-accent-deep);
}
/* Group labels: smaller, tracked-out, brand-tinted */
.fi-sidebar-group-label {
    text-transform: uppercase;
    letter-spacing: 0.12em;
    font-size: 0.68rem;
    font-weight: 700;
    opacity: 0.72;
}

/* ---- Topbar -------------------------------------------------------------- */
:where(html:not(.dark)) .fi-topbar > nav,
:where(html:not(.dark)) .fi-topbar {
    background-color: rgba(255, 255, 255, 0.82);
    backdrop-filter: saturate(1.4) blur(10px);
    border-bottom: 1px solid var(--tv-hairline);
}

/* ---- Sections / cards ---------------------------------------------------- */
:where(html:not(.dark)) .fi-section {
    border-radius: var(--tv-radius);
    border: 1px solid var(--tv-hairline);
    box-shadow: var(--tv-shadow-md);
    background-color: var(--tv-paper);
}
.fi-section-header { padding-block: 1.1rem; }

/* ---- Stat / overview widgets -------------------------------------------- */
.fi-wi-stats-overview-stat { overflow: hidden; padding: 1.6rem 1.75rem; }
/* breathing room for stat internals so values never hug the border */
.fi-wi-stats-overview-stat-content { gap: 0.4rem; }
.fi-wi-stats-overview-stat-value { line-height: 1.15; }
/* The stat grid renders inside a bordered section whose content container has
   no padding, so the cards hug the section border. Pad that container (scoped to
   stat sections only, so form/table sections are untouched) for breathing room. */
.fi-section:has(.fi-wi-stats-overview-stat) .fi-section-content-ctn { padding: 1.5rem; }
:where(html:not(.dark)) .fi-wi-stats-overview-stat {
    border-radius: var(--tv-radius);
    border: 1px solid var(--tv-hairline);
    box-shadow: var(--tv-shadow-md);
    background:
        radial-gradient(120% 120% at 100% 0%, var(--tv-accent-wash), transparent 60%),
        var(--tv-paper);
    transition: transform .18s ease, box-shadow .18s ease;
}
:where(html:not(.dark)) .fi-wi-stats-overview-stat:hover {
    transform: translateY(-2px);
    box-shadow: var(--tv-shadow-lg);
}
.fi-wi-stats-overview-stat-value { font-size: 1.9rem; line-height: 1.1; }
.fi-wi-stats-overview-stat-label { font-weight: 600; }

/* ---- Buttons ------------------------------------------------------------- */
.fi-btn {
    border-radius: 0.65rem;
    font-weight: 600;
    transition: transform .15s ease, box-shadow .15s ease, filter .15s ease;
}
.fi-btn:active { transform: translateY(1px); }
/* Solid brand buttons get a touch of depth + a subtle vertical sheen */
.fi-btn.fi-color-primary:not(.fi-btn-outlined):not(.fi-link),
.fi-btn.fi-color-success:not(.fi-btn-outlined):not(.fi-link) {
    box-shadow: 0 1px 1px rgba(11, 42, 34, 0.18), 0 6px 16px -8px rgba(194,112,61, 0.7);
    background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.14), rgba(0, 0, 0, 0.04));
}
.fi-btn.fi-color-primary:not(.fi-btn-outlined):not(.fi-link):hover,
.fi-btn.fi-color-success:not(.fi-btn-outlined):not(.fi-link):hover {
    filter: brightness(1.04);
    box-shadow: 0 2px 2px rgba(11, 42, 34, 0.2), 0 10px 22px -8px rgba(194,112,61, 0.85);
}

/* ---- Tables -------------------------------------------------------------- */
:where(html:not(.dark)) .fi-ta {
    border-radius: var(--tv-radius);
    border: 1px solid var(--tv-hairline);
    box-shadow: var(--tv-shadow-md);
    overflow: hidden;
}
:where(html:not(.dark)) .fi-ta-header-cell {
    background-color: #FBFAF6;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: 0.72rem;
}
:where(html:not(.dark)) .fi-ta-row { transition: background-color .14s ease; }
:where(html:not(.dark)) .fi-ta-row:hover { background-color: var(--tv-accent-wash); }

/* ---- Inputs -------------------------------------------------------------- */
.fi-input-wrp { border-radius: 0.65rem; }
.fi-fo-field-wrp .fi-input-wrp:focus-within {
    box-shadow: 0 0 0 3px var(--tv-accent-line);
    border-color: var(--tv-accent);
}

/* ---- Dropdowns / modals -------------------------------------------------- */
.fi-dropdown-panel { border-radius: 0.9rem; box-shadow: var(--tv-shadow-lg); }
.fi-modal-window  { border-radius: 1.1rem; box-shadow: var(--tv-shadow-lg); }

/* ---- Empty states: clean brand-tinted icon (no injected illustration) ---- */
.fi-empty-state-icon-bg {
    background-color: var(--tv-accent-wash);
    color: var(--tv-accent-deep);
}
.dark .fi-empty-state-icon-bg {
    background-color: rgba(194,112,61, 0.16);
    color: #DBA07C;
}

/* ---- Branded login (simple layout, all panels) -------------------------- */
:where(html:not(.dark)) .fi-simple-layout {
    background-color: var(--tv-ivory);
    background-image:
        radial-gradient(60% 45% at 70% 0%, var(--tv-accent-wash), transparent 70%),
        url('/brand/panel/login-aside.jpg');
    background-repeat: no-repeat, no-repeat;
    background-position: center, center;
    background-size: cover, cover;
}
:where(html:not(.dark)) .fi-simple-main {
    background-color: rgba(255, 255, 255, 0.94);
    backdrop-filter: saturate(1.2) blur(10px);
    border: 1px solid var(--tv-hairline);
    border-top: 3px solid var(--tv-gold);
    border-radius: 1.25rem;
    box-shadow: var(--tv-shadow-lg);
}

/* ========================================================================
   Dark mode — Suitiee warm-ink theme (tints Filament's neutral dark toward
   the brand: deep espresso canvas, hairline borders, terracotta accents).
   ======================================================================== */
.dark {
    --tv-d-canvas: #17120D;   /* refined charcoal with a whisper of warmth (not loud) */
    --tv-d-surface: #201913;  /* neutral-leaning dark charcoal */
    --tv-d-raise:  #2B2219;   /* header band, clearly lighter */
    --tv-d-line:   #3A2E24;   /* visible neutral hairline (~3:1 vs surface) */
    --tv-d-accent: #CD8253;
    --tv-d-mint:   #DBA07C;
    --tv-d-text:   #F1EAE1;   /* near-white body text */
    --tv-d-muted:  #B3A697;   /* neutral-grey muted text (AA on surface) */
}
/* Base + muted text contrast (Filament defaults are too dim on the ink) */
.dark, .dark .fi-body { color: var(--tv-d-text); }
.dark .fi-section-description,
.dark .fi-fo-field-wrp-hint,
.dark .fi-fo-field-wrp-helper-text,
.dark [class*="text-gray-5"],
.dark [class*="text-gray-6"] { color: var(--tv-d-muted) !important; }

/* Canvas: emerald girih watermark — visible on dark (the gold one disappeared) */
.dark .fi-body {
    background-color: var(--tv-d-canvas);
    background-image: url('/brand/pattern-girih-emerald.svg');
    background-size: 60px;
    background-attachment: fixed;
    background-blend-mode: normal;
}

/* Sidebar */
.dark .fi-sidebar { background-color: var(--tv-d-surface); border-inline-end: 1px solid var(--tv-d-line); }
.dark .fi-sidebar-item:not(.fi-active) .fi-sidebar-item-btn:hover { background-color: rgba(205, 130, 83, 0.07); }
.dark .fi-sidebar-item.fi-active > .fi-sidebar-item-btn {
    background-color: rgba(205, 130, 83, 0.10);
    box-shadow: inset 3px 0 0 var(--tv-gold);
    color: var(--tv-d-mint);
}
.dark .fi-sidebar-item.fi-active .fi-sidebar-item-icon { color: var(--tv-d-mint); }
.dark .fi-sidebar-group-label { color: var(--tv-d-muted); opacity: 0.9; }

/* Topbar: frosted + readable controls (fixes the faint locale toggle) */
.dark .fi-topbar > nav,
.dark .fi-topbar {
    background-color: rgba(23, 18, 13, 0.82);
    border-bottom: 1px solid var(--tv-d-line);
    backdrop-filter: saturate(1.15) blur(10px);
}
.dark .fi-topbar a,
.dark .fi-topbar .fi-icon-btn,
.dark .fi-topbar .fi-dropdown-trigger { color: var(--tv-d-text); }

/* Sections / cards: clean charcoal surface (texture lives on the canvas) */
.dark .fi-section {
    background-color: var(--tv-d-surface);
    border: 1px solid var(--tv-d-line);
    box-shadow: none;
}

/* Stat / overview widgets: depth on dark, restrained accent wash */
.dark .fi-wi-stats-overview-stat {
    border: 1px solid var(--tv-d-line);
    background:
        radial-gradient(130% 130% at 100% 0%, rgba(194, 112, 61, 0.05), transparent 62%),
        var(--tv-d-surface);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.28), 0 10px 26px -14px rgba(0, 0, 0, 0.5);
}
.dark .fi-wi-stats-overview-stat:hover {
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.32), 0 16px 36px -16px rgba(194, 112, 61, 0.22);
}

/* Tables: ONE rounded bordered card (the inner container's default slate bg +
   rectangular border are the "blue box" + "double border"), uniform header band */
.dark .fi-ta { border: 1px solid var(--tv-d-line); border-radius: var(--tv-radius); overflow: hidden; box-shadow: none; }
.dark .fi-ta-ctn { background-color: var(--tv-d-surface); border-color: transparent; box-shadow: none; }
.dark .fi-ta-header { background-color: var(--tv-d-raise); }
.dark .fi-ta-header-cell { background-color: var(--tv-d-raise); color: var(--tv-d-text); }
.dark .fi-ta-row:hover { background-color: rgba(205, 130, 83, 0.06); }

/* Inputs */
.dark .fi-input-wrp { border-color: var(--tv-d-line); }
.dark input::placeholder, .dark textarea::placeholder { color: var(--tv-d-muted); opacity: 1; }
.dark .fi-fo-field-wrp .fi-input-wrp:focus-within {
    box-shadow: 0 0 0 3px rgba(194, 112, 61, 0.28);
    border-color: var(--tv-d-mint);
}

/* Solid brand buttons: dark-appropriate sheen + shadow (no light-mode leak) */
.dark .fi-btn.fi-color-primary:not(.fi-btn-outlined):not(.fi-link),
.dark .fi-btn.fi-color-success:not(.fi-btn-outlined):not(.fi-link) {
    background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(0, 0, 0, 0.14));
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.32), 0 6px 16px -8px rgba(194, 112, 61, 0.45);
}

/* Floating surfaces: emerald-ink (not default slate) + real shadows on dark */
.dark .fi-dropdown-panel,
.dark .fi-modal-window {
    background-color: var(--tv-d-surface);
    border: 1px solid var(--tv-d-line);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5), 0 24px 48px -20px rgba(0, 0, 0, 0.7);
}

/* Branded login on dark: frosted glass + texture */
.dark .fi-simple-layout {
    background-color: var(--tv-d-canvas);
    background-image:
        radial-gradient(60% 45% at 70% 0%, rgba(194, 112, 61, 0.16), transparent 70%),
        url('/brand/pattern-girih-emerald.svg');
    background-size: cover, 60px;
    background-attachment: scroll, fixed;
}
.dark .fi-simple-main {
    background-color: rgba(32, 25, 19, 0.9);
    backdrop-filter: saturate(1.12) blur(12px);
    border: 1px solid var(--tv-d-line);
    border-top: 3px solid var(--tv-gold);
    box-shadow: 0 24px 48px -20px rgba(0, 0, 0, 0.7);
}

/* ---- Shared form divider (theme-aware) ---------------------------------- */
.tv-form-divider { border-top: 1px solid var(--tv-hairline); }
.dark .tv-form-divider { border-top-color: var(--tv-d-line); }

/* ---- Reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .fi-btn, .fi-sidebar-item-btn, .fi-ta-row, .fi-wi-stats-overview-stat {
        transition: none !important;
    }
    .fi-wi-stats-overview-stat:hover { transform: none; }
    /* The calendar's hover and press feedback, for anyone who asked the
       system for less movement. Colour changes stay; motion goes. */
    .tv-cal-item, .tv-cal-ev, .tv-cal-chip, .tv-cal-month__cell, .tv-cal-jump__select {
        transition: none !important;
    }
    .tv-cal-chip:active, .tv-cal-ev:hover { transform: none; }
}

/* ---- Arabic / RTL ---------------------------------------------------------
   Letter-spacing visually breaks Arabic cursive joining; zero all tracking
   when the panel renders RTL. */
[dir='rtl'] *,
[dir='rtl'] *::before,
[dir='rtl'] *::after {
    letter-spacing: 0 !important;
}

/* =========================================================================
   Setup guide (.tv-sg-*, .tv-ring, .tv-copy-*)
   Shared by the Get Started page and the dashboard nudge in all five panels.
   Written as plain CSS rather than Tailwind utilities: these panels have no
   per-panel Vite theme, so only the utilities Filament itself ships would
   compile. Logical properties throughout so RTL needs no separate rules.
   ========================================================================= */

/* ---- Progress ring ------------------------------------------------------ */
.tv-ring {
    position: relative;
    flex: 0 0 auto;
    width: var(--tv-ring-size);
    height: var(--tv-ring-size);
    display: grid;
    place-items: center;
}
.tv-ring svg {
    /* Start the sweep at twelve o'clock. */
    transform: rotate(-90deg);
    overflow: visible;
}
.tv-ring__track { stroke: var(--tv-accent-line); }
.dark .tv-ring__track { stroke: rgba(255, 255, 255, 0.12); }
.tv-ring__value {
    stroke: var(--tv-accent);
    stroke-dasharray: var(--tv-ring-dash);
    /* Animate from empty to the served offset. */
    stroke-dashoffset: var(--tv-ring-dash);
    animation: tv-ring-sweep 1s cubic-bezier(0.22, 1, 0.36, 1) 0.15s forwards;
    filter: drop-shadow(0 2px 6px rgba(194, 112, 61, 0.35));
}
@keyframes tv-ring-sweep {
    to { stroke-dashoffset: var(--tv-ring-offset); }
}
.tv-ring__label {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-weight: 800;
    color: var(--tv-ink);
}
.dark .tv-ring__label { color: #F5EFE8; }
.tv-sg-ring-num { font-size: 1.5rem; line-height: 1; }
.tv-sg-ring-num--sm { font-size: 1rem; }
.tv-sg-ring-den { font-size: 0.7em; opacity: 0.55; font-weight: 700; }

/* ---- Hero --------------------------------------------------------------- */
.tv-sg-hero {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    flex-wrap: wrap;
    padding: 1.5rem;
    border: 1px solid var(--tv-accent-line);
    border-radius: var(--tv-radius);
    background: linear-gradient(125deg, #FFFFFF 0%, var(--tv-ivory) 60%, #FBF1E7 100%);
    box-shadow: var(--tv-shadow-md);
    animation: tv-sg-rise 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.dark .tv-sg-hero {
    background: linear-gradient(125deg, #221A13 0%, #1B1510 100%);
    border-color: rgba(255, 255, 255, 0.08);
}
.tv-sg-hero--done { border-color: rgba(31, 157, 107, 0.35); }
.tv-sg-hero-body { flex: 1 1 18rem; min-width: 0; }
.tv-sg-hero-title {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 800;
    letter-spacing: -0.015em;
    color: var(--tv-ink);
}
.dark .tv-sg-hero-title { color: #F7F1EA; }
.tv-sg-hero-sub {
    margin: 0.35rem 0 0;
    font-size: 0.9rem;
    line-height: 1.6;
    color: #6B5645;
}
.dark .tv-sg-hero-sub { color: #B6A493; }

.tv-sg-meta { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.75rem; }
.tv-sg-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 700;
    background: var(--tv-accent-wash);
    color: var(--tv-accent-deep);
}
.dark .tv-sg-chip { background: rgba(194, 112, 61, 0.18); color: #DBA07C; }
.tv-sg-chip--muted {
    background: rgba(11, 42, 34, 0.06);
    color: #6B5645;
}
.dark .tv-sg-chip--muted { background: rgba(255, 255, 255, 0.08); color: #B6A493; }

/* ---- Progress bar ------------------------------------------------------- */
.tv-sg-bar {
    display: block;
    margin-top: 0.85rem;
    height: 0.5rem;
    border-radius: 999px;
    background: rgba(11, 42, 34, 0.08);
    overflow: hidden;
}
.dark .tv-sg-bar { background: rgba(255, 255, 255, 0.1); }
.tv-sg-bar--sm { height: 0.35rem; margin-top: 0.5rem; }
.tv-sg-bar-fill {
    display: block;
    height: 100%;
    width: var(--tv-sg-pct);
    border-radius: inherit;
    background: linear-gradient(90deg, var(--tv-accent), var(--tv-amber));
    transform-origin: left center;
    animation: tv-sg-fill 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.1s both;
}
[dir='rtl'] .tv-sg-bar-fill { transform-origin: right center; }
@keyframes tv-sg-fill {
    from { transform: scaleX(0); }
    to { transform: scaleX(1); }
}

/* ---- Step list ---------------------------------------------------------- */
.tv-sg-paths {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 1rem 0 0;
    animation: tv-sg-rise 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.tv-sg-paths-label {
    flex: 0 0 100%;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #9A8473;
}
.tv-sg-path {
    flex: 1 1 14rem;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    padding: 0.75rem 0.9rem;
    text-align: start;
    border: 1px solid var(--tv-accent-line);
    border-radius: var(--tv-radius);
    background: #FFFFFF;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.tv-sg-path:hover { border-color: var(--tv-ink); transform: translateY(-1px); }
.tv-sg-path.is-current {
    border-color: var(--tv-ink);
    box-shadow: inset 0 0 0 1px var(--tv-ink);
}
.tv-sg-path-label { font-size: 0.85rem; font-weight: 800; color: var(--tv-ink); }
.tv-sg-path-desc { font-size: 0.76rem; line-height: 1.5; color: #6B5645; }
.dark .tv-sg-path { background: #1B1510; border-color: rgba(255, 255, 255, 0.08); }
.dark .tv-sg-path-label { color: #F7F1EA; }
@media (prefers-reduced-motion: reduce) {
    .tv-sg-path:hover { transform: none; }
}
.tv-sg-steps {
    list-style: none;
    margin: 1.25rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
.tv-sg-step {
    border: 1px solid var(--tv-hairline);
    border-radius: var(--tv-radius);
    background: var(--tv-paper);
    box-shadow: var(--tv-shadow-sm);
    overflow: hidden;
    transition: border-color 0.18s, box-shadow 0.18s, transform 0.18s;
    /* Staggered entrance, capped so a long list does not crawl in. */
    animation: tv-sg-rise 0.45s cubic-bezier(0.22, 1, 0.36, 1) both;
    animation-delay: calc(min(var(--i), 6) * 60ms + 120ms);
}
.dark .tv-sg-step { background: #1B1510; border-color: rgba(255, 255, 255, 0.08); }
.tv-sg-step:hover {
    border-color: var(--tv-accent-line);
    box-shadow: var(--tv-shadow-md);
}
.tv-sg-step.is-done { background: linear-gradient(90deg, rgba(31, 157, 107, 0.05), transparent 40%); }
.dark .tv-sg-step.is-done { background: linear-gradient(90deg, rgba(31, 157, 107, 0.12), transparent 40%); }

.tv-sg-step-head {
    width: 100%;
    display: flex;
    align-items: flex-start;
    gap: 0.9rem;
    padding: 1rem 1.1rem;
    background: none;
    border: none;
    cursor: pointer;
    text-align: start;
    font: inherit;
    color: inherit;
}

.tv-sg-marker {
    flex: 0 0 auto;
    width: 1.85rem;
    height: 1.85rem;
    border-radius: 999px;
    display: grid;
    place-items: center;
    font-size: 0.8rem;
    font-weight: 800;
    background: var(--tv-accent-wash);
    color: var(--tv-accent-deep);
    border: 1px solid var(--tv-accent-line);
}
.dark .tv-sg-marker { background: rgba(194, 112, 61, 0.16); color: #DBA07C; border-color: rgba(255, 255, 255, 0.1); }
.is-done .tv-sg-marker {
    background: #1F9D6B;
    border-color: #1F9D6B;
    color: #fff;
}
.tv-sg-tick {
    width: 1rem;
    height: 1rem;
    animation: tv-sg-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
@keyframes tv-sg-pop {
    from { transform: scale(0.2); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

.tv-sg-step-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.tv-sg-step-title {
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--tv-ink);
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
}
.dark .tv-sg-step-title { color: #F2EAE2; }
.is-done .tv-sg-step-title { color: #4A6B5E; }
.dark .is-done .tv-sg-step-title { color: #9FC4B4; }
.tv-sg-step-desc { font-size: 0.83rem; line-height: 1.55; color: #6B5645; }
.dark .tv-sg-step-desc { color: #A89685; }
.tv-sg-step-detail {
    font-size: 0.78rem;
    font-weight: 600;
    color: #1F9D6B;
    direction: ltr;
    text-align: start;
}

.tv-sg-tag {
    padding: 0.08rem 0.45rem;
    border-radius: 999px;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    background: rgba(11, 42, 34, 0.07);
    color: #6B5645;
}
.dark .tv-sg-tag { background: rgba(255, 255, 255, 0.1); color: #B6A493; }

.tv-sg-step-aside { flex: 0 0 auto; display: flex; align-items: center; gap: 0.55rem; }
.tv-sg-mins { font-size: 0.72rem; font-weight: 600; color: #9A8473; white-space: nowrap; }
.tv-sg-caret {
    width: 1.1rem;
    height: 1.1rem;
    color: #9A8473;
    transition: transform 0.25s ease;
}
.tv-sg-step-head[aria-expanded='true'] .tv-sg-caret { transform: rotate(180deg); }

.tv-sg-step-body { padding: 0 1.1rem 1.1rem; }
.tv-sg-step-body > * + * { margin-top: 0.75rem; }

/* ---- Inline step panels ------------------------------------------------- */
.tv-sg-panel { display: flex; flex-direction: column; gap: 0.75rem; }
.tv-sg-form { display: flex; flex-direction: column; gap: 0.35rem; }
.tv-sg-form-row { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.tv-sg-label { font-size: 0.8rem; font-weight: 700; color: var(--tv-ink); }
.dark .tv-sg-label { color: #E8DED4; }
.tv-sg-input {
    flex: 1 1 14rem;
    min-width: 0;
    border-radius: 0.65rem;
    border: 1px solid var(--tv-accent-line);
    background: #fff;
    padding: 0.5rem 0.75rem;
    font-size: 0.85rem;
    color: var(--tv-ink);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.tv-sg-input:focus {
    outline: none;
    border-color: var(--tv-accent);
    box-shadow: 0 0 0 4px var(--tv-accent-wash);
}
.dark .tv-sg-input { background: #140F0A; border-color: rgba(255, 255, 255, 0.12); color: #F2EAE2; }
.tv-sg-error { font-size: 0.75rem; font-weight: 600; color: #C0392B; }
.tv-sg-note { font-size: 0.78rem; line-height: 1.55; color: #6B5645; margin: 0; }
.dark .tv-sg-note { color: #A89685; }
.tv-sg-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.tv-sg-reveal { display: flex; flex-direction: column; gap: 0.65rem; }

.tv-sg-waiting {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: 0.78rem;
    color: #6B5645;
}
.dark .tv-sg-waiting { color: #A89685; }
.tv-sg-pulse {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 999px;
    background: var(--tv-accent);
    animation: tv-sg-pulse 1.6s ease-in-out infinite;
}
@keyframes tv-sg-pulse {
    0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(194, 112, 61, 0.5); }
    50% { opacity: 0.6; box-shadow: 0 0 0 6px rgba(194, 112, 61, 0); }
}

/* ---- CTA ---------------------------------------------------------------- */
.tv-sg-cta {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.9rem;
    border-radius: 0.65rem;
    font-size: 0.83rem;
    font-weight: 700;
    text-decoration: none;
    color: #fff;
    background: linear-gradient(135deg, var(--tv-accent), var(--tv-accent-deep));
    box-shadow: 0 6px 16px -8px rgba(194, 112, 61, 0.8);
    transition: transform 0.15s, box-shadow 0.15s;
}
.tv-sg-cta:hover { transform: translateY(-1px); box-shadow: 0 10px 22px -10px rgba(194, 112, 61, 0.9); }
.tv-sg-cta-arrow { width: 1rem; height: 1rem; transition: transform 0.15s; }
[dir='rtl'] .tv-sg-cta-arrow { transform: scaleX(-1); }
.tv-sg-cta:hover .tv-sg-cta-arrow { transform: translateX(2px); }
[dir='rtl'] .tv-sg-cta:hover .tv-sg-cta-arrow { transform: scaleX(-1) translateX(2px); }

/* ---- Dashboard nudge ---------------------------------------------------- */
.tv-sg-nudge {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1rem 1.15rem;
    border: 1px solid var(--tv-accent-line);
    border-radius: var(--tv-radius);
    background: linear-gradient(120deg, #FFFFFF, var(--tv-ivory));
    box-shadow: var(--tv-shadow-sm);
    text-decoration: none;
    color: inherit;
    transition: transform 0.18s, box-shadow 0.18s, border-color 0.18s;
    animation: tv-sg-rise 0.45s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.dark .tv-sg-nudge { background: linear-gradient(120deg, #221A13, #1B1510); border-color: rgba(255, 255, 255, 0.08); }
.tv-sg-nudge:hover { transform: translateY(-2px); box-shadow: var(--tv-shadow-md); border-color: var(--tv-accent); }
.tv-sg-nudge-body { flex: 1 1 auto; min-width: 0; }
.tv-sg-nudge-title { display: block; font-weight: 800; font-size: 0.95rem; color: var(--tv-ink); }
.dark .tv-sg-nudge-title { color: #F2EAE2; }
.tv-sg-nudge-next { display: block; margin-top: 0.15rem; font-size: 0.82rem; color: #6B5645; }
.dark .tv-sg-nudge-next { color: #A89685; }
.tv-sg-nudge-label { font-weight: 700; color: var(--tv-accent-deep); }
.dark .tv-sg-nudge-label { color: #DBA07C; }
.tv-sg-nudge-cta {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--tv-accent-deep);
}
.dark .tv-sg-nudge-cta { color: #DBA07C; }

/* ---- Copyable values (also used by the docs pages) ---------------------- */
.tv-copy-field { display: flex; flex-direction: column; gap: 0.3rem; }
.tv-copy-label { font-size: 0.78rem; font-weight: 700; color: var(--tv-ink); }
.dark .tv-copy-label { color: #E8DED4; }
.tv-copy-row {
    display: flex;
    align-items: stretch;
    gap: 0.4rem;
    border: 1px solid var(--tv-accent-line);
    border-radius: 0.65rem;
    background: var(--tv-ivory);
    padding: 0.45rem 0.55rem;
}
.dark .tv-copy-row { background: #140F0A; border-color: rgba(255, 255, 255, 0.12); }
.tv-copy-field--secret .tv-copy-row {
    background: #FFF8EC;
    border-color: rgba(224, 163, 61, 0.5);
}
.dark .tv-copy-field--secret .tv-copy-row { background: #241B0F; border-color: rgba(224, 163, 61, 0.4); }
.tv-copy-value {
    flex: 1 1 auto;
    min-width: 0;
    font-family: ui-monospace, 'SF Mono', Menlo, monospace;
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--tv-accent-deep);
    word-break: break-all;
    user-select: all;
    background: none;
    margin: 0;
}
.dark .tv-copy-value { color: #DBA07C; }
.tv-copy-value--block { white-space: pre-wrap; max-height: 16rem; overflow: auto; }
.tv-copy-btn {
    flex: 0 0 auto;
    align-self: flex-start;
    border: none;
    background: none;
    padding: 0.15rem;
    cursor: pointer;
    color: #9A8473;
    transition: color 0.15s, transform 0.15s;
}
.tv-copy-btn:hover { color: var(--tv-accent); transform: scale(1.08); }
.tv-copy-btn svg { width: 1.05rem; height: 1.05rem; }
.tv-copy-note { font-size: 0.73rem; color: #9A8473; }

/* ---- Embedded API reference (partner panel) ----------------------------- */
.tv-doc-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    padding: 0.85rem 1.1rem;
    border: 1px solid var(--tv-accent-line);
    border-radius: var(--tv-radius);
    background: linear-gradient(120deg, #FFFFFF, var(--tv-ivory));
}
.dark .tv-doc-bar { background: #1E1710; border-color: rgba(255, 255, 255, 0.08); }
.tv-doc-eyebrow {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 800;
    color: var(--tv-accent-deep);
}
.dark .tv-doc-eyebrow { color: #E9C5AE; }
.tv-doc-eyebrow svg { width: 1.1rem; height: 1.1rem; fill: var(--tv-accent); }
.tv-doc-bar .tv-copy-field { flex: 1 1 16rem; min-width: 0; }
.tv-doc-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    border-radius: 0.6rem;
    padding: 0.5rem 0.85rem;
    font-size: 0.8rem;
    font-weight: 700;
    text-decoration: none;
    color: var(--tv-accent-deep);
    border: 1px solid var(--tv-accent-line);
    background: var(--tv-paper);
    transition: background 0.15s;
}
.tv-doc-link:hover { background: #FBF3EE; }
.dark .tv-doc-link { color: #DBA07C; background: #140F0A; border-color: rgba(255, 255, 255, 0.12); }

.tv-apiref {
    margin-top: 0.9rem;
    height: calc(100vh - 11rem);
    min-height: 560px;
    border: 1px solid var(--tv-accent-line);
    border-radius: var(--tv-radius);
    overflow: hidden;
    background: #fff;
    /* Tint Stoplight's own tokens toward the Suitiee palette. */
    --color-primary: #A85A30;
    --color-primary-darker: #8A4727;
    --color-primary-dark: #6E3920;
    --color-primary-light: #C2703D;
    --color-primary-tint: rgba(194, 112, 61, 0.12);
}
.dark .tv-apiref { border-color: rgba(255, 255, 255, 0.08); }
.tv-apiref .sl-elements,
.tv-apiref elements-api { height: 100%; font-family: var(--tv-font); }

/* ---- Shared entrance ---------------------------------------------------- */
@keyframes tv-sg-rise {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .tv-sg-hero,
    .tv-sg-step,
    .tv-sg-nudge,
    .tv-sg-tick,
    .tv-sg-bar-fill,
    .tv-ring__value,
    .tv-sg-pulse {
        animation: none !important;
    }
    /* Without the sweep the ring must still show the right arc. */
    .tv-ring__value { stroke-dashoffset: var(--tv-ring-offset); }
    .tv-sg-cta:hover,
    .tv-sg-nudge:hover { transform: none; }
}

/* =========================================================================
   Dashboard system (.tv-dash-*, .tv-hero, .tv-rail, .tv-chip, .tv-tile)

   One vocabulary for all five panel dashboards. Each of them used to carry
   its own ~40-line inline <style> block declaring the same hero, the same
   pulse rail and the same action tiles under a different prefix
   (tv-ad-/tv-cd-/tv-pd-/tv-vd-/tv-sd-), so a change to the shared look meant
   five edits and the five had already drifted -- different radii, different
   shadows, three different greeting gradients. Panels now differ only where
   they should: what the hero says and which tiles it offers.

   Plain CSS rather than Tailwind utilities for the same reason as the setup
   guide above: the panels have no per-panel Vite theme, so only the utilities
   Filament itself ships would compile. Logical properties throughout, so RTL
   needs no separate rules.
   ========================================================================= */

/* ---- Layout ------------------------------------------------------------- */
.tv-dash { display: flex; flex-direction: column; gap: 1.5rem; }

/* The split is a variable so a panel can weight its two columns without
   redeclaring the grid. Single column below lg in every panel. */
.tv-dash-grid { display: grid; grid-template-columns: 1fr; gap: 1.25rem; }
@media (min-width: 1024px) {
    .tv-dash-grid { grid-template-columns: var(--tv-dash-split, 1.4fr 1fr); }
}

/* ---- Entrance ----------------------------------------------------------- */
/* Staggered by --tv-i, capped so a long list does not crawl in one row at a
   time. Transform and opacity only: nothing here triggers layout. */
.tv-rise {
    animation: tv-rise 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
    animation-delay: calc(min(var(--tv-i, 0), 8) * 55ms);
}
@keyframes tv-rise {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: none; }
}

/* ---- Greeting hero ------------------------------------------------------ */
.tv-hero {
    position: relative;
    overflow: hidden;
    border-radius: 1.1rem;
    padding: 1.6rem 1.75rem;
    color: #fff;
    /* The rail beside it is as tall as its rows, so on a short hero the grid
       stretched this one and left the greeting stranded against the top edge
       with a third of the card empty. Centring costs nothing when the two are
       the same height and fixes it when they are not. */
    display: flex;
    flex-direction: column;
    justify-content: center;
    background: linear-gradient(135deg, var(--tv-accent), #5A301D);
    box-shadow: 0 18px 40px -20px rgba(110, 57, 32, 0.6);
}
/* Provider reads as the operational counterpart to the client's, so its
   gradient runs the other way. Same tokens, no second declaration. */
.tv-hero--deep { background: linear-gradient(135deg, #5A301D, var(--tv-accent)); }

.tv-hero__girih {
    position: absolute;
    inset: 0;
    background: url('/brand/pattern-girih-gold.svg') center / 420px;
    opacity: 0.08;
    pointer-events: none;
}
.tv-hero__nova {
    position: absolute;
    inset-block-start: -14px;
    inset-inline-end: -10px;
    color: var(--tv-gold);
    opacity: 0.4;
    pointer-events: none;
}
.tv-hero__eyebrow {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: #F0D9A0;
}
.tv-hero__eyebrow::before {
    content: '';
    height: 2px;
    width: 26px;
    background: var(--tv-gold);
    border-radius: 2px;
}
[dir='rtl'] .tv-hero__eyebrow { letter-spacing: 0; }
.tv-hero__title {
    position: relative;
    margin-top: 0.85rem;
    font-size: 1.6rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.1;
}
.tv-hero__meta { position: relative; margin-top: 0.3rem; font-size: 0.82rem; opacity: 0.82; }
.tv-hero__sub { position: relative; margin-top: 0.4rem; font-size: 0.9rem; opacity: 0.88; }

.tv-hero__cta {
    position: relative;
    margin-top: 1.4rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.25rem;
}
.tv-hero__btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: var(--tv-amber);
    color: #321913;
    font-weight: 800;
    border-radius: 0.7rem;
    padding: 0.7rem 1.2rem;
    font-size: 0.92rem;
    text-decoration: none;
    transition: filter 0.15s, transform 0.15s, box-shadow 0.15s;
    box-shadow: 0 8px 18px -8px rgba(224, 163, 61, 0.85);
}
.tv-hero__btn:hover {
    filter: brightness(1.05);
    transform: translateY(-1px);
    box-shadow: 0 12px 24px -10px rgba(224, 163, 61, 0.95);
}
.tv-hero__ghost {
    color: rgba(255, 255, 255, 0.9);
    font-weight: 600;
    font-size: 0.88rem;
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: border-color 0.15s;
}
.tv-hero__ghost:hover { border-color: rgba(255, 255, 255, 0.6); }

/* A single highlighted fact inside the hero -- the cleaner's next job. */
.tv-hero__capsule {
    position: relative;
    margin-top: 1.3rem;
    border-radius: 0.9rem;
    background: rgba(255, 255, 255, 0.12);
    backdrop-filter: blur(4px);
    padding: 1rem 1.1rem;
    border: 1px solid rgba(255, 255, 255, 0.16);
}
.tv-hero__capsule-label {
    font-size: 0.64rem;
    font-weight: 800;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--tv-amber);
}
[dir='rtl'] .tv-hero__capsule-label { letter-spacing: 0; }
.tv-hero__capsule-title { margin-top: 0.3rem; font-size: 1.05rem; font-weight: 800; }
.tv-hero__capsule-meta { margin-top: 0.15rem; font-size: 0.82rem; color: rgba(255, 255, 255, 0.82); }
.tv-hero__avatar {
    position: relative;
    width: 3rem;
    height: 3rem;
    border-radius: 999px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    object-fit: cover;
    flex-shrink: 0;
}

/* ---- Surface shared by the rail and the status card --------------------- */
.tv-surface {
    border: 1px solid var(--tv-hairline);
    border-radius: 1.1rem;
    background: var(--tv-paper);
    box-shadow: 0 10px 28px -16px rgba(43, 29, 20, 0.18);
}
.dark .tv-surface { background: var(--tv-d-surface); border-color: var(--tv-d-line); }

/* ---- Pulse rail (a labelled list of facts) ------------------------------ */
.tv-rail { display: flex; flex-direction: column; overflow: hidden; }
.tv-rail__head {
    padding: 0.85rem 1.2rem;
    border-bottom: 1px solid rgba(43, 29, 20, 0.06);
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--tv-accent-deep);
}
[dir='rtl'] .tv-rail__head { letter-spacing: 0; }
.dark .tv-rail__head { color: var(--tv-d-mint); border-color: var(--tv-d-line); }
.tv-rail__row { padding: 1rem 1.2rem; border-bottom: 1px solid rgba(43, 29, 20, 0.05); }
.tv-rail__row:last-child { border-bottom: 0; }
.dark .tv-rail__row { border-color: rgba(255, 255, 255, 0.06); }
.tv-rail__row--inline { display: flex; align-items: center; gap: 0.7rem; }
.tv-rail__label { font-size: 0.76rem; font-weight: 600; color: #9A8473; }
.dark .tv-rail__label { color: var(--tv-d-muted); }
.tv-rail__value {
    margin-top: 0.25rem;
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--tv-ink);
}
.dark .tv-rail__value { color: #FBF3EE; }
.tv-rail__row--inline .tv-rail__value { margin: 0; margin-inline-start: auto; }
.tv-rail__value--lg { font-size: 1.7rem; display: flex; align-items: baseline; gap: 0.4rem; }
.tv-rail__value--lg svg { width: 0.95rem; height: 0.95rem; opacity: 0.7; }
a.tv-rail__value { text-decoration: none; transition: color 0.15s; }
a.tv-rail__value:hover { color: var(--tv-accent-deep); }
.tv-rail__muted { margin-top: 0.3rem; font-size: 0.85rem; color: #9A8473; }
.dark .tv-rail__muted { color: var(--tv-d-muted); }
.tv-rail__link { color: var(--tv-accent-deep); font-weight: 700; text-decoration: none; }
.tv-rail__link:hover { text-decoration: underline; }
.dark .tv-rail__link { color: var(--tv-d-mint); }
.tv-rail__mark { color: var(--tv-gold); flex-shrink: 0; }

/* ---- Meter -------------------------------------------------------------- */
.tv-meter {
    margin-top: 0.5rem;
    height: 0.55rem;
    border-radius: 999px;
    background: var(--tv-accent-wash);
    overflow: hidden;
}
.dark .tv-meter { background: rgba(255, 255, 255, 0.1); }
.tv-meter__fill {
    display: block;
    height: 100%;
    width: var(--tv-pct, 0%);
    border-radius: inherit;
    background: linear-gradient(90deg, var(--tv-accent), var(--tv-amber));
    transform-origin: left center;
    animation: tv-sg-fill 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.1s both;
}
[dir='rtl'] .tv-meter__fill { transform-origin: right center; }

/* ---- Metric chip (a number that is also a link) ------------------------- */
.tv-chips { display: flex; flex-direction: column; gap: 0.6rem; }
/* Beside a hero the chips are a column; across the page they are a row. The
   client and partner dashboards run them full width, where a stack of three
   full-width cards pushed everything else below the fold. */
.tv-chips--row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 0.6rem;
}
.tv-chip {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    border-radius: 0.9rem;
    border: 1px solid var(--tv-hairline);
    background: var(--tv-paper);
    padding: 0.85rem 1.1rem;
    box-shadow: 0 8px 22px -16px rgba(43, 29, 20, 0.2);
    text-decoration: none;
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}
.tv-chip:hover {
    transform: translateY(-1px);
    box-shadow: 0 12px 26px -14px rgba(43, 29, 20, 0.32);
    border-color: var(--tv-accent-line);
}
.dark .tv-chip { background: var(--tv-d-surface); border-color: var(--tv-d-line); }
/* The one tile carrying something unresolved earns a gold spine. */
.tv-chip--flag { box-shadow: inset 3px 0 0 var(--tv-gold), 0 8px 22px -16px rgba(43, 29, 20, 0.2); }
.tv-chip__icon {
    display: flex;
    height: 2.5rem;
    width: 2.5rem;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    border-radius: 0.7rem;
    background: var(--tv-accent-wash);
    color: var(--tv-accent-deep);
}
.tv-chip__icon svg { width: 1.3rem; height: 1.3rem; }
.tv-chip__icon--gold { background: rgba(201, 162, 39, 0.16); color: #A87D11; }
.tv-chip__icon--amber { background: rgba(176, 122, 30, 0.14); color: #A87A1E; }
.tv-chip__icon--danger { background: rgba(185, 28, 28, 0.12); color: #B91C1C; }
.dark .tv-chip__icon { background: rgba(194, 112, 61, 0.16); color: var(--tv-d-mint); }
.tv-chip__value {
    display: block;
    font-size: 1.5rem;
    font-weight: 800;
    line-height: 1;
    color: var(--tv-ink);
    font-variant-numeric: tabular-nums;
}
.dark .tv-chip__value { color: #FBF3EE; }
.tv-chip__label { display: block; font-size: 0.78rem; color: #9A8473; margin-top: 0.1rem; }
.dark .tv-chip__label { color: var(--tv-d-muted); }

/* ---- Status card (one headline fact, with a state) ---------------------- */
.tv-status {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.75rem;
    border-radius: 1.1rem;
    padding: 1.5rem 1.6rem;
    border: 1px solid var(--tv-hairline);
    background: linear-gradient(135deg, var(--tv-ivory), var(--tv-paper));
    box-shadow: 0 10px 28px -16px rgba(43, 29, 20, 0.18);
    text-decoration: none;
    transition: transform 0.15s, box-shadow 0.15s;
}
a.tv-status:hover { transform: translateY(-2px); box-shadow: var(--tv-shadow-lg); }
.tv-status--alarm {
    background: linear-gradient(135deg, #FEFCE8, var(--tv-paper));
    border-color: rgba(201, 162, 39, 0.4);
}
.dark .tv-status { background: linear-gradient(135deg, #241B12, var(--tv-d-surface)); border-color: var(--tv-d-line); }
.dark .tv-status--alarm { background: linear-gradient(135deg, #241F0D, var(--tv-d-surface)); border-color: #3D3416; }
.tv-status__top { display: flex; align-items: center; gap: 0.7rem; }
.tv-status__badge {
    display: flex;
    height: 2.6rem;
    width: 2.6rem;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    border-radius: 0.8rem;
    background: var(--tv-accent-wash);
    color: var(--tv-accent-deep);
}
.tv-status__badge svg { width: 1.4rem; height: 1.4rem; }
.tv-status__badge--alarm { background: rgba(201, 162, 39, 0.18); color: #A87D11; }
.dark .tv-status__badge { background: rgba(194, 112, 61, 0.16); color: var(--tv-d-mint); }
.tv-status__value {
    font-size: 1.6rem;
    font-weight: 800;
    line-height: 1;
    color: var(--tv-ink);
    font-variant-numeric: tabular-nums;
}
.tv-status__headline { font-size: 1.05rem; font-weight: 800; color: var(--tv-ink); }
.dark .tv-status__value, .dark .tv-status__headline { color: #FBF3EE; }
.tv-status__label { font-size: 0.74rem; font-weight: 600; color: #9A8473; margin-top: 0.15rem; }
.dark .tv-status__label { color: var(--tv-d-muted); }
.tv-status__eyebrow {
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: #9A8473;
}
[dir='rtl'] .tv-status__eyebrow { letter-spacing: 0; }
.tv-status__cta { font-size: 0.84rem; font-weight: 800; color: #A87D11; }

/* ---- Action tiles ------------------------------------------------------- */
.tv-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 0.75rem; }
.tv-tile {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.8rem 1rem;
    border-radius: 0.85rem;
    border: 1px solid var(--tv-hairline);
    background: var(--tv-paper);
    text-decoration: none;
    transition: box-shadow 0.15s, transform 0.15s, border-color 0.15s;
}
.tv-tile:hover {
    box-shadow: 0 10px 24px -14px rgba(43, 29, 20, 0.3);
    transform: translateY(-1px);
    border-color: var(--tv-accent-line);
}
.dark .tv-tile { background: var(--tv-d-surface); border-color: var(--tv-d-line); }
.tv-tile__icon {
    display: flex;
    width: 2.4rem;
    height: 2.4rem;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    border-radius: 0.6rem;
    background: var(--tv-accent-wash);
    color: var(--tv-accent-deep);
    transition: transform 0.15s;
}
.tv-tile__icon svg { width: 1.25rem; height: 1.25rem; }
/* A fixed set of tones rather than a per-tile hex pair. The five dashboards
   between them named eleven different background colours, several one shade
   apart, because each was picked in isolation. */
.tv-tile__icon--deep { background: rgba(138, 71, 39, 0.12); color: #8A4727; }
.tv-tile__icon--gold { background: rgba(201, 162, 39, 0.16); color: #A87D11; }
.tv-tile__icon--amber { background: rgba(176, 122, 30, 0.14); color: #A87A1E; }
/* Scoped to the untoned tile: a blanket `.dark .tv-tile__icon` overrode the
   three modifiers above and made every tile the same colour after dark. */
.dark .tv-tile__icon:not([class*='--']) { background: rgba(194, 112, 61, 0.16); color: var(--tv-d-mint); }
.dark .tv-tile__icon--deep { background: rgba(219, 160, 124, 0.14); color: #E9C5AE; }
.dark .tv-tile__icon--gold { background: rgba(201, 162, 39, 0.18); color: #E3C766; }
.dark .tv-tile__icon--amber { background: rgba(224, 163, 61, 0.16); color: #F0C277; }
.tv-tile:hover .tv-tile__icon { transform: scale(1.06); }
.tv-tile__label { font-size: 0.86rem; font-weight: 600; color: #3A2E24; }
.dark .tv-tile__label { color: #E2E8F0; }

/* ---- Alert (the one red thing on a warm page) --------------------------- */
.tv-alert {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.85rem 1.1rem;
    border-radius: 0.9rem;
    border: 1px solid #F3B4B4;
    background: #FEF4F2;
    text-decoration: none;
    transition: box-shadow 0.15s;
}
.tv-alert:hover { box-shadow: 0 10px 24px -16px rgba(153, 27, 27, 0.5); }
.dark .tv-alert { background: #2A1414; border-color: #7F1D1D; }
.tv-alert__icon {
    display: flex;
    height: 2.4rem;
    width: 2.4rem;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    border-radius: 0.7rem;
    background: rgba(185, 28, 28, 0.12);
    color: #B91C1C;
}
.tv-alert__icon svg { width: 1.35rem; height: 1.35rem; }
.tv-alert__body { min-width: 0; }
.tv-alert__title { display: block; font-size: 0.9rem; font-weight: 700; color: #7F1D1D; }
.dark .tv-alert__title { color: #FCA5A5; }
.tv-alert__detail {
    display: block;
    margin-top: 0.1rem;
    font-size: 0.8rem;
    color: #9A5B54;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tv-alert__more { flex-shrink: 0; font-size: 0.75rem; color: #9A5B54; }
.dark .tv-alert__detail, .dark .tv-alert__more { color: #D9A6A0; }
.tv-alert__go {
    margin-inline-start: auto;
    flex-shrink: 0;
    font-size: 0.8rem;
    font-weight: 600;
    color: #B91C1C;
    white-space: nowrap;
}
.dark .tv-alert__go { color: #FCA5A5; }


/* ---- Today board (one row per unit, grouped by day) ---------------------
   The operations screen the overview asks for. Not a table: a unit's line
   carries a readiness badge, a list of arrivals and a list of departures with
   the clean booked for each, and columns wide enough for the worst case leave
   the common case mostly empty. A row is a two-part flex that becomes a stack
   below 640px, which is the whole responsive story.

   Logical properties throughout, so RTL needs no second set of rules. */
.tv-board {
    border-radius: 1.1rem;
    border: 1px solid var(--tv-hairline);
    background: var(--tv-paper);
    box-shadow: 0 10px 28px -18px rgba(43, 29, 20, 0.2);
    padding: 1.25rem 1.35rem 1.35rem;
}
.dark .tv-board { background: var(--tv-d-surface); border-color: var(--tv-d-line); }

.tv-board__head { margin-block-end: 0.9rem; }
.tv-board__title { font-size: 1.05rem; font-weight: 800; color: var(--tv-ink); line-height: 1.3; }
.dark .tv-board__title { color: #FBF3EE; }
.tv-board__hint { margin-block-start: 0.15rem; font-size: 0.8rem; color: #9A8473; }
.dark .tv-board__hint { color: var(--tv-d-muted); }

/* ---- Alert strip -------------------------------------------------------- */
.tv-board__alerts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-block-end: 1.1rem;
}
.tv-board__alert {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.4rem 0.75rem;
    border-radius: 999px;
    border: 1px solid #F3B4B4;
    background: #FEF4F2;
    text-decoration: none;
    font-size: 0.8rem;
    color: #7F1D1D;
    transition: box-shadow 0.15s, transform 0.15s;
}
.tv-board__alert:hover { transform: translateY(-1px); box-shadow: 0 8px 20px -14px rgba(153, 27, 27, 0.6); }
.dark .tv-board__alert { background: #2A1414; border-color: #7F1D1D; color: #FCA5A5; }
.tv-board__alert-icon { display: inline-flex; flex-shrink: 0; }
.tv-board__alert-icon svg { width: 1rem; height: 1rem; }
.tv-board__alert-count { font-weight: 800; font-variant-numeric: tabular-nums; }
.tv-board__alert-label { font-weight: 600; }

/* ---- Day group ---------------------------------------------------------- */
.tv-board__day + .tv-board__day { margin-block-start: 1.1rem; }
.tv-board__day-title {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding-block-end: 0.4rem;
    border-block-end: 1px solid var(--tv-hairline);
}
.dark .tv-board__day-title { border-color: var(--tv-d-line); }
.tv-board__day-name {
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--tv-accent-deep);
}
[dir='rtl'] .tv-board__day-name { letter-spacing: 0; }
.dark .tv-board__day-name { color: var(--tv-d-mint); }
.tv-board__day-date { font-size: 0.75rem; color: #9A8473; }
.dark .tv-board__day-date { color: var(--tv-d-muted); }

/* ---- Rows --------------------------------------------------------------- */
.tv-board__rows { list-style: none; margin: 0; padding: 0; }
.tv-board__row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.5rem 1rem;
    padding-block: 0.7rem;
    border-block-end: 1px solid var(--tv-hairline);
}
.tv-board__row:last-child { border-block-end: 0; padding-block-end: 0; }
.dark .tv-board__row { border-color: var(--tv-d-line); }

.tv-board__unit {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    /* Wide enough for a unit name and its two badges, and it gives up the
       rest so the movements take the width they need. */
    flex: 0 1 15rem;
    min-width: 0;
}
.tv-board__unit-name {
    font-size: 0.88rem;
    font-weight: 700;
    color: var(--tv-ink);
    text-decoration: none;
    overflow-wrap: anywhere;
}
a.tv-board__unit-name:hover { color: var(--tv-accent-deep); text-decoration: underline; }
.dark .tv-board__unit-name { color: #FBF3EE; }
.dark a.tv-board__unit-name:hover { color: var(--tv-d-mint); }
.tv-board__unit-badges { display: flex; flex-wrap: wrap; gap: 0.3rem; }

.tv-board__moves {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    flex: 1 1 20rem;
    min-width: 0;
}
.tv-board__move {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.82rem;
    color: #6B5646;
}
.dark .tv-board__move { color: var(--tv-d-text); }
.tv-board__move-icon { display: inline-flex; flex-shrink: 0; }
.tv-board__move-icon svg { width: 1rem; height: 1rem; }
/* The in/out arrows are drawn left-to-right, so in Arabic "leaves" pointed
   back into the row it was leaving. Mirrored rather than swapped for two
   different icons, which would have to agree with each other for ever. */
[dir='rtl'] .tv-board__move-icon svg { transform: scaleX(-1); }
/* Arrival and departure differ by colour rather than by position, so a unit
   with one of each still reads as two lines and not as a paragraph. */
.tv-board__move--in .tv-board__move-icon { color: #1F7A5A; }
.tv-board__move--out .tv-board__move-icon { color: var(--tv-accent-deep); }
.dark .tv-board__move--in .tv-board__move-icon { color: #6FCFA8; }
.dark .tv-board__move--out .tv-board__move-icon { color: var(--tv-d-mint); }
.tv-board__move-time {
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    color: var(--tv-ink);
}
.dark .tv-board__move-time { color: #FBF3EE; }
.tv-board__move-what { color: #9A8473; }
.dark .tv-board__move-what { color: var(--tv-d-muted); }
.tv-board__move-guest {
    font-weight: 600;
    color: var(--tv-ink);
    overflow-wrap: anywhere;
}
.dark .tv-board__move-guest { color: #FBF3EE; }
.tv-board__clean {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-inline-start: auto;
}
.tv-board__cleaner { font-size: 0.75rem; color: #9A8473; }
.dark .tv-board__cleaner { color: var(--tv-d-muted); }

/* A phone has no room for a right-hand rail: the clean falls under the guest
   it belongs to rather than being pushed off the edge of the row. */
@media (max-width: 640px) {
    .tv-board { padding: 1rem; }
    .tv-board__row { gap: 0.45rem; }
    .tv-board__unit { flex: 1 1 100%; }
    .tv-board__moves { flex: 1 1 100%; }
    .tv-board__clean { margin-inline-start: 0; }
}

/* ---- Empty ------------------------------------------------------------- */
.tv-board__empty { text-align: center; padding-block: 1.6rem 0.8rem; }
.tv-board__empty-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 2.75rem;
    width: 2.75rem;
    border-radius: 0.9rem;
    background: var(--tv-accent-wash);
    color: var(--tv-accent-deep);
    margin-block-end: 0.6rem;
}
.tv-board__empty-icon svg { width: 1.4rem; height: 1.4rem; }
.dark .tv-board__empty-icon { background: rgba(194, 112, 61, 0.16); color: var(--tv-d-mint); }
.tv-board__empty-heading { font-size: 0.92rem; font-weight: 700; color: var(--tv-ink); }
.dark .tv-board__empty-heading { color: #FBF3EE; }
.tv-board__empty-body { margin-block-start: 0.2rem; font-size: 0.8rem; color: #9A8473; }
.dark .tv-board__empty-body { color: var(--tv-d-muted); }

/* ---- Reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .tv-rise, .tv-meter__fill { animation: none !important; }
    .tv-chip, .tv-tile, .tv-status, .tv-hero__btn, .tv-alert, .tv-tile__icon, .tv-board__alert { transition: none !important; }
    .tv-chip:hover, .tv-tile:hover, a.tv-status:hover, .tv-hero__btn:hover, .tv-board__alert:hover { transform: none; }
    .tv-tile:hover .tv-tile__icon { transform: none; }
}

/* ---- Sandbox banner ------------------------------------------------------
   A sandboxed partner must never be left wondering why a booking produced no
   cleaner, so this sits above every page of their panel rather than only the
   dashboard. It was written with Tailwind utilities (bg-amber-50, border-b,
   px-4 …) which is the one thing that cannot work here: the panels load
   Filament's compiled CSS and this file, never the app's Vite bundle, so none
   of those classes existed and the warning rendered as unstyled text lying
   across the topbar. Plain CSS, like everything else in this stylesheet. */
.tv-sandbox {
    border-bottom: 1px solid #FCD34D;
    background: linear-gradient(180deg, #FFFBEB, #FEF3C7);
    color: #78350F;
    padding: 0.6rem 1rem;
    font-size: 0.85rem;
    line-height: 1.5;
}
.dark .tv-sandbox {
    border-bottom-color: rgba(180, 83, 9, 0.6);
    background: linear-gradient(180deg, #2A1F0A, #231A08);
    color: #FDE68A;
}
.tv-sandbox__inner {
    margin-inline: auto;
    max-width: 80rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.5rem;
}
.tv-sandbox__title {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-weight: 800;
}
.tv-sandbox__title svg { width: 1rem; height: 1rem; flex: 0 0 auto; }

/* -------------------------------------------------------------------------
   Sample data strip (.tv-sample)

   Sits under the topbar of the host and operator panels while an account is
   still looking at seeded data. Deliberately not the sandbox amber: sample
   data is a normal, invited state, and a second yellow warning would read as
   a second thing being wrong. It turns amber only once the account has real
   units or a real channel and the strip starts asking rather than explaining.

   Logical properties throughout, so RTL needs no extra rules.
   ------------------------------------------------------------------------- */
.tv-sample {
    border-bottom: 1px solid #BFDBFE;
    background: linear-gradient(180deg, #EFF6FF, #DBEAFE);
    color: #1E3A5F;
    padding: 0.6rem 1rem;
    font-size: 0.85rem;
    line-height: 1.5;
}
.tv-sample:empty { display: none; }
.dark .tv-sample {
    border-bottom-color: rgba(30, 64, 175, 0.6);
    background: linear-gradient(180deg, #0F1B2E, #0B1524);
    color: #BFDBFE;
}
.tv-sample--outgrown {
    border-bottom-color: #FCD34D;
    background: linear-gradient(180deg, #FFFBEB, #FEF3C7);
    color: #78350F;
}
.dark .tv-sample--outgrown {
    border-bottom-color: rgba(180, 83, 9, 0.6);
    background: linear-gradient(180deg, #2A1F0A, #231A08);
    color: #FDE68A;
}
.tv-sample__inner {
    margin-inline: auto;
    max-width: 80rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0.75rem;
}
.tv-sample__title {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-weight: 800;
}
.tv-sample__title svg { width: 1rem; height: 1rem; flex: 0 0 auto; }
.tv-sample__body { flex: 1 1 16rem; min-width: 0; }
.tv-sample__action {
    flex: 0 0 auto;
    margin-inline-start: auto;
    border: 1px solid currentColor;
    border-radius: 0.5rem;
    padding: 0.25rem 0.7rem;
    font-size: 0.8rem;
    font-weight: 700;
    color: inherit;
    background: rgba(255, 255, 255, 0.55);
    cursor: pointer;
    transition: background-color 75ms ease-in-out;
}
.dark .tv-sample__action { background: rgba(255, 255, 255, 0.08); }
.tv-sample__action:hover { background: rgba(255, 255, 255, 0.9); }
.dark .tv-sample__action:hover { background: rgba(255, 255, 255, 0.16); }
.tv-sample__action[disabled] { opacity: 0.6; cursor: progress; }

/* Narrow screens: the strip stacks and the button goes full width rather than
   being squeezed against the edge, where a thumb cannot reach it. */
@media (max-width: 40rem) {
    .tv-sample__inner { flex-direction: column; align-items: flex-start; }
    /* The row layout's `flex: 1 1 16rem` is a *width* floor that keeps the
       sentence off the button. Turned on its side by `flex-direction: column`
       the same declaration becomes a 16rem *height*, which on a 390px phone
       put 250px of empty blue between the sentence and the button and gave the
       strip half the first screen a new host ever sees. Height here is whatever
       the words need. */
    .tv-sample__body { flex: 0 0 auto; }
    .tv-sample__action { margin-inline-start: 0; align-self: stretch; text-align: center; }
}

/* =========================================================================
   Calendar (.tv-cal-*)

   Shared by the client, partner, admin and provider calendars.

   These four screens shipped written entirely in Tailwind utility classes --
   rounded-xl, bg-white, p-4, ring-1, grid-cols-7, border-collapse -- and not
   one of them existed at runtime. The panels load Filament's compiled CSS and
   this file; they never load the app's Vite bundle, and Filament ships only
   the utilities its own views use. A grep for any of the above in
   public/css/filament/filament/app.css returns zero. So the calendar rendered
   as a bare HTML table with unstyled text on every panel, and nothing caught
   it: the PHP tests assert the page renders, and the browser suite asserts it
   is not a 500. Both were true the whole time.

   Rewritten as plain CSS for the same reason the setup guide and the
   dashboard are. Logical properties throughout, so RTL needs no extra rules.
   ========================================================================= */

.tv-cal { display: flex; flex-direction: column; gap: 1rem; }

/* ---- Toolbar ------------------------------------------------------------ */
.tv-cal-bar { padding: 1rem 1.15rem; }
.tv-cal-bar__top {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}
.tv-cal-nav { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; }

/* ---- Month jump menu ---------------------------------------------------- */
.tv-cal-jump { display: inline-flex; align-items: center; gap: 0.4rem; }
.tv-cal-jump__label {
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #8A7A6B;
}
[dir='rtl'] .tv-cal-jump__label { letter-spacing: 0; }
.dark .tv-cal-jump__label { color: var(--tv-d-muted); }
.tv-cal-jump__select {
    border-radius: 0.6rem;
    border: 1px solid var(--tv-hairline);
    background: var(--tv-paper);
    padding: 0.3rem 0.55rem;
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--tv-ink);
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease;
}
.tv-cal-jump__select:hover { border-color: var(--tv-accent-line); background: var(--tv-accent-wash); }
.dark .tv-cal-jump__select { background: var(--tv-d-raise); border-color: var(--tv-d-line); color: #F5EFE8; }
.tv-cal-period {
    margin: 0;
    margin-inline-start: 0.5rem;
    font-size: 1rem;
    font-weight: 800;
    color: var(--tv-ink);
}
.dark .tv-cal-period { color: #F5EFE8; }

/* Segmented renderer switch */
.tv-cal-modes {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    border-radius: 0.7rem;
    background: rgba(43, 29, 20, 0.05);
    padding: 0.25rem;
}
.dark .tv-cal-modes { background: rgba(255, 255, 255, 0.06); }
.tv-cal-mode {
    border: none;
    background: none;
    border-radius: 0.55rem;
    padding: 0.4rem 0.85rem;
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    color: #8A7A6B;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.tv-cal-mode:hover { color: var(--tv-accent-deep); }
.tv-cal-chip { transition: background-color .15s ease, border-color .15s ease, transform .15s ease; }
.tv-cal-chip:active { transform: scale(0.97); }
.tv-cal-mode.is-active {
    background: var(--tv-paper);
    color: var(--tv-ink);
    box-shadow: var(--tv-shadow-sm);
}
.dark .tv-cal-mode { color: var(--tv-d-muted); }
.dark .tv-cal-mode.is-active { background: var(--tv-d-raise); color: var(--tv-d-text); }

/* Type filters */
.tv-cal-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--tv-hairline);
}
.dark .tv-cal-filters { border-top-color: var(--tv-d-line); }
.tv-cal-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    border-radius: 999px;
    border: 1px solid var(--tv-hairline);
    background: none;
    padding: 0.25rem 0.75rem;
    font: inherit;
    font-size: 0.75rem;
    font-weight: 700;
    color: #6B5645;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}
.tv-cal-chip:hover { background: var(--tv-accent-wash); border-color: var(--tv-accent-line); }
.tv-cal-chip.is-active {
    background: var(--tv-accent-deep);
    border-color: var(--tv-accent-deep);
    color: #fff;
}
.dark .tv-cal-chip { color: var(--tv-d-muted); border-color: var(--tv-d-line); }
.dark .tv-cal-chip.is-active { background: var(--tv-d-mint); border-color: var(--tv-d-mint); color: #1B1510; }
/* The type's icon, tinted to the type's colour. Carries the same meaning as
   the colour for anyone the colour does not reach. */
.tv-cal-chip__mark { display: inline-flex; align-items: center; flex: 0 0 auto; }
.tv-cal-chip__mark svg { width: 1rem; height: 1rem; }
.tv-cal-ev__icon { display: inline-flex; align-items: center; flex: 0 0 auto; opacity: 0.9; }
.tv-cal-ev__icon svg { width: 0.75rem; height: 0.75rem; }
/* The count that turned the filter row into the period summary. Tabular so a
   row of chips does not jitter as the numbers change. */
.tv-cal-chip__count {
    font-variant-numeric: tabular-nums;
    font-weight: 800;
    opacity: 0.75;
}
.tv-cal-chip.is-empty { opacity: 0.55; }
.tv-cal-chip.is-active .tv-cal-chip__count { opacity: 1; }
.tv-cal-filters__note {
    align-self: center;
    margin-inline-start: auto;
    font-size: 0.75rem;
    color: #8A7A6B;
}
.dark .tv-cal-filters__note { color: var(--tv-d-muted); }

/* ---- Period heading + what this renderer shows --------------------------- */
.tv-cal-period-block { min-width: 0; }
.tv-cal-period__hint {
    margin: 0.1rem 0 0;
    font-size: 0.75rem;
    line-height: 1.4;
    color: #8A7A6B;
}
.dark .tv-cal-period__hint { color: var(--tv-d-muted); }

/* ---- Colour key, folded away -------------------------------------------- */
.tv-cal-legend { border-top: 1px solid var(--tv-hairline); padding-top: 0.65rem; margin-top: 0.15rem; }
.dark .tv-cal-legend { border-top-color: var(--tv-d-line); }
.tv-cal-legend__toggle {
    cursor: pointer;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--tv-accent-deep);
    list-style: none;
}
.tv-cal-legend__toggle::-webkit-details-marker { display: none; }
.tv-cal-legend__toggle::before { content: '\203A'; display: inline-block; margin-inline-end: 0.4rem; transition: transform .18s ease; }
[dir='rtl'] .tv-cal-legend__toggle::before { content: '\2039'; }
.tv-cal-legend[open] .tv-cal-legend__toggle::before { transform: rotate(90deg); }
[dir='rtl'] .tv-cal-legend[open] .tv-cal-legend__toggle::before { transform: rotate(-90deg); }
.dark .tv-cal-legend__toggle { color: var(--tv-d-mint); }
.tv-cal-legend__list { margin: 0.6rem 0 0; display: grid; gap: 0.45rem; }
.tv-cal-legend__row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.35rem 0.6rem;
    font-size: 0.8rem;
}
.tv-cal-legend__row dt {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 8.5rem;
    font-weight: 700;
    color: var(--tv-ink);
}
.dark .tv-cal-legend__row dt { color: #F5EFE8; }
.tv-cal-legend__row dd { margin: 0; flex: 1 1 16rem; color: #6B5645; }
.dark .tv-cal-legend__row dd { color: var(--tv-d-muted); }

/* ---- Event chip (shared by timeline and month) -------------------------- */
.tv-cal-ev {
    display: block;
    margin-bottom: 0.25rem;
    border-radius: 0.35rem;
    padding: 0.15rem 0.4rem;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1.3;
    color: #fff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tv-cal-ev:last-child { margin-bottom: 0; }
.tv-cal-ev { transition: filter .14s ease, transform .14s ease; }
.tv-cal-ev:hover { filter: brightness(1.08); }
/* A clean that exists but has no slot yet reads as provisional rather than
   simply another colour, so it cannot be mistaken for a booked visit. */
.tv-cal-ev.is-tentative { opacity: 0.62; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.45); }
.tv-cal-ev__caption {
    display: block;
    font-weight: 500;
    opacity: 0.85;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---- Timeline ----------------------------------------------------------- */
.tv-cal-scroll { overflow-x: auto; border-radius: var(--tv-radius); }
/* Only true while the grid is actually cut off, which is the only time the
   sentence is worth the line it costs. */
.tv-cal-scrollhint { margin: 0; padding: 0.75rem 1.1rem 0; font-size: 0.75rem; color: #8A7A6B; }
.dark .tv-cal-scrollhint { color: var(--tv-d-muted); }
@media (min-width: 60rem) { .tv-cal-scrollhint { display: none; } }
.tv-cal-grid { width: 100%; min-width: 52rem; border-collapse: collapse; font-size: 0.85rem; }
.tv-cal-grid th, .tv-cal-grid td { padding: 0; }
.tv-cal-corner {
    /* Sticky with the row heads below it, or the two columns come apart. */
    position: sticky;
    inset-inline-start: 0;
    z-index: 2;
    position: sticky;
    inset-inline-start: 0;
    z-index: 2;
    width: 11rem;
    background: #FBFAF6;
    border-bottom: 1px solid var(--tv-hairline);
    border-inline-end: 1px solid var(--tv-hairline);
}
.dark .tv-cal-corner { background: var(--tv-d-raise); border-color: var(--tv-d-line); }
.tv-cal-dayhead {
    border-bottom: 1px solid var(--tv-hairline);
    background: #FBFAF6;
    padding: 0.45rem 0.25rem;
    text-align: center;
    font-size: 0.7rem;
    font-weight: 600;
    color: #8A7A6B;
}
.dark .tv-cal-dayhead { background: var(--tv-d-raise); color: var(--tv-d-muted); border-color: var(--tv-d-line); }
.tv-cal-dayhead.is-today { background: var(--tv-accent-wash); color: var(--tv-accent-deep); }
.dark .tv-cal-dayhead.is-today { background: rgba(194, 112, 61, 0.18); color: var(--tv-d-mint); }
.tv-cal-dayhead__num { font-size: 0.9rem; font-weight: 800; font-variant-numeric: tabular-nums; }

.tv-cal-row { background: var(--tv-paper); }
.dark .tv-cal-row { background: var(--tv-d-surface); }
/* The row that needs a decision, pinned to the top by eventsByUnit(). */
.tv-cal-row.is-unassigned { background: #FFFBEB; }
.dark .tv-cal-row.is-unassigned { background: rgba(201, 162, 39, 0.08); }
/* Pinned while the week scrolls under it -- a grid of coloured cells whose
   row labels have slid off the screen says nothing at all. */
.tv-cal-rowhead {
    position: sticky;
    inset-inline-start: 0;
    z-index: 1;
    background: inherit;
    border-bottom: 1px solid var(--tv-hairline);
    border-inline-end: 1px solid var(--tv-hairline);
    padding: 0.6rem 0.75rem;
    text-align: start;
    vertical-align: top;
}
.dark .tv-cal-rowhead { border-color: var(--tv-d-line); }
.tv-cal-rowhead__name {
    display: block;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--tv-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dark .tv-cal-rowhead__name { color: #F5EFE8; }
.tv-cal-rowhead__hint {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.66rem;
    font-weight: 500;
    line-height: 1.3;
    color: #A87D11;
    white-space: normal;
}
.dark .tv-cal-rowhead__hint { color: #E3C766; }
.tv-cal-cell {
    border-bottom: 1px solid var(--tv-hairline);
    /* Day columns need a visible edge, or two events on consecutive days read
       as one bar spanning both. */
    border-inline-end: 1px solid rgba(43, 29, 20, 0.05);
    padding: 0.35rem 0.3rem;
    vertical-align: top;
    min-width: 4.5rem;
}
.tv-cal-cell:last-child { border-inline-end: 0; }
.tv-cal-cell.is-today { background: var(--tv-accent-wash); }
.dark .tv-cal-cell.is-today { background: rgba(194, 112, 61, 0.12); }
.dark .tv-cal-cell { border-color: rgba(255, 255, 255, 0.06); }
.tv-cal-dayhead { border-inline-end: 1px solid rgba(43, 29, 20, 0.05); }
.tv-cal-dayhead:last-child { border-inline-end: 0; }
.dark .tv-cal-dayhead { border-inline-end-color: rgba(255, 255, 255, 0.06); }

/* ---- Agenda ------------------------------------------------------------- */
.tv-cal-agenda { overflow: hidden; }
.tv-cal-agenda__day { border-bottom: 1px solid var(--tv-hairline); }
.tv-cal-agenda__day:last-child { border-bottom: 0; }
.dark .tv-cal-agenda__day { border-color: var(--tv-d-line); }
.tv-cal-agenda__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    background: #FBFAF6;
    padding: 0.5rem 1.1rem;
    font-size: 0.78rem;
    color: #8A7A6B;
}
.dark .tv-cal-agenda__head { background: var(--tv-d-raise); color: var(--tv-d-muted); }
.tv-cal-agenda__head.is-today { background: var(--tv-accent-wash); }
.dark .tv-cal-agenda__head.is-today { background: rgba(194, 112, 61, 0.18); }
/* "Today" carries the weight; the date beside it is the supporting detail,
   which is the opposite of how this read when every header was a date. */
.tv-cal-agenda__name { font-weight: 800; color: var(--tv-ink); }
.dark .tv-cal-agenda__name { color: #F5EFE8; }
.tv-cal-agenda__head.is-today .tv-cal-agenda__name { color: var(--tv-accent-deep); }
.dark .tv-cal-agenda__head.is-today .tv-cal-agenda__name { color: var(--tv-d-mint); }
.tv-cal-agenda__date { font-weight: 500; }
.tv-cal-agenda__count {
    margin-inline-start: auto;
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
}
.tv-cal-agenda__day.is-past { opacity: 0.72; }

/* ---- One event, as a row (agenda + the day a month cell opens) ---------- */
.tv-cal-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0.85rem;
    padding: 0.7rem 1.1rem;
    border-bottom: 1px solid rgba(43, 29, 20, 0.05);
    font-size: 0.85rem;
}
.tv-cal-item:last-child { border-bottom: 0; }
/* A row that lights up under the cursor is how a list of fourteen things
   stays readable while the eye tracks across four columns of it. */
.tv-cal-item { transition: background-color .14s ease; }
.tv-cal-item:hover { background: var(--tv-accent-wash); }
.dark .tv-cal-item:hover { background: rgba(194, 112, 61, 0.12); }
.dark .tv-cal-item { border-color: rgba(255, 255, 255, 0.05); }
.tv-cal-item__time {
    flex: 0 0 auto;
    min-width: 6.5rem;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    color: var(--tv-ink);
}
.dark .tv-cal-item__time { color: #F5EFE8; }
.tv-cal-item__type {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    flex: 0 0 auto;
    min-width: 9rem;
    color: #6B5645;
}
.dark .tv-cal-item__type { color: var(--tv-d-muted); }
.tv-cal-item__unit {
    flex: 1 1 8rem;
    min-width: 0;
    font-weight: 600;
    color: var(--tv-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dark .tv-cal-item__unit { color: #F5EFE8; }
.tv-cal-item__notes { display: inline-flex; align-items: center; gap: 0.5rem; flex: 0 0 auto; }
.tv-cal-item__flag {
    border-radius: 999px;
    border: 1px solid rgba(201, 162, 39, 0.5);
    background: #FFFBEB;
    padding: 0.1rem 0.55rem;
    font-size: 0.7rem;
    font-weight: 700;
    color: #8A6D12;
}
.dark .tv-cal-item__flag { background: rgba(201, 162, 39, 0.12); border-color: #6B5410; color: #E3C766; }
.tv-cal-item__who { font-size: 0.75rem; color: #8A7A6B; }
.dark .tv-cal-item__who { color: var(--tv-d-muted); }

/* ---- Month grid --------------------------------------------------------- */
.tv-cal-month { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); overflow: hidden; }
.tv-cal-month__head {
    border-bottom: 1px solid var(--tv-hairline);
    background: #FBFAF6;
    padding: 0.45rem 0.5rem;
    text-align: center;
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #8A7A6B;
}
[dir='rtl'] .tv-cal-month__head { letter-spacing: 0; }
.dark .tv-cal-month__head { background: var(--tv-d-raise); color: var(--tv-d-muted); border-color: var(--tv-d-line); }
/* The cell is a button now: a month grid that can only ever show three of a
   day's events has to offer the rest somewhere, and the day itself is the
   obvious control. Reset the button chrome rather than inherit a form look. */
.tv-cal-month__cell {
    display: block;
    width: 100%;
    min-height: 6rem;
    border: 0;
    border-bottom: 1px solid var(--tv-hairline);
    border-inline-end: 1px solid var(--tv-hairline);
    padding: 0.35rem;
    background: transparent;
    font: inherit;
    color: inherit;
    text-align: start;
    cursor: pointer;
    transition: background-color .15s ease, box-shadow .15s ease;
}
button.tv-cal-month__cell.is-quiet { cursor: default; }
button.tv-cal-month__cell:hover { background: var(--tv-accent-wash); }
.tv-cal-month__cell.is-focused {
    background: var(--tv-accent-wash);
    box-shadow: inset 0 0 0 2px var(--tv-accent);
}
.dark .tv-cal-month__cell.is-focused { background: rgba(194, 112, 61, 0.2); }
.dark .tv-cal-month__cell { border-color: rgba(255, 255, 255, 0.06); }
.tv-cal-month__cell.is-outside { background: rgba(43, 29, 20, 0.025); }
.dark .tv-cal-month__cell.is-outside { background: rgba(255, 255, 255, 0.02); }
.tv-cal-month__cell.is-today { background: var(--tv-accent-wash); }
.dark .tv-cal-month__cell.is-today { background: rgba(194, 112, 61, 0.12); }
.tv-cal-month__num {
    margin-bottom: 0.25rem;
    font-size: 0.7rem;
    font-variant-numeric: tabular-nums;
    color: #8A7A6B;
}
.dark .tv-cal-month__num { color: var(--tv-d-muted); }
.tv-cal-month__cell.is-outside .tv-cal-month__num { opacity: 0.45; }
.tv-cal-month__cell.is-today .tv-cal-month__num { font-weight: 800; color: var(--tv-accent-deep); opacity: 1; }
.dark .tv-cal-month__cell.is-today .tv-cal-month__num { color: var(--tv-d-mint); }
.tv-cal-ev__at { font-variant-numeric: tabular-nums; opacity: 0.85; margin-inline-end: 0.25rem; }
.tv-cal-more { padding-inline-start: 0.25rem; font-size: 0.68rem; font-weight: 700; color: var(--tv-accent-deep); }
.dark .tv-cal-more { color: var(--tv-d-mint); }

/* ---- The day a month cell opens ----------------------------------------- */
.tv-cal-day { overflow: hidden; }
.tv-cal-day__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    background: var(--tv-accent-wash);
    padding: 0.55rem 1.1rem;
    font-size: 0.8rem;
    color: #6B5645;
}
.dark .tv-cal-day__head { background: rgba(194, 112, 61, 0.18); color: var(--tv-d-muted); }
.tv-cal-day__close {
    margin-inline-start: 0.75rem;
    border: 0;
    background: none;
    padding: 0;
    font: inherit;
    font-weight: 700;
    color: var(--tv-accent-deep);
    cursor: pointer;
}
.tv-cal-day__close:hover { text-decoration: underline; }
.dark .tv-cal-day__close { color: var(--tv-d-mint); }
.tv-cal-day__empty { margin: 0; padding: 1.25rem 1.1rem; font-size: 0.85rem; color: #8A7A6B; }
.dark .tv-cal-day__empty { color: var(--tv-d-muted); }

/* ---- Empty state -------------------------------------------------------- */
.tv-cal-empty {
    padding: 3rem 1.25rem;
    text-align: center;
    font-size: 0.9rem;
    color: #8A7A6B;
}
.dark .tv-cal-empty { color: var(--tv-d-muted); }
.tv-cal-empty__title { margin: 0; font-weight: 800; color: var(--tv-ink); }
.dark .tv-cal-empty__title { color: #F5EFE8; }
.tv-cal-empty__hint {
    margin: 0.4rem auto 0;
    max-width: 32rem;
    font-size: 0.82rem;
    line-height: 1.65;
}
.tv-cal-empty__action {
    margin-top: 0.85rem;
    border: 1px solid var(--tv-accent-line);
    border-radius: 999px;
    background: var(--tv-accent-wash);
    padding: 0.3rem 0.9rem;
    font: inherit;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--tv-accent-deep);
    cursor: pointer;
}
.tv-cal-empty__action:hover { background: var(--tv-accent-line); }
.dark .tv-cal-empty__action { color: var(--tv-d-mint); border-color: var(--tv-d-line); }

/* ---- Wallet forecast banner --------------------------------------------- */
.tv-cal-forecast {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.85rem;
    border-radius: var(--tv-radius);
    border: 1px solid #F3B4B4;
    background: #FEF4F2;
    padding: 1rem 1.15rem;
}
.dark .tv-cal-forecast { background: #2A1414; border-color: #7F1D1D; }
.tv-cal-forecast__icon { flex: 0 0 auto; color: #B91C1C; margin-top: 0.1rem; }
.tv-cal-forecast__icon svg { width: 1.25rem; height: 1.25rem; }
.dark .tv-cal-forecast__icon { color: #FCA5A5; }
.tv-cal-forecast__body { flex: 1 1 18rem; min-width: 0; }
.tv-cal-forecast__title { margin: 0; font-size: 0.9rem; font-weight: 800; color: #7F1D1D; }
.dark .tv-cal-forecast__title { color: #FCA5A5; }
.tv-cal-forecast__text { margin: 0.25rem 0 0; font-size: 0.85rem; line-height: 1.6; color: #9A5B54; }
.dark .tv-cal-forecast__text { color: #D9A6A0; }
.tv-cal-forecast__note { margin: 0.25rem 0 0; font-size: 0.75rem; font-style: italic; color: #9A5B54; opacity: 0.85; }

/* =========================================================================
   System health, logs and failed jobs (.tv-sys-*)

   Same story as the calendar: written in Tailwind utilities the panels never
   compile, so the admin observability screens -- the ones that exist to make
   silent failures loud -- rendered as undifferentiated runs of text. "SMS No
   Orbit token — no OTP can be delivered Fix this →" was one line with no
   status dot, no separation and no visible link.
   ========================================================================= */

/* ---- Status rows -------------------------------------------------------- */
.tv-sys-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.tv-sys-list--gap { gap: 0.5rem; }

.tv-sys-problem {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.75rem;
    border-radius: 0.7rem;
    border: 1px solid var(--tv-hairline);
    padding: 0.65rem 0.9rem;
    font-size: 0.875rem;
}
.tv-sys-problem--critical { border-color: #F3B4B4; background: #FEF4F2; }
.tv-sys-problem--warning { border-color: rgba(201, 162, 39, 0.45); background: #FFFBEB; }
.dark .tv-sys-problem--critical { border-color: #7F1D1D; background: rgba(127, 29, 29, 0.25); }
.dark .tv-sys-problem--warning { border-color: #6B5410; background: rgba(201, 162, 39, 0.12); }
.tv-sys-problem__title { font-weight: 800; color: var(--tv-ink); }
.dark .tv-sys-problem__title { color: #F5EFE8; }
.tv-sys-problem__detail { color: #6B5645; }
.dark .tv-sys-problem__detail { color: var(--tv-d-muted); }
.tv-sys-problem__fix {
    margin-inline-start: auto;
    white-space: nowrap;
    font-weight: 700;
    text-decoration: none;
    color: var(--tv-accent-deep);
}
.tv-sys-problem__fix:hover { text-decoration: underline; }
.dark .tv-sys-problem__fix { color: var(--tv-d-mint); }

.tv-sys-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--tv-hairline);
    font-size: 0.875rem;
}
.tv-sys-row:last-child { border-bottom: 0; }
.dark .tv-sys-row { border-color: var(--tv-d-line); }
.tv-sys-row__label { display: flex; align-items: center; gap: 0.55rem; font-weight: 600; }
.tv-sys-row__label a { color: inherit; text-decoration: none; }
.tv-sys-row__label a:hover { text-decoration: underline; }
.tv-sys-row__detail { color: #8A7A6B; }
.dark .tv-sys-row__detail { color: var(--tv-d-muted); }

/* The one thing that turns a list of sentences into a scannable status board. */
.tv-sys-dot { width: 0.55rem; height: 0.55rem; flex: 0 0 auto; border-radius: 999px; }
.tv-sys-dot--ok { background: #1F9D6B; }
.tv-sys-dot--warning { background: #C9A227; }
.tv-sys-dot--critical { background: #B91C1C; }

.tv-sys-clear { display: flex; align-items: center; gap: 0.75rem; font-size: 0.9rem; font-weight: 600; }
.tv-sys-clear svg { width: 1.5rem; height: 1.5rem; color: #1F9D6B; flex: 0 0 auto; }

/* ---- Log viewer --------------------------------------------------------- */
.tv-sys-filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem; }
.tv-sys-field { display: flex; flex-direction: column; gap: 0.25rem; flex: 1 1 12rem; min-width: 0; }
.tv-sys-field__label { font-size: 0.8rem; font-weight: 700; color: var(--tv-ink); }
.dark .tv-sys-field__label { color: #E8DED4; }
/* `.tv-sg-input` carries `flex: 1 1 14rem`, which was written for the setup
   guide's `.tv-sg-form-row` -- a ROW, where 14rem is a width. `.tv-sys-field`
   stacks its label and its control in a COLUMN, so the same basis is read as a
   height and every filter control grew to 224 px: one search box taller than
   the section around it, on Logs and on the knowledge base both. */
.tv-sys-field > .tv-sg-input { flex: 0 0 auto; }
.tv-sys-hint { font-size: 0.75rem; color: #8A7A6B; margin: 0; }
.dark .tv-sys-hint { color: var(--tv-d-muted); }

.tv-sys-entry {
    border-bottom: 1px solid var(--tv-hairline);
    padding: 0.7rem 0;
}
.tv-sys-entry:last-child { border-bottom: 0; }
.dark .tv-sys-entry { border-color: var(--tv-d-line); }
.tv-sys-entry__head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.tv-sys-entry__level {
    border-radius: 0.35rem;
    padding: 0.1rem 0.45rem;
    font-family: ui-monospace, 'SF Mono', Menlo, monospace;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    background: rgba(43, 29, 20, 0.07);
    color: #6B5645;
}
.dark .tv-sys-entry__level { background: rgba(255, 255, 255, 0.1); color: var(--tv-d-muted); }
.tv-sys-entry__level--error, .tv-sys-entry__level--critical, .tv-sys-entry__level--alert, .tv-sys-entry__level--emergency {
    background: rgba(185, 28, 28, 0.12);
    color: #B91C1C;
}
.tv-sys-entry__level--warning { background: rgba(201, 162, 39, 0.18); color: #A87D11; }
.tv-sys-entry__at {
    font-family: ui-monospace, 'SF Mono', Menlo, monospace;
    font-size: 0.72rem;
    color: #8A7A6B;
}
.dark .tv-sys-entry__at { color: var(--tv-d-muted); }
.tv-sys-entry__message {
    margin: 0.35rem 0 0;
    font-family: ui-monospace, 'SF Mono', Menlo, monospace;
    font-size: 0.78rem;
    line-height: 1.6;
    word-break: break-word;
    color: var(--tv-ink);
}
.dark .tv-sys-entry__message { color: #E8DED4; }
.tv-sys-entry__toggle { cursor: pointer; font-size: 0.75rem; color: #8A7A6B; margin-top: 0.35rem; }
.dark .tv-sys-entry__toggle { color: var(--tv-d-muted); }

.tv-sys-pre {
    margin: 0.35rem 0 0;
    max-height: 24rem;
    overflow: auto;
    border-radius: 0.55rem;
    background: #FBFAF6;
    padding: 0.75rem;
    font-family: ui-monospace, 'SF Mono', Menlo, monospace;
    font-size: 0.72rem;
    line-height: 1.65;
    color: var(--tv-ink);
}
.dark .tv-sys-pre { background: #140F0A; color: #E8DED4; }

/* ---- Failed job detail -------------------------------------------------- */
.tv-sys-dl { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 0.9rem; margin: 0; }
.tv-sys-dl dt {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #8A7A6B;
}
[dir='rtl'] .tv-sys-dl dt { letter-spacing: 0; }
.dark .tv-sys-dl dt { color: var(--tv-d-muted); }
.tv-sys-dl dd {
    margin: 0.15rem 0 0;
    font-family: ui-monospace, 'SF Mono', Menlo, monospace;
    font-size: 0.8rem;
    word-break: break-word;
    color: var(--tv-ink);
}
.dark .tv-sys-dl dd { color: #E8DED4; }
.tv-sys-subhead {
    margin: 0 0 0.35rem;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #8A7A6B;
}
[dir='rtl'] .tv-sys-subhead { letter-spacing: 0; }
.dark .tv-sys-subhead { color: var(--tv-d-muted); }

/* =========================================================================
   Analytics (.tv-an-*)

   Shared by the host, partner and platform analytics screens. Plain CSS for
   the same reason as everything else here: panels never load the app's Vite
   bundle, so a Tailwind utility written in a panel view resolves to nothing.
   ========================================================================= */

.tv-an { display: flex; flex-direction: column; gap: 1.25rem; }

/* ---- Period bar --------------------------------------------------------- */
.tv-an-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    padding: 0.85rem 1.15rem;
}
.tv-an-bar__label {
    margin: 0;
    margin-inline-start: 0.35rem;
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--tv-ink);
}
.dark .tv-an-bar__label { color: #F5EFE8; }
.tv-an-bar__note {
    margin-inline-start: auto;
    font-size: 0.78rem;
    color: #8A7A6B;
}
.dark .tv-an-bar__note { color: var(--tv-d-muted); }

/* ---- Metric cards ------------------------------------------------------- */
.tv-an-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 0.85rem;
}
.tv-an-card {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.15rem 1.2rem;
    border-radius: var(--tv-radius);
    border: 1px solid var(--tv-hairline);
    background: var(--tv-paper);
    box-shadow: 0 10px 26px -18px rgba(43, 29, 20, 0.28);
}
.dark .tv-an-card { background: var(--tv-d-surface); border-color: var(--tv-d-line); }
.tv-an-card__top { display: flex; align-items: center; gap: 0.55rem; }
.tv-an-card__icon {
    display: grid;
    place-items: center;
    width: 2.1rem;
    height: 2.1rem;
    flex: 0 0 auto;
    border-radius: 0.6rem;
    background: var(--tv-accent-wash);
    color: var(--tv-accent-deep);
}
.tv-an-card__icon svg { width: 1.15rem; height: 1.15rem; }
.dark .tv-an-card__icon { background: rgba(194, 112, 61, 0.18); color: var(--tv-d-mint); }
.tv-an-card__label { font-size: 0.8rem; font-weight: 600; color: #8A7A6B; line-height: 1.3; }
.dark .tv-an-card__label { color: var(--tv-d-muted); }
.tv-an-card__value {
    font-size: 1.9rem;
    font-weight: 800;
    line-height: 1.1;
    color: var(--tv-ink);
    font-variant-numeric: tabular-nums;
}
.dark .tv-an-card__value { color: #FBF3EE; }
.tv-an-card__value svg { width: 0.95rem; height: 0.95rem; opacity: 0.7; }

/* Change against the previous period. Never colour alone: the arrow carries
   the direction for anyone who cannot separate the two greens. */
.tv-an-delta {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.8rem;
    font-weight: 700;
}
.tv-an-delta svg { width: 0.9rem; height: 0.9rem; }
.tv-an-delta--good { color: #1F9D6B; }
.tv-an-delta--bad { color: #C0392B; }
.tv-an-delta--flat, .tv-an-delta--unknown { color: #8A7A6B; }
.dark .tv-an-delta--good { color: #6EC9A3; }
.dark .tv-an-delta--bad { color: #E88C7D; }
.dark .tv-an-delta--flat, .dark .tv-an-delta--unknown { color: var(--tv-d-muted); }
.tv-an-card__hint { font-size: 0.75rem; line-height: 1.45; color: #9A8473; }
.dark .tv-an-card__hint { color: var(--tv-d-muted); }

/* ---- Per-unit table ----------------------------------------------------- */
.tv-an-table { width: 100%; border-collapse: collapse; font-size: 0.87rem; }
.tv-an-table th {
    text-align: start;
    padding: 0.6rem 0.9rem;
    background: #FBFAF6;
    border-bottom: 1px solid var(--tv-hairline);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #8A7A6B;
    white-space: nowrap;
}
[dir='rtl'] .tv-an-table th { letter-spacing: 0; }
.dark .tv-an-table th { background: var(--tv-d-raise); color: var(--tv-d-muted); border-color: var(--tv-d-line); }
.tv-an-table td {
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid var(--tv-hairline);
    color: var(--tv-ink);
    vertical-align: top;
}
.dark .tv-an-table td { color: #E8DED4; border-color: rgba(255, 255, 255, 0.06); }
.tv-an-table tr:last-child td { border-bottom: 0; }
.tv-an-table tbody tr:hover { background: var(--tv-accent-wash); }
.dark .tv-an-table tbody tr:hover { background: rgba(205, 130, 83, 0.06); }
.tv-an-num { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tv-an-unit { font-weight: 700; }
.tv-an-city { display: block; font-size: 0.76rem; font-weight: 500; color: #9A8473; margin-top: 0.1rem; }
.dark .tv-an-city { color: var(--tv-d-muted); }
.tv-an-flag { color: #C0392B; font-weight: 700; }
.tv-an-muted { color: #9A8473; }
.dark .tv-an-muted { color: var(--tv-d-muted); }

/* A best/worst marker, so the answer to "which unit" is visible without
   reading every row. */
.tv-an-rank {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    border-radius: 999px;
    padding: 0.05rem 0.5rem;
    margin-inline-start: 0.4rem;
    font-size: 0.65rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
[dir='rtl'] .tv-an-rank { letter-spacing: 0; }
.tv-an-rank--best { background: rgba(31, 157, 107, 0.14); color: #177952; }
.tv-an-rank--worst { background: rgba(192, 57, 43, 0.12); color: #C0392B; }
.dark .tv-an-rank--best { background: rgba(31, 157, 107, 0.22); color: #6EC9A3; }
.dark .tv-an-rank--worst { background: rgba(192, 57, 43, 0.2); color: #E88C7D; }

.tv-an-empty { padding: 3rem 1rem; text-align: center; color: #8A7A6B; }
.dark .tv-an-empty { color: var(--tv-d-muted); }

/* =========================================================================
   Panel utility bridge

   The panels load Filament's compiled CSS and this file, never the app's Vite
   bundle. Filament ships only the utilities its own views use, so every
   Tailwind class hand-written into a panel Blade view has always resolved to
   nothing -- see the .tv-cal-* and .tv-sys-* blocks for what that looked like.

   Seven partner screens and three smaller ones are still written that way,
   between them referencing 155 distinct utilities: the settings and
   integration page alone uses 107. Rewriting all of them into bespoke
   components would be a large change to working markup for no behavioural
   gain, so the utilities they already ask for are defined here instead.

   Two deliberate constraints:

   - **Scoped to `.fi-body`.** The public site DOES have a real Tailwind build,
     and these definitions must never reach it.
   - **Mapped to the brand palette, not to Tailwind's.** `text-gray-500` here
     resolves to the warm ink-tinted grey the rest of the panel uses, not to
     Tailwind's cool slate. That is the difference between these pages merely
     working and them looking like the same product.

   This is a bridge for markup that already exists. New work should use the
   .tv-* components above.
   ========================================================================= */

.fi-body {
    --u-g50:  #FBFAF6;
    --u-g100: #F3EFE8;
    --u-g200: rgba(43, 29, 20, 0.10);
    --u-g300: #DCD3C7;
    --u-g400: #A89685;
    --u-g500: #8A7A6B;
    --u-g600: #6B5645;
    --u-g700: #4A3B2E;
    --u-g900: #2B1D14;
    --u-surface: #FFFFFF;
}
.dark .fi-body {
    --u-g50:  #241C15;
    --u-g100: #2A2119;
    --u-g200: rgba(255, 255, 255, 0.10);
    --u-g300: #3A2E24;
    --u-g400: #8C7C6C;
    --u-g500: #A2907E;
    --u-g600: #B6A493;
    --u-g700: #CFC2B4;
    --u-g900: #F1EAE1;
    --u-surface: #201913;
}

/* ---- Layout ------------------------------------------------------------- */
.fi-body .flex { display: flex; }
.fi-body .inline-flex { display: inline-flex; }
.fi-body .grid { display: grid; }
.fi-body .block { display: block; }
.fi-body .hidden { display: none; }
.fi-body .flex-col { flex-direction: column; }
.fi-body .flex-wrap { flex-wrap: wrap; }
.fi-body .flex-1 { flex: 1 1 0%; }
.fi-body .shrink-0 { flex-shrink: 0; }
.fi-body .w-full { width: 100%; }
.fi-body .min-w-64 { min-width: 16rem; }
.fi-body .items-center { align-items: center; }
.fi-body .items-baseline { align-items: baseline; }
.fi-body .items-start { align-items: flex-start; }
.fi-body .items-end { align-items: flex-end; }
.fi-body .items-stretch { align-items: stretch; }
.fi-body .justify-between { justify-content: space-between; }
.fi-body .justify-center { justify-content: center; }
.fi-body .justify-end { justify-content: flex-end; }
.fi-body .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.fi-body .overflow-hidden { overflow: hidden; }
.fi-body .overflow-x-auto { overflow-x: auto; }
.fi-body .object-cover { object-fit: cover; }
.fi-body .relative { position: relative; }
.fi-body .absolute { position: absolute; }

/* Arbitrary values need their brackets escaped in a selector. */
.fi-body .aspect-\[4\/3\] { aspect-ratio: 4 / 3; }
.fi-body .min-w-\[40rem\] { min-width: 40rem; }

@media (min-width: 640px) {
    .fi-body .sm\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .fi-body .sm\:text-sm { font-size: 0.875rem; line-height: 1.35rem; }
}
@media (min-width: 1024px) {
    .fi-body .lg\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .fi-body .lg\:grid-cols-\[minmax\(16rem\2c 22rem\)_1fr\] {
        grid-template-columns: minmax(16rem, 22rem) 1fr;
    }
}

/* ---- Spacing ------------------------------------------------------------ */
.fi-body .gap-1 { gap: 0.25rem; }
.fi-body .gap-1\.5 { gap: 0.375rem; }
.fi-body .gap-2 { gap: 0.5rem; }
.fi-body .gap-3 { gap: 0.75rem; }
.fi-body .gap-4 { gap: 1rem; }
.fi-body .p-3 { padding: 0.75rem; }
.fi-body .p-4 { padding: 1rem; }
.fi-body .p-6 { padding: 1.5rem; }
.fi-body .px-2 { padding-inline: 0.5rem; }
.fi-body .px-3 { padding-inline: 0.75rem; }
.fi-body .px-4 { padding-inline: 1rem; }
.fi-body .py-0\.5 { padding-block: 0.125rem; }
.fi-body .py-1 { padding-block: 0.25rem; }
.fi-body .py-2 { padding-block: 0.5rem; }
.fi-body .py-2\.5 { padding-block: 0.625rem; }
.fi-body .py-3 { padding-block: 0.75rem; }
.fi-body .py-8 { padding-block: 2rem; }
.fi-body .py-12 { padding-block: 3rem; }
.fi-body .mb-1 { margin-bottom: 0.25rem; }
.fi-body .mb-3 { margin-bottom: 0.75rem; }
.fi-body .mb-4 { margin-bottom: 1rem; }
.fi-body .mt-0\.5 { margin-top: 0.125rem; }
.fi-body .mt-1 { margin-top: 0.25rem; }
.fi-body .mt-2 { margin-top: 0.5rem; }
.fi-body .mt-3 { margin-top: 0.75rem; }
.fi-body .mt-4 { margin-top: 1rem; }
.fi-body .mt-6 { margin-top: 1.5rem; }
/* Logical, so RTL mirrors without a second rule. */
.fi-body .ms-2 { margin-inline-start: 0.5rem; }

/* space-y is a sibling rule, not a margin on the container. */
.fi-body .space-y-1\.5 > * + * { margin-top: 0.375rem; }
.fi-body .space-y-2 > * + * { margin-top: 0.5rem; }
.fi-body .space-y-3 > * + * { margin-top: 0.75rem; }
.fi-body .space-y-4 > * + * { margin-top: 1rem; }
.fi-body .space-y-6 > * + * { margin-top: 1.5rem; }
.fi-body .space-y-8 > * + * { margin-top: 2rem; }

/* ---- Type --------------------------------------------------------------- */
.fi-body .text-xs { font-size: 0.75rem; line-height: 1.1rem; }
.fi-body .text-sm { font-size: 0.875rem; line-height: 1.35rem; }
.fi-body .text-base { font-size: 1rem; line-height: 1.55rem; }
.fi-body .font-medium { font-weight: 500; }
.fi-body .font-semibold { font-weight: 700; }
.fi-body .font-mono { font-family: ui-monospace, 'SF Mono', Menlo, monospace; }
.fi-body .uppercase { text-transform: uppercase; }
.fi-body .tracking-wide { letter-spacing: 0.025em; }
.fi-body .tracking-wider { letter-spacing: 0.05em; }
[dir='rtl'] .fi-body .tracking-wide,
[dir='rtl'] .fi-body .tracking-wider { letter-spacing: 0; }
.fi-body .tabular-nums { font-variant-numeric: tabular-nums; }
.fi-body .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fi-body .break-all { word-break: break-all; }
.fi-body .whitespace-nowrap { white-space: nowrap; }
.fi-body .whitespace-pre-line { white-space: pre-line; }
.fi-body .text-center { text-align: center; }
/* start/end rather than left/right wherever the markup allows it. */
.fi-body .text-start, .fi-body .text-left { text-align: start; }
.fi-body .text-end, .fi-body .text-right { text-align: end; }

/* Three the first sweep missed. `pr-4` is the one that shows: 24 uses across Unit
   Pricing and the PMS Directory, both of which are tables, so every cell in them
   rendered with no gutter between columns. Mapped to padding-inline-end rather than
   padding-right for the same reason text-left resolves to `start` above -- a physical
   right-padding is on the wrong side in Arabic, and both these screens are
   partner-facing. */
.fi-body .pr-4 { padding-inline-end: 1rem; }
.fi-body .-mx-2 { margin-inline: -0.5rem; }
.fi-body .select-all { user-select: all; }

/* ---- Colour ------------------------------------------------------------- */
.fi-body .text-gray-400 { color: var(--u-g400); }
.fi-body .text-gray-500 { color: var(--u-g500); }
.fi-body .text-gray-600 { color: var(--u-g600); }
.fi-body .text-gray-700 { color: var(--u-g700); }
.fi-body .text-gray-900, .fi-body .text-gray-950 { color: var(--u-g900); }
.fi-body .text-white { color: #fff; }
.fi-body .text-white\/90 { color: rgba(255, 255, 255, 0.9); }
.fi-body .text-white\/70 { color: rgba(255, 255, 255, 0.7); }
.fi-body .text-primary-600 { color: var(--tv-accent-deep); }
.fi-body .text-danger-600 { color: #C0392B; }
.fi-body .text-amber-700 { color: #A87D11; }
.fi-body .text-warning-600 { color: #A87D11; }
.fi-body .text-warning-700 { color: #8A6A0E; }
.fi-body .text-warning-800 { color: #6E540B; }
.dark .fi-body .dark\:text-gray-100,
.dark .fi-body .dark\:text-white { color: #F1EAE1; }
.dark .fi-body .dark\:text-gray-300 { color: #CFC2B4; }
.dark .fi-body .dark\:text-gray-400 { color: var(--tv-d-muted); }
.dark .fi-body .dark\:text-gray-500 { color: #8C7C6C; }
.dark .fi-body .dark\:text-primary-400 { color: var(--tv-d-mint); }
.dark .fi-body .dark\:text-danger-400 { color: #E88C7D; }
.dark .fi-body .dark\:text-warning-200 { color: #F0DFA6; }
.dark .fi-body .dark\:text-warning-300 { color: #E3C766; }
.dark .fi-body .dark\:text-warning-400 { color: #D8B84E; }

.fi-body .bg-white { background-color: var(--u-surface); }
.fi-body .bg-gray-50 { background-color: var(--u-g50); }
.fi-body .bg-gray-100 { background-color: var(--u-g100); }
.fi-body .bg-white\/10 { background-color: rgba(255, 255, 255, 0.1); }
.fi-body .bg-warning-50 { background-color: #FFFBEB; }
.fi-body .hover\:bg-gray-200:hover { background-color: var(--u-g300); }
.dark .fi-body .dark\:bg-gray-800 { background-color: #2A2119; }
.dark .fi-body .dark\:bg-gray-800\/50 { background-color: rgba(42, 33, 25, 0.5); }
.dark .fi-body .dark\:bg-gray-900 { background-color: #140F0A; }
.dark .fi-body .dark\:bg-warning-900\/10 { background-color: rgba(201, 162, 39, 0.1); }
.dark .fi-body .dark\:bg-amber-900\/30 { background-color: rgba(146, 106, 16, 0.3); }

/* ---- Borders, radius, elevation ----------------------------------------- */
.fi-body .border { border: 1px solid var(--u-g200); }
.fi-body .border-b { border-bottom: 1px solid var(--u-g200); }
.fi-body .border-gray-50 { border-color: var(--u-g50); }
.fi-body .border-gray-100 { border-color: var(--u-g100); }
.fi-body .border-gray-200 { border-color: var(--u-g200); }
.fi-body .border-gray-300 { border-color: var(--u-g300); }
.fi-body .border-warning-200 { border-color: #FDE68A; }
.fi-body .border-warning-300 { border-color: #FCD34D; }
.fi-body .last\:border-0:last-child { border: 0; }
.fi-body .last\:border-b-0:last-child { border-bottom: 0; }
.dark .fi-body .dark\:border-gray-600 { border-color: #4A3B2E; }
.dark .fi-body .dark\:border-gray-700 { border-color: var(--tv-d-line); }
.dark .fi-body .dark\:border-gray-800 { border-color: #2A2119; }
.dark .fi-body .dark\:border-white\/10 { border-color: rgba(255, 255, 255, 0.1); }
.dark .fi-body .dark\:border-white\/5 { border-color: rgba(255, 255, 255, 0.05); }
.dark .fi-body .dark\:border-warning-600 { border-color: #A87D11; }
.dark .fi-body .dark\:border-warning-700 { border-color: #8A6A0E; }
.dark .fi-body .dark\:border-warning-800 { border-color: #6E540B; }

.fi-body .divide-y > * + * { border-top: 1px solid var(--u-g200); }
.fi-body .divide-gray-100 > * + * { border-top-color: var(--u-g100); }
.dark .fi-body .dark\:divide-gray-700\/50 > * + * { border-top-color: rgba(58, 46, 36, 0.5); }

.fi-body .rounded-lg { border-radius: 0.65rem; }
.fi-body .rounded-xl { border-radius: 0.9rem; }
.fi-body .rounded-full { border-radius: 999px; }
.fi-body .shadow-sm { box-shadow: var(--tv-shadow-sm); }
.fi-body .ring-1 { box-shadow: 0 0 0 1px var(--u-g200); }
.fi-body .ring-gray-950\/5 { box-shadow: 0 0 0 1px rgba(43, 29, 20, 0.05); }
.dark .fi-body .dark\:ring-white\/10 { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1); }

.fi-body .transition, .fi-body .transition-colors {
    transition: background-color 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.fi-body .duration-75 { transition-duration: 75ms; }
.fi-body .cursor-pointer { cursor: pointer; }
.fi-body .antialiased { -webkit-font-smoothing: antialiased; }

/* Bare <input>/<select>/<textarea> written outside Filament's own field
   components -- the settings page has several -- otherwise render as a browser
   default line with no box. */
.fi-body input.fi-input:not([type='checkbox']):not([type='radio']),
.fi-body select.fi-input,
.fi-body textarea.fi-input {
    width: 100%;
    border: 1px solid var(--u-g300);
    border-radius: 0.65rem;
    background: var(--u-surface);
    padding: 0.55rem 0.8rem;
    font-size: 0.875rem;
    color: var(--u-g900);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.fi-body input.fi-input:focus,
.fi-body select.fi-input:focus,
.fi-body textarea.fi-input:focus {
    outline: none;
    border-color: var(--tv-accent);
    box-shadow: 0 0 0 3px var(--tv-accent-line);
}

/* Bound through Alpine `:class` or a Blade ternary rather than written as a
   literal attribute, so a plain scan of class="..." misses them: the copy
   buttons swap state, and the API-keys table stripes its rows. */
.fi-body .bg-amber-100 { background-color: #FDF0C8; }
.fi-body .bg-gray-50\/50 { background-color: rgba(251, 250, 246, 0.5); }
.dark .fi-body .dark\:bg-gray-800\/30 { background-color: rgba(42, 33, 25, 0.3); }
.dark .fi-body .dark\:hover\:bg-gray-700:hover { background-color: #3A2E24; }
.dark .fi-body .dark\:text-amber-300 { color: #E3C766; }

/* Focus rings on hand-rolled inputs. The input rule above already draws the
   ring; these exist so the class names in the markup are not lying. */
.fi-body .focus\:border-primary-500:focus { border-color: var(--tv-accent); }
.fi-body .focus\:ring-1:focus,
.fi-body .focus\:ring-primary-500:focus { box-shadow: 0 0 0 3px var(--tv-accent-line); }
.fi-body .focus\:ring-inset:focus { box-shadow: inset 0 0 0 2px var(--tv-accent-line); }


/* ---- Integrations hub ---------------------------------------------------
   The hub (Connect / No-code mapping / Developer, both panels) adds the
   utilities below to the bridge. Two groups are new here and worth naming:

   - **Responsive card columns.** The connector catalogue is a card grid; without
     `sm:grid-cols-2` / `xl:grid-cols-3` it renders as one full-width card per
     row on a 27-inch monitor, which is how it first shipped in review.
   - **Semantic tints.** The mapping tester says "read it" or "could not read
     it" in a tinted panel, and the request form opens in a brand-tinted one.
     Filament's own success/danger/primary tints are on components, not on
     utilities, so the four surfaces here are the panel's palette rather than
     Tailwind's.
   ------------------------------------------------------------------------- */

@media (min-width: 640px) {
    .fi-body .sm\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1280px) {
    .fi-body .xl\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.fi-body .grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.fi-body .min-w-0 { min-width: 0; }
.fi-body .max-w-xl { max-width: 36rem; }
.fi-body .max-w-2xl { max-width: 42rem; }
.fi-body .mx-auto { margin-inline: auto; }
.fi-body .mt-auto { margin-top: auto; }
.fi-body .align-top { vertical-align: top; }

/* Logical insets, so a copy button pinned to the far edge of a code block
   mirrors in Arabic instead of sitting on top of the first token. */
.fi-body .top-2 { top: 0.5rem; }
.fi-body .end-2 { inset-inline-end: 0.5rem; }
.fi-body .ms-1 { margin-inline-start: 0.25rem; }

.fi-body .p-1 { padding: 0.25rem; }
.fi-body .p-5 { padding: 1.25rem; }
.fi-body .pt-1 { padding-top: 0.25rem; }
.fi-body .gap-x-6 { column-gap: 1.5rem; }
.fi-body .gap-y-1 { row-gap: 0.25rem; }
.fi-body .space-y-1 > * + * { margin-top: 0.25rem; }
.fi-body .space-y-5 > * + * { margin-top: 1.25rem; }
.fi-body .leading-relaxed { line-height: 1.7; }

.fi-body .rounded { border-radius: 0.375rem; }
.fi-body .border-t { border-top: 1px solid var(--u-g200); }
.fi-body .border-dashed { border-style: dashed; }

.fi-body .text-gray-800 { color: var(--u-g700); }
.fi-body .text-primary-700 { color: var(--tv-accent-deep); }
.fi-body .text-success-700 { color: #16714E; }
.fi-body .text-danger-700 { color: #A32A1E; }
.fi-body .hover\:text-gray-800:hover { color: var(--u-g700); }
.fi-body .hover\:border-gray-300:hover { border-color: var(--u-g300); }

.fi-body .bg-primary-50 { background-color: #FBF1EA; }
.fi-body .bg-primary-50\/60 { background-color: rgba(251, 241, 234, 0.6); }
.fi-body .bg-success-50\/60 { background-color: rgba(232, 246, 240, 0.6); }
.fi-body .bg-danger-50\/60 { background-color: rgba(251, 235, 233, 0.6); }
.fi-body .border-primary-200 { border-color: #EBD3C2; }
.fi-body .border-primary-500 { border-color: var(--tv-accent); }
.fi-body .border-success-200 { border-color: #BFE3D4; }
.fi-body .border-danger-200 { border-color: #F0C7C1; }

.dark .fi-body .dark\:bg-gray-800\/60 { background-color: rgba(42, 33, 25, 0.6); }
.dark .fi-body .dark\:bg-primary-900\/10 { background-color: rgba(194, 112, 61, 0.1); }
.dark .fi-body .dark\:bg-primary-900\/20 { background-color: rgba(194, 112, 61, 0.2); }
.dark .fi-body .dark\:bg-success-900\/10 { background-color: rgba(31, 157, 107, 0.1); }
.dark .fi-body .dark\:bg-danger-900\/10 { background-color: rgba(192, 57, 43, 0.1); }
.dark .fi-body .dark\:border-primary-800 { border-color: #6A4028; }
.dark .fi-body .dark\:border-success-800 { border-color: #14563C; }
.dark .fi-body .dark\:border-danger-800 { border-color: #6E2019; }
.dark .fi-body .dark\:text-gray-200 { color: #E2D7CB; }
.dark .fi-body .dark\:text-primary-300 { color: #E5B48D; }
.dark .fi-body .dark\:text-success-300 { color: #86D9B8; }
.dark .fi-body .dark\:text-danger-300 { color: #F0A79A; }
.dark .fi-body .dark\:hover\:text-gray-200:hover { color: #E2D7CB; }

@media (prefers-reduced-motion: reduce) {
    .fi-body .transition, .fi-body .transition-colors { transition: none !important; }
}

/* =========================================================================
   Empty states, brand marks and micro-motion

   Competitor teardown (COMPETITORS.md) put a number on something we already
   half-did: every empty screen in Msool has the same shape -- a soft tinted
   disc, an icon, a heading that states the fact, a grey hint, and often a CTA.
   Never a bare table with no rows.

   Ours had the right copy and an inconsistent treatment: a small flat swatch
   behind the icon and no sense of deliberate design. Filament already renders
   the structure on every table, so lifting it once here lifts every list in
   all five panels.
   ========================================================================= */

/* ---- Empty states ------------------------------------------------------- */
.fi-empty-state { padding-block: 2.75rem; }

/* A disc with a halo, rather than a flat square of colour. The ring is what
   makes it read as a designed object instead of a missing image. */
.fi-empty-state-icon-bg {
    position: relative;
    width: 4.5rem;
    height: 4.5rem;
    border-radius: 999px;
    background:
        radial-gradient(120% 120% at 30% 20%, rgba(255, 255, 255, 0.9), transparent 60%),
        var(--tv-accent-wash);
    color: var(--tv-accent-deep);
    box-shadow:
        0 0 0 1px var(--tv-accent-line),
        0 0 0 10px rgba(194, 112, 61, 0.05),
        0 10px 24px -14px rgba(43, 29, 20, 0.35);
    display: grid;
    place-items: center;
    /* Settles in rather than appearing. Nothing here moves layout. */
    animation: tv-empty-in 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.fi-empty-state-icon-bg .fi-icon,
.fi-empty-state-icon-bg svg { width: 2rem; height: 2rem; }

.dark .fi-empty-state-icon-bg {
    background:
        radial-gradient(120% 120% at 30% 20%, rgba(255, 255, 255, 0.06), transparent 60%),
        rgba(194, 112, 61, 0.16);
    color: #DBA07C;
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.08),
        0 0 0 10px rgba(194, 112, 61, 0.06);
}

@keyframes tv-empty-in {
    from { opacity: 0; transform: scale(0.88); }
    to { opacity: 1; transform: none; }
}

.fi-empty-state-heading {
    margin-top: 1rem;
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--tv-ink);
}
.dark .fi-empty-state-heading { color: #F5EFE8; }
.fi-empty-state-description {
    margin-top: 0.35rem;
    font-size: 0.87rem;
    line-height: 1.6;
    color: #8A7A6B;
    max-width: 30rem;
    margin-inline: auto;
}
.dark .fi-empty-state-description { color: var(--tv-d-muted); }
.fi-empty-state-actions { margin-top: 1.15rem; }

/* ---- Channel marks ------------------------------------------------------
   The calendar step tells a host to "paste an iCal link from Airbnb,
   Booking.com or Gathern" in prose. Msool shows the logos instead, which is
   read instantly and in any language, so we do too -- we are an integration
   partner of all three. Each brand mark carries its own colour in --tv-brand;
   the trailing .ics glyph stays on currentColor because it stands for "every
   other calendar" and belongs to nobody.
   ------------------------------------------------------------------------- */
/* Its own row, not inline: sitting beside the step's CTA crowded both. */
.tv-marks {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-block: 0.6rem 0.25rem;
}
.tv-mark {
    display: grid;
    place-items: center;
    width: 2.15rem;
    height: 2.15rem;
    border-radius: 0.65rem;
    border: 1px solid var(--tv-hairline);
    background: var(--tv-paper);
    color: #6B5645;
    box-shadow: var(--tv-shadow-sm);
    transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1), color 0.18s, border-color 0.18s;
    animation: tv-empty-in 0.45s cubic-bezier(0.22, 1, 0.36, 1) both;
    animation-delay: calc(var(--tv-i, 0) * 70ms);
}
.tv-mark svg { width: 1.1rem; height: 1.1rem; }
/* A wide full-colour wordmark cannot go in a square slot without being
   squashed -- see public/brand/channels/PROVENANCE.md. */
.tv-mark--wordmark { width: auto; min-width: 2.15rem; padding-inline: 0.5rem; }
.tv-mark--wordmark svg { width: auto; height: 0.95rem; max-width: 4.5rem; }
/* Inline beside a label, in a table cell rather than in a row of its own. */
.tv-mark--sm { width: 1.6rem; height: 1.6rem; border-radius: 0.5rem; box-shadow: none; }
.tv-mark--sm svg { width: 0.85rem; height: 0.85rem; }
.tv-mark--sm.tv-mark--wordmark { width: auto; min-width: 1.6rem; padding-inline: 0.4rem; }
/* Taller and wider than the square marks get: a wordmark has letterforms to
   read, and at 0.7rem Agoda was a smudge. */
.tv-mark--sm.tv-mark--wordmark svg { width: auto; height: 0.95rem; max-width: 4.25rem; }
.tv-chan-cell { display: inline-flex; align-items: center; gap: 0.45rem; }
.tv-chan-cell__name { font-size: 0.8rem; font-weight: 600; color: var(--tv-ink); }
.dark .tv-chan-cell__name { color: #F5EFE8; }
.tv-mark:hover {
    transform: translateY(-2px) scale(1.06);
    color: var(--tv-accent-deep);
    border-color: var(--tv-accent-line);
}
.dark .tv-mark { background: var(--tv-d-surface); border-color: var(--tv-d-line); color: var(--tv-d-muted); }

/* A brand mark keeps its own colour. Tinting a logo to the surface -- on hover
   or in dark mode -- is the one thing these must not do, because the colour is
   half of what makes the channel recognisable at a glance. In dark mode they
   sit on an ivory chip instead, which is how a navy wordmark stays legible on
   a dark surface without being recoloured. */
.tv-mark--brand,
.tv-mark--brand:hover { color: var(--tv-brand); }
/* The mark files carry no fill attribute of their own, so a path defaults to
   black however the box is coloured -- which is how Airbnb and Booking.com
   rendered as black blobs while Gathern, whose file does declare one, came
   through orange. Only the tinted marks: the Agoda wordmark ships with its own
   fills and must keep them. */
.tv-mark--brand svg,
.tv-mark--brand svg path { fill: currentColor; }
.tv-mark--brand:hover { border-color: color-mix(in srgb, var(--tv-brand) 45%, transparent); }
.dark .tv-mark--brand {
    background: var(--tv-ivory);
    border-color: rgba(0, 0, 0, 0.10);
    color: var(--tv-brand);
}
.tv-marks__more { font-size: 0.78rem; font-weight: 600; color: #9A8473; }
.dark .tv-marks__more { color: var(--tv-d-muted); }

/* ---- Micro-motion -------------------------------------------------------
   Small, cheap and everywhere: the difference between a panel that feels
   inert and one that feels responsive. Transform and opacity only.
   ------------------------------------------------------------------------- */

/* Section cards lift very slightly on hover, so a page of them reads as a set
   of objects rather than as a wall. */
:where(html:not(.dark)) .fi-section:hover { box-shadow: var(--tv-shadow-lg); }
.fi-section { transition: box-shadow 0.22s ease; }

/* A sidebar item's icon leans toward its label on hover. */
.fi-sidebar-item-btn .fi-sidebar-item-icon { transition: transform 0.18s ease; }
.fi-sidebar-item-btn:hover .fi-sidebar-item-icon { transform: scale(1.12); }

/* Badges pop when they appear, so a count that has just changed is noticed. */
.fi-badge { animation: tv-empty-in 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) both; }

/* Loading shimmer, for anything that has to wait on a query. */
.tv-skeleton {
    border-radius: 0.6rem;
    background: linear-gradient(
        90deg,
        rgba(43, 29, 20, 0.06) 25%,
        rgba(43, 29, 20, 0.11) 37%,
        rgba(43, 29, 20, 0.06) 63%
    );
    background-size: 400% 100%;
    animation: tv-shimmer 1.4s ease-in-out infinite;
}
.dark .tv-skeleton {
    background: linear-gradient(
        90deg,
        rgba(255, 255, 255, 0.05) 25%,
        rgba(255, 255, 255, 0.1) 37%,
        rgba(255, 255, 255, 0.05) 63%
    );
    background-size: 400% 100%;
}
/* A lazy widget's stand-in: the card it becomes, with shimmer where the
   numbers go (resources/views/filament/shared/lazy-placeholder.blade.php). */
.tv-wi-placeholder { display: block; min-width: 0; }
.tv-wi-placeholder-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: 1rem;
}
.tv-wi-placeholder-stat,
.tv-wi-placeholder-section {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
    padding: 1.6rem 1.75rem;
    border: 1px solid var(--tv-hairline);
    border-radius: var(--tv-radius);
    background: #FFFFFF;
}
.dark .tv-wi-placeholder-stat,
.dark .tv-wi-placeholder-section { background: var(--tv-d-surface); border-color: var(--tv-d-line); }
.tv-wi-placeholder .tv-skeleton { display: block; height: 0.8rem; }
.tv-wi-placeholder .tv-skeleton--title { width: 38%; }
.tv-wi-placeholder .tv-skeleton--value { width: 55%; height: 1.7rem; }
.tv-wi-placeholder .tv-skeleton--hint { width: 28%; height: 0.65rem; }
.tv-wi-placeholder .tv-skeleton--block { height: 12rem; }
.tv-wi-placeholder .tv-skeleton--row { width: 100%; height: 1rem; }

@keyframes tv-shimmer {
    from { background-position: 100% 50%; }
    to { background-position: 0 50%; }
}

/* Livewire marks anything mid-request; fading it stops a table flashing. */
.fi-body [wire\:loading] { transition: opacity 0.15s ease; }

@media (prefers-reduced-motion: reduce) {
    .fi-empty-state-icon-bg,
    .tv-mark,
    .fi-badge { animation: none !important; }
    .tv-skeleton { animation: none !important; background-position: 0 50%; }
    .fi-section,
    .fi-sidebar-item-btn .fi-sidebar-item-icon,
    .tv-mark { transition: none !important; }
    .tv-mark:hover { transform: none; }
    .fi-sidebar-item-btn:hover .fi-sidebar-item-icon { transform: none; }
}

/* =========================================================================
   Unified guest inbox (roadmap N5, slice 1)

   Two columns on a desktop, stacked on a phone: the list is what an operator
   scans and the thread is what they read, and on 390px there is room for one
   of those at a time.

   Every horizontal rule here is a LOGICAL property -- margin-inline,
   border-inline, inset-inline -- so the Arabic panel mirrors without a single
   [dir='rtl'] override. The one place direction is stated outright is a phone
   number, which is Latin digits inside Arabic text and reads backwards
   otherwise.
   ========================================================================= */

.tv-inbox { display: flex; flex-direction: column; gap: 0.75rem; }

.tv-inbox__notice {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.6rem;
    align-items: baseline;
    padding: 0.75rem 1rem;
    border-radius: 0.85rem;
    border: 1px solid rgba(224, 163, 61, 0.45);
    background: rgba(224, 163, 61, 0.12);
    color: var(--tv-ink);
    font-size: 0.85rem;
}
.dark .tv-inbox__notice { color: var(--tv-d-text); border-color: rgba(224, 163, 61, 0.35); }

/* One column below 60rem. Not a media query on a device width: the sidebar
   takes its own space, so the breakpoint that matters is how much is left. */
.tv-inbox__grid {
    display: grid;
    grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
    gap: 0.75rem;
    align-items: start;
}
@media (max-width: 60rem) {
    .tv-inbox__grid { grid-template-columns: minmax(0, 1fr); }
}

.tv-inbox__list,
.tv-inbox__thread {
    background: var(--tv-paper);
    border: 1px solid var(--tv-hairline);
    border-radius: var(--tv-radius);
    box-shadow: var(--tv-shadow-sm);
    overflow: hidden;
}
.dark .tv-inbox__list,
.dark .tv-inbox__thread { background: var(--tv-d-surface); border-color: var(--tv-d-line); }

.tv-inbox__list {
    max-height: 40rem;
    overflow-y: auto;
    /* A soft bottom edge. The list is a bounded scroll box, so on a phone it routinely
       cuts a row in half -- and a half-drawn row with a hard edge reads as a clipped
       layout rather than as "there is more below". */
    mask-image: linear-gradient(to bottom, #000 calc(100% - 1.25rem), transparent);
}
@media (max-width: 60rem) { .tv-inbox__list { max-height: 22rem; } }

.tv-inbox__controls {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem;
    background: var(--tv-paper);
    border-bottom: 1px solid var(--tv-hairline);
}
.dark .tv-inbox__controls { background: var(--tv-d-surface); border-color: var(--tv-d-line); }

.tv-inbox__search {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border-radius: 0.7rem;
    border: 1px solid var(--tv-hairline);
    background: var(--tv-ivory);
    color: inherit;
    font: inherit;
    font-size: 0.85rem;
}
.dark .tv-inbox__search { background: var(--tv-d-canvas); border-color: var(--tv-d-line); }
.tv-inbox__search:focus { outline: 2px solid var(--tv-accent); outline-offset: 1px; }

.tv-inbox__filters { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.tv-inbox__filter {
    padding: 0.25rem 0.6rem;
    border-radius: 999px;
    border: 1px solid var(--tv-hairline);
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 0.72rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}
.tv-inbox__filter.is-on {
    background: var(--tv-accent-wash);
    border-color: var(--tv-accent-line);
    color: var(--tv-accent-deep);
}
.dark .tv-inbox__filter { border-color: var(--tv-d-line); }
.dark .tv-inbox__filter.is-on { color: var(--tv-d-mint); }

.tv-inbox__row {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    width: 100%;
    /* text-align: start, not left: the Arabic panel would otherwise ragged-right
       every row in a column that reads right-to-left. */
    text-align: start;
    padding: 0.7rem 0.85rem;
    border: 0;
    border-bottom: 1px solid var(--tv-hairline);
    background: transparent;
    color: inherit;
    font: inherit;
    cursor: pointer;
}
.dark .tv-inbox__row { border-color: var(--tv-d-line); }
.tv-inbox__row:hover { background: var(--tv-accent-wash); }
.tv-inbox__row.is-open { background: var(--tv-accent-wash); box-shadow: inset 3px 0 0 var(--tv-gold); }
.dark .tv-inbox__row.is-open { background: rgba(194, 112, 61, 0.18); }

.tv-inbox__row-top { display: flex; align-items: baseline; gap: 0.5rem; }
.tv-inbox__who {
    /* A guest's name is Latin as often as it is Arabic, whichever way the panel runs.
       `plaintext` takes each one's direction from its own first strong character, so a
       Latin name in the Arabic panel keeps its own order instead of being reflowed. */
    unicode-bidi: plaintext;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-weight: 600;
    font-size: 0.86rem;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tv-inbox__row.is-unread .tv-inbox__who { font-weight: 800; }
.tv-inbox__dot {
    flex: none;
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background: var(--tv-accent);
}
.tv-inbox__when {
    margin-inline-start: auto;
    flex: none;
    font-size: 0.68rem;
    opacity: 0.7;
    font-variant-numeric: tabular-nums;
}

.tv-inbox__row-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.68rem;
    opacity: 0.85;
}
.tv-inbox__provider {
    padding: 0.1rem 0.4rem;
    border-radius: 999px;
    background: var(--tv-accent-wash);
    color: var(--tv-accent-deep);
    font-weight: 700;
}
.dark .tv-inbox__provider { color: var(--tv-d-mint); background: rgba(194, 112, 61, 0.2); }
.tv-inbox__closed {
    padding: 0.1rem 0.4rem;
    border-radius: 999px;
    border: 1px solid var(--tv-hairline);
    font-weight: 600;
}
.tv-inbox__unit { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.tv-inbox__preview {
    /* Same reason as the name above, and it matters more here: a guest writes in their
       own language, and an English sentence reflowed by an Arabic paragraph puts the full
       stop at the front of the line. */
    unicode-bidi: plaintext;
    text-align: start;
    font-size: 0.78rem;
    opacity: 0.8;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tv-inbox__empty {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 2rem 1.25rem;
    text-align: center;
    font-size: 0.85rem;
}
.tv-inbox__empty strong { font-weight: 800; }
.tv-inbox__empty span { opacity: 0.75; }
.tv-inbox__empty--thread { padding-block: 5rem; }

.tv-inbox__thread { display: flex; flex-direction: column; min-height: 24rem; }

.tv-inbox__context {
    padding: 0.85rem 1rem;
    border-bottom: 1px solid var(--tv-hairline);
    background: var(--tv-ivory);
}
.dark .tv-inbox__context { background: var(--tv-d-raise); border-color: var(--tv-d-line); }

.tv-inbox__context-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.tv-inbox__guest { font-size: 1rem; font-weight: 800; margin: 0; }
.tv-inbox__actions { display: flex; gap: 0.35rem; margin-inline-start: auto; }
.tv-inbox__action {
    padding: 0.25rem 0.7rem;
    border-radius: 999px;
    border: 1px solid var(--tv-hairline);
    background: var(--tv-paper);
    color: inherit;
    font: inherit;
    font-size: 0.72rem;
    font-weight: 600;
    cursor: pointer;
}
.dark .tv-inbox__action { background: var(--tv-d-surface); border-color: var(--tv-d-line); }
.tv-inbox__action:hover { background: var(--tv-accent-wash); }

/* Wrapping row rather than a stretched grid: with two facts on a wide screen, equal
   columns pushed "Stay" halfway across the card and away from the label it belongs to. */
.tv-inbox__facts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 2.5rem;
    margin: 0.6rem 0 0;
    font-size: 0.78rem;
}
.tv-inbox__facts > div { min-width: 8rem; }
.tv-inbox__facts dt { font-size: 0.66rem; text-transform: uppercase; opacity: 0.65; font-weight: 700; }
.tv-inbox__facts dd { margin: 0; font-weight: 600; }
.tv-inbox__status { opacity: 0.7; font-weight: 500; }

.tv-inbox__messages {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1rem;
    flex: 1;
    max-height: 28rem;
    overflow-y: auto;
}

/* The two sides of the conversation. Aligned with the inline axis so the
   guest sits where a reader of that language expects them to. */
.tv-inbox__bubble {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    max-width: min(38rem, 82%);
    padding: 0.55rem 0.75rem;
    border-radius: 0.9rem;
    font-size: 0.85rem;
    border: 1px solid var(--tv-hairline);
}
.dark .tv-inbox__bubble { border-color: var(--tv-d-line); }
.tv-inbox__bubble--guest { margin-inline-end: auto; background: var(--tv-ivory); }
.dark .tv-inbox__bubble--guest { background: var(--tv-d-raise); }
.tv-inbox__bubble--property { margin-inline-start: auto; background: var(--tv-accent-wash); border-color: var(--tv-accent-line); }
.dark .tv-inbox__bubble--property { background: rgba(194, 112, 61, 0.2); }
.tv-inbox__bubble--system {
    margin-inline: auto;
    background: transparent;
    border-style: dashed;
    font-size: 0.75rem;
    opacity: 0.85;
}
.tv-inbox__bubble.is-failed { border-color: #B3261E; }

.tv-inbox__text {
    margin: 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    /* The guest's own direction, not the panel's. See .tv-inbox__preview. */
    unicode-bidi: plaintext;
    text-align: start;
}
.tv-inbox__attachment { font-size: 0.75rem; font-weight: 600; text-decoration: underline; overflow-wrap: anywhere; }
.tv-inbox__stamp { font-size: 0.65rem; opacity: 0.6; font-variant-numeric: tabular-nums; }
.tv-inbox__error { font-size: 0.68rem; color: #B3261E; overflow-wrap: anywhere; }

.tv-inbox__reply {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.85rem 1rem;
    border-top: 1px solid var(--tv-hairline);
}
.dark .tv-inbox__reply { border-color: var(--tv-d-line); }
.tv-inbox__box {
    width: 100%;
    padding: 0.6rem 0.75rem;
    border-radius: 0.8rem;
    border: 1px solid var(--tv-hairline);
    background: var(--tv-ivory);
    color: inherit;
    font: inherit;
    font-size: 0.85rem;
    resize: vertical;
}
.dark .tv-inbox__box { background: var(--tv-d-canvas); border-color: var(--tv-d-line); }
.tv-inbox__box:focus { outline: 2px solid var(--tv-accent); outline-offset: 1px; }
.tv-inbox__reply-foot { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.tv-inbox__hint { font-size: 0.7rem; opacity: 0.7; }
.tv-inbox__reply-foot .fi-btn { margin-inline-start: auto; }

/* ---------------------------------------------------------------------------
   The PMS strip: one line under the top bar in the last week of a trial, in the
   grace days after a paid period, or once the account is locked out. See
   resources/views/filament/shared/pms-strip.blade.php and PmsPanelState::strip().
   --------------------------------------------------------------------------- */
.fi-pms-strip {
    margin: .75rem 1rem 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    border: 1px solid;
    border-radius: .75rem;
    padding: .5rem 1rem;
    font-size: .875rem;
    line-height: 1.4;
}
.fi-pms-strip a {
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
    white-space: nowrap;
}
.fi-pms-strip.is-info { border-color: #b8d3c8; background: #eef6f2; color: #1f4d3a; }
.fi-pms-strip.is-warning { border-color: #e6c58a; background: #fbf3e2; color: #6b4a12; }
.fi-pms-strip.is-danger { border-color: #e2a39a; background: #fbecea; color: #7a2e25; }
.dark .fi-pms-strip.is-info { border-color: rgba(120, 190, 160, .35); background: rgba(60, 130, 100, .14); color: #cfe9dc; }
.dark .fi-pms-strip.is-warning { border-color: rgba(230, 197, 138, .35); background: rgba(180, 130, 40, .14); color: #f3e2bd; }
.dark .fi-pms-strip.is-danger { border-color: rgba(226, 163, 154, .35); background: rgba(170, 60, 50, .16); color: #f5cfca; }

/* The plan cards on Billing → Subscription. */
.fi-pms-plan { border: 1px solid rgba(0, 0, 0, .08); border-radius: .875rem; padding: 1.25rem; }
.dark .fi-pms-plan { border-color: rgba(255, 255, 255, .1); }
.fi-pms-muted { color: #6b7280; }
.dark .fi-pms-muted { color: #9ca3af; }

/* =========================================================================
   Boards (.tv-sb-*)

   The admin Growth -> Sales team screen, and the figures section of the host
   and operator dashboards (resources/views/filament/shared/board/), which
   draw the same tiles, funnel, column chart, table and list over a portfolio
   of units. The prefix is the sales board's, where the vocabulary was born.
   Plain CSS for the same reason as everything else in this file: panels never
   load the app's Vite bundle, so a Tailwind utility written in a panel view
   resolves to nothing.

   THE SERIES AND FUNNEL HEX VALUES BELOW WERE CHECKED WITH A COLOUR-VISION
   AND CONTRAST VALIDATOR. Do not "tidy" them into the brand ramp: the three
   series hues are the set that stays distinguishable to a deuteranope, and
   the four funnel tones are one ordinal ramp rather than four decisions.
   A fourth rep does NOT get a fourth hue -- see SalesBoard::SERIES.

   Light is the base rule, dark is the `.dark` override, matching .tv-an-*
   above. Dark mode here is Filament's class on <html>, never a media query.
   ========================================================================= */

.tv-sb {
    --tv-sb-surface: #FFFFFF;
    --tv-sb-raise: #F5F0E7;
    --tv-sb-ink: #2B1D14;
    --tv-sb-ink-2: #6B5A4E;
    --tv-sb-muted: #9A8473;
    --tv-sb-line: rgba(11, 42, 34, 0.08);
    --tv-sb-grid: #ECE6DC;
    --tv-sb-accent: #C2703D;
    --tv-sb-accent-ink: #A85A2C;
    --tv-sb-accent-wash: rgba(194, 112, 61, 0.08);
    --tv-sb-accent-line: rgba(194, 112, 61, 0.22);

    /* Series: three reps plus one grey. Validated -- see the note above. */
    --tv-sb-s1: #C2703D;
    --tv-sb-s2: #0EA5A4;
    --tv-sb-s3: #7B5EA7;
    --tv-sb-s0: #B8AEA3;

    /* Funnel: one ordinal terracotta ramp, light to dark. Validated. */
    --tv-sb-t1: #DDA27F;
    --tv-sb-t2: #D08858;
    --tv-sb-t3: #C2703D;
    --tv-sb-t4: #A85A2C;

    --tv-sb-track: #EFD9C9;
    --tv-sb-good: #17805A;
    --tv-sb-bad: #C0392B;
    --tv-sb-warn-bg: rgba(224, 163, 61, 0.18);
    --tv-sb-warn-ink: #8A4B12;
    --tv-sb-shadow: 0 1px 2px rgba(11, 42, 34, 0.04), 0 10px 28px -12px rgba(11, 42, 34, 0.16);
    --tv-sb-radius: 1rem;

    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    color: var(--tv-sb-ink);
    min-width: 0;
}
.dark .tv-sb {
    --tv-sb-surface: #221A15;
    --tv-sb-raise: #2B2119;
    --tv-sb-ink: #F3EBE0;
    --tv-sb-ink-2: #C9BBAE;
    --tv-sb-muted: #9A8A7C;
    --tv-sb-line: rgba(255, 255, 255, 0.08);
    --tv-sb-grid: #35291F;
    --tv-sb-accent: #D98A5A;
    --tv-sb-accent-ink: #E8A57C;
    --tv-sb-accent-wash: rgba(217, 138, 90, 0.12);
    --tv-sb-accent-line: rgba(217, 138, 90, 0.30);
    --tv-sb-s1: #C97A48;
    --tv-sb-s2: #1FA9A7;
    --tv-sb-s3: #9B84CF;
    --tv-sb-s0: #7A6E64;
    --tv-sb-t1: #7A4A2E;
    --tv-sb-t2: #9C5C36;
    --tv-sb-t3: #BF6E3E;
    --tv-sb-t4: #D98A5A;
    --tv-sb-track: #4A3527;
    --tv-sb-good: #3BBF8A;
    --tv-sb-bad: #E06B5A;
    --tv-sb-warn-bg: rgba(224, 163, 61, 0.20);
    --tv-sb-warn-ink: #E8A57C;
    --tv-sb-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 10px 28px -12px rgba(0, 0, 0, 0.5);
}

.tv-sb [x-cloak] { display: none !important; }

/* ---- Cards -------------------------------------------------------------- */
.tv-sb-card,
.tv-sb-controls,
.tv-sb-tile {
    background: var(--tv-sb-surface);
    border: 1px solid var(--tv-sb-line);
    border-radius: var(--tv-sb-radius);
    box-shadow: var(--tv-sb-shadow);
    min-width: 0;
}
.tv-sb-card { padding: 1.1rem 1.25rem; }
.tv-sb-card__title {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.625rem;
    margin: 0 0 0.85rem;
    flex-wrap: wrap;
}
.tv-sb-card__title h2,
.tv-sb-card__title h3 { margin: 0; font-size: 0.95rem; font-weight: 700; color: var(--tv-sb-ink); }
/* A link in the card's corner ("All units"), pushed past the hint. */
.tv-sb-card__corner { margin-inline-start: auto; }
.tv-sb-link { color: inherit; text-decoration: none; }
.tv-sb-link:hover { text-decoration: underline; text-underline-offset: 2px; }
.tv-sb-muted { color: var(--tv-sb-muted); }
.tv-sb-hint, .tv-sb-note { color: var(--tv-sb-muted); font-size: 0.75rem; line-height: 1.45; }
.tv-sb-note { margin: 0.4rem 0 0; }
.tv-sb-empty { color: var(--tv-sb-muted); padding: 2.5rem 1rem; text-align: center; margin: 0; }

/* Off-screen but in the accessibility tree: the chart's figures in a table,
   for anybody who cannot hover a bar to read one. */
.tv-sb-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ---- Controls ----------------------------------------------------------- */
.tv-sb-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.625rem 0.875rem;
    padding: 0.625rem 0.75rem;
}
.tv-sb-seg {
    display: inline-flex;
    padding: 3px;
    gap: 2px;
    background: var(--tv-sb-raise);
    border-radius: 999px;
    flex-wrap: wrap;
}
.tv-sb-seg__btn {
    border: 0;
    background: transparent;
    padding: 0.375rem 0.75rem;
    border-radius: 999px;
    cursor: pointer;
    font: inherit;
    font-weight: 600;
    font-size: 0.8rem;
    color: var(--tv-sb-ink-2);
    white-space: nowrap;
}
.tv-sb-seg__btn:hover { color: var(--tv-sb-ink); }
.tv-sb-seg__btn--on {
    background: var(--tv-sb-surface);
    color: var(--tv-sb-ink);
    box-shadow: 0 1px 2px rgba(11, 42, 34, 0.1);
}
.dark .tv-sb-seg__btn--on { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.45); }

.tv-sb-stepper { display: inline-flex; align-items: center; gap: 0.25rem; }
.tv-sb-step {
    border: 1px solid var(--tv-sb-line);
    background: var(--tv-sb-surface);
    width: 1.875rem;
    height: 1.875rem;
    border-radius: 50%;
    cursor: pointer;
    color: var(--tv-sb-ink-2);
    display: inline-grid;
    place-items: center;
    padding: 0;
}
.tv-sb-step svg { width: 1.1rem; height: 1.1rem; }
/* The chevrons point at "earlier" and "later", which swap sides in Arabic. */
[dir='rtl'] .tv-sb-step svg { transform: scaleX(-1); }
.tv-sb-step:hover:not(:disabled) { border-color: var(--tv-sb-accent-line); color: var(--tv-sb-ink); }
.tv-sb-step:disabled { opacity: 0.4; cursor: default; }
.tv-sb-stepper__label {
    font-weight: 700;
    padding-inline: 0.5rem;
    font-size: 0.9rem;
    color: var(--tv-sb-ink);
}
.tv-sb-spacer { flex: 1 1 0; min-width: 0; }

/* ---- Headline tiles ----------------------------------------------------- */
.tv-sb-kpis {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.875rem;
}
.tv-sb-tile {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 1.05rem 1.15rem;
}
.tv-sb-tile__label { font-size: 0.8rem; font-weight: 600; color: var(--tv-sb-ink-2); }
.tv-sb-tile__value {
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.01em;
    color: var(--tv-sb-ink);
    /* Not `overflow-wrap: anywhere`: it breaks the line between the figure and the
       riyal glyph, which is one word however the browser sees it. */
    white-space: nowrap;
}
.tv-sb-tile--hero .tv-sb-tile__value { font-size: 2.5rem; }
/* A count of things that went wrong, when there are any. */
.tv-sb-tile__value--bad { color: var(--tv-sb-bad); }
/* "Off market": a word where a number would be, and not pretending to be one. */
.tv-sb-tile__value--muted { color: var(--tv-sb-muted); font-size: 1.35rem; padding-block: 0.3rem; }
.tv-sb-tile__value svg { width: 0.62em; height: 0.62em; opacity: 0.75; }

.tv-sb-delta {
    font-size: 0.75rem;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    flex-wrap: wrap;
}
.tv-sb-delta__arrow { font-size: 0.65em; }
.tv-sb-delta--good { color: var(--tv-sb-good); }
.tv-sb-delta--bad { color: var(--tv-sb-bad); }
.tv-sb-delta--flat { color: var(--tv-sb-muted); }

.tv-sb-spark { margin-top: 0.15rem; height: 34px; }
.tv-sb-spark__svg { width: 100%; height: 34px; display: block; }
.tv-sb-trend .tv-sb-spark__svg { height: 26px; }
.tv-sb-spark__area { fill: var(--tv-sb-accent); opacity: 0.1; }
.tv-sb-spark__line {
    fill: none;
    stroke: var(--tv-sb-s0);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}
.tv-sb-spark__ring { stroke: var(--tv-sb-surface); stroke-width: 9; stroke-linecap: round; fill: none; }
.tv-sb-spark__dot { stroke: var(--tv-sb-accent); stroke-width: 5.5; stroke-linecap: round; fill: none; }

.tv-sb-meter {
    height: 8px;
    border-radius: 4px;
    background: var(--tv-sb-track);
    overflow: hidden;
    margin-top: 0.4rem;
    display: block;
}
.tv-sb-meter > i { display: block; height: 100%; background: var(--tv-sb-accent); border-radius: 4px; }
.tv-sb-meter--inline { width: 44px; margin: 0; flex: 0 0 auto; }

/* ---- Bands -------------------------------------------------------------- */
.tv-sb-band { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.875rem; }

/* ---- Funnel ------------------------------------------------------------- */
.tv-sb-funnel {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    /* The value sits just past the end of its bar, so the full-width bar needs
       somewhere for its number to go. Without this the longest bar's label pushes
       the whole document sideways. */
    padding-inline-end: 7ch;
}
.tv-sb-stage {
    display: grid;
    grid-template-columns: 8ch minmax(0, 1fr);
    align-items: center;
    gap: 0.75rem;
}
.tv-sb-stage__name { font-size: 0.8rem; font-weight: 600; color: var(--tv-sb-ink-2); }
.tv-sb-stage__bar { position: relative; height: 24px; }
.tv-sb-stage__fill {
    display: block;
    height: 100%;
    inline-size: var(--tv-sb-w);
    border-start-end-radius: 4px;
    border-end-end-radius: 4px;
    transition: inline-size 240ms ease;
}
.tv-sb-stage__value {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    inset-inline-start: calc(var(--tv-sb-w) + 0.5rem);
    font-weight: 700;
    font-size: 0.8rem;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.tv-sb-drop {
    padding-inline-start: calc(8ch + 0.75rem);
    color: var(--tv-sb-muted);
    font-size: 0.72rem;
    margin: -0.25rem 0 0;
}
.tv-sb-funnel__foot { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.75rem; }
.tv-sb-tone-1 { background: var(--tv-sb-t1); }
.tv-sb-tone-2 { background: var(--tv-sb-t2); }
.tv-sb-tone-3 { background: var(--tv-sb-t3); }
.tv-sb-tone-4 { background: var(--tv-sb-t4); }

/* ---- Series colours ----------------------------------------------------- */
/* One class for both an SVG band (fill) and an HTML swatch (background). */
.tv-sb-f0 { fill: var(--tv-sb-s0); background-color: var(--tv-sb-s0); }
.tv-sb-f1 { fill: var(--tv-sb-s1); background-color: var(--tv-sb-s1); }
.tv-sb-f2 { fill: var(--tv-sb-s2); background-color: var(--tv-sb-s2); }
.tv-sb-f3 { fill: var(--tv-sb-s3); background-color: var(--tv-sb-s3); }

/* "Other reps" is the same grey as Campaigns, hatched. A second grey would be
   indistinguishable from the first; a fourth HUE would be indistinguishable
   from the third for a colour-blind reader. Texture is the only axis left. */
.tv-sb-bar--other { fill: url(#tv-sb-hatch); }
.tv-sb-hatch-bg { fill: var(--tv-sb-s0); }
.tv-sb-hatch-line { stroke: var(--tv-sb-surface); stroke-width: 2.5; }
.tv-sb-key--other {
    background-image: repeating-linear-gradient(
        45deg,
        transparent 0 2px,
        var(--tv-sb-surface) 2px 4px
    );
}
.tv-sb-avatar--other { opacity: 0.95; }

/* ---- Chart -------------------------------------------------------------- */
.tv-sb-chart { position: relative; min-width: 0; }
.tv-sb-chart__svg { width: 100%; height: auto; display: block; overflow: visible; }
.tv-sb-grid { stroke: var(--tv-sb-grid); stroke-width: 1; }
.tv-sb-axis { stroke: var(--tv-sb-s0); stroke-width: 1; }
.tv-sb-tick { font-size: 11px; fill: var(--tv-sb-muted); font-variant-numeric: tabular-nums; }
/* The chart's SVG scales with its card, and so does every label in it. On a narrow
   card an 11px tick lands at about five real pixels, so the type is set larger in
   the SVG's own units to come out the same size on screen. */
@media (max-width: 900px) {
    .tv-sb-tick { font-size: 16px; }
}
.tv-sb-bar { transition: opacity 160ms ease; }
.tv-sb-week--dim { opacity: 0.4; }
.tv-sb-hit { fill: transparent; cursor: crosshair; }
.tv-sb-hit:focus-visible { fill: var(--tv-sb-accent-wash); outline: none; }

.tv-sb-tip {
    position: absolute;
    z-index: 20;
    pointer-events: none;
    background: var(--tv-sb-ink);
    color: var(--tv-sb-surface);
    border-radius: 0.5rem;
    padding: 0.5rem 0.625rem;
    font-size: 0.72rem;
    box-shadow: var(--tv-sb-shadow);
    min-width: 11rem;
    max-width: 15rem;
}
.tv-sb-tip__t { font-weight: 700; margin-bottom: 0.25rem; }
.tv-sb-tip__r { display: flex; justify-content: space-between; gap: 0.75rem; }
.tv-sb-tip__r b { font-weight: 700; }
.tv-sb-tip svg { width: 0.62em; height: 0.62em; }

.tv-sb-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.875rem;
    font-size: 0.75rem;
    color: var(--tv-sb-ink-2);
    margin-top: 0.625rem;
}
.tv-sb-legend span { display: inline-flex; align-items: center; gap: 0.375rem; }
.tv-sb-key {
    width: 10px;
    height: 10px;
    border-radius: 2px;
    display: inline-block;
    flex: 0 0 auto;
}

/* ---- Leaderboard -------------------------------------------------------- */
.tv-sb-scroll { overflow-x: auto; margin-inline: -1.25rem; padding-inline: 1.25rem; }
.tv-sb-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.82rem;
    /* Eleven columns. Narrow enough to sit beside the follow-ups on a laptop and
       wide enough to stay readable; below the breakpoint it has the card to itself
       and, on a phone, scrolls inside it. */
    min-width: 700px;
}
.tv-sb-table th {
    text-align: start;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--tv-sb-muted);
    padding: 0.5rem 0.4rem;
    border-bottom: 1px solid var(--tv-sb-line);
    white-space: nowrap;
}
[dir='rtl'] .tv-sb-table th { letter-spacing: 0; }
.tv-sb-table td {
    padding: 0.6rem 0.4rem;
    border-bottom: 1px solid var(--tv-sb-line);
    vertical-align: middle;
    color: var(--tv-sb-ink);
}
.tv-sb-table tbody tr:hover { background: var(--tv-sb-accent-wash); }
.tv-sb-table tfoot td {
    font-weight: 700;
    border-bottom: 0;
    border-top: 2px solid var(--tv-sb-line);
}
.tv-sb-num { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tv-sb-num svg { width: 0.7em; height: 0.7em; opacity: 0.7; }
.tv-sb-rank { color: var(--tv-sb-muted); font-variant-numeric: tabular-nums; width: 2ch; }
.tv-sb-rep { display: flex; align-items: center; gap: 0.6rem; }
.tv-sb-rep__name { font-weight: 700; white-space: nowrap; }
.tv-sb-avatar {
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    display: inline-grid;
    place-items: center;
    color: #FFFFFF;
    font-weight: 700;
    font-size: 0.7rem;
    flex: 0 0 auto;
}
.tv-sb-codes { display: flex; gap: 0.35rem; flex-wrap: wrap; margin-top: 0.2rem; }
.tv-sb-code {
    font-family: ui-monospace, 'SF Mono', Menlo, monospace;
    font-size: 0.66rem;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    background: var(--tv-sb-raise);
    color: var(--tv-sb-ink-2);
    border: 1px solid var(--tv-sb-line);
    cursor: pointer;
    unicode-bidi: isolate;
}
.tv-sb-code:hover { border-color: var(--tv-sb-accent-line); color: var(--tv-sb-ink); }
.tv-sb-conv { display: inline-flex; align-items: center; gap: 0.5rem; justify-content: flex-end; }
.tv-sb-trend { width: 76px; }
.tv-sb-trend .tv-sb-spark__svg { width: 76px; }

/* ---- Follow-ups --------------------------------------------------------- */
.tv-sb-follow { margin: 0; padding: 0; list-style: none; }
.tv-sb-follow > li {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.25rem 0.625rem;
    padding: 0.625rem 0;
    border-bottom: 1px solid var(--tv-sb-line);
    align-items: center;
}
.tv-sb-follow > li:last-child { border-bottom: 0; }
.tv-sb-follow__who { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; min-width: 0; }
.tv-sb-follow__name { font-weight: 700; overflow-wrap: anywhere; }
.tv-sb-follow__open { grid-row: 1 / span 2; grid-column: 2; }
.tv-sb-follow__meta {
    grid-column: 1;
    margin: 0;
    color: var(--tv-sb-muted);
    font-size: 0.72rem;
    display: flex;
    align-items: center;
    gap: 0.3rem;
    flex-wrap: wrap;
}
.tv-sb-follow__empty {
    display: block;
    color: var(--tv-sb-muted);
    padding: 1.5rem 0;
    border-bottom: 0;
}
.tv-sb-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: 0 0 auto; }

.tv-sb-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    background: var(--tv-sb-raise);
    color: var(--tv-sb-ink-2);
}
.tv-sb-chip--warn { background: var(--tv-sb-warn-bg); color: var(--tv-sb-warn-ink); }
.tv-sb-chip--live { background: rgba(23, 128, 90, 0.14); color: var(--tv-sb-good); }
.tv-sb-ghost {
    border: 1px solid var(--tv-sb-line);
    background: var(--tv-sb-surface);
    border-radius: 999px;
    padding: 0.3rem 0.7rem;
    cursor: pointer;
    font-weight: 600;
    font-size: 0.75rem;
    color: var(--tv-sb-ink-2);
    text-decoration: none;
    white-space: nowrap;
}
.tv-sb-ghost:hover { border-color: var(--tv-sb-accent-line); color: var(--tv-sb-ink); }

/* ---- On a dashboard ----------------------------------------------------- */
/* The board is a section of the page rather than the page, so it carries its
   own heading in the controls bar and the stages get room for a host's words. */
.tv-sb-controls__heading {
    margin: 0;
    font-size: 1rem;
    font-weight: 800;
    color: var(--tv-sb-ink);
    padding-inline: 0.25rem 0.5rem;
    letter-spacing: -0.01em;
}
.tv-sb--embedded .tv-sb-stage { grid-template-columns: 11ch minmax(0, 1fr); }
.tv-sb--embedded .tv-sb-drop { padding-inline-start: calc(11ch + 0.75rem); }
/* Eight columns, not eleven. */
.tv-sb--embedded .tv-sb-table { min-width: 600px; }
.tv-sb--embedded .tv-sb-follow__name { font-size: 0.9rem; }

/* ---- Widths ------------------------------------------------------------- */
/* The funnel and the chart sit side by side once the content column is wide
   enough for the chart to be worth the space it takes. */
@media (min-width: 1100px) {
    /* :not(--wide), because the wide band carries both classes and would otherwise
       take this split and give the eleven-column table the NARROWER half. */
    .tv-sb-band:not(.tv-sb-band--wide) { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
}
/* The leaderboard is eleven columns wide, so it keeps the whole content column
   to itself until the screen is genuinely wide. Below this it is full width and
   the follow-ups sit underneath -- which is also the phone order. */
/* The leaderboard is eleven columns wide and the panel's sidebar takes 16rem of
   whatever the screen has, so this is the width at which two thirds of the content
   column is genuinely wider than the table. Below it the table has the card to
   itself and the chasing list sits underneath -- a full table above a full list
   beats half a table beside one. */
@media (min-width: 1560px) {
    .tv-sb-band--wide { grid-template-columns: minmax(0, 8fr) minmax(0, 4fr); }
}
@media (max-width: 820px) {
    .tv-sb-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .tv-sb-tile--hero .tv-sb-tile__value { font-size: 2rem; }
}
@media (max-width: 460px) {
    .tv-sb-kpis { grid-template-columns: minmax(0, 1fr); }
    .tv-sb-tile__value { font-size: 1.6rem; }
    .tv-sb-card { padding: 1rem; }
    .tv-sb-scroll { margin-inline: -1rem; padding-inline: 1rem; }
    .tv-sb-stage { grid-template-columns: 7ch minmax(0, 1fr); }
    .tv-sb-drop { padding-inline-start: calc(7ch + 0.75rem); }
    .tv-sb--embedded .tv-sb-stage { grid-template-columns: 9ch minmax(0, 1fr); }
    .tv-sb--embedded .tv-sb-drop { padding-inline-start: calc(9ch + 0.75rem); }
}
@media (prefers-reduced-motion: reduce) {
    .tv-sb-stage__fill, .tv-sb-bar { transition: none; }
}


/* ---- The other doors on the host sign-in / sign-up (sign-in-doors.blade.php) ------ */
.fi-doors { display: grid; gap: 0.6rem; margin-bottom: 1.25rem; }
.fi-door {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.65rem;
    border: 1px solid var(--tv-hairline);
    border-radius: 0.8rem;
    padding: 0.7rem 1rem;
    background: #fff;
    font-weight: 700;
    font-size: 0.92rem;
    color: var(--tv-ink, #2B1D14);
    transition: border-color 0.15s, background-color 0.15s, transform 0.15s;
}
.fi-door:hover { border-color: #DBA07C; background: #FCF7EF; transform: translateY(-1px); }
.fi-door svg { width: 1.15rem; height: 1.15rem; flex: none; }
.fi-doors__or { position: relative; margin-top: 0.75rem; text-align: center; font-size: 0.75rem; font-weight: 600; color: #9A8473; }
.fi-doors__or::before { content: ''; position: absolute; inset-inline: 0; top: 50%; height: 1px; background: var(--tv-hairline); }
.fi-doors__or span { position: relative; padding: 0 0.75rem; background: rgba(255, 255, 255, 0.94); }
.dark .fi-door { background: rgba(255, 255, 255, 0.04); color: #F5EFE6; }
.dark .fi-doors__or span { background: #1F1712; }
