/*
 * Haven Energy - Django Admin theme
 *
 * Phase 0 of the Haven Ops dashboard reskin. This file is loaded site-wide
 * from `templates/admin/base_site.html`, so any change here cascades to every
 * page under `/admin/*`, including the long-tail Prisma / HubSpot / sync /
 * permissions changelists.
 *
 * Structure:
 *   1. Fonts
 *   2. Haven palette tokens (CSS custom properties)
 *   3. Light / dark theme semantic tokens
 *   4. Django admin variable overrides (the heavy lift)
 *   5. Typography + base element defaults
 *   6. Legacy chrome (logo, collapsible sidebar, save-loading) - preserved
 *   7. Haven component primitives (.hv-*) used by later phases
 */

/* -------------------------------------------------------------------------
 * 1. Fonts
 *
 * Acid Grotesk for display (headings, KPI values). Inter for UI/body via
 * the system font stack so we don't ship a 200kB woff2 just for body text.
 * ------------------------------------------------------------------------- */

@font-face {
  font-family: 'Acid Grotesk';
  src: url("../fonts/FFF-AcidGrotesk-Book.1efdb01d273c.otf") format('opentype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Acid Grotesk';
  src: url("../fonts/FFF-AcidGrotesk-Medium.8a65093af62a.woff2") format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* -------------------------------------------------------------------------
 * 2. Haven palette tokens
 *
 * Raw brand colors. Do not use these directly in component CSS - use the
 * semantic tokens in section 3 so light/dark switching works.
 * ------------------------------------------------------------------------- */

:root {
  --haven-volt: #ddff0e;
  --haven-pine: #013300;
  --haven-black: #050505;
  --haven-white: #ffffff;

  --haven-cream-50: #fcffe9;
  --haven-cream-100: #f9ffd3;
  --haven-cream-400: #f1ff9f;

  --haven-stone: #eeeee8;
  --haven-bone: #babaad;
  --haven-sand: #ecdba8;
  --haven-mist: #e6f1fe;
  --haven-toast: #dcae79;
  --haven-walnut: #76552f;
  --haven-lavender: #dec9f6;
  --haven-olive: #87ab6d;

  --haven-status-red: #b33a2a;
  --haven-status-red-soft: #fae6e0;
  --haven-status-amber: #9b6b16;
  --haven-status-amber-soft: #f8eac3;
  --haven-status-green: #2d6a3e;
  --haven-status-green-soft: #e2f0dc;

  /* Spacing / radius / shadow scales */
  --haven-radius-sm: 6px;
  --haven-radius-md: 8px;
  --haven-radius-lg: 12px;
  --haven-radius-xl: 16px;
  --haven-radius-pill: 999px;

  --haven-shadow-card: 0 4px 12px rgba(5, 5, 5, 0.06);
  --haven-shadow-popover: 0 12px 36px rgba(5, 5, 5, 0.14);
}

/* -------------------------------------------------------------------------
 * 3. Semantic tokens (light + dark themes)
 *
 * Use these in component CSS. Switching `data-theme="dark"` on <html>
 * flips every page automatically.
 * ------------------------------------------------------------------------- */

:root,
:root[data-theme='light'] {
  --haven-bg: #ffffff;
  --haven-bg-alt: var(--haven-cream-50);
  --haven-surface: #ffffff;
  --haven-surface-2: var(--haven-cream-50);

  --haven-border: rgba(5, 5, 5, 0.08);
  --haven-border-strong: rgba(5, 5, 5, 0.16);

  --haven-fg: var(--haven-black);
  --haven-fg-muted: rgba(5, 5, 5, 0.6);
  --haven-fg-faint: rgba(5, 5, 5, 0.4);

  --haven-scrim: rgba(5, 5, 5, 0.2);
  --haven-shadow: var(--haven-shadow-card);
  --haven-popover-shadow: var(--haven-shadow-popover);

  --haven-status-red-fg: var(--haven-status-red);
  --haven-status-red-bg: var(--haven-status-red-soft);
  --haven-status-amber-fg: var(--haven-status-amber);
  --haven-status-amber-bg: var(--haven-status-amber-soft);
  --haven-status-green-fg: var(--haven-status-green);
  --haven-status-green-bg: var(--haven-status-green-soft);

  /* Hover bg for solid "dark on light" buttons (.hv-button--secondary,
   * .object-tools a, Django's --button-hover-bg). In light mode the
   * button bg is --haven-fg (near-black) and we deepen it slightly on
   * hover; in dark mode the bg flips to a light cream and hovering
   * must DARKEN it (otherwise the dark text turns invisible -- see
   * bugbot report). */
  --haven-button-hover-bg: #1a1a1a;
  /* Stone-style grouping card bg (Task completion module). Stone is a
   * raw light-only token; the dark variant uses an elevated dark
   * surface so nested cards still read as a hierarchy. */
  --haven-section-bg: var(--haven-stone);
}

:root[data-theme='dark'] {
  --haven-bg: #0d0d0d;
  --haven-bg-alt: #141414;
  --haven-surface: #171717;
  --haven-surface-2: rgba(255, 255, 255, 0.04);

  --haven-border: rgba(255, 255, 255, 0.08);
  --haven-border-strong: rgba(255, 255, 255, 0.16);

  --haven-fg: #f4f4f0;
  --haven-fg-muted: rgba(244, 244, 240, 0.62);
  --haven-fg-faint: rgba(244, 244, 240, 0.4);

  --haven-scrim: rgba(0, 0, 0, 0.55);
  --haven-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  --haven-popover-shadow: 0 12px 36px rgba(0, 0, 0, 0.5);

  --haven-status-red-fg: #e47a6d;
  --haven-status-red-bg: rgba(228, 122, 109, 0.16);
  --haven-status-amber-fg: #d9a45a;
  --haven-status-amber-bg: rgba(217, 164, 90, 0.16);
  --haven-status-green-fg: #79b488;
  --haven-status-green-bg: rgba(121, 180, 136, 0.16);

  /* See light-mode comment. In dark mode the secondary button bg is
   * --haven-fg (#f4f4f0), so the hover state must move toward a slightly
   * dimmer cream rather than toward black. */
  --haven-button-hover-bg: #d8d8d0;
  /* Elevated dark surface for stone-style grouping cards. */
  --haven-section-bg: var(--haven-bg-alt);
}

/* -------------------------------------------------------------------------
 * 4. Django admin CSS variable overrides
 *
 * This is the cheap win: Django's stock admin already drives the entire UI
 * off these CSS vars. Remap them to Haven tokens and the whole admin -
 * including every long-tail Prisma/HubSpot/permissions changelist - inherits
 * the new look for free.
 * ------------------------------------------------------------------------- */

:root,
:root[data-theme='light'],
:root[data-theme='dark'] {
  --primary: var(--haven-fg);
  --primary-fg: var(--haven-bg);

  --secondary: var(--haven-fg);
  --accent: var(--haven-volt);

  --body-bg: var(--haven-bg);
  --body-fg: var(--haven-fg);
  --body-quiet-color: var(--haven-fg-muted);
  --body-loud-color: var(--haven-fg);

  /* Header is constant brand chrome regardless of theme (matches Haven's
   * dark navbar + volt accent identity). */
  --header-bg: var(--haven-black);
  --header-color: var(--haven-white);
  --header-branding-color: var(--haven-volt);
  --header-link-color: var(--haven-white);

  --breadcrumbs-fg: var(--haven-fg-muted);
  --breadcrumbs-link-fg: var(--haven-fg);
  --breadcrumbs-bg: var(--haven-bg-alt);

  --link-fg: var(--haven-fg);
  --link-hover-color: var(--haven-walnut);
  --link-selected-fg: var(--haven-fg);

  --hairline-color: var(--haven-border);
  --border-color: var(--haven-border);

  --darkened-bg: var(--haven-bg-alt);
  --selected-bg: var(--haven-cream-100);
  --selected-row: var(--haven-cream-50);

  --button-fg: var(--haven-bg);
  --button-bg: var(--haven-fg);
  --button-hover-bg: var(--haven-button-hover-bg);

  --default-button-bg: var(--haven-volt);
  /* Volt is a bright brand color in both themes; default-button text
   * must stay dark regardless of theme (--haven-fg flips light in
   * dark mode). */
  --default-button-fg: var(--haven-black);
  --default-button-hover-bg: var(--haven-cream-400);

  --close-button-bg: var(--haven-fg-muted);
  --close-button-hover-bg: var(--haven-fg);

  --delete-button-bg: var(--haven-status-red);
  --delete-button-hover-bg: #962e21;

  --object-tools-bg: var(--haven-fg);
  --object-tools-fg: var(--haven-bg);
  --object-tools-hover-bg: var(--haven-button-hover-bg);

  --message-success-bg: var(--haven-status-green-bg);
  --message-warning-bg: var(--haven-status-amber-bg);
  --message-error-bg: var(--haven-status-red-bg);

  --error-fg: var(--haven-status-red-fg);
}

/* Default-styled Django primary buttons (e.g. .submit-row .default) use the
 * volt color, which is bright in both themes. Pin the text to brand-black
 * so dark theme doesn't flip --haven-fg to light-on-volt. */
input[type='submit'].default,
button.default,
.submit-row input.default {
  color: var(--haven-black) !important;
}

/* -------------------------------------------------------------------------
 * 5. Typography + base element defaults
 *
 * Inter for UI via the system stack (no extra payload). Acid Grotesk for
 * Haven-styled headings via the .hv-display utility (and a few well-known
 * admin headings).
 * ------------------------------------------------------------------------- */

html,
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  background: var(--haven-bg);
  color: var(--haven-fg);
}

.hv-display,
.hv-display h1,
.hv-display h2,
.hv-display h3 {
  font-family: 'Acid Grotesk', 'Inter', system-ui, sans-serif;
  font-weight: 500;
  letter-spacing: -0.02em;
}

#header {
  border-bottom: 1px solid var(--haven-border);
}

#branding h1 {
  font-family: 'Acid Grotesk', 'Inter', system-ui, sans-serif;
  font-weight: 500;
  letter-spacing: -0.01em;
}

/* -------------------------------------------------------------------------
 * 6. Legacy chrome - preserved from the pre-Phase-0 stylesheet
 *
 * Logo alignment was for the old Django #header (now removed in the shell
 * rewrite below; brand mark lives in the sidebar). Save-loading spinner
 * behavior unchanged.
 * ------------------------------------------------------------------------- */

#recent-actions-module .module-header {
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

#recent-actions-module .module-header::after {
  content: '▼';
  font-size: 10px;
  margin-left: 8px;
  transition: transform 0.2s ease;
  opacity: 0.6;
}

#recent-actions-module.collapsed .module-header::after {
  transform: rotate(-90deg);
}

#recent-actions-module.collapsed .module-content {
  display: none;
}

@keyframes haven-admin-spin {
  to {
    transform: rotate(360deg);
  }
}

input[type='submit'].haven-admin-save-loading.haven-admin-save-loading--submitter {
  color: transparent !important;
  text-shadow: none !important;
  background-repeat: no-repeat !important;
  background-position: center !important;
  background-size: 22px 22px !important;
  cursor: wait;
  opacity: 1 !important;
}

input[type='submit'].haven-admin-save-loading--primary.haven-admin-save-loading--submitter {
  background-color: var(--default-button-bg) !important;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' fill='none'%3E%3Ccircle cx='12' cy='12' r='9' stroke='%23050505' stroke-width='3' stroke-dasharray='42' stroke-dashoffset='10' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='0.75s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/svg%3E") !important;
}

input[type='submit'].haven-admin-save-loading--secondary.haven-admin-save-loading--submitter {
  background-color: var(--button-bg) !important;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' fill='none'%3E%3Ccircle cx='12' cy='12' r='9' stroke='%23ffffff' stroke-width='3' stroke-dasharray='42' stroke-dashoffset='10' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='0.75s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/svg%3E") !important;
}

/* In dark theme, --button-bg flips to a light foreground, so the white
 * spinner above becomes invisible. Swap to a dark stroke. */
[data-theme='dark'] input[type='submit'].haven-admin-save-loading--secondary.haven-admin-save-loading--submitter {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' fill='none'%3E%3Ccircle cx='12' cy='12' r='9' stroke='%23050505' stroke-width='3' stroke-dasharray='42' stroke-dashoffset='10' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='0.75s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/svg%3E") !important;
}

.haven-admin-save-loading--submitter {
  pointer-events: none;
  cursor: wait;
}

.haven-admin-spinner {
  display: inline-block;
  width: 1.25em;
  height: 1.25em;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  border-radius: 50%;
  vertical-align: middle;
  animation: haven-admin-spin 0.75s linear infinite;
}

/* -------------------------------------------------------------------------
 * 7. Haven component primitives
 *
 * Opt-in classes for later-phase templates. They use the semantic tokens
 * above so light/dark switching works automatically. Nothing in this section
 * is applied to existing markup in Phase 0 - it's a library for phases 1-5
 * to consume.
 * ------------------------------------------------------------------------- */

/* Theme + logout buttons in the topbar (added in base_site.html in Phase 0).
 * Always lives in the dark brand header, so colors are constant regardless
 * of theme. */
.hv-topbar-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--haven-radius-pill);
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: transparent;
  color: var(--haven-white);
  cursor: pointer;
  transition: background 0.14s ease, opacity 0.14s ease;
  opacity: 0.75;
  padding: 0;
}

.hv-topbar-button:hover,
.hv-topbar-button:focus {
  opacity: 1;
  background: rgba(255, 255, 255, 0.08);
  outline: none;
}

.hv-topbar-button svg {
  width: 18px;
  height: 18px;
}

.hv-topbar-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: 12px;
}

/* Card */
.hv-card {
  background: var(--haven-surface);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-xl);
  box-shadow: var(--haven-shadow);
  padding: 24px;
}

.hv-card--compact {
  padding: 16px;
  border-radius: var(--haven-radius-lg);
}

/* KPI card */
.hv-kpi {
  background: var(--haven-surface);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-xl);
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  position: relative;
}

.hv-kpi__label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--haven-fg-muted);
}

.hv-kpi__value {
  font-family: 'Acid Grotesk', 'Inter', system-ui, sans-serif;
  font-weight: 500;
  font-size: 42px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--haven-fg);
}

.hv-kpi__delta {
  font-size: 12px;
  color: var(--haven-fg-muted);
}

.hv-kpi__delta--up-bad,
.hv-kpi__delta--down-bad {
  color: var(--haven-status-red-fg);
}

.hv-kpi__delta--up-good,
.hv-kpi__delta--down-good {
  color: var(--haven-status-green-fg);
}

/* Chips */
.hv-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: var(--haven-radius-pill);
  font-size: 12px;
  font-weight: 500;
  background: var(--haven-bg-alt);
  color: var(--haven-fg);
  border: 1px solid var(--haven-border);
}

.hv-chip--workspace {
  background: var(--haven-volt);
  /* Volt is bright in both themes, so always pair with the constant
   * brand-black instead of --haven-fg (which becomes light in dark mode
   * and produces light-on-volt = unreadable). */
  color: var(--haven-black);
  border-color: transparent;
  font-weight: 600;
}

/* Status pills */
.hv-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: var(--haven-radius-pill);
  font-size: 12px;
  font-weight: 600;
}

.hv-pill--blocked {
  background: var(--haven-lavender);
  color: #3c1c66;
}

.hv-pill--inprogress {
  background: var(--haven-mist);
  color: #1c3a66;
}

.hv-pill--closed {
  background: var(--haven-status-green-bg);
  color: var(--haven-status-green-fg);
}

.hv-pill--unassigned {
  background: var(--haven-surface-2);
  color: var(--haven-fg-muted);
}

/* SLA pill */
.hv-sla {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: var(--haven-radius-pill);
  font-size: 12px;
  font-weight: 600;
  background: var(--haven-surface-2);
  color: var(--haven-fg-muted);
}

.hv-sla--past {
  background: var(--haven-status-red-bg);
  color: var(--haven-status-red-fg);
}

.hv-sla--due {
  background: var(--haven-status-amber-bg);
  color: var(--haven-status-amber-fg);
}

/* Avatar */
.hv-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--haven-radius-pill);
  background: #5b6ee8;
  color: #ffffff;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

.hv-avatar--empty {
  background: transparent;
  color: var(--haven-fg-faint);
  border: 1px dashed var(--haven-border-strong);
}

.hv-avatar--lg {
  width: 40px;
  height: 40px;
  font-size: 14px;
}

.hv-avatar--xl {
  width: 72px;
  height: 72px;
  font-size: 22px;
  border-radius: var(--haven-radius-lg);
}

/* Tabs */
.hv-tabs {
  display: flex;
  align-items: center;
  gap: 22px;
  border-bottom: 1px solid var(--haven-border);
  margin: 0 0 16px 0;
  padding: 0;
  list-style: none;
}

.hv-tabs__tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--haven-fg-muted);
  text-decoration: none;
  background: transparent;
  border: none;
  border-top: 0;
  border-left: 0;
  border-right: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  margin-bottom: -1px;
  cursor: pointer;
  font-family: inherit;
  box-shadow: none;
  appearance: none;
  white-space: nowrap;
}

.hv-tabs__tab:hover,
.hv-tabs__tab:focus {
  color: var(--haven-fg);
  background: transparent;
  outline: none;
}

.hv-tabs__tab:focus-visible {
  outline: 2px solid var(--haven-volt);
  outline-offset: 2px;
}

.hv-tabs__tab.is-active,
.hv-tabs__tab[aria-selected='true'] {
  color: var(--haven-fg);
  font-weight: 700;
  border-bottom-color: var(--haven-fg);
}

.hv-tabs__count {
  font-size: 11px;
  font-weight: 600;
  background: var(--haven-bg-alt);
  border-radius: var(--haven-radius-pill);
  padding: 2px 8px;
  color: var(--haven-fg-muted);
}

/* Filter bar */
.hv-filterbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: var(--haven-surface);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-lg);
  margin-bottom: 16px;
}

.hv-filterbar__search {
  flex: 1 1 220px;
  min-width: 0;
}

.hv-filterbar__input {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 12px;
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-md);
  background: var(--haven-bg);
  color: var(--haven-fg);
  font-size: 13px;
}

.hv-filterbar__input:focus {
  outline: 2px solid var(--haven-border-strong);
  outline-offset: 1px;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.hv-deal-search-empty {
  display: none;
  padding: 24px 16px;
  text-align: center;
  color: var(--haven-fg-muted);
  font-size: 14px;
}

.hv-tab-panel.is-filter-deal-search-empty .hv-deal-search-empty {
  display: block;
}

.hv-task-row-cell.is-deal-search-hidden {
  display: none !important;
}

/* Task row */
.hv-task-row {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  align-items: center;
  gap: 16px;
  padding: 14px 16px;
  background: var(--haven-surface);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-lg);
  position: relative;
  text-decoration: none;
  color: var(--haven-fg);
  transition: background 0.14s ease;
}

.hv-task-row + .hv-task-row {
  margin-top: 8px;
}

.hv-task-row:hover {
  background: var(--haven-surface-2);
}

/* Past-due left-accent stripe is rendered by .hv-task-row--past-due::before
 * (see section 8). No box-shadow fallback is needed -- the pseudo-element
 * fully covers the same area and keeping both meant two source-of-truth
 * locations for the same visual. */

.hv-task-row__title {
  font-size: 13px;
  font-weight: 600;
}

.hv-task-row__meta {
  font-size: 12px;
  color: var(--haven-fg-muted);
}

/* Bulk action bar */
.hv-bulk-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--haven-fg);
  color: var(--haven-bg);
  border-radius: var(--haven-radius-lg);
  margin-bottom: 12px;
}

.hv-bulk-bar__count {
  font-size: 13px;
  font-weight: 600;
}

.hv-bulk-bar .hv-button {
  background: rgba(255, 255, 255, 0.12);
  color: var(--haven-bg);
  border-color: transparent;
}

.hv-bulk-bar .hv-button:hover {
  background: rgba(255, 255, 255, 0.2);
}

.hv-bulk-bar .hv-button--primary {
  background: var(--haven-volt);
  color: var(--haven-black);
}

/* Button */
.hv-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: var(--haven-radius-md);
  border: 1px solid var(--haven-border-strong);
  background: var(--haven-surface);
  color: var(--haven-fg);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.14s ease;
}

.hv-button:hover {
  background: var(--haven-bg-alt);
}

.hv-button--primary {
  background: var(--haven-volt);
  color: var(--haven-black);
  border-color: transparent;
}

.hv-button--primary:hover {
  background: var(--haven-cream-400);
}

.hv-button--secondary {
  background: var(--haven-fg);
  color: var(--haven-bg);
  border-color: transparent;
}

.hv-button--secondary:hover {
  background: var(--haven-button-hover-bg);
}

.hv-button--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--haven-fg-muted);
}

.hv-button--ghost:hover {
  background: var(--haven-bg-alt);
  color: var(--haven-fg);
}

.hv-button--danger {
  background: var(--haven-status-red-fg);
  color: #ffffff;
  border-color: transparent;
}

.hv-button--danger:hover {
  background: #962e21;
}

.hv-button--sm {
  padding: 5px 10px;
  font-size: 12px;
}

/* Slide-over panel (driven by haven-panels.js) */
.hv-panel-scrim {
  position: fixed;
  inset: 0;
  background: var(--haven-scrim);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
  z-index: 90;
}

.hv-panel-scrim.is-open {
  opacity: 1;
  pointer-events: auto;
}

.hv-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 460px;
  max-width: 100vw;
  background: var(--haven-surface);
  border-left: 1px solid var(--haven-border);
  box-shadow: var(--haven-popover-shadow);
  transform: translateX(100%);
  transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
  z-index: 100;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.hv-panel.is-open {
  transform: translateX(0);
}

.hv-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--haven-border);
}

.hv-panel__body {
  flex: 1;
  overflow: auto;
  padding: 20px;
}

/* -------------------------------------------------------------------------
 * 8. Dashboard (operator index page) - Phase 1
 *
 * Layout for `templates/admin/task_dashboard.html`: page header, KPI strip,
 * 2-column body (main task list + right aside), tab panels, aside cards.
 * ------------------------------------------------------------------------- */

.hv-dashboard {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.hv-dashboard__header h1 {
  margin: 0;
  font-size: 32px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--haven-fg);
}

.hv-dashboard__kpi-strip {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
}

@media (max-width: 1080px) {
  .hv-dashboard__kpi-strip {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 720px) {
  .hv-dashboard__kpi-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.hv-dashboard__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 304px;
  gap: 24px;
  align-items: start;
}

@media (max-width: 1080px) {
  .hv-dashboard__body {
    grid-template-columns: 1fr;
  }
}

.hv-dashboard__main {
  background: var(--haven-surface);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-xl);
  padding: 8px 18px 18px;
  box-shadow: var(--haven-shadow);
}

.hv-dashboard__main .hv-tabs {
  margin: 0 -6px 14px;
  padding: 0 6px;
}

.hv-dashboard__aside {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Tab panels */
.hv-tab-panel {
  display: none;
}

.hv-tab-panel.is-active {
  display: block;
}

/* Task lists */
.hv-task-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.hv-task-list > li {
  list-style: none;
  margin: 0;
}

.hv-task-list > li + li {
  margin-top: 8px;
}

.hv-task-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  background: var(--haven-bg);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-lg);
  text-decoration: none;
  color: var(--haven-fg);
  transition: background 0.14s ease, border-color 0.14s ease;
  position: relative;
  overflow: hidden;
}

.hv-task-row:hover {
  background: var(--haven-surface-2);
  border-color: var(--haven-border-strong);
  text-decoration: none;
}

.hv-task-row--past-due::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--haven-status-red-fg);
}

.hv-task-row__main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.hv-task-row__title {
  font-size: 14px;
  font-weight: 600;
  color: var(--haven-fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hv-task-row__meta {
  font-size: 12px;
  color: var(--haven-fg-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hv-task-row__meta--faint {
  color: var(--haven-fg-faint);
  font-style: italic;
}

/* Static (non-clickable) KPI tile - kills the link affordance so the
 * tile reads as a stat, not a button. */
.hv-kpi--static {
  cursor: default;
}

/* Tabs row: tabs on the left, filter toggles anchored to the right.
 * Intentionally no bottom border on the row itself - the underline
 * only spans the tabs nav so the trailing space next to the toggle
 * stays clean. `align-items: stretch` lets the toggle pick up the
 * tabs' vertical padding so its text baseline sits on the same line
 * as the tab labels. */
.hv-tabs-row {
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: 16px;
}

.hv-tabs-row .hv-tabs {
  flex: 1 1 auto;
  min-width: 0;
}

.hv-past-sla-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 500;
  color: var(--haven-fg);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  padding: 0 0 12px 0;
}

.hv-past-sla-toggle input[type="checkbox"] {
  margin: 0;
  accent-color: var(--haven-fg);
  cursor: pointer;
}

/* Past-SLA filter: hide rows that aren't flagged past-SLA across the
 * non-terminal panels (In progress / Unclaimed / Blocked). The Closed
 * today panel is intentionally excluded -- terminal tasks have
 * sla_seconds_past_due == None so they would otherwise all disappear,
 * making "Closed today" look empty while the KPI still shows
 * completions. */
.hv-dashboard.is-filter-past-sla
  .hv-tab-panel:not([data-haven-tab-panel="closed-today"]):not([data-haven-tab-panel="timed-delays"])
  .hv-task-list > .hv-task-row-cell:not(.is-past-sla) {
  display: none;
}

/* Inline empty state shown when the past-SLA filter wipes a panel clean.
 * Uses :has() to detect "no visible past-SLA rows anywhere in the panel",
 * which is well-supported across evergreen browsers as of 2024. */
.hv-past-sla-empty {
  display: none;
  padding: 24px 16px;
  text-align: center;
  color: var(--haven-fg-muted);
  font-size: 14px;
}

.hv-dashboard.is-filter-past-sla
  .hv-tab-panel:not([data-haven-tab-panel="closed-today"]):not([data-haven-tab-panel="timed-delays"]):not(:has(.hv-task-row-cell.is-past-sla))
  .hv-past-sla-empty {
  display: block;
}

/* Closed-state status chip. Visually similar weight to the SLA chips but
 * neutral coloring so completed work doesn't read as "On track" (live). */
.hv-due--closed {
  color: var(--haven-fg-muted);
}

.hv-due--closed .hv-due__dot {
  background: var(--haven-fg-muted);
}

/* Unclaimed-row Claim button. The form has to be a sibling of the row
 * anchor (nesting a <form> inside an <a> is invalid HTML), so on
 * claimable rows we promote the LI itself to be the visual card and
 * lay out the anchor + form as flex children inside it. */
.hv-task-row-cell {
  list-style: none;
}

.hv-task-row-cell--claimable {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--haven-bg);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-lg);
  padding-right: 14px;
  transition: background 0.14s ease, border-color 0.14s ease;
  overflow: hidden;
}

.hv-task-row-cell--claimable:hover {
  background: var(--haven-surface-2);
  border-color: var(--haven-border-strong);
}

/* Inside a claimable cell the inner row anchor loses its own card chrome
 * so the LI is the only visible border. */
.hv-task-row-cell--claimable .hv-task-row {
  flex: 1 1 auto;
  min-width: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 12px 16px;
}

.hv-task-row-cell--claimable .hv-task-row:hover {
  background: transparent;
  border-color: transparent;
}

.hv-task-row__claim-form {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  margin: 0;
}

.hv-task-row__close-early-form {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  margin: 0;
}

/* Outlined pill matching the mock's Claim button. */
.hv-task-row__claim-form .hv-button,
.hv-task-row__close-early-form .hv-button {
  background: var(--haven-bg);
  color: var(--haven-fg);
  border: 1px solid var(--haven-fg);
  border-radius: var(--haven-radius-pill);
  padding: 6px 18px;
  font-weight: 500;
}

.hv-task-row__claim-form .hv-button:hover,
.hv-task-row__close-early-form .hv-button:hover {
  background: var(--haven-fg);
  color: var(--haven-bg);
}

/* Grouped (Unclaimed) layout */
.hv-task-group + .hv-task-group {
  margin-top: 24px;
}

.hv-task-group__heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 0 0 10px 0;
  font-size: 13px;
  font-weight: 500;
}

.hv-task-group__count {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--haven-fg-muted);
}

.hv-empty-state {
  padding: 36px 16px;
  text-align: center;
  color: var(--haven-fg-muted);
  font-size: 13px;
}

.hv-empty-state--inline {
  padding: 12px 0;
  text-align: left;
}

/* Aside cards */
.hv-aside-card__title {
  margin: 0 0 12px 0;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--haven-fg-muted);
}

.hv-aside-card__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.hv-aside-card__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  font-size: 13px;
  border-bottom: 1px solid var(--haven-border);
}

.hv-aside-card__row:last-child {
  border-bottom: none;
}

.hv-aside-card__row-label {
  color: var(--haven-fg);
}

.hv-aside-card__row-value {
  color: var(--haven-fg-muted);
  font-size: 12px;
  font-weight: 500;
}

.hv-aside-card__empty {
  margin: 0;
  font-size: 13px;
  color: var(--haven-fg-muted);
}

/* Section label inside the priorities card (e.g. "Global" vs a workspace's
 * task types). Smaller than the card title; first one hugs the title. */
.hv-aside-card__subhead {
  margin: 14px 0 4px 0;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--haven-fg-muted);
}

.hv-aside-card__subhead:first-of-type {
  margin-top: 0;
}

/* -------------------------------------------------------------------------
 * 9. Global polish - softens stock Django admin chrome so it doesn't
 *    fight the new tokens. These are deliberately small nudges, not a
 *    full rebuild of admin form chrome (that's later phases).
 * ------------------------------------------------------------------------- */

/* The Haven shell (section 10 below) takes over container/main/sidebar
 * layout. We keep this rule as a fallback for the login page where the
 * shell is bypassed. */
.login #container {
  background: var(--haven-bg-alt);
}

/* The default Django changelist tables get a slightly softer header and
 * cleaner row separators. */
#changelist .results,
.module table {
  background: var(--haven-surface);
  border-radius: var(--haven-radius-lg);
  overflow: hidden;
}

#changelist-form .results thead th {
  background: var(--haven-bg-alt);
  color: var(--haven-fg);
  font-weight: 600;
  border-bottom: 1px solid var(--haven-border);
}

#changelist-form .results tbody tr:hover {
  background: var(--haven-surface-2);
}

#changelist-filter h2,
#changelist-filter h3 {
  background: var(--haven-bg-alt);
  color: var(--haven-fg);
  border-radius: var(--haven-radius-md) var(--haven-radius-md) 0 0;
}

/* Module / fieldset boxes - rounded card treatment */
.module {
  border-radius: var(--haven-radius-lg);
  border: 1px solid var(--haven-border);
  box-shadow: var(--haven-shadow);
  overflow: hidden;
}

.module h2,
.module caption,
.inline-group h2 {
  background: var(--haven-bg-alt);
  color: var(--haven-fg);
  font-weight: 600;
  text-transform: none;
  letter-spacing: -0.005em;
  border-bottom: 1px solid var(--haven-border);
}

/* Submit row - inline buttons with Haven button feel */
.submit-row {
  background: var(--haven-bg-alt);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-lg);
  padding: 12px 16px;
}

.submit-row input,
.submit-row a.deletelink {
  border-radius: var(--haven-radius-md);
  padding: 8px 14px;
  font-weight: 500;
}

.submit-row input.default {
  background: var(--haven-volt);
  color: var(--haven-black) !important;
  border: 1px solid var(--haven-volt);
}

.submit-row input.default:hover,
.submit-row input.default:focus {
  background: var(--haven-cream-400);
  border-color: var(--haven-cream-400);
}

/* Links - keep them quietly different from body text */
a,
a:link,
a:visited {
  color: var(--haven-fg);
  text-decoration: underline;
  text-decoration-color: var(--haven-border-strong);
  text-underline-offset: 2px;
}

a:hover {
  color: var(--haven-walnut);
  text-decoration-color: var(--haven-walnut);
}

/* Don't underline links in chrome that already provides affordance */
#header a,
#user-tools a,
.breadcrumbs a,
#nav-sidebar a,
.hv-task-row,
.hv-button,
.hv-topbar-button,
.hv-tabs__tab,
.hv-chip,
.hv-pill,
.object-tools a {
  text-decoration: none;
}

/* Breadcrumbs only render inside the topbar slot (see haven-breadcrumbs.js).
 * The original Django wrapper from base.html is hidden so the historical
 * full-width cream bar never appears -- no default `.breadcrumbs` rule
 * here on purpose, so nothing leaks a background. */
nav[aria-label='Breadcrumbs']:not(.hv-breadcrumbs) {
  display: none;
}

.hv-topbar__breadcrumbs-slot {
  flex: 1;
  display: flex;
  align-items: center;
  min-width: 0;
}

.hv-topbar__breadcrumbs-slot .hv-breadcrumbs {
  display: block;
  min-width: 0;
  background: transparent;
}

/* Match sidebar item typography: 13px / 500 / Acid Grotesk (inherited),
 * no underline on links, no background. !important on the visual reset
 * defends against the original `.breadcrumbs` rule reappearing if a stock
 * Django stylesheet loads after us. */
.hv-topbar__breadcrumbs-slot .breadcrumbs {
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  font-size: 13px;
  font-weight: 500;
  color: var(--haven-fg-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.hv-topbar__breadcrumbs-slot .breadcrumbs a {
  color: var(--haven-fg-muted);
  font-weight: 500;
  text-decoration: none !important;
}

.hv-topbar__breadcrumbs-slot .breadcrumbs a:hover {
  color: var(--haven-fg);
  text-decoration: none !important;
}

/* Object tools - the buttons that sit above changelists ("Add user", etc.) */
.object-tools a {
  background: var(--haven-fg);
  color: var(--haven-bg);
  border-radius: var(--haven-radius-md);
  padding: 8px 14px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
}

.object-tools a:hover,
.object-tools a:focus {
  background: var(--haven-button-hover-bg);
}

.object-tools a.addlink {
  background: var(--haven-volt);
  color: var(--haven-black);
  border: 1px solid var(--haven-volt);
}

.object-tools a.addlink:hover {
  background: var(--haven-cream-400);
  border-color: var(--haven-cream-400);
}

/* -------------------------------------------------------------------------
 * 10. Shell - sidebar + topbar + main layout
 *
 * Replaces Django admin's dark `#header` and `.main` flex with the mockup's
 * 2-column app shell. The dark header is removed via a `{% block header %}`
 * override in base_site.html; this CSS section also hides any residual
 * `#header` element and reshapes `#container` / `.main` into a sidebar +
 * content layout that fills the viewport.
 *
 * Login is excluded - login.html hides nav-sidebar so the shell collapses
 * to a single centered column on that page.
 * ------------------------------------------------------------------------- */

#header {
  display: none;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background: var(--haven-bg-alt);
}

#container {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  width: 100%;
  background: var(--haven-bg-alt);
}

.main {
  display: flex;
  flex: 1;
  min-height: 0;
}

#footer {
  display: none;
}

/* Sidebar --------------------------------------------------------------
 *
 * Selectors use `#nav-sidebar.hv-sidebar` (specificity 110) to outweigh
 * Django's stock `#nav-sidebar` rules in nav_sidebar.css. The id stays
 * on the element so Django's nav_sidebar.js quick-filter still works. */

#nav-sidebar.hv-sidebar {
  width: 224px;
  flex: 0 0 224px;
  background: var(--haven-bg-alt);
  border-right: 1px solid var(--haven-border);
  display: flex;
  flex-direction: column;
  padding: 14px 12px 12px;
  gap: 12px;
  position: sticky;
  top: 0;
  left: 0;
  margin-left: 0;
  height: 100vh;
  overflow-y: auto;
  transition: width 0.18s ease, flex-basis 0.18s ease;
  box-sizing: border-box;
  visibility: visible;
  z-index: 15;
}

[data-haven-sidebar='collapsed'] #nav-sidebar.hv-sidebar {
  width: 64px;
  flex: 0 0 64px;
  padding: 14px 6px 12px;
}

/* When collapsed, the logo disappears entirely and the expand button
 * becomes the sole sidebar header item (matches the mockup). The button
 * also widens to fill the 64px column for a bigger hit area. */
[data-haven-sidebar='collapsed'] #nav-sidebar.hv-sidebar .hv-sidebar__header {
  justify-content: center;
  padding: 2px 0 8px;
}

[data-haven-sidebar='collapsed'] #nav-sidebar.hv-sidebar .hv-sidebar__brand {
  display: none;
}

[data-haven-sidebar='collapsed'] #nav-sidebar.hv-sidebar .hv-sidebar__collapse {
  width: 36px;
  height: 36px;
}

/* Neutralize Django's `.main > #nav-sidebar + .content` width caps which
 * assume a 23px toggle column we don't render. */
.main > #nav-sidebar + .content,
.main.shifted > #nav-sidebar + .content {
  max-width: none;
}

.hv-sidebar__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 6px 8px;
}

.hv-sidebar__brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  color: var(--haven-fg);
  font-family: 'Acid Grotesk', 'Inter', system-ui, sans-serif;
  font-weight: 500;
  font-size: 16px;
  letter-spacing: -0.01em;
  min-width: 0;
}

.hv-sidebar__logo {
  flex-shrink: 0;
  display: inline-flex;
}

.hv-sidebar__brand-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

[data-haven-sidebar='collapsed'] .hv-sidebar__brand-text {
  display: none;
}

.hv-sidebar__collapse {
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--haven-fg-muted);
  border-radius: var(--haven-radius-pill);
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: color 0.14s ease, background 0.14s ease, transform 0.18s ease;
}

.hv-sidebar__collapse:hover {
  background: var(--haven-surface-2);
  color: var(--haven-fg);
}

[data-haven-sidebar='collapsed'] .hv-sidebar__collapse {
  transform: rotate(180deg);
}

.hv-sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.hv-sidebar__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--haven-radius-md);
  color: var(--haven-fg);
  text-decoration: none !important;
  font-size: 13px;
  font-weight: 500;
  transition: background 0.14s ease, color 0.14s ease;
  min-width: 0;
}

.hv-sidebar__item:hover {
  background: var(--haven-surface-2);
  color: var(--haven-fg);
}

.hv-sidebar__item.is-active {
  background: var(--haven-fg);
  color: var(--haven-bg);
}

.hv-sidebar__item.is-active .hv-sidebar__icon {
  color: var(--haven-volt);
}

.hv-sidebar__icon {
  display: inline-flex;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: var(--haven-fg-muted);
}

.hv-sidebar__item.is-active .hv-sidebar__icon,
.hv-sidebar__item:hover .hv-sidebar__icon {
  color: inherit;
}

.hv-sidebar__icon svg {
  width: 18px;
  height: 18px;
}

.hv-sidebar__label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

[data-haven-sidebar='collapsed'] .hv-sidebar__label,
[data-haven-sidebar='collapsed'] .hv-sidebar__user-meta,
[data-haven-sidebar='collapsed'] .hv-sidebar__divider,
[data-haven-sidebar='collapsed'] .hv-sidebar__user-action {
  display: none;
}

[data-haven-sidebar='collapsed'] .hv-sidebar__item {
  justify-content: center;
  padding: 8px 6px;
}

.hv-sidebar__divider {
  margin: 4px 6px;
  border: none;
  border-top: 1px solid var(--haven-border);
}

/* App groups: <details> wrapper around an icon+label summary and a nested
 * list of model links. Summary toggles expansion only; the per-model <a>s
 * are the navigation targets. */
.hv-sidebar__group {
  /* Make the group a flex column so the sub list animates nicely when
   * collapsed/expanded by the native <details> toggle. */
  display: block;
}

.hv-sidebar__item--group {
  list-style: none;
  cursor: pointer;
  /* Push the caret to the far right of the row. */
  justify-content: flex-start;
}

.hv-sidebar__item--group::-webkit-details-marker {
  display: none;
}

.hv-sidebar__caret {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--haven-fg-muted);
  transition: transform 0.16s ease, color 0.14s ease;
  flex-shrink: 0;
}

.hv-sidebar__item--group:hover .hv-sidebar__caret,
.hv-sidebar__item--group.is-active .hv-sidebar__caret {
  color: inherit;
}

.hv-sidebar__group[open] > .hv-sidebar__item--group .hv-sidebar__caret {
  transform: rotate(90deg);
}

.hv-sidebar__sub {
  list-style: none;
  margin: 2px 0 4px 18px;
  padding: 2px 0 2px 12px;
  /* Subtle vertical guide line to associate children with their parent. */
  border-left: 1px solid var(--haven-border);
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* Belt + suspenders: Django's base.css gives stock <li> a disc marker, so
 * explicitly suppress it for each child here too. */
.hv-sidebar__sub li {
  list-style: none;
  margin: 0;
  padding: 0;
}

.hv-sidebar__sub li::marker {
  content: '';
}

.hv-sidebar__sub-item {
  display: block;
  padding: 6px 10px;
  border-radius: var(--haven-radius-md);
  color: var(--haven-fg-muted);
  text-decoration: none !important;
  /* Match the parent .hv-sidebar__item: same 13px / 500 / Acid Grotesk. */
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background 0.14s ease, color 0.14s ease;
}

.hv-sidebar__sub-item:hover {
  background: var(--haven-surface-2);
  color: var(--haven-fg);
}

.hv-sidebar__sub-item.is-active {
  background: var(--haven-fg);
  color: var(--haven-bg);
}

/* Collapsed sidebar: hide carets + nested lists, center the icon. The
 * native <details> may still open/close on click but with the sub list
 * hidden it's a visual no-op. */
[data-haven-sidebar='collapsed'] .hv-sidebar__caret,
[data-haven-sidebar='collapsed'] .hv-sidebar__sub {
  display: none;
}

[data-haven-sidebar='collapsed'] .hv-sidebar__item--group {
  justify-content: center;
}

.hv-sidebar__spacer {
  flex: 1;
}

.hv-sidebar__user {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border-radius: var(--haven-radius-lg);
  background: var(--haven-surface);
  border: 1px solid var(--haven-border);
}

[data-haven-sidebar='collapsed'] .hv-sidebar__user {
  flex-direction: column;
  padding: 8px 4px;
  background: transparent;
  border: none;
}

.hv-sidebar__user-meta {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}

.hv-sidebar__user-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--haven-fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hv-sidebar__user-role {
  font-size: 11px;
  color: var(--haven-fg-muted);
}

.hv-sidebar__logout {
  margin: 0;
  display: inline-flex;
}

.hv-sidebar__user-action {
  background: transparent;
  border: none;
  cursor: pointer;
  width: 28px;
  height: 28px;
  border-radius: var(--haven-radius-pill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--haven-fg-muted);
  padding: 0;
  transition: color 0.14s ease, background 0.14s ease;
}

.hv-sidebar__user-action:hover {
  background: var(--haven-bg-alt);
  color: var(--haven-fg);
}

/* Stock Django toggle-nav-sidebar button (renders inside our sidebar's
 * include chain in some flows) - we use our own collapse, so hide it. */
#toggle-nav-sidebar {
  display: none;
}

/* Main content column ---------------------------------------------------- */

.main > .content,
#content-start.content {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--haven-bg);
}

/* Topbar ----------------------------------------------------------------- */

.hv-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 32px;
  background: var(--haven-bg);
  border-bottom: 1px solid var(--haven-border);
}

.hv-topbar__search {
  flex: 1;
  display: flex;
  justify-content: center;
}

.hv-search {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  max-width: 520px;
  padding: 7px 14px;
  border-radius: var(--haven-radius-pill);
  background: var(--haven-bg-alt);
  border: 1px solid var(--haven-border);
  color: var(--haven-fg-muted);
}

.hv-search__icon {
  flex-shrink: 0;
  opacity: 0.7;
}

.hv-search__input {
  flex: 1;
  border: none;
  background: transparent;
  font-size: 13px;
  color: var(--haven-fg);
  outline: none;
  padding: 0;
  margin: 0;
}

.hv-search__input::placeholder {
  color: var(--haven-fg-muted);
}

.hv-search__hint {
  font-size: 11px;
  color: var(--haven-fg-faint);
  background: var(--haven-surface);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-sm);
  padding: 1px 6px;
  font-family: 'Inter', system-ui, sans-serif;
}

.hv-topbar__actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.hv-topbar__logout-form {
  margin: 0;
  display: inline-flex;
}

/* Topbar buttons live on a light topbar now (not the old dark header), so
 * recolor them accordingly. */
.hv-topbar .hv-topbar-button {
  background: var(--haven-bg);
  border: 1px solid var(--haven-border);
  color: var(--haven-fg);
  width: 36px;
  height: 36px;
  opacity: 0.8;
}

.hv-topbar .hv-topbar-button:hover,
.hv-topbar .hv-topbar-button:focus {
  background: var(--haven-bg-alt);
  opacity: 1;
}

/* Content area inside the column - this is Django admin's #content div, the
 * place where pages render their own content. */
#content {
  padding: 24px 32px 80px;
  background: var(--haven-bg);
  flex: 1;
}

/* The dashboard #content already widens itself; keep that override. Other
 * pages get a saner default. */
.dashboard #content {
  width: auto;
  max-width: 1320px;
  margin-right: 0;
  margin-left: 0;
  background: var(--haven-bg);
}

/* Suppress Django admin's `#content-main` float that comes with colMS so the
 * dashboard's grid takes the full main column. */
.dashboard #content-main {
  width: 100%;
  max-width: none;
  float: none;
}

/* Login page sits on a centered single column - hide the shell pieces that
 * leak in from base_site overrides. */
.login .hv-topbar,
.login .hv-sidebar,
.login #toggle-nav-sidebar {
  display: none !important;
}

.login #container,
.login .main {
  display: block;
}

.login #content {
  max-width: 420px;
  margin: 60px auto;
  background: var(--haven-surface);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-xl);
  padding: 32px;
}

/* Responsive: shrink padding on narrow viewports. The sidebar's collapsed
 * state is driven by the explicit toggle (data-haven-sidebar='collapsed')
 * so we don't try to force-collapse via @media here - the selectors would
 * have to match `#nav-sidebar.hv-sidebar`'s 110 specificity to overpower
 * the base rules, and silently desyncing visible width from visible labels
 * was confusing. */
@media (max-width: 720px) {
  .hv-topbar {
    padding: 10px 16px;
  }
  #content {
    padding: 16px;
  }
}

/* -------------------------------------------------------------------------
 * 11. Phase 1 polish - mockup-aligned dashboard details
 *
 * - Workspace selector as page title (button + chevron)
 * - KPI drill-in arrow + alert variant
 * - Inline meta with dot separators in task rows
 * - Dot-style due indicator (replaces SLA pill)
 * - Two-tier task counts (workspace name on top, unclaimed + my tasks below)
 * - Task row trailing chevron + revised grid template
 * ------------------------------------------------------------------------- */

/* Dashboard heading: workspace selector ----------------------------------- */

.hv-dashboard__header {
  margin: 0 0 18px 0;
}

.hv-workspace-select {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 4px 4px 0;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--haven-fg);
  font-family: 'Acid Grotesk', 'Inter', system-ui, sans-serif;
  font-weight: 500;
  font-size: 40px;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.hv-workspace-select:disabled {
  cursor: default;
}

/* Single-workspace viewers see a plain heading, no chevron or hover. */
.hv-workspace-select--static {
  cursor: default;
  margin: 0;
}

.hv-workspace-select__label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hv-workspace-select__chev {
  display: inline-flex;
  color: var(--haven-fg-muted);
  margin-top: 4px;
  transition: transform 0.15s ease, color 0.15s ease;
}

.hv-workspace-select:not(:disabled):hover .hv-workspace-select__chev {
  color: var(--haven-fg);
}

.hv-workspace-select[aria-expanded="true"] .hv-workspace-select__chev {
  transform: rotate(180deg);
  color: var(--haven-fg);
}

/* Dropdown menu (multi-workspace viewers) ----------------------------- */

.hv-workspace-select-wrap {
  position: relative;
  display: inline-block;
}

.hv-workspace-select__menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 260px;
  max-width: 360px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--haven-surface);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-md);
  box-shadow: var(--haven-shadow);
  z-index: 50;
}

.hv-workspace-select__menu li {
  list-style: none;
}

.hv-workspace-select__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 10px;
  border-radius: 8px;
  font-family: 'Acid Grotesk', 'Inter', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: var(--haven-fg);
  text-decoration: none !important;
  cursor: pointer;
}

.hv-workspace-select__option:hover {
  background: var(--haven-surface-2);
  color: var(--haven-fg);
}

.hv-workspace-select__option.is-selected {
  background: var(--haven-surface-2);
}

.hv-workspace-select__option-label {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hv-workspace-select__option-check {
  display: inline-flex;
  flex: 0 0 auto;
  color: var(--haven-volt);
  visibility: hidden;
}

.hv-workspace-select__option.is-selected .hv-workspace-select__option-check {
  visibility: visible;
  color: var(--haven-fg);
}

/* Page-load feedback (used by workspace filter clicks) ---------------- */

.hv-page-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 100%;
  background: transparent;
  overflow: hidden;
  z-index: 9999;
  pointer-events: none;
}

.hv-page-progress::after {
  content: '';
  display: block;
  height: 100%;
  width: 40%;
  background: var(--haven-volt);
  border-radius: 0 2px 2px 0;
  animation: hv-page-progress-slide 1.1s ease-in-out infinite;
}

@keyframes hv-page-progress-slide {
  0%   { transform: translateX(-100%); }
  60%  { transform: translateX(180%); }
  100% { transform: translateX(260%); }
}

.hv-is-loading {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity 0.12s ease;
  cursor: progress;
}

/* Past-SLA KPI: number is red when non-zero. Background/hover stay neutral
 * so the tile reads as a stat, not a clickable alert. */
.hv-kpi--alert .hv-kpi__value {
  color: var(--haven-status-red-fg);
}

/* Inline task-row meta with dot separators ------------------------------- */

.hv-task-row__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
  font-size: 12px;
  color: var(--haven-fg-muted);
  overflow: hidden;
  white-space: nowrap;
  margin-top: 2px;
}

.hv-task-row__meta-item {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.hv-task-row__meta-item + .hv-task-row__meta-item::before {
  content: '';
  display: inline-block;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--haven-fg-faint);
  margin: 0 8px 0 0;
}

/* Task row layout: avatar + main + chip + due + chev -------------------- */

.hv-task-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 12px 14px;
  padding: 12px 14px;
  background: var(--haven-bg);
  border: 1px solid var(--haven-border);
  border-radius: var(--haven-radius-lg);
  text-decoration: none !important;
  color: var(--haven-fg);
  transition: background 0.14s ease, border-color 0.14s ease;
  position: relative;
  /* Required so the .hv-task-row--past-due::before stripe is clipped to
   * the rounded corners. Repeated here on the authoritative definition so
   * the dependency is explicit rather than inherited from the earlier
   * .hv-task-row block via the cascade. */
  overflow: hidden;
}

.hv-task-row__chev {
  color: var(--haven-fg-faint);
  display: inline-flex;
  transition: color 0.14s ease, transform 0.14s ease;
}

.hv-task-row:hover .hv-task-row__chev {
  color: var(--haven-fg-muted);
  transform: translateX(2px);
}

/* Due indicator: colored dot + label ------------------------------------- */

.hv-due {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 500;
  color: var(--haven-fg-muted);
  white-space: nowrap;
}

.hv-due__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
  display: inline-block;
}

.hv-due--ok {
  color: var(--haven-status-green-fg);
}

.hv-due--past {
  color: var(--haven-status-red-fg);
  font-weight: 600;
}

.hv-due--due {
  color: var(--haven-status-amber-fg);
}

/* Two-tier task counts in aside card ------------------------------------ */

.hv-aside-card__row--stack {
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}

.hv-aside-card__row--stack .hv-aside-card__row-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--haven-fg);
}

.hv-aside-card__row-detail {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--haven-fg-muted);
}

.hv-aside-card__row-detail strong {
  color: var(--haven-fg);
  font-weight: 600;
}

.hv-aside-card__row-sub {
  color: var(--haven-fg-faint);
  position: relative;
  padding-left: 10px;
}

.hv-aside-card__row-sub::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--haven-fg-faint);
  transform: translateY(-50%);
}

/* Structured "Expected logic" summary ----------------------------------- */
/* The .conditional-logic-summary wrapper (background, left accent, padding)
 * is styled per-surface in task_actions_page.html / add_blocker.html. These
 * rules style the structured OR/AND tree rendered by _logic_summary.html and
 * are shared by both surfaces. Token-only so dark mode is automatic. */

.conditional-logic-summary__label {
  margin: 0 0 6px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.conditional-logic-summary__help {
  position: relative;
  display: inline-flex;
  cursor: help;
  outline: none;
}

.conditional-logic-summary__help-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid var(--haven-border);
  color: var(--haven-fg-muted);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
}

.conditional-logic-summary__help:hover .conditional-logic-summary__help-icon,
.conditional-logic-summary__help:focus .conditional-logic-summary__help-icon {
  border-color: var(--haven-volt);
  color: var(--haven-fg);
}

/* On-demand help explaining the section. Token-driven (high contrast in
 * both themes); shown on hover and keyboard focus. */
.conditional-logic-summary__help-tip {
  position: absolute;
  left: 0;
  top: calc(100% + 6px);
  z-index: 30;
  display: none;
  width: max-content;
  max-width: 360px;
  padding: 7px 9px;
  border-radius: var(--haven-radius-sm);
  background: var(--haven-fg);
  color: var(--haven-bg);
  font-size: 11px;
  font-weight: 400;
  line-height: 1.4;
  white-space: normal;
  overflow-wrap: anywhere;
  box-shadow: var(--haven-popover-shadow);
}

.conditional-logic-summary__help:hover .conditional-logic-summary__help-tip,
.conditional-logic-summary__help:focus .conditional-logic-summary__help-tip,
.conditional-logic-summary__help:focus-within .conditional-logic-summary__help-tip {
  display: block;
}

.conditional-logic-summary__single {
  margin: 0;
  overflow-wrap: anywhere;
}

.conditional-logic-summary__groups,
.conditional-logic-summary__criteria {
  list-style: none;
  margin: 0;
  padding: 0;
}

.conditional-logic-summary__group + .conditional-logic-summary__group {
  margin-top: 6px;
}

.conditional-logic-summary__join {
  display: block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--haven-fg-muted);
  margin-bottom: 2px;
}

.conditional-logic-summary__group > .conditional-logic-summary__criteria {
  padding-left: 14px;
}

.conditional-logic-summary__criterion {
  position: relative;
  overflow-wrap: anywhere;
}

.conditional-logic-summary__group > .conditional-logic-summary__criteria > .conditional-logic-summary__criterion::before {
  content: '•';
  position: absolute;
  left: -12px;
  color: var(--haven-fg-faint);
}

.conditional-logic-summary__and {
  font-size: 11px;
  font-weight: 700;
  color: var(--haven-fg-muted);
  margin-right: 2px;
}

.conditional-logic-summary__related {
  color: var(--haven-fg-muted);
}

.conditional-logic-summary__op {
  color: var(--haven-fg-muted);
}

.conditional-logic-summary__value {
  font-weight: 600;
}
