/* ============================================================================
   v0.4.10 - PLANNING-HORIZON TABS, MAIN TASK FOMO CARD, PROGRESS PERCENTAGES.
   Matches the v4 design mockup: Day/Week/Month/Quarter/Global pills at the top,
   one prominent "main task" card pulsing above the two-column task layout.
   Animations honor prefers-reduced-motion (accessibility - see vault doc
   "FOMO and attention UI best practices" for the research behind these timings).
   ============================================================================ */

/* ----- Planning-horizon tabs (Day / Week / Month / Quarter / Global) ----- */
.horizon-tabs {
    display: flex;
    gap: 28px;
    align-items: center;
    padding: 4px 24px 10px;
    margin: -4px 0 14px;
    border-bottom: 1px solid var(--chronos-outline);
}
.horizon-tab {
    background: none;
    border: none;
    padding: 6px 0;
    font-family: inherit;
    font-size: 16px;
    font-weight: 500;
    color: var(--chronos-muted);
    cursor: pointer;
    position: relative;
    transition: color 120ms ease;
}
.horizon-tab:hover { color: var(--chronos-text); }
.horizon-tab.active {
    color: var(--chronos-text);
    font-weight: 600;
}
.horizon-tab.active::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 2px;
    background: var(--chronos-violet);
    border-radius: 1px;
}

/* v0.4.16: "Без дедлайна" toggle - pinned to the far right of the horizon bar
   via margin-left:auto. A pill, not an underline tab, so it reads as a distinct
   filter rather than another horizon. Active = solid violet fill. */
.horizon-flag {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: none;
    border: 1px solid var(--chronos-outline);
    border-radius: var(--radius-pill);
    padding: 5px 12px 5px 10px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    color: var(--chronos-fg-muted);
    cursor: pointer;
    transition: color 120ms ease, background 120ms ease, border-color 120ms ease;
}
.horizon-flag .material-icons { font-size: 16px; }
.horizon-flag:hover {
    border-color: var(--chronos-violet);
    color: var(--chronos-violet);
}
.horizon-flag.active {
    background: var(--chronos-violet);
    border-color: var(--chronos-violet);
    color: #FFFFFF;
}

/* ----- Main task FOMO card (above the two columns) -----
   v0.4.10.2: timings/colours synced with the research doc
   `06 Decisions/FOMO and attention UI best practices.md` section 8.1-8.2.
   Ambient state: violet halo, opacity-only breath at 2.4s (matches Upgrade
   button cadence so the visual language stays coherent - same "important
   but not alarming" semantic load).
   Urgent state: dark red #DC2626 (WCAG-AA-bound, not the brighter #EF4444),
   layout-affecting scale pulse 1.00->1.03 at 1.8s (faster than ambient =
   reads as "more urgent"), wider glow. No looping shake - see WCAG 2.3.3.
*/
.main-task {
    position: relative;
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--chronos-violet) 9%, var(--chronos-card-bg)) 0%,
        var(--chronos-card-bg) 60%
    );
    border: 1px solid var(--chronos-violet);
    border-radius: 14px;
    padding: 16px 18px 14px;
    margin: 12px 0 18px;
    /* Static violet halo. Alpha is animated below, not spread - keeps layout still. */
    box-shadow: 0 0 24px 2px rgba(124, 58, 237, 0.35);
    animation: main-task-pulse 2.4s ease-in-out infinite;
}
/* v0.4.11: loss-framed copy per FOMO research §1.4 - the badge ("KEEPS STREAK")
   carries the loss frame ("if you don't finish this, your streak protection
   expires") versus the neutral "MAIN" gain frame. Loss framing has the 2.25×
   Kahneman/Tversky multiplier behind it. v0.4.22.5: text moved to a real
   element (.main-task-badge, localized via resx) - CSS no longer hardcodes it. */
.main-task-badge {
    position: absolute;
    top: -10px;
    left: 16px;
    background: var(--chronos-violet);
    color: white;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.9px;
    padding: 3px 10px;
    border-radius: 999px;
    box-shadow: 0 2px 4px rgba(124, 58, 237, 0.25);
}
.main-task-head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}
.main-task-body {
    flex: 1;
    min-width: 0;
    cursor: pointer;
}
.main-task-title {
    font-size: 18px;
    font-weight: 600;
    line-height: 1.3;
}
.main-task-desc {
    margin-top: 4px;
    font-size: 14px;
}
.main-task .task-labels { margin-top: 8px; }
.main-task .task-due {
    font-size: 12px;
    font-weight: 500;
    color: var(--chronos-violet);
}
.main-task .bar-row { margin-top: 10px; }

.main-task.urgent {
    border-color: #DC2626;
    background: linear-gradient(
        135deg,
        rgba(220, 38, 38, 0.10) 0%,
        var(--chronos-card-bg) 60%
    );
    box-shadow: 0 0 32px 4px rgba(220, 38, 38, 0.55);
    /* Both halo-alpha AND a small scale pulse - the 3% scale change reads as
       "this is moving" without breaking the layout grid (containers shift by
       <1px since the card is centered). 1.8s is faster than ambient 2.4s = the
       eye picks it up as escalation. */
    animation: main-task-urgent-pulse 1.8s ease-in-out infinite;
}
.main-task.urgent .main-task-badge {
    background: #DC2626;
    box-shadow: 0 2px 4px rgba(220, 38, 38, 0.4);
}
.main-task.urgent .main-task-title { color: #DC2626; }
.main-task.urgent .task-due { color: #DC2626; font-weight: 700; }

@keyframes main-task-pulse {
    0%, 100% { box-shadow: 0 0 24px 2px rgba(124, 58, 237, 0.35); }
    50%      { box-shadow: 0 0 28px 3px rgba(124, 58, 237, 0.55); }
}
@keyframes main-task-urgent-pulse {
    0%, 100% {
        box-shadow: 0 0 32px 4px rgba(220, 38, 38, 0.45);
        transform: scale(1.00);
    }
    50% {
        box-shadow: 0 0 36px 6px rgba(220, 38, 38, 0.65);
        transform: scale(1.03);
    }
}

/* v0.4.11: inline subtask preview under the main task. Mirrors the v4 Figma
   mockup which shows subtasks indented under the main row. Each line is its
   own clickable strip - opens the detail modal where the user can actually
   tick subtasks. The mini-bar is a thinner variant of .bar. */
.main-task-subs {
    margin-top: 10px;
    padding-left: 38px; /* aligns with .main-task-body (checkbox width + gap) */
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.main-task-sub {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 13px;
    line-height: 1.4;
}
.main-task-sub:hover { color: var(--chronos-violet); }
.main-task-sub input[type="checkbox"] {
    accent-color: var(--chronos-violet);
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    cursor: pointer; /* toggles right on the card - no detail-modal hop needed */
}
.main-task-sub span { flex: 1; min-width: 0; }
.main-task-sub-more {
    padding-left: 22px;
    font-size: 12px;
    cursor: pointer;
}
.bar-mini {
    width: 80px;
    height: 4px;
    flex-shrink: 0;
}

/* Completed tasks - collapsed section under the working columns. */
.completed-section {
    margin-top: 18px;
    border-top: 1px solid var(--chronos-outline);
    padding-top: 10px;
}
.completed-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--chronos-fg-muted);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
    transition: color 0.15s, background 0.15s;
}
.completed-toggle:hover {
    color: var(--chronos-fg-primary);
    /* fg-derived so the hover wash works on both the light and dark shells */
    background: color-mix(in srgb, var(--chronos-fg-muted) 14%, transparent);
}
.completed-toggle .material-icons { font-size: 18px; }
.completed-count {
    padding: 1px 8px;
    border-radius: 999px;
    background: rgba(22, 163, 74, 0.16);
    color: #4ade80;
    font-size: 11px;
}
/* ---- Almanac: all-time archive of completed tasks (modal) ---- */
.almanac-card {
    /* .modal-card caps at 520px - the almanac needs room for its timeline columns,
       so raise the cap here (this file loads after 04-compose-filter-modal.css). */
    width: 90%;
    max-width: 680px;
    max-height: 88vh;
    overflow-y: auto;
}
.almanac-total {
    margin-left: auto;
    margin-right: 8px;
    padding: 1px 10px;
    border-radius: 999px;
    background: rgba(22, 163, 74, 0.16);
    color: #16a34a;
    font-size: 12px;
    font-weight: 800;
}
.almanac-empty { padding: 18px 4px 8px; }
.almanac-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.almanac-entry {
    border: 1px solid var(--chronos-outline);
    border-radius: 10px;
    overflow: hidden;
}
.almanac-entry-head {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 10px 12px;
    border: none;
    background: transparent;
    color: var(--chronos-fg-primary);
    font-size: 14px;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
    transition: background 0.15s;
}
.almanac-entry-head:hover { background: color-mix(in srgb, var(--chronos-fg-muted) 10%, transparent); }
.almanac-chevron { font-size: 18px; color: var(--chronos-fg-muted); }
.almanac-entry-title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.almanac-entry-when {
    flex-shrink: 0;
    font-size: 12px;
    font-weight: 600;
    color: #16a34a;
    font-variant-numeric: tabular-nums;
}
.almanac-entry-body {
    padding: 4px 14px 14px 38px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.almanac-facts { display: flex; flex-wrap: wrap; gap: 6px 22px; }
.almanac-fact { display: flex; gap: 8px; font-size: 13px; }
.almanac-fact-label { color: var(--chronos-fg-muted); }
.almanac-sub-head {
    margin-top: 4px;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--chronos-fg-muted);
}
.almanac-subs, .almanac-log { list-style: none; margin: 0; padding: 0; }
.almanac-subs li, .almanac-log li {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 3px 0;
    font-size: 13px;
}
.almanac-sub-mark { flex-shrink: 0; }
.almanac-subs li span:nth-child(2), .almanac-log-note {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.almanac-sub-when {
    flex-shrink: 0;
    font-size: 12px;
    color: var(--chronos-fg-muted);
    font-variant-numeric: tabular-nums;
}
.almanac-reopen { align-self: flex-start; margin-top: 4px; }

/* ---- Reopen dialog (almanac "return to work") ---- */
.reopen-card { z-index: 210; }
.reopen-task-name {
    margin: 0;
    font-size: 15px;
    font-weight: 700;
}
.reopen-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 13px;
}
.reopen-field input[type="datetime-local"] {
    padding: 8px 10px;
    border: 1px solid var(--chronos-outline);
    border-radius: 8px;
    font: inherit;
    color: inherit;
    background: transparent;
}
.reopen-actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}
.reopen-regen {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border-radius: 10px;
    border: 1px solid rgba(124, 58, 237, 0.45);
    background: rgba(124, 58, 237, 0.14);
    color: var(--chronos-violet);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s, transform 0.1s;
}
.reopen-regen:hover:not(:disabled) { background: rgba(124, 58, 237, 0.24); transform: translateY(-1px); }
.reopen-regen:disabled { cursor: not-allowed; opacity: 0.5; }
.reopen-regen-locked { opacity: 0.75; }
.reopen-note { margin: 0; font-size: 12px; }

/* ---- Empty board placeholder ---- */
.board-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 46px 20px;
    color: var(--chronos-fg-muted);
    font-size: 15px;
    text-align: center;
}
.board-empty-glyph { font-size: 34px; opacity: 0.7; }

/* v0.4.11: confetti shower - celebrates milestone moments only (research §8.5).
   40 particles, each spawned at a deterministic x spread across the viewport via
   the --x custom property (0-99, computed in markup - CSS calc() has no modulo
   operator, so the spread can't be derived from --i here). Falls 2.5s with
   rotation. Hidden under prefers-reduced-motion (motion is decorative; the streak
   number popping up is the substantive signal). */
.confetti {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 1000;
    overflow: hidden;
}
.confetti-piece {
    position: absolute;
    top: -12vh;
    left: calc(var(--x) * 1%);
    width: 8px;
    height: 14px;
    /* HSL stepped every 37° → vibrant rainbow without picking palette manually. */
    background: hsl(calc(var(--i) * 37), 70%, 60%);
    border-radius: 1px;
    animation: confetti-fall 2.5s cubic-bezier(0.4, 0.0, 0.6, 1.0) forwards;
    animation-delay: calc(var(--i) * 25ms);
    transform-origin: center;
    opacity: 0;
}
@keyframes confetti-fall {
    0%   { transform: translateY(0) rotate(0deg)   scale(0.8); opacity: 0; }
    10%  { opacity: 1; }
    100% { transform: translateY(112vh) rotate(720deg) scale(1.0); opacity: 0.3; }
}
@media (prefers-reduced-motion: reduce) {
    .confetti { display: none; }
}

/* One-shot shake for the moment a task enters the urgent state - fires on
   state transition only (loop is a WCAG 2.3.3 violation). Apply by adding the
   `.shake-once` class server-side when IsUrgent flips false -> true, drop it
   after ~600ms. Currently the urgency state is computed at reload time, so
   the user sees it pre-shaken; future per-tick recompute will surface the
   transition naturally. */
@keyframes shake-once {
    0%, 100% { transform: translateX(0); }
    10%, 30%, 50%, 70%, 90% { transform: translateX(-6px) rotate(-1.5deg); }
    20%, 40%, 60%, 80%      { transform: translateX(6px) rotate(1.5deg); }
}
.shake-once { animation: shake-once 500ms ease-in-out 1; }

/* Accessibility: under prefers-reduced-motion we kill all keyframes but keep
   the colour signal (red border, glow as static box-shadow) and copy. This is
   the WCAG 2.3.3 + research-doc 8.7 path: respect the opt-out completely
   rather than try to hide motion behind reduced-amplitude motion. */
@media (prefers-reduced-motion: reduce) {
    .main-task,
    .main-task.urgent,
    .shake-once {
        animation: none !important;
    }
    /* Keep glow alive as a static shadow so the visual hierarchy survives. */
    .main-task { box-shadow: 0 0 24px 2px rgba(124, 58, 237, 0.45); }
    .main-task.urgent { box-shadow: 0 0 32px 4px rgba(220, 38, 38, 0.55); }
}

/* ----- Progress bar + percentage label row -----
   Wraps an existing .bar with its label so both flex grow correctly.
   The label is right-aligned, tabular-nums so "5%" and "100%" don't jitter.
*/
.bar-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.bar-row .bar { flex: 1; }
.bar-pct {
    font-size: 11px;
    font-weight: 600;
    color: var(--chronos-muted);
    font-variant-numeric: tabular-nums;
    min-width: 34px;
    text-align: right;
}

/* ============================================================================
   v0.4.8 - TASK ROW clickable area, label chips, detail modal sidebar,
   create-task modal extras (textarea, date input, color swatches), AI confirm
   rows. All built on top of the existing .modal-* vocabulary.
   ============================================================================ */

/* Click target inside .task-head (everything except the checkbox). */
.task-body {
    display: flex;
    flex: 1;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    min-width: 0;
}
.task-body:hover .task-title { color: var(--chronos-violet); }

.task-text { flex: 1; min-width: 0; }
.task-labels {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 4px;
}
.task-due {
    font-size: 12px;
    white-space: nowrap;
}

/* Label chip - used in task rows, picker, detail sidebar. --chip-color is set
   per-instance so a single rule paints every variant. .selected gives the
   picker variant a filled appearance. */
.label-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 8px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--chip-color, var(--chronos-violet)) 18%, transparent);
    color: var(--chip-color, var(--chronos-violet));
    border: 1px solid color-mix(in srgb, var(--chip-color, var(--chronos-violet)) 35%, transparent);
    font-size: 12px;
    font-weight: 500;
    line-height: 1.6;
    cursor: pointer;
    user-select: none;
}
.label-chip.selected {
    background: var(--chip-color, var(--chronos-violet));
    color: white;
    border-color: var(--chip-color, var(--chronos-violet));
}
.label-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--chip-color, var(--chronos-violet));
}
.label-chip.selected .label-dot { background: white; }

/* v0.5.2: day-priority. The card chip is a .label-chip variant (colour via
   --chip-color); the create-modal pills are the same idea, bigger + tappable with
   a filled selected state. */
.label-chip.priority-chip { font-weight: 700; }
.priority-pick { display: flex; flex-wrap: wrap; gap: 8px; }
.priority-pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 13px;
    border-radius: var(--radius-pill);
    border: 1px solid color-mix(in srgb, var(--chip-color, var(--chronos-violet)) 40%, transparent);
    background: color-mix(in srgb, var(--chip-color, var(--chronos-violet)) 12%, transparent);
    color: var(--chronos-fg-primary);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.1s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.priority-pill .priority-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--chip-color, var(--chronos-violet));
    flex-shrink: 0;
}
.priority-pill:hover { transform: translateY(-1px); }
.priority-pill.selected {
    background: var(--chip-color, var(--chronos-violet));
    color: #fff;
    box-shadow: 0 2px 10px color-mix(in srgb, var(--chip-color, var(--chronos-violet)) 45%, transparent);
}
.priority-pill.selected .priority-dot { background: rgba(255, 255, 255, 0.9); }

/* v0.5.6: compact pill variant for tight surfaces (detail sidebar, AI-draft rows). */
.priority-pick-compact { gap: 6px; }
.priority-pill-sm { padding: 4px 10px; font-size: 12px; gap: 6px; }
.priority-pill-sm .priority-dot { width: 8px; height: 8px; }
.priority-pill:disabled { opacity: 0.55; cursor: default; transform: none; }

/* ============================================================================
   v0.5.6 - TASK CARD skin. .task-row was a bare flex column sitting directly
   on the board; now it is a real card: surface + hairline + soft shadow, a
   priority-coloured left edge (--task-accent comes inline from TaskRow, same
   hue as the chip), graded due-date pills, and a two-line description clamp.
   Token-driven throughout so the dark theme restyles it for free.
   ============================================================================ */
.task-row {
    position: relative;
    padding: 12px 14px 11px;
    border-radius: 12px;
    /* Recessed a step below the white board panel so the card reads as an object;
       hover "lifts" it back to the panel surface + a real shadow. */
    background: var(--chronos-card-inset);
    border: 1px solid var(--chronos-outline);
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.12s ease,
                background 0.15s ease;
}
/* Priority edge - inset stripe, rounded, breathing 10px off the card's corners.
   Painted only when a priority is set (the accent var is slate for None, so the
   .has-priority gate - not the colour - is what hides it). */
.task-row::before {
    content: '';
    position: absolute;
    left: 0;
    top: 10px;
    bottom: 10px;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--task-accent, transparent);
    opacity: 0;
}
.task-row.has-priority::before { opacity: 1; }
.task-row:hover {
    background: var(--chronos-card-bg);
    border-color: color-mix(in srgb, var(--chronos-violet) 35%, var(--chronos-outline));
    box-shadow: 0 6px 18px rgba(17, 24, 39, 0.08);
    transform: translateY(-1px);
}
.task-row .task-title {
    font-size: 14px;
    line-height: 1.35;
    overflow-wrap: anywhere;
}
.task-row .task-supporting {
    margin-top: 1px;
    font-size: 12.5px;
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.task-row .task-labels { margin-top: 6px; }
.task-row .bar-row { margin-top: 3px; }

/* Due-date pressure grades (set in TaskRow.DueClass): overdue screams, today
   warns, later stays a quiet neutral pill. Completed rows fall back to .muted. */
.task-row .task-due {
    font-size: 11.5px;
    padding: 2px 8px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--chronos-fg-muted) 10%, transparent);
}
.task-due.due-overdue {
    color: #DC2626;
    font-weight: 700;
    background: rgba(239, 68, 68, 0.12);
}
.task-due.due-today {
    color: #B45309;
    font-weight: 700;
    background: rgba(245, 158, 11, 0.14);
}

/* Checkbox affordance: a soft violet ring on hover says "tappable" before commit. */
.task-check .checkbox-ui { transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease; }
.task-check:hover .checkbox-ui {
    border-color: var(--chronos-violet);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--chronos-violet) 15%, transparent);
}
@media (prefers-reduced-motion: reduce) {
    .task-row { transition: none; }
    .task-row:hover { transform: none; }
}

/* ============================================================================
   v0.5.7: "Состояние дня" as a topbar HISTOGRAM chip + Material-style popover
   (was a board card that duplicated the aggregate progress bar). The chip shows
   one mini bar per quality component - bar height mirrors the component's
   weight in the score (Main 45 > Intensity 25 > Respite/Engagement 15), lit
   when earned. Material notes applied: tonal container, hover/pressed state
   layer (8%/12% overlay), focus-visible ring, elevation-3 popover, motion
   under 200ms with a standard-decelerate curve, reduced-motion respected.
   ============================================================================ */
.daystate-slot { position: relative; display: inline-flex; }
/* v0.5.8.3: the chip is a MESSAGE, not an ornament - the tier verdict tints the whole
   surface (fill + border + glow via --ds-accent), the Quality percent is printed in it,
   and a weak day breathes a soft alarm pulse (same FOMO cadence family as the streak
   surfaces). Strong days glow calm green - the accent rewards, not just warns. */
.daystate-chip {
    --ds-accent: var(--chronos-fg-muted);
    position: relative;
    display: inline-flex;
    align-items: flex-end;
    gap: 3.5px;
    height: 36px;
    padding: 7px 11px 8px;
    border-radius: 11px;
    background: color-mix(in srgb, var(--ds-accent) 10%, var(--chronos-chip-bg));
    border: 1.5px solid color-mix(in srgb, var(--ds-accent) 45%, transparent);
    cursor: pointer;
    box-shadow:
        inset 0 -2px 0 var(--ds-accent),
        0 0 10px color-mix(in srgb, var(--ds-accent) 28%, transparent);
    transition: box-shadow 0.15s ease, border-color 0.15s ease, transform 0.12s ease;
}
.daystate-chip:hover { transform: translateY(-1px); }
.daystate-strong { --ds-accent: #10B981; }
.daystate-fair   { --ds-accent: #F59E0B; }
.daystate-weak   { --ds-accent: #EF4444; }
/* The day is slipping - a slow attention pulse until Quality climbs out of Weak. */
.daystate-weak {
    animation: daystate-alarm 2.6s ease-in-out infinite;
}
@keyframes daystate-alarm {
    0%, 100% {
        box-shadow: inset 0 -2px 0 #EF4444, 0 0 7px rgba(239, 68, 68, 0.28);
    }
    50% {
        box-shadow: inset 0 -2px 0 #EF4444, 0 0 17px rgba(239, 68, 68, 0.6);
    }
}
/* The verdict number - the message spelled out beside the bars. */
.daystate-pct {
    align-self: center;
    margin-left: 4px;
    font-size: 12.5px;
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--ds-accent);
}
/* State layer: a currentColor overlay that fades in on hover/press - Material's
   interaction feedback without repainting the surface itself. */
.daystate-chip::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
}
.daystate-chip:hover::after  { opacity: 0.08; }
.daystate-chip:active::after { opacity: 0.12; }
.daystate-chip:focus-visible {
    outline: 2px solid var(--chronos-violet);
    outline-offset: 2px;
}
/* The four component bars. Heights ∝ score weights; "off" is a 26% tint of the
   same hue so the silhouette stays readable before anything is earned. */
.dsh-bar {
    width: 6px;
    border-radius: 3px 3px 1px 1px;
    transition: background 0.2s cubic-bezier(0, 0, 0, 1), box-shadow 0.2s ease;
}
.dsh-main      { height: 20px; background: color-mix(in srgb, #7C3AED 26%, transparent); }
.dsh-intensity { height: 14px; background: color-mix(in srgb, #EF4444 26%, transparent); }
.dsh-respite   { height: 10px; background: color-mix(in srgb, #10B981 26%, transparent); }
.dsh-engage    { height: 10px; background: color-mix(in srgb, #0EA5E9 26%, transparent); }
.dsh-main.on      { background: #7C3AED; box-shadow: 0 0 6px rgba(124, 58, 237, 0.5); }
.dsh-intensity.on { background: #EF4444; box-shadow: 0 0 6px rgba(239, 68, 68, 0.45); }
.dsh-respite.on   { background: #10B981; box-shadow: 0 0 6px rgba(16, 185, 129, 0.45); }
.dsh-engage.on    { background: #0EA5E9; box-shadow: 0 0 6px rgba(14, 165, 233, 0.45); }

/* Detail popover - elevation 3, anchored under the chip; pinned to the viewport
   on phones (same pattern as the pet bubble). */
.daystate-pop {
    position: absolute;
    top: calc(100% + 10px);
    left: 50%;
    transform: translateX(-50%);
    width: min(320px, calc(100vw - 24px));
    padding: 12px 14px;
    border-radius: 14px;
    background: var(--chronos-card-bg);
    border: 1px solid var(--chronos-outline);
    box-shadow: 0 12px 28px rgba(17, 24, 39, 0.18), 0 2px 8px rgba(17, 24, 39, 0.10);
    z-index: 120;
    text-align: left;
    cursor: default;
    animation: daystate-pop-in 0.16s cubic-bezier(0, 0, 0, 1);
    transform-origin: top center;
}
@keyframes daystate-pop-in {
    from { opacity: 0; transform: translateX(-50%) translateY(-5px) scale(0.97); }
    to   { opacity: 1; transform: translateX(-50%) translateY(0)    scale(1); }
}
.dsp-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--chronos-fg-muted);
    margin-bottom: 10px;
}
.dsp-comps {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--chronos-outline);
}
.dsp-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    color: var(--chronos-fg-secondary);
}
.dsp-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}
.dsp-dot-main      { background: #7C3AED; }
.dsp-dot-intensity { background: #EF4444; }
.dsp-dot-respite   { background: #10B981; }
.dsp-dot-engage    { background: #0EA5E9; }
.dsp-label { flex: 1; }
.dsp-mark {
    font-weight: 800;
    color: var(--chronos-fg-muted);
    font-variant-numeric: tabular-nums;
}
.dsp-mark.earned { color: #10B981; }
.dsp-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 10px;
    font-size: 12px;
}
@media (max-width: 700px) {
    .daystate-pop {
        position: fixed;
        top: 62px;
        left: 12px;
        right: 12px;
        width: auto;
        transform: none;
        animation: none;
    }
}
@media (prefers-reduced-motion: reduce) {
    .daystate-pop { animation: none; }
    .daystate-chip::after { transition: none; }
    .dsh-bar { transition: none; }
    /* Keep the alarm as a static strong glow - signal survives, motion doesn't. */
    .daystate-weak {
        animation: none;
        box-shadow: inset 0 -2px 0 #EF4444, 0 0 14px rgba(239, 68, 68, 0.5);
    }
}

.day-state-bars { display: flex; flex-direction: column; gap: 8px; }
.dsb { display: grid; grid-template-columns: 72px 1fr 42px; align-items: center; gap: 10px; }
.dsb-label { font-size: 12.5px; font-weight: 600; color: var(--chronos-fg-secondary); }
.dsb-track {
    height: 8px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--chronos-fg-muted) 18%, transparent);
    overflow: hidden;
}
.dsb-fill { height: 100%; border-radius: 999px; transition: width 0.4s cubic-bezier(0.22, 1, 0.36, 1); }
.dsb-quality { background: linear-gradient(90deg, var(--chronos-violet), var(--chronos-lavender)); }
.dsb-result { background: color-mix(in srgb, var(--chronos-fg-muted) 55%, transparent); }
.dsb-pct {
    font-size: 12px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: right;
    color: var(--chronos-fg-primary);
}
.day-state-points { font-weight: 800; color: var(--chronos-violet); }

/* v0.5.6: pet coach as a SPEECH BUBBLE hanging off the topbar pet slot (was a
   board card in v0.5.4) - the ranked suggestions are now literally the pet's
   message. The row/reason/title classes below are shared with the old naming.
   Free tier has no bubble: the locked egg itself is the upsell. */
.pet-slot { position: relative; }
.pet-slot-talks .pet-emoji { cursor: pointer; transition: transform 0.15s ease; }
.pet-slot-talks .pet-emoji:hover { transform: translateY(-1px) scale(1.08); }

/* Waiting-picks counter pinned to the pet while the bubble is closed. */
.pet-bubble-badge {
    position: absolute;
    top: -3px;
    right: -5px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--chronos-violet);
    color: #fff;
    font-size: 10px;
    font-weight: 800;
    line-height: 16px;
    text-align: center;
    pointer-events: none;
    box-shadow: 0 0 0 2px var(--chronos-bg);
    animation: pet-badge-pop 0.25s ease-out;
}
@keyframes pet-badge-pop {
    from { transform: scale(0.4); opacity: 0; }
    to   { transform: scale(1);   opacity: 1; }
}

/* The bubble: card surface + violet tint, tail pointing up at the pet. Sits above
   page content (z 120) but under every modal backdrop (z 200+). */
.pet-bubble {
    position: absolute;
    top: calc(100% + 12px);
    left: 50%;
    transform: translateX(-50%);
    width: min(380px, calc(100vw - 24px));
    padding: 12px 14px;
    border-radius: 14px;
    background: color-mix(in srgb, var(--chronos-violet) 7%, var(--chronos-card-bg));
    border: 1px solid color-mix(in srgb, var(--chronos-violet) 26%, var(--chronos-outline));
    box-shadow: 0 14px 34px rgba(17, 24, 39, 0.18), 0 2px 8px rgba(124, 58, 237, 0.10);
    z-index: 120;
    text-align: left;
    cursor: default;
    animation: pet-bubble-in 0.18s cubic-bezier(0.22, 1, 0.36, 1);
    transform-origin: top center;
}
.pet-bubble::before {
    content: '';
    position: absolute;
    top: -6px;
    left: 50%;
    width: 11px;
    height: 11px;
    margin-left: -6px;
    transform: rotate(45deg);
    background: color-mix(in srgb, var(--chronos-violet) 7%, var(--chronos-card-bg));
    border-left: 1px solid color-mix(in srgb, var(--chronos-violet) 26%, var(--chronos-outline));
    border-top: 1px solid color-mix(in srgb, var(--chronos-violet) 26%, var(--chronos-outline));
}
@keyframes pet-bubble-in {
    from { opacity: 0; transform: translateX(-50%) translateY(-6px) scale(0.96); }
    to   { opacity: 1; transform: translateX(-50%) translateY(0)    scale(1); }
}
.pet-bubble-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 0.04em;
    color: var(--chronos-fg-secondary);
    margin-bottom: 9px;
}
.pet-bubble-close {
    border: none;
    background: transparent;
    color: var(--chronos-fg-muted);
    font-size: 17px;
    line-height: 1;
    padding: 0 2px;
    cursor: pointer;
    border-radius: 6px;
}
.pet-bubble-close:hover { color: var(--chronos-fg-primary); }

/* Phones: the topbar is dense - pin the bubble to the viewport under the bar
   instead of centering on the tiny pet slot (which would overflow the left edge). */
@media (max-width: 700px) {
    .pet-bubble {
        position: fixed;
        top: 62px;
        left: 12px;
        right: 12px;
        width: auto;
        transform: none;
        animation: none;
    }
    .pet-bubble::before { display: none; }
}
@media (prefers-reduced-motion: reduce) {
    .pet-bubble { animation: none; }
    .pet-bubble-badge { animation: none; }
}

.pet-coach-empty { font-size: 12.5px; }

/* v0.5.8: the AI layer inside the bubble - the pet's advice paragraph, the violet
   "why" tag on AI picks, a non-clickable title variant (pick outside the current
   horizon), and a three-dot thinking shimmer while the call is in flight. */
.pet-bubble-advice {
    margin: 0 0 9px;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--chronos-fg-secondary);
}
.pet-coach-reason.reason-ai {
    background: color-mix(in srgb, var(--chronos-violet) 16%, transparent);
    color: var(--chronos-violet);
    text-transform: none;
    letter-spacing: 0;
    max-width: 110px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pet-coach-title-static { cursor: default; }
.pet-coach-title-static:hover { color: var(--chronos-fg-primary); }
.pet-coach-thinking {
    display: flex;
    gap: 5px;
    padding: 2px 0 8px;
}
.pet-coach-thinking span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--chronos-violet);
    opacity: 0.35;
    animation: pet-think 1.1s ease-in-out infinite;
}
.pet-coach-thinking span:nth-child(2) { animation-delay: 0.18s; }
.pet-coach-thinking span:nth-child(3) { animation-delay: 0.36s; }
@keyframes pet-think {
    0%, 100% { opacity: 0.35; transform: translateY(0); }
    45%      { opacity: 1;    transform: translateY(-2px); }
}
@media (prefers-reduced-motion: reduce) {
    .pet-coach-thinking span { animation: none; opacity: 0.7; }
}
.pet-coach-list { display: flex; flex-direction: column; gap: 6px; }
.pet-coach-row {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 10px;
}
.pet-coach-reason {
    font-size: 10px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 2px 8px;
    border-radius: 999px;
    white-space: nowrap;
    color: #fff;
}
.reason-overdue { background: #EF4444; }
.reason-duetoday { background: #F59E0B; }
.reason-highintensity { background: #7C3AED; }
.reason-soon { background: #0EA5E9; }
.reason-backlog { background: #94A3B8; }
.pet-coach-title {
    font-size: 13.5px;
    color: var(--chronos-fg-primary);
    cursor: pointer;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pet-coach-title:hover { color: var(--chronos-violet); }
.pet-coach-main { flex-shrink: 0; }

.label-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* Create-task modal extras. */
.modal-card-wide { max-width: 640px; }

.modal-textarea {
    border: 1px solid var(--chronos-outline);
    border-radius: 8px;
    padding: 10px 12px;
    font-family: inherit;
    font-size: 14px;
    background: white;
    outline: none;
    resize: vertical;
    min-height: 80px;
}
.modal-textarea:focus { border-color: var(--chronos-violet); }

.modal-search[type="date"] {
    cursor: pointer;
}

.label-new {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 4px;
}
.label-new-name { flex: 1; min-width: 160px; }
.label-new-colors {
    display: flex;
    gap: 4px;
}
.color-swatch {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 2px solid transparent;
    cursor: pointer;
    padding: 0;
}
.color-swatch:hover { transform: scale(1.1); }
.color-swatch.selected {
    border-color: var(--chronos-text);
    box-shadow: 0 0 0 1px white inset;
}

/* "Any colour" picker - the last swatch in the row. A rainbow conic gradient
   signals free choice; the real <input type="color"> is stretched over it and
   made invisible so the whole disc is the click target that opens the native
   colour dialog. Goes .selected (shared ring above) when the active colour is
   not one of the preset swatches. */
.color-swatch-custom {
    position: relative;
    overflow: hidden;
    display: inline-flex;
    background: conic-gradient(from 0deg,
        #EF4444, #F59E0B, #10B981, #0EA5E9, #7C3AED, #EC4899, #EF4444);
}
.color-swatch-custom input[type="color"] {
    position: absolute;
    inset: -4px;
    width: calc(100% + 8px);
    height: calc(100% + 8px);
    margin: 0;
    padding: 0;
    border: none;
    background: none;
    opacity: 0;
    cursor: pointer;
}

/* Bottom-bar "+ New task" CTA - replaces the old label-card stub. */
.new-task-cta {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 18px;
    cursor: pointer;
    background: var(--chronos-card-bg);
    border: 1px solid var(--chronos-outline);
    border-radius: 16px;
    flex: 1;
    text-align: left;
    font-family: inherit;
}
.new-task-cta:hover { border-color: var(--chronos-violet); }
.new-task-cta:disabled { opacity: 0.5; cursor: not-allowed; }
.new-task-cta .material-icons {
    color: var(--chronos-violet);
    font-size: 28px;
}
.new-task-cta-label {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}
.new-task-cta-label span:first-child { font-weight: 600; }

/* Detail modal - GitLab-style 2-column layout. */
.modal-card-detail {
    max-width: 800px;
    min-width: 520px;
}
.detail-title {
    flex: 1;
    word-break: break-word;
}
.detail-body {
    display: grid;
    grid-template-columns: 1fr 220px;
    gap: 20px;
    align-items: start;
}
.detail-main {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.detail-desc {
    margin: 0;
    white-space: pre-wrap;
    line-height: 1.5;
}
.detail-sidebar {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding-left: 16px;
    border-left: 1px solid var(--chronos-outline);
}
.detail-section {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.subtask-list {
    list-style: none;
    padding: 0;
    margin: 6px 0 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
/* A calm checklist row on-brand with the rest of the app: violet-accent checkbox, a soft
   hover wash, and a tabular percent so the number column keeps a fixed width (10% -> 100%
   never nudges the layout). Only 'background' transitions - nothing that moves geometry, so
   ticking a step can't make the row jump. Stable Ordinal + @key stop the list reshuffling. */
.subtask-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 8px;
    border-radius: 8px;
    cursor: pointer;
    transition: background var(--d1, 120ms) var(--e-quart, ease);
}
.subtask-item:hover { background: var(--chronos-hover-bg); }
.subtask-item input[type="checkbox"] {
    accent-color: var(--chronos-violet);
    width: 17px;
    height: 17px;
    margin: 0;
    flex-shrink: 0;
    cursor: pointer;
}
.subtask-title { flex: 1; min-width: 0; line-height: 1.4; }
.subtask-done { text-decoration: line-through; color: var(--chronos-muted); }
.subtask-progress {
    font-size: 12px;
    margin-left: auto;
    flex-shrink: 0;
    color: var(--chronos-muted);
    font-variant-numeric: tabular-nums;
}

@media (max-width: 480px) {
    .modal-card-detail {
        min-width: 0;
        width: 92vw;
    }
    .detail-body {
        grid-template-columns: 1fr;
    }
    .detail-sidebar {
        padding-left: 0;
        border-left: none;
        border-top: 1px solid var(--chronos-outline);
        padding-top: 14px;
        margin-top: 0;
    }
}

