/* ============================================================================
   SB Time Tracker — product-specific styles.
   The shared Liquid Glass design system (tokens, orbs, MudBlazor chrome, brand
   lockups, sb-landing auth cards, sb-status pages, dashboard glass) lives in
   Sb.DesignSystem (_content/Sb.DesignSystem/sb.css), linked BEFORE this sheet
   in App.razor. Only Time Tracker feature styles belong here.
   ============================================================================ */

/* -- Timer (AppBar pill + popover form) ------------------------------------ */
.timer-host {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    margin-right: 6px;
}
.timer-pill {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 12px;
    border-radius: 999px;
    border: 1px solid var(--mkt-border);
    background: rgba(255, 255, 255, 0.6);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    color: var(--mkt-text-soft);
    cursor: pointer;
    white-space: nowrap;
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.timer-pill:hover {
    color: var(--mkt-primary);
    border-color: rgba(0, 122, 255, 0.35);
}
.timer-pill--running {
    border-color: rgba(52, 199, 89, 0.45);
    background: rgba(52, 199, 89, 0.10);
    color: var(--mkt-text);
}
.timer-elapsed {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
}
.timer-project {
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
    color: var(--mkt-text-soft);
}
.timer-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #34C759;
    flex-shrink: 0;
}
@media (prefers-reduced-motion: no-preference) {
    .timer-dot {
        animation: timer-pulse 2s ease-in-out infinite;
    }
}
@keyframes timer-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.35; }
}
.timer-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: 320px;
    max-width: 92vw;
    padding: 16px;
}
.timer-form-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--mkt-text);
    font-variant-numeric: tabular-nums;
}
.timer-summary {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 12px;
    background: rgba(118, 118, 128, 0.06);
    border: 0.5px solid var(--mkt-border-soft);
}
.timer-summary-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
    margin-top: 4px;
}
.timer-summary-project { font-size: 14px; font-weight: 600; color: var(--mkt-text); }
.timer-summary-desc    { font-size: 13px; color: var(--mkt-text-soft); }
.timer-summary-meta    { font-size: 12px; color: var(--mkt-text-faint); margin-top: 2px; }

@media (max-width: 700px) {
    .timer-project, .timer-pill-label { display: none; }

    /* Tenant switcher (the appbar's only outlined menu button): cap the company
       name so the bell / apps / account menus stay on-screen at phone widths.
       The label goes block so text-overflow can ellipsize its inline content. */
    .mud-appbar .mud-menu .mud-button-outlined { max-width: 128px; }
    .mud-appbar .mud-menu .mud-button-outlined .mud-button-label {
        display: block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}

/* -- Timesheet segment bar (multi-segment partial submissions) ------------- */
.ts-segment-bar {
    display: inline-flex;
    height: 26px;
    border-radius: 13px;
    overflow: hidden;
    gap: 2px;
    min-width: 200px;
    align-items: stretch;
}

.ts-seg {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 600;
    padding: 0 8px;
    color: white;
    white-space: nowrap;
    cursor: default;
}

.ts-seg-open      { background: var(--mud-palette-grey-default, #6b6b6b); color: #f5f5f5; }
.ts-seg-submitted { background: var(--mud-palette-info, #2196F3); }
.ts-seg-approved  { background: var(--mud-palette-success, #4CAF50); }
.ts-seg-rejected  { background: var(--mud-palette-warning, #FF9800); }

.day-entry-row--selected {
    background: rgba(0, 122, 255, 0.10);
}

/* -- Lock badge ----------------------------------------------------------- */
/* Universal-contrast wrapper for lock icons that sit on project-colored
   entry cards (Week glass-card, Day timeline). The white circle lifts the
   category-colored icon off any background; subtle shadow gives depth.
   Pair with EntryLockVisuals.IconFor / ColorHexFor for the icon inside.
   Use the --sm variant inline within tight rows like the Month pill.
   Not needed on flat surfaces (day-list row, dialog title) — those use
   the icon directly without the badge. */
.entry-lock-badge {
    position: absolute;
    top: 5px;
    right: 5px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: white;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);
}
.entry-lock-badge .mud-icon-root {
    font-size: 12px !important;
}

.entry-lock-badge--sm {
    position: relative;
    top: auto;
    right: auto;
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.20);
}
.entry-lock-badge--sm .mud-icon-root {
    font-size: 9px !important;
}

/* Note badge — reuses the white-circle lock-badge chrome for contrast over project-colored
   cards, but a quiet muted glyph so it never competes with the colored lock states. */
.entry-note-badge .mud-icon-root {
    color: var(--mkt-text-soft, #6E6E73) !important;
}

/* Badge cluster — top-right group that lays the lock + note badges out in a horizontal row so
   multiple indicators stack side by side instead of overlapping. The cluster owns the absolute
   positioning; badges inside it go relative and flow with the flex gap. */
.entry-badge-cluster {
    position: absolute;
    top: 5px;
    right: 5px;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 4px;
}
.entry-badge-cluster .entry-lock-badge {
    position: relative;
    top: auto;
    right: auto;
}

/* -- Settings > Import & Export reference sidebar lists ------------------- */
.ref-list {
    margin: 0.25rem 0 0;
    padding-left: 1.1rem;
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--mud-palette-text-primary);
}
.ref-list li {
    margin-bottom: 0.35rem;
}
.ref-list code {
    font-size: 0.8rem;
    padding: 0 0.25rem;
    border-radius: 3px;
    background: rgba(0,0,0,0.05);
}

/* -- Day column header (today highlight) ---------------------------------- */
.day-header {
    border-radius: 12px;
    padding: 6px 4px;
    text-align: center;
    margin-bottom: 8px;
    transition: background 0.2s ease;
}

.day-header--today {
    background: linear-gradient(180deg, #3395FF 0%, #007AFF 100%);
    color: white;
    box-shadow: 0 2px 8px rgba(0, 122, 255, 0.25);
}

.day-header--today .mud-typography {
    color: white !important;
}

/* -- Month cell ----------------------------------------------------------- */
.month-cell {
    min-height: 100px;
    background: var(--mkt-surface);
    box-shadow: var(--mkt-shadow-card);
    border-radius: 14px;
    border: 1px solid var(--mkt-border);
    padding: 8px;
    cursor: pointer;
    transition: background 0.2s ease, transform 0.15s ease;
}

.month-cell:hover {
    background: var(--mkt-primary-soft);
    transform: translateY(-1px);
}

.month-cell--outside {
    opacity: 0.45;
}

/* Hover-revealed quick-add "+" in a month cell — opens the lightweight quick-add popover. Kept out
   of the way (invisible until hover/focus) so the grid stays calm. */
.month-quickadd-plus {
    appearance: none;
    border: none;
    background: transparent;
    color: var(--mkt-primary);
    font-size: 16px;
    line-height: 1;
    font-weight: 600;
    width: 20px;
    height: 20px;
    border-radius: 6px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s ease, background 0.15s ease;
}
.month-cell:hover .month-quickadd-plus,
.month-quickadd-plus:focus-visible {
    opacity: 1;
}
.month-quickadd-plus:hover {
    background: rgba(0, 122, 255, 0.10);
}

/* -- Quick-add popover (QuickEntryPopover) --------------------------------- */
/* A plain fixed panel, deliberately NOT a MudMenu: MudSelect/MudAutocomplete option lists render
   at body level through MudPopoverProvider, so inside a menu an option click read as an
   outside-click and dismissed it mid-selection. The backdrop only closes on a DIRECT click, and
   the z-indexes below sit under MudBlazor's popover layer (1200) so option lists stack above. */
.qa-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1150;
    background: transparent;
}

.qa-panel {
    position: fixed;
    z-index: 1151;
    width: 320px;
    max-width: calc(100vw - 16px);
    padding: 14px;
    background: var(--mkt-surface);
    border: 1px solid var(--mkt-border);
    border-radius: var(--sb-radius-card, 12px);
    box-shadow: var(--mkt-shadow-card-hover, 0 8px 24px rgba(0, 0, 0, 0.12));
}

.qa-panel:focus { outline: none; }

.qa-panel-head {
    display: flex;
    /* center, not baseline — the head now carries an icon button that has to line up with the text */
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
}

.qa-panel-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--mkt-text);
}

.qa-panel-day {
    font-size: 12px;
    color: var(--mkt-text-faint);
    font-variant-numeric: tabular-nums;
    /* Pushes the day label right; the expand button sits after it. (Was justify-content:space-between
       on the head, which strands the day label in the middle now that there are three children.) */
    margin-left: auto;
}

/* Negative block margin keeps the 30px icon button from growing the header — the panel's
   position:fixed clamp() budget assumes a ~340px-tall box. Geometry only: the hover is MudBlazor's
   own neutral overlay + ripple, deliberately left as-is. There is no shared icon-button re-skin to
   inherit — sb.css re-skins .mud-button-filled/-outlined/-text and scopes its only .mud-icon-button
   rules to .mud-appbar — and nothing brand-colored belongs on this control. */
.qa-panel-expand {
    flex: 0 0 auto;
    margin: -6px -4px -6px 0;
}

/* MudTooltip wraps its child in an inline root, so THAT root is the head's actual flex item. */
.qa-panel-head .mud-tooltip-root {
    display: inline-flex;
    flex: 0 0 auto;
}

.qa-panel-foot {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 8px;
    flex-wrap: wrap;
}

/* Duration presets — quiet pills, one row, no glow. */
.qa-chips {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
}

/* ── Quiet pill (shared) ──────────────────────────────────────────────────────
   The calendar's two toggle-pill rows — the quick-add duration presets (.qa-chip) and the project
   legend/filter (.tc-legend-item / .tc-legend-clear, defined further down) — are the same control:
   a hairline full-pill <button> that tints to brand on hover and again when it is "on". The shared
   declarations live here once; each row keeps only what genuinely differs (its padding, and the
   legend's inline-flex dot+label layout). Declared before every per-class override, which is what
   lets those win on equal specificity. */
.qa-chip,
.tc-legend-item,
.tc-legend-clear {
    appearance: none;
    cursor: pointer;
    font-size: 12px;
    font-weight: 500;
    line-height: 1.4;
    color: var(--mkt-text-soft);
    background: var(--mkt-surface);
    border: 1px solid var(--mkt-border);
    border-radius: 999px;
    transition: background var(--sb-transition), border-color var(--sb-transition), color var(--sb-transition);
}

.qa-chip:hover,
.tc-legend-item:hover,
.tc-legend-clear:hover {
    background: var(--mkt-primary-soft);
    border-color: rgba(0, 122, 255, 0.4);
    color: var(--mkt-primary);
}

.qa-chip--on,
.tc-legend-item--on {
    background: rgba(0, 122, 255, 0.10);
    border-color: rgba(0, 122, 255, 0.45);
    color: var(--mkt-primary);
}

.qa-chip { padding: 3px 9px; }

/* "Log this again" chips inside the panel — the same quiet pill as the duration presets, one row,
   capped at 3 by the component so the panel's height budget grows by a single line (the popover's
   PanelHeightPx reserves for it). Scrolls rather than wraps: a second line would break the
   clamp() positioning assumption. */
.qa-recent {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    margin: 0 0 10px;
}

.qa-recent::-webkit-scrollbar { display: none; }

.qa-recent-chip {
    flex: 0 0 auto;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Phones: the same panel becomes a bottom sheet — full width, anchored to the bottom edge, within
   thumb reach of the FAB that opened it. The component positions itself with INLINE left/top, so
   these overrides must be !important; nothing about the panel's contents changes. */
@media (max-width: 600px) {
    .qa-panel {
        left: 0 !important;
        right: 0;
        top: auto !important;
        bottom: 0;
        width: 100%;
        max-width: none;
        padding: 16px 16px calc(16px + env(safe-area-inset-bottom, 0px));
        border-radius: 16px 16px 0 0;
        border-bottom: 0;
        box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.16);
    }
}

.month-cell--today-badge {
    background: linear-gradient(180deg, #3395FF 0%, #007AFF 100%);
    color: white;
    border-radius: 50%;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.8125rem;
    box-shadow: 0 1px 4px rgba(0, 122, 255, 0.3);
}

/* -- Month entry pill ----------------------------------------------------- */
.month-entry-pill {
    border-radius: 6px;
    padding: 2px 6px;
    margin-bottom: 2px;
    font-size: 0.7rem;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: white !important;
    font-weight: 500;
    border: 0.5px solid rgba(0, 0, 0, 0.06);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
    transition: transform 0.1s ease, filter 0.1s ease;
}

.month-entry-pill:hover {
    filter: brightness(0.97);
}

/* Select mode: .month-entry-pill--selected shares the one .tg-block--selected rule below. */

/* -- Day view sidebar entry rows ------------------------------------------ */
.day-entry-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 4px;
    border-bottom: 0.5px solid rgba(60, 60, 67, 0.08);
    cursor: pointer;
    border-radius: 10px;
    transition: background 0.15s ease;
}

.day-entry-row:hover {
    background: rgba(0, 122, 255, 0.04);
}

.day-entry-dot {
    width: 4px;
    height: 36px;
    border-radius: 2px;
    flex-shrink: 0;
}

/* -- Logged-time box in dialog -------------------------------------------- */
.logged-time-box {
    background: rgba(118, 118, 128, 0.06);
    border: 0.5px solid rgba(60, 60, 67, 0.08);
    border-radius: 14px;
    padding: 16px;
    margin-bottom: 12px;
}

/* -- Entry editor drawer (right-anchored side panel) ----------------------
   Opened via DialogPosition.CenterRight + Class="time-entry-drawer" from both
   MyTime (self) and Approvals (manager editing a selected employee). Mirrors
   PM's pm-task-drawer: turns the centered modal into a full-height panel flush
   to the right edge. Width is tuned for a single-column EDIT FORM, narrower
   than PM's 760px. */
.mud-dialog-container.mud-dialog-centerright:has(.time-entry-drawer) {
    padding-right: 0;
    align-items: stretch;
}

.time-entry-drawer.mud-dialog {
    margin: 0;
    height: 100dvh;
    max-height: 100dvh;
    width: min(560px, 96vw);
    max-width: 96vw;
    border-radius: 0 !important;
    display: flex;
    flex-direction: column;
    box-shadow: -16px 0 60px rgba(0, 0, 0, 0.16) !important;
}

.time-entry-drawer .mud-dialog-content {
    flex: 1 1 auto;
    overflow-y: auto;
    max-height: none !important;
}

.time-entry-drawer .mud-dialog-actions {
    flex: 0 0 auto;
    border-top: 0.5px solid var(--mkt-border);
}

/* -- AI "Draft my week" review rows --------------------------------------- */
.draft-rows {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.draft-row {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    border: 1px solid var(--mkt-border);
    border-radius: var(--sb-radius-control);
    background: var(--mkt-surface);
}

.draft-row--disabled {
    opacity: 0.6;
    background: var(--mkt-bg);
}

.draft-row-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

/* ==========================================================================
   Time-positioned grid (.tg) — Week + Day
   --------------------------------------------------------------------------
   Position IS the data: an entry's top edge is its start time, its height is
   its duration. 48px per hour (0.8px/min, 12px per 15-minute snap) — the same
   constants TimeCalendarView.PxPerMinute and time-grid.js use, so C#, JS and
   CSS agree on the geometry. Solid surfaces, hairline rules, no glass.
   ========================================================================== */
.tg {
    position: relative;                /* ghost + now-line are positioned against this */
    background: var(--mkt-surface);
    border: 1px solid var(--mkt-border);
    border-radius: 14px;
    box-shadow: var(--mkt-shadow-card);
    overflow: hidden;
    /* Touch drag is deliberately deferred — let vertical scrolling win on phones. */
    touch-action: pan-y;
}

/* Day view nests the grid inside the Timeline dash-card, which already supplies the chrome —
   flatten it so we don't get a card inside a card (design system §4). */
.tg--flat {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
}
.tg--flat .tg-head { background: var(--mkt-surface); }

/* The one scroll container: the head band sticks, the hours scroll under it.
   Horizontal overflow never reaches the page body (minmax(0,1fr) columns). */
.tg-scroll {
    max-height: 620px;
    overflow-y: auto;
    overflow-x: hidden;
}

.tg-head {
    position: sticky;
    top: 0;
    z-index: 3;
    display: grid;
    gap: 0;
    background: var(--mkt-surface);
    border-bottom: 1px solid var(--mkt-border);
}

.tg-corner { border-right: 1px solid var(--mkt-border-soft, var(--mkt-border)); }

.tg-head-col {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    padding: 6px 4px;
    border-right: 1px solid var(--mkt-border-soft, var(--mkt-border));
}
.tg-head-col:last-child { border-right: 0; }
.tg-head-col .day-header { margin-bottom: 0; }

/* Untimed lane — duration-only entries and every legacy midnight-anchored row. Keeps a stable
   min-height so a week with none doesn't sit a different height from one with some. */
.tg-untimed {
    min-height: 26px;
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 3px;
    border-radius: 8px;
    background: rgba(0, 0, 0, 0.025);
    border: 1px dashed transparent;
    transition: border-color var(--sb-transition), background var(--sb-transition);
}
.tg-untimed--filled { background: rgba(0, 0, 0, 0.035); }
.tg--draggable.tg-dragging .tg-untimed { border-color: rgba(0, 122, 255, 0.45); }

.tg-untimed-label {
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mkt-text-faint);
}

.tg-untimed-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 3px 6px;
    border-radius: 7px;
    color: white;
    font-size: 11px;
    line-height: 1.3;
    cursor: pointer;
    border: 0.5px solid rgba(0, 0, 0, 0.08);
    transition: filter var(--sb-transition);
}
.tg-untimed-card:hover { filter: brightness(1.05); }
.tg-untimed-desc {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tg-untimed-dur { flex: 0 0 auto; opacity: 0.9; font-variant-numeric: tabular-nums; }
/* Inline (not overlaid) ⋯ on the compact untimed card — smaller chrome than the block variant. */
.entry-action-badge--flat { flex: 0 0 auto; }
.entry-action-badge--flat .mud-icon-button { width: 16px; height: 16px; }
.entry-action-badge--flat .mud-icon-button .mud-icon-root { font-size: 11px !important; }

.tg-body { display: grid; gap: 0; }

/* Shared hour axis. */
.tg-gutter {
    display: flex;
    flex-direction: column;
    border-right: 1px solid var(--mkt-border-soft, var(--mkt-border));
}
.tg-hour-label {
    font-size: 10.5px;
    font-weight: 500;
    color: var(--mkt-text-faint);
    text-align: right;
    padding-right: 6px;
    transform: translateY(-6px);
    font-variant-numeric: tabular-nums;
}

/* One day column. Hour + half-hour rules are painted, not divs — 7 columns × 16 hours of line
   elements is DOM the grid doesn't need. */
.tg-col {
    position: relative;
    /* Its own stacking context, so block / now-line z-indexes stay UNDER the sticky head band
       instead of painting over it while the hours scroll. */
    z-index: 0;
    min-width: 0;
    border-right: 1px solid var(--mkt-border-soft, var(--mkt-border));
    background-image:
        repeating-linear-gradient(to bottom,
            rgba(60, 60, 67, 0.14) 0 1px, transparent 1px 48px),
        repeating-linear-gradient(to bottom,
            transparent 0 24px, rgba(60, 60, 67, 0.06) 24px 25px, transparent 25px 48px);
}
.tg-col:last-child { border-right: 0; }

/* Focusable hour slot: the keyboard route to quick add, and the surface a drag-create starts on. */
.tg-slot {
    position: absolute;
    left: 0;
    right: 0;
    z-index: 1;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
    transition: background var(--sb-transition);
}
.tg-slot:hover { background: rgba(0, 122, 255, 0.045); }
.tg-slot:focus-visible {
    outline: 2px solid var(--mkt-primary);
    outline-offset: -2px;
    background: rgba(0, 122, 255, 0.06);
}

/* Now-line — 2px brand rule across today's column, moved by the component's 60s ticker. */
.tg-now {
    position: absolute;
    left: 0;
    right: 0;
    height: 2px;
    z-index: 4;
    background: var(--mkt-primary);
    pointer-events: none;
}
.tg-now::before {
    content: "";
    position: absolute;
    left: -3px;
    top: -3px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--mkt-primary);
}

/* A positioned entry. */
.tg-block {
    position: absolute;
    z-index: 2;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 3px 6px;
    border-radius: 8px;
    color: white;
    cursor: pointer;
    border: 0.5px solid rgba(0, 0, 0, 0.10);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.10);
    transition: filter var(--sb-transition), box-shadow var(--sb-transition);
}
.tg-block:hover { filter: brightness(1.05); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.14); }
.tg-block:focus-visible { outline: 2px solid white; outline-offset: -3px; }

.tg-block-desc {
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tg-block-sub {
    font-size: 10.5px;
    opacity: 0.85;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Money + duration share one row and the money slot keeps an empty span when hidden, so the
   _showMoney toggle can never change a block's box (the no-bounce contract, my-time §3). */
.tg-block-foot {
    margin-top: auto;
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 6px;
    font-size: 10px;
    color: rgba(255, 255, 255, 0.95);
}
.tg-block-money { font-weight: 600; }

/* Short blocks drop the sub-line and foot rather than clipping them mid-glyph. The trigger is
   DURATION, never the money toggle. */
.tg-block--dense .tg-block-sub,
.tg-block--dense .tg-block-foot { display: none; }
.tg-block--dense .tg-block-desc { font-size: 10.5px; }

/* The ONE select-mode treatment for a project-coloured entry, whatever shape it takes (grid block,
   untimed card, Month pill). Declared once so "selected" can never look like two different states
   in two views. Ordered after each shape's own box-shadow so it wins on equal specificity. */
.tg-block--selected,
.tg-untimed-card--selected,
.month-entry-pill--selected {
    outline: 2px solid #007AFF;
    outline-offset: 1px;
    box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.18);
}

/* Running entry: a quiet 1px pulsing border — calm, no glow, and it honours reduced motion. */
.tg-block--running {
    border: 1px solid rgba(255, 255, 255, 0.9);
    animation: tg-running-pulse 2.4s ease-in-out infinite;
}
@keyframes tg-running-pulse {
    0%, 100% { border-color: rgba(255, 255, 255, 0.9); }
    50%      { border-color: rgba(255, 255, 255, 0.35); }
}
@media (prefers-reduced-motion: reduce) {
    .tg-block--running { animation: none; }
}

/* Resize grips — 6px, revealed on hover/focus so resting blocks stay calm. */
.tg-handle {
    position: absolute;
    left: 0;
    right: 0;
    height: 6px;
    cursor: ns-resize;
    opacity: 0;
    background: rgba(255, 255, 255, 0.75);
    transition: opacity var(--sb-transition);
}
.tg-handle--top { top: 0; }
.tg-handle--bottom { bottom: 0; }
.tg-block:hover .tg-handle,
.tg-block:focus-within .tg-handle { opacity: 1; }

.tg--draggable .tg-block { cursor: grab; }
.tg--draggable.tg-dragging { cursor: grabbing; user-select: none; }

/* Drag preview. Client-side only — nothing is written until pointerup. */
.tg-ghost {
    position: absolute;
    z-index: 5;
    display: none;
    pointer-events: none;
    border-radius: 8px;
    border: 1px dashed var(--mkt-primary);
    background: rgba(0, 122, 255, 0.12);
    color: var(--mkt-primary);
    font-size: 10.5px;
    font-weight: 600;
    padding: 2px 6px;
    font-variant-numeric: tabular-nums;
}

/* Per-day add target sits under the untimed lane in the sticky band. */
.tg-add-btn.mud-button-root { min-height: 24px; font-size: 11px; }

/* Phones: Day view only, tighter chrome, and no resize grips (touch drag is deferred). */
@media (max-width: 599.98px) {
    .tg-scroll { max-height: 460px; }
    .tg-handle { display: none; }
    .tg-block { padding: 2px 4px; }
}

/* The host's IsMobile parameter, made visible. The media queries above cover VIEWPORT width; this
   class covers what the host actually decided (BrowserViewport breakpoint), which is the same
   signal that locks the page to Day view — so the two can't disagree. It also fixes the thing a
   media query can't: hover-revealed affordances have no "hover" on a touch device, so the ⋯ menu
   is made permanently visible rather than being unreachable. */
.tg--mobile .tg-scroll { max-height: 460px; }
.tg--mobile .tg-block { padding: 2px 4px; }
.tg--mobile .tg-handle { display: none; }
.tg--mobile .tg-head-col { padding: 4px 2px; }
.tg--mobile .entry-action-badge,
.day-entry-row--mobile .entry-action-flat { opacity: 1; }

/* -- Month grid container ------------------------------------------------- */
.month-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 6px;
}

/* Weekly right rail — an 8th, narrow column holding each grid week's total, its timesheet
   segment bar and (when the owner can) a Submit button. Only applied when the host supplies
   WeekSummaries, so a rail-less consumer keeps the plain 7-column grid. */
.month-grid--rail {
    grid-template-columns: repeat(7, minmax(0, 1fr)) 132px;
}

.month-rail {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    padding: 8px;
    min-height: 100px;
    border-radius: 14px;
    /* Flat inset track, not a second card — no card-in-card (design system §4). */
    background: rgba(0, 0, 0, 0.025);
    border: 1px solid var(--mkt-border-soft, var(--mkt-border));
}

.month-rail-total {
    font-size: 13px;
    font-weight: 600;
    color: var(--mkt-text);
    font-variant-numeric: tabular-nums;
}

.month-rail-submit.mud-button-root {
    padding: 2px 8px;
    min-height: 26px;
    font-size: 11px;
}

/* Month is desktop-only (phones are locked to Day), but keep the grid sane if it is ever
   rendered narrow: drop the rail rather than squeezing the seven day columns. */
@media (max-width: 959.98px) {
    .month-grid--rail { grid-template-columns: repeat(7, minmax(0, 1fr)); }
    .month-rail { display: none; }
}

/* -- Day context: capacity underbar, holiday / PTO paint ------------------- */
/* 3px progress track under the Week day-header total. Always occupies the same space once a
   daily target exists, so toggling money or hovering never resizes the header. */
.tc-cap-track {
    height: 3px;
    margin: 4px 6px 0;
    border-radius: 2px;
    background: rgba(0, 0, 0, 0.10);
    overflow: hidden;
}
.day-header--today .tc-cap-track {
    background: rgba(255, 255, 255, 0.30);
}
.tc-cap-fill {
    height: 100%;
    border-radius: 2px;
    background: var(--mkt-primary);
    transition: width var(--sb-transition);
}
.day-header--today .tc-cap-fill {
    background: white;
}
/* Over target — the contrast-tuned warning hex, not the raw palette orange. */
.tc-cap-fill--over {
    background: #B25000;
}
.day-header--today .tc-cap-fill--over {
    background: #FFD9B0;
}

/* Holiday / PTO caption under the day header (Week) or the Day-summary total (Day). */
.tc-day-context {
    margin-top: 3px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--mkt-text-faint);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.day-header--today .tc-day-context { color: rgba(255, 255, 255, 0.85); }
.tc-day-context--flat { text-transform: none; letter-spacing: 0; font-size: 12px; }

/* Calm solid tints (no stripes, no glass) marking a company holiday or an approved day off.
   Applied to the Month cell and to the grid's head + hour columns.
   background-COLOR, never the `background` shorthand: the shorthand would reset .tg-col's painted
   hour rules (same specificity, later in the sheet — it would silently win). */
.tc-day--holiday { background-color: rgba(178, 80, 0, 0.06); }
.tc-day--pto     { background-color: rgba(30, 142, 62, 0.07); }
.month-cell.tc-day--holiday:hover { background-color: rgba(178, 80, 0, 0.10); }
.month-cell.tc-day--pto:hover     { background-color: rgba(30, 142, 62, 0.11); }

/* Month cells are too tight for the caption — a dot carries it, with the name on hover. */
.tc-day-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    display: inline-block;
    flex-shrink: 0;
}
.tc-day-dot--holiday { background: #B25000; }
.tc-day-dot--pto     { background: #1E8E3E; }

/* -- Per-entry ⋯ action affordance ---------------------------------------- */
/* Lives inside the absolutely-positioned .entry-badge-cluster on grid blocks and untimed cards, so
   it can never change their height (the no-bounce contract). Hidden until the block is hovered or
   anything inside it takes focus — keyboard users get it too. */
/* Both variants (overlay badge / flat row) hide the same way and reveal on the same three signals —
   hovering the host, focus landing anywhere inside the host, or focus landing on the menu itself.
   One rule each so the two can't drift into different reveal behaviour; only the button chrome below
   differs. */
.entry-action-badge,
.entry-action-flat {
    display: inline-flex;
    opacity: 0;
    transition: opacity var(--sb-transition);
}
.tg-block:hover .entry-action-badge,
.tg-block:focus-within .entry-action-badge,
.tg-untimed-card:hover .entry-action-badge,
.tg-untimed-card:focus-within .entry-action-badge,
.entry-action-badge:focus-within,
.day-entry-row:hover .entry-action-flat,
.day-entry-row:focus-within .entry-action-flat,
.entry-action-flat:focus-within {
    opacity: 1;
}
.entry-action-badge .mud-icon-button {
    width: 20px;
    height: 20px;
    padding: 0;
    background: white;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);
    color: var(--mkt-text-soft);
}
.entry-action-badge .mud-icon-button .mud-icon-root {
    font-size: 13px !important;
}

/* Flat surfaces (Day summary rows) render the same menu without the white-circle chrome. */
.entry-action-flat .mud-icon-button {
    width: 24px;
    height: 24px;
    padding: 0;
    color: var(--mkt-text-faint);
}

/* Non-interactive explanatory line inside the ⋯ menu (why Edit/Delete are disabled). */
.tc-menu-note {
    padding: 6px 16px 2px;
    font-size: 11px;
    line-height: 1.35;
    color: var(--mkt-text-faint);
    max-width: 220px;
    white-space: normal;
}

/* -- App content shell (MainLayout MudContainer) -------------------------- */
/* Left-align the page content to the drawer and use the full width the drawer already
   reserves, instead of MudBlazor centering the container (which left a large gutter between
   the nav rail and the form). The compound selector beats .mud-container's centering without
   !important. Paired with MaxWidth.ExtraExtraLarge in MainLayout. See W2. */
.mud-container.sb-app-shell {
    margin-left: 0;
    margin-right: auto;
}

/* -- Toolbar -------------------------------------------------------------- */
.glass-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 20px;
    padding: 12px 16px;
    background: var(--mkt-surface);
    border: 1px solid var(--mkt-border);
    border-radius: 18px;
    box-shadow: var(--mkt-shadow-card);
}

/* -- My Time command bar + calendar chrome (tc-*) -------------------------- */
/* The period label doubles as the page heading — /time has no separate h1. */
.tc-period-label {
    font-size: 18px;
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1.2;
    color: var(--mkt-text);
    margin: 0 0 0 4px;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Contextual strip shown only while select mode is active — keeps the bulk
   tools out of the everyday toolbar without hiding selection state. */
.tc-select-strip {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: -8px 0 16px;
    padding: 8px 14px;
    border-radius: 14px;
    background: rgba(0, 122, 255, 0.08);
    border: 1px solid rgba(0, 122, 255, 0.25);
}
.tc-select-strip strong {
    font-size: 14px;
    color: var(--mkt-primary);
    font-variant-numeric: tabular-nums;
}

/* Timesheet status strip — anchors the segment bar + submit/approve actions
   as one deliberate band instead of floating controls. */
.ts-status-strip {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 16px;
    padding: 8px 14px;
    background: var(--mkt-surface);
    border: 1px solid var(--mkt-border);
    box-shadow: var(--mkt-shadow-card);
    border-radius: 14px;
}

/* Split button (Submit + dropdown). The global .mud-button-filled radius is
   !important, so these must be too — inline styles lose that fight (the old
   inline 4px radii silently never applied). */
.tc-split { display: inline-flex; gap: 1px; }
.tc-split > .mud-button-root:first-child { border-radius: 12px 0 0 12px !important; }
.tc-split .mud-menu .mud-button-root { border-radius: 0 12px 12px 0 !important; }

/* The "Log again" rows in the New Entry ▾ menu carry the project's colour dot inline. */
.tc-menu-recent .sb-dot { margin-right: 8px; }

/* Per-day add target (Week view) — quiet dashed affordance, lights up on hover. */
.tc-add-btn.mud-button-root {
    border: 1px dashed var(--mkt-border);
    border-radius: 10px !important;
    color: var(--mkt-text-faint) !important;
    font-weight: 500 !important;
}
.tc-add-btn.mud-button-root:hover {
    border-color: rgba(0, 122, 255, 0.4);
    color: var(--mkt-primary) !important;
    background: rgba(0, 122, 255, 0.04);
}

/* First-run hint when the visible week has no entries at all. */
.tc-empty {
    text-align: center;
    padding: 4px 16px 16px;
    color: var(--mkt-text-faint);
    font-size: 14px;
}

/* The "Log it again" chip row that used to sit between the command bar and the calendar is GONE
   (2026-08-04): it collided with the legend/filter row underneath. Those shapes now render as
   items in the New Entry ▾ menu (.tc-menu-recent, above) and as chips inside the quick-add panel
   (.qa-recent, in the popover block). No .tc-recent-* rules remain. */

/* Project legend + click-to-filter. One quiet pill per project in the visible period; the "on"
   state is a brand tint, never a glow. Desktop only — the host doesn't render it on phones. */
.tc-legend {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin: -8px 0 16px;
}

/* Pill chrome (hairline, hover tint, --on tint) comes from the shared "quiet pill" rule up in the
   quick-add section; only the legend's own layout lives here. */
.tc-legend-item,
.tc-legend-clear {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
}

.tc-legend-name {
    max-width: 150px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tc-legend-hours {
    font-variant-numeric: tabular-nums;
    color: var(--mkt-text-faint);
}

.tc-legend-item--on .tc-legend-hours { color: inherit; }

.tc-legend-clear {
    font-weight: 600;
    color: var(--mkt-primary);
    border-color: rgba(0, 122, 255, 0.45);
}

/* Mobile "log time" FAB. Below the quick-add panel (1151) and MudBlazor's overlay layer (1200+)
   so it can never sit on top of the sheet it opens. */
.tc-fab {
    position: fixed;
    right: 16px;
    bottom: 16px;
    z-index: 1050;
}

/* Month view "+N more" — drills into the Day view for that date. */
.tc-more-link {
    font-size: 12px;
    font-weight: 500;
    color: var(--mkt-primary);
    cursor: pointer;
}
.tc-more-link:hover { text-decoration: underline; }

/* /my-dashboard — Today & recent rows open the shared entry drawer (EntryEditDialog). */
.dash-entry-row {
    padding: 6px 8px;
    margin: 0 -8px 4px;
    border-radius: 8px;
    cursor: pointer;
    transition: background var(--sb-transition);
}

.dash-entry-row:hover,
.dash-entry-row:focus-visible {
    background: var(--mkt-primary-soft);
}

/* /my-dashboard — running-timer strip atop the Today & recent card (an sb-subpanel row). */
.dash-timer-strip {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
}

.dash-timer-strip-text {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex: 1 1 auto;
    min-width: 0;
}

.dash-timer-strip-project {
    font-size: 13.5px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-timer-strip-elapsed {
    font-size: 13.5px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--mkt-primary);
}

/* /my-dashboard — the consolidated week strip (7 chronological day cells). */
.dash-week-strip {
    display: flex;
    align-items: stretch;
    gap: 6px;
    flex-wrap: wrap;
}

.dash-day-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-width: 60px;
    padding: 6px 10px;
    background: var(--mkt-surface);
    border: 1px solid var(--mkt-border-soft);
    border-radius: 10px;
    font-family: inherit;
    transition: border-color var(--sb-transition), background var(--sb-transition);
}

button.dash-day-cell { cursor: pointer; }

button.dash-day-cell:hover,
button.dash-day-cell:focus-visible {
    border-color: var(--mkt-primary);
    background: var(--mkt-primary-soft);
}

.dash-day-cell--today { border-color: var(--mkt-primary); }
.dash-day-cell--future { opacity: 0.55; }
.dash-day-cell--quiet { min-width: 34px; padding: 6px 4px; opacity: 0.55; }
.dash-day-cell--filled .dash-day-hours { color: var(--mkt-text); }

.dash-day-abbrev {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--mkt-text-faint);
    white-space: nowrap;
}

.dash-day-hours {
    font-size: 13px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--mkt-text-soft);
    white-space: nowrap;
}

.dash-day-log { color: var(--mkt-primary); }

/* /my-dashboard — Catch up rows (flat rows inside one card; no card-in-card). */
.dash-catchup-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 0;
}

.dash-catchup-row + .dash-catchup-row {
    border-top: 1px solid var(--mkt-border-soft);
}

/* /dashboard (manager) — mobile adjustments */
@media (max-width: 599.98px) {
    /* Reduce row spacing — mb-4 (32px) → 16px between sections on mobile. */
    .manager-dashboard .mud-grid.mb-4 {
        margin-bottom: 16px !important;
    }
}

/* /time — mobile is locked to Day view; hide desktop-only chrome. */
@media (max-width: 959.98px) {
    .my-time-desktop-only { display: none !important; }

    /* Tighten the glass toolbar on mobile and let it wrap cleanly. */
    .my-time-toolbar {
        padding: 8px 10px;
        gap: 6px;
    }
    .my-time-toolbar > .mud-button,
    .my-time-toolbar > .mud-icon-button,
    .my-time-toolbar > .tc-split {
        flex: 0 0 auto;
    }
    .tc-period-label {
        font-size: 15px;
        white-space: normal;
    }
    /* The New Entry split's ▾ half is .my-time-desktop-only, so below this breakpoint the primary
       button is a whole button again and must not keep its half-square right edge. Scoped to
       --add: the timesheet Submit split keeps its ▾ at every width. */
    .tc-split--add > .mud-button-root:first-child {
        border-radius: var(--sb-radius-control, 10px) !important;
    }
}

/* /invoices — list grid: progressive column collapse (row click reaches full detail) */
@media (max-width: 959.98px) {
    .inv-col-date { display: none !important; }
}
@media (max-width: 599.98px) {
    .inv-col-due, .inv-col-number { display: none !important; }
    .inv-row-cta { display: none !important; } /* MoreVert menu carries Finalise/Send/Mark-as-sent */
    /* Filters: two per row on phones; !important beats the inline min-widths
       (MudTextField puts its inline Style on the inner .mud-input, not the root). */
    .invoices-filter-row > * { flex: 1 1 calc(50% - 8px); min-width: 0 !important; }
    .invoices-filter-row .mud-input { min-width: 0 !important; max-width: 100%; }
}

/* /invoices/{id} — secondary header actions collapse into the overflow menu on phones */
.invoice-actions-overflow { display: none; }
@media (max-width: 599.98px) {
    .invoice-detail-header .invoice-action-secondary { display: none !important; }
    .invoice-actions-overflow { display: inline-flex !important; }
}

/* -- Projects list card (mirrors PM's pm-project-card) ---------------------- */
.project-card {
    cursor: pointer;
    height: 100%;
    background: var(--mkt-surface) !important;
    border: 1px solid var(--mkt-border) !important;
    box-shadow: var(--mkt-shadow-card) !important;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.project-card:hover {
    transform: translateY(-1px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.07) !important;
}
