/* minicrm-specific compositions and theme. Reusable controls remain owned by KD UI. */

.crm-login-heading {
  text-wrap: balance;
}

.crm-login-shell {
  min-height: 100vh;
  min-height: 100dvh;
}

/* Desktop story column. Spacing is written here because these utilities are not in the precompiled output.css. */
.crm-login-story { max-width: 36rem; }
.crm-login-headline {
  max-width: 20ch;
  font-size: clamp(2rem, 1.2rem + 1.6vw, 2.75rem);
  line-height: 1.1;
}
.crm-login-lede {
  max-width: 34rem;
  margin-top: 1.25rem;
  font-size: 1rem;
  line-height: 1.75;
}

.crm-login-workflow {
  display: grid;
  gap: 1.5rem;
  margin-top: 2.5rem;
}

.crm-login-step {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  align-items: start;
  gap: 1rem;
}

/* Form column. dvh keeps the panel inside the visible viewport when a mobile address bar collapses. */
.crm-login-panel {
  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
  align-items: center;
  justify-content: center;
  padding: max(2rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(2rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));
}
.crm-login-form-wrap { width: 100%; max-width: 24rem; }
.crm-login-mobile-brand {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  width: fit-content;
  margin-bottom: 2rem;
  border-radius: var(--radius-sm, 0.375rem);
}
.crm-login-header { margin-bottom: 1.5rem; }
.crm-login-header .crm-login-heading { font-size: 1.75rem; line-height: 1.2; }
.crm-login-header p { margin-top: 0.5rem; line-height: 1.5; }

/* Secondary link: a 44px tap target, underlined so it does not rely on colour alone. */
.crm-login-back { margin-top: 0.75rem; text-align: center; }
.crm-login-back a {
  display: inline-flex;
  min-height: 2.75rem;
  align-items: center;
  padding-inline: 0.5rem;
  border-radius: var(--radius-sm, 0.375rem);
  text-decoration: underline;
  text-decoration-color: color-mix(in oklch, currentColor 35%, transparent);
  text-underline-offset: 0.25em;
  transition: color 150ms ease-out, text-decoration-color 150ms ease-out;
}
.crm-login-back a:hover { color: var(--foreground); text-decoration-color: currentColor; }
/* Below the desktop split the whole column shares one left edge, so the link's text lines up with the heading and the card.
   The negative margin cancels the link's own padding while keeping its full tap target. */
@media (max-width: 63.99rem) {
  .crm-login-back { text-align: left; }
  .crm-login-back a { margin-inline-start: -0.5rem; }
}
.crm-login-back a:focus-visible,
.crm-login-mobile-brand:focus-visible,
.crm-login-brand:focus-visible {
  outline: 2px solid var(--foreground);
  outline-offset: 2px;
}

@media (min-width: 40rem) {
  .crm-login-panel { padding-inline: 2rem; }
  .crm-login-header .crm-login-heading { font-size: 1.875rem; }
}

@media (max-width: 30rem) {
  .crm-login-mobile-brand { margin-bottom: 1.5rem; }
  .crm-login-header { margin-bottom: 1.25rem; }
}

/* Phones: start at the top instead of floating in the vertical middle. A centred form leaves a large empty gap above the logo,
   and the form would jump when the keyboard opens and the viewport shrinks. */
@media (max-width: 39.99rem) {
  .crm-login-panel {
    align-items: flex-start;
    padding-top: max(2.5rem, env(safe-area-inset-top));
  }
  /* Phones use one centre axis: the logo lockup, heading, subtitle and return link. The card is full width. */
  .crm-login-mobile-brand { margin-inline: auto; }
  .crm-login-header { text-align: center; }
  .crm-login-back { text-align: center; }
  .crm-login-back a { margin-inline-start: 0; }
}

/* Phone landscape: too short for one column (the button would sit under the fold, and under the keyboard),
   so the intro and the form sit side by side. */
@media (min-width: 40rem) and (max-width: 63.99rem) and (max-height: 34rem) {
  .crm-login-panel { padding-block: max(1rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-bottom)); }
  .crm-login-form-wrap {
    display: grid;
    max-width: 46rem;
    grid-template-columns: minmax(0, 1fr) minmax(0, 22rem);
    align-items: center;
    gap: 2.5rem;
  }
  .crm-login-mobile-brand { margin-bottom: 1rem; }
  .crm-login-header { margin-bottom: 0; }
}

@media (min-width: 64rem) {
  .crm-login-shell {
    display: grid;
    grid-template-columns: minmax(0, 1.08fr) minmax(26rem, 0.92fr);
  }

  .crm-login-context {
    display: flex;
    min-height: 100vh;
    min-height: 100dvh;
    flex-direction: column;
    justify-content: space-between;
    padding: 3rem;
  }

  .crm-login-mobile-brand {
    display: none;
  }
}


/* Logo lockup (bars + "minicrm" wordmark). One image per theme: the black-text artwork for light,
   the white-text artwork for dark. The swap follows the app's own theme class (html.dark, set by the theme
   switcher), not the operating system, so the two always agree. Only the height is set: the artwork keeps its proportions. */
.crm-logo { height: 1.75rem; width: auto; flex: none; }
.crm-logo--sm { height: 1.225rem; }
.crm-logo--md { height: 1.5rem; }
.crm-logo--lg { height: 1.6875rem; }
.crm-logo--dark { display: none; }
.dark .crm-logo--light { display: none; }
.dark .crm-logo--dark { display: block; }
.crm-login-brand { display: flex; flex-direction: column; align-items: flex-start; gap: 0.25rem; width: fit-content; }
/* Logo + tagline lockups. --crm-logo-h is the logo height; the tagline starts 0.965 logo-heights in from the left edge
   of the artwork, which is where the "m" of the wordmark starts. */
.crm-login-brand { --crm-logo-h: 1.6875rem; }
.crm-login-mobile-brand { --crm-logo-h: 1.5rem; }
.crm-brand { --crm-logo-h: 1.3125rem; }
.crm-login-brand small,
.crm-login-mobile-brand small,
.crm-brand-tagline { margin-left: calc(var(--crm-logo-h) * 0.965); }

/* Shared CRM record-detail pattern: fields left, actions and activity right. */
.crm-record-grid {
  display: grid;
  align-items: start;
  gap: 1.5rem;
}
@media (min-width: 1024px) {
  .crm-record-grid { grid-template-columns: minmax(0, 1fr) 22rem; }
  .crm-record-grid > aside { position: sticky; top: 2rem; }
}

#main-content { overflow-x: clip; }

.crm-skip-link {
  position: fixed;
  z-index: 100;
  left: 1rem;
  top: 1rem;
  transform: translateY(-200%);
  border-radius: var(--radius-md);
  background: var(--primary);
  color: var(--primary-foreground);
  padding: 0.625rem 0.875rem;
}
.crm-skip-link:focus-visible { transform: translateY(0); }

/* Dashboard: KPIs, then the activity heatmap, then the work lists. */
.crm-dashboard { display: grid; gap: 1.5rem; grid-template-columns: minmax(0, 1fr); }
.crm-dashboard > * { min-width: 0; }
.crm-kpis-desktop {
  display: none;
  grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
  gap: 0.75rem;
}
.crm-kpis-mobile { display: flex; }
.crm-dashboard-lower { display: grid; gap: 1.5rem; grid-template-columns: minmax(0, 1fr); align-items: start; }
.crm-dashboard-lower > * { min-width: 0; }
.crm-dashboard-flush { padding-inline: 0; }
.crm-dashboard-group {
  margin: 0;
  padding: 0.5rem 1.5rem;
  border-block: 1px solid var(--border);
  background: color-mix(in oklab, var(--muted) 40%, transparent);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--muted-foreground);
}
.crm-dashboard-flush .item { padding-inline: 1.5rem; }
.crm-dashboard-flush .item h3 a,
.crm-dashboard-flush .item p a { text-decoration: none; }
.crm-dashboard-flush .item h3 a:hover,
.crm-dashboard-flush .item p a:hover { text-decoration: underline; }
.crm-dashboard-flush .item aside form { display: inline; }
.crm-dashboard-flush .empty { padding-inline: 1.5rem; }

@media (min-width: 40rem) {
  .crm-kpis-desktop { display: grid; }
  .crm-kpis-mobile { display: none; }
}
@media (min-width: 64rem) {
  .crm-dashboard-lower { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); }
}

@media (max-width: 639.98px) {
  /* Give the task text the full row; buttons drop underneath. */
  .crm-dashboard-task { flex-wrap: wrap; }
  .crm-dashboard-task > section { flex-basis: 100%; }
  .crm-dashboard-task > aside { flex-basis: 100%; }
}


/* Messages list (blocks/templates_list.html): the full message body always clamped to three lines
   (the browser's own ellipsis, no fade) - reading the whole thing happens in Edit, not here. */
.crm-message-preview { display: flex; flex-direction: column; gap: 0.5rem; }
.crm-message-box { background: var(--muted); border-radius: var(--radius-md); padding: 0.75rem 0.875rem; }
.crm-message-box p { margin: 0; font-size: 0.8125rem; line-height: 1.55; color: var(--muted-foreground); overflow-wrap: anywhere; display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 3; }

/* The category as a small colour dot next to the title - same meaning, same palette as a contact tag
   or a message's own pill (app/tag_colors.py), just quieter: a marker to scan by, not another pill. */
.crm-message-dot { display: inline-block; width: 0.5rem; height: 0.5rem; margin-right: 0.5rem; border-radius: 50%; vertical-align: middle; flex-shrink: 0; }
.crm-message-dot[data-variant="orange"] { background: #f3840f; }
.crm-message-dot[data-variant="pink"] { background: #e31a5a; }
.crm-message-dot[data-variant="plum"] { background: #9f1574; }
.crm-message-dot[data-variant="violet"] { background: #5a2692; }
.crm-message-dot[data-variant="blue"] { background: #143495; }
.crm-message-dot[data-variant="green"] { background: #00704a; }

.crm-message-meta { margin: 0; font-size: 0.8125rem; color: var(--muted-foreground); }

/* Message template editor (blocks/template_form.html): fields and a live preview. Side by side on
   a wide screen (the same 64rem hinge as the contact/lead profile rail); behind an Edit/Preview tab
   on a narrow one, since there's no room for both columns at once.
   Named "-split" so it never collides with .crm-message-editor, the unrelated lead-message form. */
.crm-message-editor-split { display: grid; gap: 1.25rem; grid-template-columns: minmax(0, 1fr); }
.crm-message-editor-tabs { display: flex; gap: 2px; padding: 3px; background: var(--muted); border-radius: 0.625rem; }
.crm-message-editor-tabs button { flex: 1; padding: 0.4375rem 0; border: 0; border-radius: 0.5rem; background: none; font: inherit; font-size: 0.8125rem; font-weight: 500; color: var(--muted-foreground); cursor: pointer; }
.crm-message-editor-tabs button.is-active { background: var(--card); color: var(--foreground); font-weight: 600; box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.06); }
.crm-message-editor-col { display: grid; gap: 1.25rem; grid-template-columns: minmax(0, 1fr); align-content: start; }
.crm-message-editor-row { display: flex; gap: 1rem; }
.crm-message-editor-row > .field:first-child { flex: 1.6; min-width: 0; }
.crm-message-editor-row > .field:last-child { flex: 1; min-width: 0; }
.crm-message-preview-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.crm-message-preview-label { font-size: 0.8125rem; font-weight: 600; color: var(--foreground); }
.crm-message-preview-name { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8125rem; color: var(--muted-foreground); }
.crm-message-preview-name .input { width: 7rem; padding: 0.25rem 0.5rem; font-size: 0.8125rem; }
.crm-message-preview-box { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-xl); padding: 1.25rem; min-height: 12rem; }
.crm-message-preview-box .crm-message { font-size: 0.84375rem; }
.crm-message-preview-box mark { background: var(--crm-mark); color: var(--foreground); border-radius: 0.2em; padding-inline: 0.25em; }
.crm-message-preview-hint { margin: 0; font-size: 0.75rem; color: var(--muted-foreground); }
@media (max-width: 63.99rem) {
  [data-editor-panel="preview"] { display: none; }
  [data-message-editor][data-active-panel="preview"] [data-editor-panel="edit"] { display: none; }
  [data-message-editor][data-active-panel="preview"] [data-editor-panel="preview"] { display: grid; }
}
@media (min-width: 64rem) {
  .crm-message-editor-tabs { display: none; }
  .crm-message-editor-split { grid-template-columns: minmax(0, 1fr) minmax(20rem, 26rem); align-items: start; }
  .crm-message-editor-preview { position: sticky; top: 4.5rem; }
}

/* Log activity (blocks/interaction_form.html): Kind and Direction as one-tap pickers instead of
   dropdowns - this form is filled in several times a day, so a plain select costs two clicks for
   what's really a quick pick from a handful of options. */
.crm-kind-picker { display: flex; flex-direction: row; flex-wrap: wrap; gap: 0.375rem; }
.crm-kind-pill { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; flex: 1 1 4.5rem; min-width: 4.5rem; padding: 0.5rem 0.25rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--card); font: inherit; font-size: 0.71875rem; font-weight: 500; color: var(--muted-foreground); cursor: pointer; }
.crm-kind-pill:hover { background: var(--muted); }
.crm-kind-pill.is-active { background: var(--foreground); border-color: var(--foreground); color: var(--background); }
.crm-seg { display: inline-flex; flex-direction: row; background: var(--muted); border-radius: var(--radius-md); padding: 3px; width: 100%; max-width: 16rem; }
.crm-seg-btn { flex: 1; text-align: center; padding: 0.4375rem 0; border: 0; border-radius: calc(var(--radius-md) - 3px); background: none; font: inherit; font-size: 0.8125rem; font-weight: 500; color: var(--muted-foreground); cursor: pointer; }
.crm-seg-btn.is-active { background: var(--card); color: var(--foreground); font-weight: 600; box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.06); }
.crm-duration { display: flex; flex-direction: row; align-items: center; gap: 0.5rem; }
.crm-duration .input { flex: 1 1 5rem; min-width: 0; text-align: center; }
.crm-duration-chips { display: flex; flex-direction: row; gap: 0.375rem; }
.crm-chip { padding: 0.375rem 0.625rem; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--card); font: inherit; font-size: 0.75rem; font-weight: 500; color: var(--muted-foreground); cursor: pointer; }
.crm-chip:hover { background: var(--muted); }
.crm-chip.is-active { background: var(--foreground); border-color: var(--foreground); color: var(--background); font-weight: 600; }

/* Add/edit contact (blocks/contact_form.html): section legends read as small tracked eyebrows -
   clearly a level above a field label, not the same weight - scoped to this form since fieldset()
   is shared and other forms may want the plain KD UI legend style. The name row grows a live
   avatar tile and Tags grows a live pill preview (block scripts in the template). */
#contact-form .fieldset > legend { font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted-foreground); }
.crm-identity-row { display: flex; flex-direction: row; gap: 0.875rem; align-items: flex-start; }
.crm-identity-row > .kdui-avatar-initials { flex-shrink: 0; margin-top: 1.625rem; }
.crm-identity-row > .grid { flex: 1 1 auto; min-width: 0; }
.crm-tags-preview { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.625rem; }
.crm-tags-preview:empty { display: none; }

@media (pointer: coarse) {
  a, button, summary, [role="button"] { min-height: 44px; }
  button[data-size^="icon"], .btn[data-size^="icon"] { min-width: 44px; min-height: 44px; }
  html { touch-action: manipulation; -webkit-tap-highlight-color: color-mix(in oklab, var(--primary) 18%, transparent); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
}

/* App frame: sticky header (menu button while the sidebar is hidden, then the search, both on the left) above the page content. */
.crm-topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  height: 3.5rem;
  /* Same edges as .crm-content-inner (80rem max, centred). */
  padding-inline: max(1rem, calc((100% - 80rem) / 2));
}
.crm-topbar-search { min-width: 0; flex: 1 1 auto; max-width: 32rem; }
/* The show-menu button only exists while the sidebar is hidden; the hide button lives in the sidebar header. */
.crm-menu-toggle { display: none; flex: none; }
.sidebar[aria-hidden="true"] ~ .crm-main .crm-menu-toggle { display: inline-flex; }
.crm-section-title { margin: 0 0 1rem; font-size: 1.125rem; font-weight: 600; line-height: 1.75rem; letter-spacing: -0.01em; }
/* Contact page: a profile column and the timeline as the main area, at a readable width. One column on a phone. */
.crm-profile-page { max-width: 68rem; }
.crm-profile { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.75rem; align-items: start; margin-top: 1.25rem; }
.crm-profile-rail { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.25rem; min-width: 0; }
.crm-profile-main { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.75rem; min-width: 0; }
/* The person's card (crm/contact_card.html), shared by the contact page and the lead page.
   One left edge: tile, text column, actions, rows, then quiet meta. The look comes from the tokens, so dark mode follows. */
.crm-card { position: relative; display: grid; gap: 1rem; padding: 1.25rem; background: var(--card); color: var(--card-foreground, var(--foreground)); border: 1px solid var(--border); border-radius: var(--radius-xl); box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); }
.crm-card-menu { position: absolute; top: 0.75rem; right: 0.75rem; }
/* Identity (tile + name/role/company) always owns the card's full width, so a long name wraps
   instead of crowding the action button; `primary` gets its own row underneath, right-aligned,
   so the card keeps one fixed shape no matter how long the name is. */
.crm-card-id { display: grid; grid-template-columns: 3.5rem minmax(0, 1fr); column-gap: 0.875rem; align-items: start; padding-right: 1.875rem; }
/* The primary action is the last thing on the card, not squeezed against the name or buried under a
   "Managed by" line a small team doesn't need to see (who owns the record stays in the database). */
.crm-card-action { display: flex; justify-content: flex-end; padding-top: 0.75rem; border-top: 1px solid var(--border); }
.crm-card-tile { position: relative; width: 3.5rem; height: 3.5rem; border-radius: var(--radius-xl); overflow: hidden; }
.crm-card-tile .kdui-avatar-initials { width: 100%; height: 100%; border-radius: inherit; font-size: 1.125rem; }
.crm-card-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* A logo or favicon is shown at its real size on a white tile, never stretched to fill it. */
.crm-card-logo { position: absolute; inset: 0; display: grid; place-items: center; background: #fff; border: 1px solid var(--border); border-radius: inherit; }
.crm-card-logo img { display: block; width: 2rem; height: 2rem; object-fit: contain; }
.crm-card-who { min-width: 0; display: grid; gap: 1px; }
.crm-card-name { margin: 0; font-size: 1.25rem; line-height: 1.625rem; font-weight: 600; letter-spacing: -0.02em; overflow-wrap: anywhere; }
.crm-card-role, .crm-card-company { margin: 0; font-size: 0.8125rem; line-height: 1.125rem; }
.crm-card-role { color: var(--muted-foreground); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.crm-card-company { font-weight: 500; }
.crm-card-badge { margin-top: 0.375rem; justify-self: start; }
.crm-card-rows { margin: 0; padding: 0.625rem 0 0; list-style: none; display: grid; gap: 2px; border-top: 1px solid var(--border); }
.crm-card-row { display: grid; grid-template-columns: 1rem minmax(0, 1fr) auto; align-items: center; gap: 0.75rem; min-height: 2.125rem; margin-inline: -0.5rem; padding-inline: 0.5rem; border-radius: var(--radius-md); font-size: 0.84375rem; color: var(--foreground); text-decoration: none; }
a.crm-card-row:hover { background: var(--muted); }
.crm-card-row > svg { color: var(--muted-foreground); }
.crm-card-row > span:not(.crm-card-external) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-card-row.is-muted { color: var(--muted-foreground); }
.crm-card-row.is-strong { font-weight: 500; }
.crm-card-external { display: inline-flex; color: var(--muted-foreground); }
.crm-card-external svg { width: 0.875rem; height: 0.875rem; }
.crm-card-tags { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-top: -0.25rem; }
.crm-card-facts { margin: 0; display: grid; grid-template-columns: 5.25rem minmax(0, 1fr); gap: 0.5rem 0.75rem; padding-top: 0.875rem; border-top: 1px solid var(--border); font-size: 0.8125rem; }
.crm-card-facts dt { color: var(--muted-foreground); }
.crm-card-facts dd { margin: 0; min-width: 0; }
.crm-card-facts a { color: var(--foreground); text-underline-offset: 3px; }
.crm-card-note { padding-top: 0.875rem; border-top: 1px solid var(--border); }
.crm-card-note p { margin: 0; font-size: 0.8125rem; line-height: 1.55; color: var(--muted-foreground); white-space: pre-wrap; overflow-wrap: anywhere; }
.crm-card-note.is-clamped p { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.crm-card-more { margin-top: 0.25rem; padding: 0; border: 0; background: none; color: var(--foreground); font: inherit; font-size: 0.78125rem; font-weight: 500; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
/* On touch screens a link is at least 44px tall; centre its text so it lines up with the row's icon. */
.crm-profile .item section a { display: flex; align-items: center; }
.crm-note-form { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.25rem; }
.crm-note-form .input { flex: 1; min-width: 12rem; }
/* A small "change this and save" form inline with a heading, e.g. the lead's channel while it is still unsent. */
.crm-inline-form { display: flex; align-items: center; gap: 0.5rem; }
/* KD UI item rows already sit inside a padded card or column here: align them with the headings and keep them compact. */
.crm-profile .item:not([data-variant]) { padding: 0.25rem 0; }
.crm-profile .item[data-variant="outline"] { padding: 0.625rem 0.875rem; }
.crm-back { margin-bottom: 1.25rem; }
.crm-prose { max-width: 48rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.crm-message { font-size: 0.875rem; line-height: 1.75; white-space: pre-wrap; overflow-wrap: anywhere; }
.crm-stack > * + * { margin-top: 1rem; }
.crm-wrap { overflow-wrap: anywhere; }
.crm-people { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; }
.crm-people a { display: inline-flex; align-items: center; gap: 0.5rem; }
.crm-feed-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem; margin-bottom: 1.25rem; }
.crm-feed-head .crm-section-title { margin: 0; }
.crm-feed-more { margin-top: 0.5rem; }
.crm-feed-head .kdui-filter-tabs { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
@media (min-width: 64rem) {
  .crm-profile { grid-template-columns: 22rem minmax(0, 1fr); gap: 3rem; }
  .crm-profile-rail { position: sticky; top: 4.5rem; }
}
.crm-content { padding: 1rem 1rem 2.5rem; }
.crm-content-inner { width: 100%; max-width: 80rem; margin-inline: auto; }
/* Sidebar footer: avatar + first name, then theme and sign-out icons. */
.crm-sidebar-user { display: flex; align-items: center; gap: 0.25rem; padding: 0.25rem 0.5rem; }
.crm-sidebar-user-who { display: flex; flex: 1; align-items: center; gap: 0.5rem; min-width: 0; }
.crm-sidebar-user-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.875rem; font-weight: 500; }
.crm-sidebar-user form { display: contents; }
@media (min-width: 48rem) {
  .crm-topbar { padding-inline: max(2rem, calc((100% - 80rem) / 2)); }
  .crm-content { padding: 2rem 2rem 2.5rem; }
}

/* Pipeline strip above the leads board: the open pipeline total, and a bar showing where that money sits by
   stage. The bar's colours and order match the columns directly below it, so it needs no legend of its own. */
.crm-pipeline { margin-bottom: 1.5rem; }
.crm-pipeline-fig span { display: block; font-size: 0.75rem; color: var(--muted-foreground); }
.crm-pipeline-fig strong { font-size: var(--crm-text-2xl); font-weight: 650; line-height: 1.15; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }

/* Sales funnel: one row per step (name, bar, "N leads · $X"). */
.crm-funnel-total { margin: 0 0 1.25rem; font-size: var(--crm-text-2xl); font-weight: 700; line-height: 1.1; }
.crm-funnel-total span { font-size: 0.875rem; font-weight: 400; color: var(--muted-foreground); }
.crm-funnel { display: grid; gap: 0.875rem; }
.crm-funnel-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "label figures" "bar bar";
  align-items: center;
  gap: 0.375rem 1rem;
}
.crm-funnel-label { grid-area: label; font-size: 0.875rem; font-weight: 500; }
.crm-funnel-bar { grid-area: bar; min-width: 0; }
.crm-funnel-figures { grid-area: figures; font-size: 0.875rem; color: var(--muted-foreground); white-space: nowrap; }
@media (min-width: 40rem) {
  .crm-funnel-row {
    grid-template-columns: 10rem minmax(0, 1fr) 11rem;
    grid-template-areas: "label bar figures";
    gap: 1rem;
  }
  .crm-funnel-figures { text-align: right; }
}

/* Lead form: the message editor with its blank-notice and Copy button underneath. */

.crm-message-editor { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.5rem; }
.crm-message-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.crm-message-tools [hidden] { display: none; }
.crm-message-blanks { flex: 1 1 16rem; }
.crm-message-copy { margin-left: auto; }

/* Prepared messages: every [blank] still to fill in is painted yellow behind the text (see minicrm.js). The copy of the
   text sits exactly under the textarea, so only the colour shows through its transparent background. */
.crm-hilite { position: relative; }
.crm-hilite > textarea { position: relative; background: transparent; }
.crm-hilite__mirror {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  border-style: solid;
  border-color: transparent;
  color: transparent;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}
.crm-hilite__mirror mark { background: var(--crm-mark); color: transparent; border-radius: 0.2em; }
.crm-blank-hint { margin: 0 0 0.75rem; font-size: 0.875rem; color: var(--muted-foreground); }
.crm-blank-hint[hidden] { display: none; }
.crm-blank-hint mark { background: var(--crm-mark); color: var(--foreground); border-radius: 0.2em; padding-inline: 0.25em; }

/* Leads board: the amount and close date on a card open the "Amount and close date" dialog when clicked. Until they are
   filled in they read as a muted prompt. */
.crm-add { font-weight: 400; color: var(--muted-foreground); border-bottom: 1px dashed var(--border); }
.crm-add::before { content: "+ "; }
.kdui-kanban-card:has([data-edit-deal]) .kdui-kanban-card__foot { cursor: pointer; }
.kdui-kanban-card:has([data-edit-deal]) .kdui-kanban-card__foot:hover span { text-decoration: underline; text-underline-offset: 0.2em; }
/* The whole card is HTML5-draggable for mouse users; touch users already have "Move to …" in the card menu, so
   this just keeps a touch-drag attempt from fighting the page's own scroll. */
.kdui-kanban-card { touch-action: manipulation; }

/* An empty column is a dead end without something to look at. */
.crm-kanban-empty { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; color: var(--muted-foreground); }
.crm-kanban-empty svg { width: 1.5rem; height: 1.5rem; opacity: 0.6; }

/* Leads board: chevron funnel headers. Each open-stage column head is a solid arrow pointing at the
   next stage, so direction, colour and the stage name arrive together instead of as separate widgets
   (a thin border plus a value bar above the board — the two used to say the same thing twice). The lane
   underneath keeps a faint wash of the same colour so the funnel reads all the way down the column, not
   just across a 3px line. Won/Closed (the dock) are the funnel's endpoints, not links in the chain, so
   their heads stay flat capsules instead of arrows. */
.kdui-kanban__head {
  position: relative;
  margin: 0 0 0.75rem;
  padding: 0.5rem 1.25rem 0.5rem 0.875rem;
  border-top: 0;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: var(--kdui-kanban-color, var(--muted));
  clip-path: polygon(0 0, calc(100% - 0.625rem) 0, 100% 50%, calc(100% - 0.625rem) 100%, 0 100%);
}
.kdui-kanban__head h2 { color: #fff; }
.kdui-kanban__head .kdui-kanban__total { color: rgb(255 255 255 / 0.85); }
.kdui-kanban__head .kdui-kanban__count { background: rgb(255 255 255 / 0.28); color: #fff; }
.kdui-kanban__col--compact .kdui-kanban__head { clip-path: none; border-radius: var(--radius-lg); }
.kdui-kanban__lane { background: color-mix(in oklab, var(--kdui-kanban-color, var(--muted)) 7%, var(--card)); }

/* ==========================================================================
   Theme layer: one calm white canvas. Only KD UI design tokens and a few
   selectors are overridden here; no KD UI file is edited. To change the look
   for good, change these tokens (or change KD UI and re-sync).
   ========================================================================== */
:root {
  --crm-accent: oklch(0.47 0.19 277);
  --crm-stage-1: #f97316;
  --crm-stage-2: #ec4899;
  --crm-stage-3: #8b5cf6;
  --crm-stage-4: #3b82f6;
  --crm-stage-5: #16a34a;
  --crm-stage-6: #94a3b8;
  --crm-mark: #fef08a;
  /* KD UI's light-mode --muted-foreground (oklch(0.556 0 0)) is ~3.5:1 on a white card, under the 4.5:1 AA
     minimum for the dates, notes and hints that lean on it most. This keeps it visibly muted but readable
     (~6.7:1). Dark mode's --muted-foreground already clears AA and is left as KD UI ships it. */
  --muted-foreground: #5c5c5c;
  /* KD UI's own type tokens stop at --text-lg; this is minicrm's next step, for the two big headline
     numbers (pipeline total, sales-funnel total) so their size is a shared, deliberate value rather than
     two separate literals that happen to match. */
  --crm-text-2xl: 1.875rem;
}
.dark {
  --crm-accent: oklch(0.8 0.1 277);
  --crm-stage-1: #fb923c;
  --crm-stage-2: #f472b6;
  --crm-stage-3: #a78bfa;
  --crm-stage-4: #60a5fa;
  --crm-stage-5: #4ade80;
  --crm-stage-6: #64748b;
  --crm-mark: #854d0e;
}

/* Sidebar: KD UI's own colours and spacing, untouched. The header holds the logo with its tagline underneath, as a link to the dashboard. */
.crm-brand { display: flex; flex-direction: column; align-items: flex-start; gap: 0.25rem; padding: 0.375rem 0.5rem; border-radius: var(--radius-sm, 0.375rem); }
.crm-brand .crm-logo { height: var(--crm-logo-h); }
.crm-brand:focus-visible { outline: 2px solid var(--foreground); outline-offset: 2px; }
.crm-brand-tagline { font-weight: 400; line-height: 1.2; }

/* Page and header share the canvas. Cards, KPI cards and their radius, ring and shadow are KD UI's own; do not restyle them here. */
.crm-main { background: var(--background); }
.crm-topbar { border-bottom: 0; background: color-mix(in oklab, var(--background) 82%, transparent); backdrop-filter: blur(12px); }

/* Sales funnel: each step wears its own logo colour; the label always names it too. */
.crm-funnel-row .crm-funnel-label::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  margin-right: 0.625rem;
  border-radius: 9999px;
  background: var(--c);
}
.crm-funnel-row .progress > .crm-funnel-fill { background: var(--c); }

/* Avatars: KD UI's initials avatar with the photo laid on top when there is one. */
.crm-avatar { position: relative; display: inline-flex; }
.crm-avatar > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 9999px; }

/* User form: the photo card (a KD UI card) centres its content. */

.crm-section-gap { margin-bottom: 1.25rem; }

/* Data table rows with a `url` (see data_table.html): the avatar and name link to the row's own
   page, styled plain so they read the same as the div they replace, until hovered. */
a.kdui-table-user { color: inherit; text-decoration: none; }
a.kdui-table-user:hover .kdui-table-user__primary { text-decoration: underline; }
.kdui-table-mobile-card__link { display: flex; align-items: flex-start; gap: 0.75rem; flex: 1 1 auto; min-width: 0; color: inherit; text-decoration: none; }
.kdui-table-mobile-card__link:hover .kdui-table-mobile-card__primary { text-decoration: underline; }

/* Project header: a hero photo, with the title/description and the agent trigger beside it. */
.crm-project-hero { display: flex; align-items: flex-start; gap: 1.5rem; flex-wrap: wrap; }
.crm-project-hero__img { width: 6.5rem; height: 6.5rem; border-radius: var(--radius-lg); object-fit: cover; flex-shrink: 0; }
.crm-project-hero__img--fallback { display: flex; align-items: center; justify-content: center; background: var(--muted); }
.crm-project-hero__agent { flex-shrink: 0; align-self: center; }
.crm-project-meta { display: flex; flex-wrap: wrap; gap: 0.25rem 0.75rem; font-size: 0.875rem; color: var(--muted-foreground); margin-top: 0.5rem; }

/* Agent trigger (the robot avatar + name that opens the agent drawer). Configured agents borrow
   the same deterministic 8-colour palette avatar_initials() uses for people and projects, so the
   agent reads as a peer of those avatars rather than a one-off ornament; not-yet-configured uses
   a dashed "empty slot" treatment, the same visual grammar an invite-to-fill control uses elsewhere. */
.crm-agent-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  background: var(--background);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  cursor: pointer;
  padding: 0.375rem 0.875rem 0.375rem 0.375rem;
  transition: border-color 150ms ease, background-color 150ms ease;
}
.crm-agent-trigger:hover { border-color: var(--foreground); background: var(--muted); }
.crm-agent-robot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: calc(var(--radius-lg) - 0.25rem);
  flex-shrink: 0;
  border: 1.5px dashed var(--border);
  color: var(--muted-foreground);
}
.crm-agent-robot svg { width: 1.375rem; height: 1.375rem; }
.crm-agent-robot--on { border-style: solid; border-color: transparent; }
.crm-agent-trigger__name { font-size: 0.875rem; font-weight: 500; color: var(--foreground); }
.crm-agent-trigger:not(.crm-agent-trigger--on) .crm-agent-trigger__name { color: var(--muted-foreground); font-weight: 400; }

/* Agent drawer content. The macro's default footer is column-stacked (for a lone Close button);
   this drawer has two, laid out side by side like alert_dialog's footer. */
.drawer footer { flex-direction: row !important; justify-content: flex-end; }
.crm-agent-drawer-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }

.crm-agent-identity { display: flex; align-items: center; gap: 0.875rem; padding: 1rem; margin: 0 1rem; background: var(--muted); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.crm-agent-identity__avatar { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; width: 3.5rem; height: 3.5rem; border-radius: var(--radius-lg); }
.crm-agent-identity__avatar svg { width: 1.875rem; height: 1.875rem; }
.crm-agent-identity__field { min-width: 0; flex: 1; }
.crm-agent-identity__label { display: block; font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted-foreground); }
.crm-agent-identity__input { display: block; width: 100%; margin-top: 0.125rem; border: none; background: transparent; padding: 0.125rem 0 0.25rem; font-size: 1.1875rem; font-weight: 600; color: var(--foreground); font-family: inherit; }
.crm-agent-identity__input:focus { outline: none; }
input.crm-agent-identity__input { border-bottom: 1.5px solid transparent; }
input.crm-agent-identity__input:focus { border-bottom-color: var(--foreground); }

.crm-agent-rules { margin: 1.25rem 1rem 0; }
.crm-agent-rules__head { display: flex; align-items: center; justify-content: space-between; font-size: 0.8125rem; font-weight: 600; }
.crm-agent-rules__count { font-size: 0.6875rem; font-weight: 500; color: var(--muted-foreground); background: var(--muted); border-radius: 999px; padding: 0.125rem 0.5625rem; }
.crm-agent-rules__list { margin-top: 0.5rem; border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; }
.crm-agent-rule-row { position: relative; display: flex; align-items: center; gap: 0.625rem; padding: 0.625rem 0.75rem; cursor: pointer; }
.crm-agent-rule-row + .crm-agent-rule-row { border-top: 1px solid var(--border); }
.crm-agent-rule-row:hover { background: var(--muted); }
.crm-agent-rule-row--readonly { cursor: default; }
.crm-agent-rule-row input[type="checkbox"] { position: absolute; opacity: 0; width: 1px; height: 1px; }
.crm-agent-rule-row__box { flex-shrink: 0; width: 1.125rem; height: 1.125rem; border-radius: 0.3125rem; border: 1.5px solid var(--border); display: inline-flex; align-items: center; justify-content: center; }
.crm-agent-rule-row__box svg { opacity: 0; }
.crm-agent-rule-row input:checked ~ .crm-agent-rule-row__box { background: var(--foreground); border-color: var(--foreground); }
.crm-agent-rule-row input:checked ~ .crm-agent-rule-row__box svg { opacity: 1; }
.crm-agent-rule-row input:focus-visible ~ .crm-agent-rule-row__box { outline: 2px solid var(--ring, var(--foreground)); outline-offset: 1px; }
.crm-agent-rule-row__title { font-size: 0.84375rem; color: var(--foreground); }
.crm-agent-rule-row input:not(:checked) ~ .crm-agent-rule-row__title { color: var(--muted-foreground); }

.crm-agent-preview { margin: 1.5rem 1rem 0; }
.crm-agent-preview__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.5rem; font-size: 0.8125rem; font-weight: 600; }
.crm-agent-preview__note { margin: 0 0 0.625rem; font-size: 0.71875rem; font-style: italic; color: var(--muted-foreground); opacity: 0.8; }
.crm-agent-preview__body { background: var(--muted); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 1rem 1.125rem; max-width: none; }

/* Rendered markdown (notes, the AGENTS.md preview): normal flow, not crm-prose's pre-wrap. */
.crm-markdown { max-width: 48rem; overflow-wrap: anywhere; font-size: 0.875rem; line-height: 1.6; }
.crm-markdown > * + * { margin-top: 0.75rem; }
.crm-markdown ul, .crm-markdown ol { padding-left: 1.25rem; }
.crm-markdown code { background: var(--muted); border-radius: var(--radius-sm); padding: 0.125rem 0.375rem; font-size: 0.8125rem; }
.crm-markdown pre { background: var(--muted); border-radius: var(--radius-md); padding: 0.75rem 1rem; overflow-x: auto; }
.crm-markdown pre code { background: none; padding: 0; }

/* Notes: one big "stage" that shows either the new-note editor or whichever note was clicked in
   the index below, plus Edit/Delete for that note — never both an editor and a note at once.
   Panel switching is plain show/hide (see data-note-show in project-notes-editor.js); only the
   panel that's about to show gets its CodeMirror editor mounted, since CM lays out badly while
   display:none. */
.crm-note-view__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.crm-note-view__date { font-size: 0.75rem; color: var(--muted-foreground); }
.crm-note-view__new { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.8125rem; font-weight: 500; color: var(--muted-foreground); background: none; border: 0; padding: 0.25rem 0.4375rem; border-radius: var(--radius-sm); cursor: pointer; }
.crm-note-view__new:hover { background: var(--muted); color: var(--foreground); }
.crm-note-view__body { margin-top: 0.875rem; }
.crm-note-view__actions { display: flex; align-items: center; gap: 2px; padding-top: 0.875rem; margin-top: 0.875rem; border-top: 1px solid var(--border); }
.crm-note-action { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.8125rem; font-weight: 500; color: var(--muted-foreground); background: none; border: 0; padding: 0.375rem 0.5rem; border-radius: var(--radius-sm); cursor: pointer; }
.crm-note-action:hover { background: var(--muted); color: var(--foreground); }
.crm-note-action--danger { color: #b0433f; }
.crm-note-action--danger:hover { background: #fdeceb; }
.crm-note-divider { width: 1px; height: 0.875rem; background: var(--border); }

.crm-note-index { margin-top: 1.5rem; }
.crm-note-index__label { font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted-foreground); margin-bottom: 0.25rem; }
.crm-note-index__list { border-top: 1px solid var(--border); }
.crm-note-index-row { cursor: pointer; display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; padding: 0.5625rem 0.5rem; border-bottom: 1px solid var(--border); border-radius: var(--radius-sm); }
.crm-note-index-row:hover, .crm-note-index-row.is-active { background: var(--muted); }
.crm-note-index-row__title { font-size: 0.8125rem; font-weight: 500; color: var(--foreground); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-note-index-row.is-active .crm-note-index-row__title { font-weight: 600; }
.crm-note-index-row__date { font-size: 0.71875rem; color: var(--muted-foreground); flex-shrink: 0; }

/* Markdown cheat sheet popover (Notes card). */
.crm-md-cheatsheet { display: grid; gap: 0.5rem; margin-top: 0.5rem; }
.crm-md-cheatsheet > div { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; }
.crm-md-cheatsheet dt { font-family: monospace; font-size: 0.8125rem; background: var(--muted); border-radius: var(--radius-sm); padding: 0.125rem 0.375rem; flex-shrink: 0; }
.crm-md-cheatsheet dd { font-size: 0.8125rem; color: var(--muted-foreground); text-align: right; }

/* CodeMirror live-markdown editor mount point (see app/static/js/vendor/codemirror-bundle.js). */
.crm-note-editor { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--background); }
.crm-note-editor .cm-editor { border-radius: var(--radius-md); }
.crm-note-editor .cm-editor.cm-focused { outline: 2px solid var(--ring, var(--primary)); outline-offset: -1px; }

