/* The nested frequency grid inside a routine's child row never scrolls
   itself — the OUTER routines grid's .mud-table-container is the horizontal
   scroller (the child-row td spans the outer table's full width). The global
   `.mud-data-grid .mud-table-container { overflow: auto !important }` rule in
   utilities.css makes the nested container the sticky containing block anyway,
   so its StickyRight column pins against a box that doesn't scroll and sits
   off-screen. Restoring `visible` here lets the sticky cell pin against the
   outer scroller. Extra specificity (3 classes) is required to beat that rule. */
.routines-grid .routine-frequencies-grid .mud-table-container {
    overflow: visible !important;
}

/* Routine schedule — adapted from assets/schedule/schedule.css.
   Theme-aware: all *chrome* colours track the MudBlazor palette so the
   grid renders correctly in both light and dark mode. */

/* ------------------------------------------------------------------
   Status palette.

   The hues are borrowed from the conventions users already know from
   other modern software — grey = not started, blue = active, amber =
   attention, red = failed/late, green = success, purple = success but
   off-schedule — rather than invented for this grid. An earlier version
   picked six maximally-separated hues off the colour wheel; green vs
   teal read as one colour at chip size, which is exactly the pair the
   reader most needs to tell apart.

   Chip identity is deliberately NOT derived from the semantic MudBlazor
   palette. Two of those tokens are unusable here:
     * --mud-palette-info is #DBEAFE in the light theme (Theme.cs) — an
       alert *background* tint, not a hue. Using it as a chip colour
       rendered "In progress" as white-on-white (ClickUp 86d3qm12c).
     * --mud-palette-warning is never customised by this app, so both
       "Not completed" and "Completed late" collapsed onto MudBlazor's
       default #ff9800.

   TEXT COLOURS ARE NOT ALL WHITE, ON PURPOSE. Chip text is 600 10.5px
   uppercase — small bold, so WCAG AA wants 4.5:1. White on the amber
   (#F59E0B) is 2.2:1 and on the green (#16A34A) is 3.1:1; both fail.
   Those two therefore carry near-black text (8.4:1 and 5.9:1). Do not
   "fix" them back to white. Blue / red / purple keep white (5.2 / 4.8 /
   6.5:1).

   Five statuses carry a solid fill. "Planned" — the majority of chips on
   screen — carries a lighter fill with a solid border, so it is
   unambiguously a chip without drowning out the handful of Overdue /
   Not-completed chips that actually need attention.

   One palette serves both themes: these fills are saturated enough to
   hold their identity on the dark surface (#16233B) too, so there is
   deliberately no .mud-theme-dark override here.
   ------------------------------------------------------------------ */
.schedule,
.routine-year-strip {
    /* Lifecycle order: planned → in progress → not completed → overdue →
       completed on time → completed late. */
    --rs-planned-bg: #D1D5DB; /* planned — no job generated yet */
    --rs-planned-fg: #374151;
    --rs-planned-br: #9CA3AF;
    --rs-active-bg: #2563EB; /* in progress */
    --rs-active-fg: #FFFFFF;
    --rs-blocked-bg: #F59E0B; /* not completed */
    --rs-blocked-fg: #451A03; /* near-black — see the contrast note above */
    --rs-overdue-bg: #DC2626; /* overdue */
    --rs-overdue-fg: #FFFFFF;
    --rs-done-bg: #16A34A; /* completed on time (within tolerance) */
    --rs-done-fg: #052E16; /* near-black — see the contrast note above */
    --rs-late-bg: #7C3AED; /* completed late (outside tolerance) */
    --rs-late-fg: #FFFFFF;
}

.schedule {
    background: var(--mud-palette-surface);
    border-radius: 8px;
    border: 1px solid var(--mud-palette-lines-default);
    overflow: visible;
    isolation: isolate;
}

/* Toolbar */
.sched-toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    flex-wrap: wrap;
}

.year-nav {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

.year-nav-label {
    font: 600 16px var(--mud-typography-default-family, sans-serif);
    color: var(--mud-palette-text-primary);
    padding: 0 8px;
    min-width: 60px;
    text-align: center;
}

.toolbar-spacer {
    flex: 1;
}

.search-input {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--mud-palette-background-gray);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    padding: 5px 10px;
    font-size: 13px;
    min-width: 220px;
}

.search-input:focus-within {
    border-color: var(--mud-palette-primary);
    box-shadow: 0 0 0 2px rgba(var(--mud-palette-primary-rgb), 0.22);
}

.search-input input {
    border: 0;
    outline: 0;
    background: transparent;
    flex: 1;
    font: 400 13px var(--mud-typography-default-family, sans-serif);
    color: var(--mud-palette-text-primary);
}

/* Filter pills */
.sched-filters {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
    padding: 10px 16px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-background-gray);
}

.filter-label {
    font: 500 11px var(--mud-typography-default-family, sans-serif);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    margin-right: 4px;
}

.filter-pill {
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 999px;
    padding: 4px 11px;
    font: 500 12px var(--mud-typography-default-family, sans-serif);
    color: var(--mud-palette-text-primary);
    cursor: pointer;
    display: inline-flex;
    gap: 5px;
    align-items: center;
    transition: all 120ms ease-out;
}

.filter-pill:hover {
    background: var(--mud-palette-background-gray);
}

.filter-pill.is-on {
    background: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    border-color: var(--mud-palette-primary);
}

.filter-pill .pill-count {
    font-size: 10.5px;
    font-weight: 600;
    opacity: 0.7;
    background: color-mix(in srgb, var(--mud-palette-text-primary) 8%, transparent);
    border-radius: 999px;
    padding: 0 6px;
}

.filter-pill.is-on .pill-count {
    background: rgba(255, 255, 255, 0.18);
    opacity: 1;
}

/* Status dot on each filter pill, so the filter row doubles as a key and the
   reader doesn't have to travel to the footer legend to decode a colour. */
.filter-pill .pill-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: none;
    background: currentColor;
}

.filter-pill .pill-dot.in-progress { color: var(--rs-active-bg); }
.filter-pill .pill-dot.cant { color: var(--rs-blocked-bg); }
.filter-pill .pill-dot.overdue { color: var(--rs-overdue-bg); }
.filter-pill .pill-dot.completed-in { color: var(--rs-done-bg); }

/* On the active (primary-filled) pill the status hue would fight the fill —
   fall back to the pill's own text colour. */
.filter-pill.is-on .pill-dot {
    color: currentColor;
    opacity: 0.85;
}

/* Grid */
.sched-grid-wrap {
    overflow: visible;
    position: relative;
}

.sched-grid {
    --col-width: minmax(72px, 1fr);
    --routine-col: 320px;
    min-width: 1080px;
}

.sched-row {
    display: grid;
    grid-template-columns: var(--routine-col) repeat(12, var(--col-width));
    border-bottom: 1px solid var(--mud-palette-lines-default);
    position: relative;
}

.sched-row:last-child {
    border-bottom: 0;
}

.sched-row.is-data:hover {
    background: var(--mud-palette-background-gray);
}

.sched-row.is-data:hover,
.sched-row.is-data:has(.task:hover) {
    z-index: 100;
}

.sched-row.is-data:hover .sched-rowhead {
    background: var(--mud-palette-background-gray);
}

.sched-row.is-header {
    background: var(--mud-palette-surface);
}

.sched-month {
    padding: 11px 0 9px;
    text-align: center;
    font: 500 11px var(--mud-typography-default-family, sans-serif);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    border-left: 1px solid var(--mud-palette-lines-default);
    position: relative;
}

.sched-month.is-today {
    color: var(--mud-palette-primary);
    font-weight: 600;
    background: rgba(var(--mud-palette-primary-rgb), 0.06);
}

.sched-month .today-pin {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 5px solid var(--mud-palette-primary);
}

.sched-rowhead {
    padding: 12px 16px;
    background: var(--mud-palette-surface);
    display: flex;
    flex-direction: column;
    gap: 2px;
    border-right: 1px solid var(--mud-palette-lines-default);
    min-width: 0;
    position: sticky;
    left: 0;
    z-index: 1;
}

.sched-row.is-header .sched-rowhead {
    background: var(--mud-palette-surface);
    font: 500 11px var(--mud-typography-default-family, sans-serif);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    padding: 11px 16px 9px;
    justify-content: center;
}

.sched-row-code {
    font: 500 10.5px ui-monospace, 'SF Mono', monospace;
    color: var(--mud-palette-text-secondary);
    letter-spacing: 0.04em;
}

.sched-row-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.sched-row-name {
    font: 500 13.5px var(--mud-typography-default-family, sans-serif);
    color: var(--mud-palette-text-primary);
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 2px;
}

.sched-row-meta {
    display: flex;
    gap: 6px;
    align-items: center;
    font: 400 11.5px var(--mud-typography-default-family, sans-serif);
    color: var(--mud-palette-text-secondary);
    justify-content: flex-end;
    margin-top: 4px;
    flex-wrap: wrap;
}

.sched-row-meta .meta-sep {
    color: var(--mud-palette-text-disabled);
}

.freq-tag {
    background: var(--mud-palette-background-gray);
    border: 1px solid var(--mud-palette-lines-default);
    font: 600 9.5px var(--mud-typography-default-family, sans-serif);
    padding: 1px 5px;
    border-radius: 3px;
    color: var(--mud-palette-text-primary);
    letter-spacing: 0.06em;
}

/* Cell */
.sched-cell {
    border-left: 1px solid var(--mud-palette-lines-default);
    padding: 6px 4px;
    display: flex;
    gap: 3px;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    min-height: 60px;
    position: relative;
}

.sched-cell:hover,
.sched-cell:has(.task:hover) {
    z-index: 200;
}

/* Current month. The old 3.5% primary wash was effectively invisible across a
   12-column grid; the wash is now keyed off text-primary (so it darkens in
   light mode and lightens in dark) and the column carries a continuous left
   rule up through the header. Deliberately neutral — the grid already spends
   six hues on status, and a seventh accent colour here would compete. */
.sched-cell.is-today-col,
.sched-month.is-today {
    box-shadow: inset 1px 0 0 color-mix(in srgb, var(--mud-palette-primary) 45%, transparent);
}

.sched-cell.is-today-col {
    background: color-mix(in srgb, var(--mud-palette-text-primary) 5%, transparent);
}

/* Task chip */
.task {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    height: 22px;
    padding: 0 7px;
    border-radius: 6px;
    font: 600 10.5px var(--mud-typography-default-family, sans-serif);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    transition: transform 120ms ease-out, box-shadow 120ms ease-out;
    border: 1px solid transparent;
    position: relative;
    white-space: nowrap;
    user-select: none;
}

.task:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
    z-index: 300;
}

.task.completed-in {
    background: var(--rs-done-bg);
    color: var(--rs-done-fg);
}

.task.completed-out {
    background: var(--rs-late-bg);
    color: var(--rs-late-fg);
}

.task.in-progress {
    background: var(--rs-active-bg);
    color: var(--rs-active-fg);
}

.task.cant {
    background: var(--rs-blocked-bg);
    color: var(--rs-blocked-fg);
}

.task.overdue {
    background: var(--rs-overdue-bg);
    color: var(--rs-overdue-fg);
}

/* The one tinted chip — see the palette note above for why. */
.task.planned {
    background: var(--rs-planned-bg);
    color: var(--rs-planned-fg);
    border-color: var(--rs-planned-br);
}

.task.planned:hover {
    border-color: var(--rs-planned-fg);
}

/* Asset-scoped chips get a halo ring rather than the old dotted primary
   outline, which clashed once every chip carried its own hue. The inner
   surface-coloured ring creates the gap; the outer ring picks up the
   chip's own text colour so it reads as part of the chip. */
.task.is-asset {
    box-shadow: 0 0 0 1.5px var(--mud-palette-surface), 0 0 0 3px currentColor;
}

.task.is-asset:hover {
    box-shadow: 0 0 0 1.5px var(--mud-palette-surface), 0 0 0 3px currentColor,
                0 4px 12px rgba(0, 0, 0, 0.12);
}

.task.is-asset::before {
    content: '';
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: currentColor;
    margin-right: 4px;
    opacity: 0.85;
}

.legend-swatch.is-asset {
    box-shadow: 0 0 0 1px var(--mud-palette-background-gray), 0 0 0 2px var(--mud-palette-text-secondary);
}

.task.is-draggable {
    cursor: grab;
}

.task.is-draggable:active {
    cursor: grabbing;
    opacity: 0.5;
}

/* Hover popover */
.task-pop {
    position: absolute;
    top: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    padding: 12px 14px;
    width: 240px;
    z-index: 1000;
    pointer-events: none;
    text-align: left;
    text-transform: none;
    letter-spacing: 0;
    color: var(--mud-palette-text-primary);
    /* visibility (not display) so the reveal can transition; visibility:hidden
       keeps it out of the accessibility tree exactly as display:none did. */
    visibility: hidden;
    opacity: 0;
    transform: translateX(-50%) translateY(-4px);
    transition: opacity 130ms ease-out, transform 130ms ease-out, visibility 130ms;
}

.task:hover .task-pop {
    visibility: visible;
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.task-pop::before {
    content: '';
    position: absolute;
    top: -6px;
    left: 50%;
    transform: translateX(-50%) rotate(45deg);
    width: 10px;
    height: 10px;
    background: var(--mud-palette-surface);
    border-left: 1px solid var(--mud-palette-lines-default);
    border-top: 1px solid var(--mud-palette-lines-default);
}

.task-pop-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font: 500 11px var(--mud-typography-default-family, sans-serif);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    margin-bottom: 6px;
}

.task-pop-status .dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
    background: currentColor;
}

/* The popover's status line inherits its colour from the chip it belongs to,
   so the swatch, chip and popover can never drift apart. (This replaced a
   GetStatusDotColor() switch in the code-behind that hardcoded six hexes
   unrelated to this stylesheet.) Planned uses its foreground token — its
   background token is a near-white tint and would be invisible as text. */
.task.completed-in .task-pop-status { color: var(--rs-done-bg); }
.task.completed-out .task-pop-status { color: var(--rs-late-bg); }
.task.in-progress .task-pop-status { color: var(--rs-active-bg); }
.task.cant .task-pop-status { color: var(--rs-blocked-bg); }
.task.overdue .task-pop-status { color: var(--rs-overdue-bg); }
.task.planned .task-pop-status { color: var(--rs-planned-fg); }

.task-pop-title {
    font: 500 14px var(--mud-typography-default-family, sans-serif);
    color: var(--mud-palette-text-primary);
    margin-bottom: 6px;
    line-height: 1.3;
}

.task-pop-rows {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 4px 12px;
    font: 400 12px var(--mud-typography-default-family, sans-serif);
    margin: 0;
}

.task-pop-rows dt {
    color: var(--mud-palette-text-secondary);
    margin: 0;
}

.task-pop-rows dd {
    margin: 0;
    color: var(--mud-palette-text-primary);
}

/* Flip popover on right-edge cells */
.sched-cell.is-edge-right .task-pop {
    left: auto;
    right: 0;
    transform: translateY(-4px);
}

.sched-cell.is-edge-right .task:hover .task-pop {
    transform: translateY(0);
}

.sched-cell.is-edge-right .task-pop::before {
    left: auto;
    right: 14px;
    transform: rotate(45deg);
}

/* Footer legend */
.legend {
    display: flex;
    gap: 18px;
    flex-wrap: wrap;
    align-items: center;
    padding: 12px 16px;
    background: var(--mud-palette-background-gray);
    border-top: 1px solid var(--mud-palette-lines-default);
}

.legend-title {
    font: 500 11px var(--mud-typography-default-family, sans-serif);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    margin-right: 4px;
}

.legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font: 400 12px var(--mud-typography-default-family, sans-serif);
    color: var(--mud-palette-text-primary);
}

/* Swatches read off the same tokens as the chips — 6px radius to match the
   chip silhouette, so the legend is a literal key to the grid. */
.legend-swatch {
    width: 16px;
    height: 16px;
    border-radius: 6px;
    border: 1px solid transparent;
    display: inline-block;
    flex: none;
}

.legend-swatch.completed-in {
    background: var(--rs-done-bg);
}

.legend-swatch.completed-out {
    background: var(--rs-late-bg);
}

.legend-swatch.in-progress {
    background: var(--rs-active-bg);
}

.legend-swatch.cant {
    background: var(--rs-blocked-bg);
}

.legend-swatch.overdue {
    background: var(--rs-overdue-bg);
}

.legend-swatch.planned {
    background: var(--rs-planned-bg);
    border-color: var(--rs-planned-br);
}

/* Scope legend ("Routine schedule" / "Asset-specific schedule"). Neutral by
   design — scope is orthogonal to status, and reusing a status swatch here
   implied these rows meant something they don't. */
.legend-swatch.scope {
    background: var(--mud-palette-surface);
    border-color: var(--mud-palette-text-secondary);
}

.legend-divider {
    width: 1px;
    height: 18px;
    background: var(--mud-palette-lines-default);
    margin: 0 4px;
}

.legend-freq {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font: 400 11.5px var(--mud-typography-default-family, sans-serif);
    color: var(--mud-palette-text-secondary);
}

.legend-freq .freq-tag {
    font-size: 9.5px;
}

.sched-empty {
    padding: 28px 16px;
    text-align: center;
    color: var(--mud-palette-text-secondary);
    font: 400 13px var(--mud-typography-default-family, sans-serif);
}

/* ============================================================
   Per-frequency year strip — Property page Routines tab.
   Compact 12-month row per frequency; chips reuse the .task
   status colours above so the strip always matches the
   Routine Schedule tab.
   ============================================================ */
.routine-year-strip {
    display: inline-flex;
    gap: 3px;
    align-items: center;
}

.routine-year-strip .rys-cell {
    width: 26px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 5px;
    box-sizing: border-box;
}

/* Size override: the shared .task chip is larger and animates on hover;
   inside the strip it must stay a fixed compact square. */
.routine-year-strip .task {
    min-width: 26px;
    width: 26px;
    height: 20px;
    padding: 0;
    font-size: 8.5px;
    cursor: default;
}

.routine-year-strip .task:hover {
    transform: none;
    box-shadow: none;
}

.routine-year-strip .rys-empty {
    background: var(--mud-palette-background-gray);
    border: 1px solid var(--mud-palette-lines-default);
}

.routine-year-strip .rys-month {
    color: var(--mud-palette-text-secondary);
    font: 600 9.5px var(--mud-typography-default-family, sans-serif);
    background: transparent;
}

/* Hint shown after an all-empty strip when the frequency's first
   occurrence falls outside the strip year (Start Month floor). */
.routine-year-strip .rys-first-due {
    margin-left: 4px;
    white-space: nowrap;
    color: var(--mud-palette-text-secondary);
    font: 500 10.5px var(--mud-typography-default-family, sans-serif);
}

/* ============================================================
   "Assets needed" flag — Property page Routines tab.
   Shown next to a routine's name when the property has no active
   assets of that routine's AssetType, so inspections can't be
   scheduled for it. Warning-toned, theme-aware, gently pulsing to
   draw attention when the reader arrives from the Data Readiness
   "Add Assets for Routines" action. Motion respects reduced-motion.
   ============================================================ */
.routine-name-with-flag {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.routine-assets-needed-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 1px 3px 1px 8px;
    border-radius: 999px;
    font: 600 11.5px var(--mud-typography-default-family, sans-serif);
    white-space: nowrap;
    color: var(--mud-palette-warning);
    background: color-mix(in srgb, var(--mud-palette-warning) 14%, var(--mud-palette-surface));
    border: 1px solid color-mix(in srgb, var(--mud-palette-warning) 45%, transparent);
    animation: routineAssetsPulse 2s ease-in-out infinite;
}

.routine-assets-needed-pill__label {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.routine-assets-needed-pill__label .mud-icon-root {
    font-size: 15px;
}

/* Compact "+" affordance seated inside the warning pill: secondary-coloured glyph
   on a white background so it reads clearly against the pale warning fill. */
.routine-assets-needed-pill__add.mud-icon-button {
    width: 20px;
    height: 20px;
    padding: 0;
    background-color: #fff !important;
    border: 1px solid var(--mud-palette-secondary);
    color: var(--mud-palette-secondary) !important;
}

.routine-assets-needed-pill__add.mud-icon-button:hover {
    background-color: color-mix(in srgb, var(--mud-palette-secondary) 10%, #fff) !important;
}

.routine-assets-needed-pill__add .mud-icon-root {
    font-size: 15px;
    color: var(--mud-palette-secondary) !important;
    fill: currentColor !important;
}

@keyframes routineAssetsPulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(var(--mud-palette-warning-rgb), 0); }
    50%      { box-shadow: 0 0 0 4px rgba(var(--mud-palette-warning-rgb), 0.28); }
}

@media (prefers-reduced-motion: reduce) {
    .routine-assets-needed-pill { animation: none; }

    .task,
    .task-pop {
        transition: none;
    }

    .task:hover {
        transform: none;
    }

    /* Keep the popover positioned, just drop the travel. */
    .task-pop { transform: translateX(-50%); }
    .task:hover .task-pop { transform: translateX(-50%); }
    .sched-cell.is-edge-right .task-pop,
    .sched-cell.is-edge-right .task:hover .task-pop { transform: none; }
}
