:root {
  /* Surfaces — cool neutral */
  --paper: #f6f7f9; --paper-warm: #eef1f5; --paper-card: #ffffff;
  /* Text — slate scale */
  --ink: #0f172a; --ink-soft: #334155; --ink-muted: #64748b;
  /* Hairlines */
  --line: #e2e8f0; --line-soft: #eef2f6;
  /* Accent (indigo) — primary highlight / link / focus role */
  --brass: #4f46e5; --brass-dark: #4338ca; --brass-soft: #c7d2fe;
  /* Semantic hues */
  --sage: #16a34a; --rust: #dc2626; --plum: #7c3aed; --amber: #b45309;
  --surge: #ea580c; /* Surge Spaces brand orange */
  /* Elevation */
  --shadow-sm: 0 1px 2px rgba(15,23,42,0.04), 0 1px 3px rgba(15,23,42,0.05);
  --shadow-md: 0 6px 20px rgba(15,23,42,0.08);
  --shadow-lg: 0 16px 40px rgba(15,23,42,0.14);
}
html, body { background: var(--paper); color: var(--ink); font-family: 'Inter', system-ui, -apple-system, sans-serif; font-feature-settings: 'cv11'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; }
/* Kill iOS double-tap-to-zoom everywhere (a double-tap on the tab bar zoomed
   the whole app). `manipulation` keeps scrolling and pinch-zoom — this is not
   the user-scalable=no accessibility footgun. touch-action doesn't inherit,
   so this must be `*`; zero specificity lets .si-v-canvas's `none` still win. */
* { touch-action: manipulation; }
.font-display { font-family: 'Inter', system-ui, sans-serif; font-weight: 600; letter-spacing: -0.021em; }
.font-mono { font-family: 'JetBrains Mono', ui-monospace, monospace; }
.text-ink { color: var(--ink); } .text-ink-soft { color: var(--ink-soft); } .text-muted { color: var(--ink-muted); }
.bg-paper { background: var(--paper); } .bg-paper-warm { background: var(--paper-warm); } .bg-paper-card { background: var(--paper-card); }
.bg-ink { background: var(--ink); } .bg-brass { background: var(--brass); }
.text-brass { color: var(--brass); } .text-brass-dark { color: var(--brass-dark); }
.text-sage { color: var(--sage); } .text-rust { color: var(--rust); } .text-plum { color: var(--plum); } .text-amber { color: var(--amber); }
.text-surge { color: var(--surge); }
.border-line { border-color: var(--line); } .border-line-soft { border-color: var(--line-soft); }
.relative-content { position: relative; z-index: 1; }
.nav-item { display: flex; align-items: center; gap: 10px; padding: 7px 12px; border-radius: 6px; font-size: 13.5px; font-weight: 500; color: var(--ink-soft); cursor: pointer; transition: all 0.15s; letter-spacing: -0.005em; }
@media (hover: hover) { .nav-item:hover { background: var(--paper-warm); color: var(--ink); } }
.nav-item.active { background: rgba(79,70,229,0.09); color: var(--brass-dark); font-weight: 600; }
/* Indented child rows inside an expanded group in the property nav */
.nav-item-child { padding-left: 32px; font-size: 12.5px; color: var(--ink-muted); }
@media (hover: hover) { .nav-item-child:hover { color: var(--ink); } }
/* Subtle marker for a group whose currently-open building is among its children */
.nav-group-has-active { color: var(--ink); font-weight: 600; }
.nav-section-label { font-size: 10px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-muted); padding: 0 12px; margin-bottom: 6px; }
.card { background: var(--paper-card); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-sm); transition: all 0.2s; }
@media (hover: hover) { .card-hover:hover { border-color: var(--ink-soft); transform: translateY(-1px); box-shadow: 0 4px 16px rgba(15,23,42,0.06); } }
/* Group cards: stacked-paper visual hint behind the card, suggesting multiple buildings */
.card-group { position: relative; box-shadow: var(--shadow-md); }
@media (hover: hover) { .card-group.card-hover:hover { box-shadow: var(--shadow-lg); } }
.group-flyout { position: absolute; inset: 0; z-index: 30; background: var(--paper-card);
    display: none; flex-direction: column; }
.card-group.open .group-flyout { display: flex; animation: groupFlyoutIn 0.16s ease-out; }
.group-flyout-header { display: flex; align-items: center; justify-content: space-between;
    padding: 12px 16px; border-bottom: 1px solid var(--line-soft); }
.group-flyout-list { flex: 1; overflow-y: auto; }
.group-flyout-item { display: flex; align-items: center; gap: 10px; padding: 10px 16px;
    cursor: pointer; border-bottom: 1px solid var(--line-soft); }
@media (hover: hover) { .group-flyout-item:hover { background: var(--paper-warm); } }
.group-flyout-item:last-child { border-bottom: none; }
.group-flyout-thumb { width: 44px; height: 32px; background-size: cover; background-position: center;
    background-color: var(--paper-warm); border: 1px solid var(--line-soft); border-radius: 2px; flex-shrink: 0; }
@keyframes groupFlyoutIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
/* Summary row in the flyout — reads like a building row but tinted to stand apart. */
.group-flyout-summary { background: color-mix(in srgb, var(--brass) 6%, transparent); }
@media (hover: hover) { .group-flyout-summary:hover { background: color-mix(in srgb, var(--brass) 11%, transparent); } }
.group-flyout-summary-icon { width: 44px; height: 32px; display: flex; align-items: center; justify-content: center;
    color: var(--brass); background: color-mix(in srgb, var(--brass) 12%, var(--paper-card));
    border: 1px solid color-mix(in srgb, var(--brass) 25%, transparent); border-radius: 2px; flex-shrink: 0; }
/* Lifecycle tabs — split a group's buildings into Active / In Construction / Planned. */
.group-flyout-tabs { display: flex; gap: 2px; padding: 8px 12px 0; border-bottom: 1px solid var(--line-soft);
    overflow-x: auto; flex-shrink: 0; }
.group-flyout-tab { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; cursor: pointer;
    padding: 6px 11px; border: none; background: none; font-size: 12px; font-weight: 500; color: var(--ink-muted);
    border-bottom: 2px solid transparent; margin-bottom: -1px; }
@media (hover: hover) { .group-flyout-tab:hover { color: var(--ink); } }
.group-flyout-tab.active { color: var(--brass); border-bottom-color: var(--brass); }
.gf-tab-count { font-family: 'JetBrains Mono', monospace; font-size: 10px; padding: 1px 5px; border-radius: 999px;
    background: var(--paper-warm); color: var(--ink-muted); border: 1px solid var(--line-soft); }
.group-flyout-tab.active .gf-tab-count { background: color-mix(in srgb, var(--brass) 12%, var(--paper-card));
    color: var(--brass); border-color: color-mix(in srgb, var(--brass) 25%, transparent); }
/* Group settings — per-building rows with a lifecycle status dropdown. */
.group-mem-row { display: flex; align-items: center; gap: 8px; padding: 5px 6px; border-radius: 4px; }
@media (hover: hover) { .group-mem-row:hover { background: var(--paper-card); } }
.group-mem-check { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; cursor: pointer; margin: 0; }
.group-mem-info { min-width: 0; }
.group-mem-name { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.group-mem-addr { font-size: 11px; color: var(--ink-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.group-mem-status { flex-shrink: 0; max-width: 150px; font-size: 12px; padding: 4px 8px; border: 1px solid var(--line);
    border-radius: 4px; background: var(--paper-card); color: var(--ink); cursor: pointer; }
.group-mem-section-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-muted);
    font-weight: 600; margin: 2px 2px 4px; }
.group-mem-add-toggle { display: flex; align-items: center; gap: 6px; width: 100%; padding: 8px 6px; margin-top: 6px;
    background: none; border: none; border-top: 1px solid var(--line-soft); font-size: 12px; font-weight: 500;
    color: var(--ink); cursor: pointer; }
@media (hover: hover) { .group-mem-add-toggle:hover { color: var(--brass); } }
.group-mem-add-toggle i { transition: transform 0.15s ease; }
.group-mem-add-toggle.open i { transform: rotate(90deg); }
/* Group summary popup */
.gsum-totals { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; padding: 14px 16px;
    background: var(--paper-warm); border: 1px solid var(--line-soft); border-radius: 6px; margin-bottom: 16px; }
.gsum-tile { text-align: left; }
.gsum-buildings { display: flex; flex-direction: column; gap: 18px; }
.gsum-building { border: 1px solid var(--line); border-radius: 6px; overflow: hidden; background: var(--paper-card); }
.gsum-building-head { display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 10px 14px; cursor: pointer; background: var(--paper-warm); border-bottom: 1px solid var(--line-soft);
    transition: background 0.12s ease; }
@media (hover: hover) { .gsum-building-head:hover { background: color-mix(in srgb, var(--brass) 7%, var(--paper-warm)); } }
.gsum-table-wrap { overflow-x: auto; }
.gsum-table { margin: 0; }
/* On phones the per-building tenant table is swapped for the same card list
   used on the Units/Tenants tab (see the mobile media query below). */
.gsum-mobile { display: none; }
@media (max-width: 640px) {
  .gsum-totals { grid-template-columns: repeat(3, 1fr); }
}
.property-img { aspect-ratio: 4/3; background-size: cover; background-position: center; position: relative; overflow: hidden; background-color: var(--paper-warm); }
.property-img::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 50%, rgba(15,23,42,0.4)); }
.pill { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: 3px; font-size: 11px; font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase; }
.pill-dot { width: 6px; height: 6px; border-radius: 50%; }
.pill-occupied { background: rgba(22,163,74,0.12); color: var(--sage); } .pill-occupied .pill-dot { background: var(--sage); }
.pill-vacant { background: rgba(220,38,38,0.12); color: var(--rust); } .pill-vacant .pill-dot { background: var(--rust); }
.pill-notice { background: rgba(79,70,229,0.15); color: var(--brass-dark); } .pill-notice .pill-dot { background: var(--brass); }
/* Holdover = lease past its end date but still in place — amber, distinct from vacant's red */
.pill-holdover { background: rgba(180,83,9,0.12); color: var(--amber); } .pill-holdover .pill-dot { background: var(--amber); }
.pill-overdue { background: var(--rust); color: white; }
.pill-due-soon { background: rgba(79,70,229,0.15); color: var(--brass-dark); }
.pill-scheduled { background: var(--paper-warm); color: var(--ink-soft); border: 1px solid var(--line); }
.pill-done { background: rgba(22,163,74,0.12); color: var(--sage); }
/* Task priority */
.pill-priority-low    { background: var(--paper-warm); color: var(--ink-soft); border: 1px solid var(--line); }
.pill-priority-medium { background: var(--paper-warm); color: var(--ink-soft); border: 1px solid var(--line); }
.pill-priority-high   { background: rgba(79,70,229,0.15); color: var(--brass-dark); }
.pill-priority-urgent { background: var(--rust); color: #fff; }
/* Generic avatar (timeline, kanban initials, mentions). Use the same class
   everywhere so we never style avatars inline again. */
.avatar { display: inline-flex; align-items: center; justify-content: center; color: white; font-weight: 600; border-radius: 50%; flex-shrink: 0; }
.avatar-xs { width: 20px; height: 20px; font-size: 9px; }
.avatar-sm { width: 24px; height: 24px; font-size: 10px; }
.avatar-md { width: 28px; height: 28px; font-size: 10.5px; }
.type-tag { display: inline-flex; align-items: center; padding: 2px 7px; font-size: 10.5px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; border: 1px solid var(--line); color: var(--ink-soft); background: var(--paper-card); border-radius: 2px; }
/* Property hero "back to portfolio" pill — an unmistakable, high-contrast
   return path that reads the same over any hero image, desktop or mobile. */
.hero-back { display: inline-flex; align-items: center; gap: 6px; padding: 6px 13px 6px 10px; border-radius: 999px; font-size: 12.5px; font-weight: 600; letter-spacing: 0.01em; color: #fff; background: rgba(15,23,42,0.42); border: 1px solid rgba(255,255,255,0.28); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); cursor: pointer; transition: background 0.15s, border-color 0.15s; -webkit-tap-highlight-color: transparent; }
@media (hover: hover) { .hero-back:hover { background: rgba(15,23,42,0.62); border-color: rgba(255,255,255,0.5); } }
.hero-back i { flex: 0 0 auto; }
/* Data Rooms lives in the desktop stats band; on the hero it's a mobile-only
   primary action, so hide it here and reveal it in the phone media query.
   Filled indigo (vs. the translucent back pill) marks it as the main CTA. */
.hero-share { display: none; background: var(--brass); border-color: rgba(255,255,255,0.35); }
@media (hover: hover) { .hero-share:hover { background: var(--brass-dark); border-color: rgba(255,255,255,0.6); } }
.btn-primary { background: var(--ink); color: var(--paper); padding: 8px 14px; border-radius: 8px; font-size: 13px; font-weight: 500; display: inline-flex; align-items: center; gap: 6px; transition: all 0.15s; cursor: pointer; }
@media (hover: hover) { .btn-primary:hover { background: var(--ink-soft); } }
.btn-secondary { background: transparent; color: var(--ink); padding: 7px 13px; border-radius: 8px; border: 1px solid var(--line); font-size: 13px; font-weight: 500; display: inline-flex; align-items: center; gap: 6px; transition: all 0.15s; cursor: pointer; }
@media (hover: hover) { .btn-secondary:hover { background: var(--paper-warm); border-color: var(--ink-soft); } }
.btn-icon { width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px; border: 1px solid var(--line); background: var(--paper-card); cursor: pointer; transition: all 0.15s; color: var(--ink-soft); }
@media (hover: hover) { .btn-icon:hover { background: var(--paper-warm); color: var(--ink); } }
.btn-danger { background: var(--rust); color: white; padding: 8px 14px; border-radius: 8px; font-size: 13px; font-weight: 500; display: inline-flex; align-items: center; gap: 6px; transition: all 0.15s; cursor: pointer; border: none; }
@media (hover: hover) { .btn-danger:hover { background: #9a4a30; } }
.tab { padding: 10px 2px; margin-right: 24px; font-size: 13.5px; font-weight: 500; color: var(--ink-muted); cursor: pointer; border-bottom: 2px solid transparent; transition: all 0.15s; letter-spacing: -0.005em; }
@media (hover: hover) { .tab:hover { color: var(--ink-soft); } }
.tab.active { color: var(--ink); border-bottom-color: var(--brass); }
/* Mobile section picker: a native <select> replaces the horizontal tab scroll
   on phones (shown via the media query below). Hidden on desktop. */
.tabs-mobile { display: none; }
.tab-select-wrap { position: relative; }
.tab-select { appearance: none; -webkit-appearance: none; width: 100%; border: none; background: transparent; font-family: inherit; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); padding: 13px 34px 13px 0; cursor: pointer; }
.tab-select:focus { outline: none; }
.tab-select-chevron { position: absolute; right: 2px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--brass); pointer-events: none; }
.kpi-value { font-family: 'Inter', system-ui, sans-serif; font-weight: 600; font-size: 30px; line-height: 1; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.kpi-label { font-size: 11px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-muted); }
/* Hover tooltip for KPI qualifiers (e.g. Net Income = rent + other income).
   A span.info-tip[data-tip] wraps a small info icon; the bubble renders above
   on hover. Pure CSS so it works inside any re-rendered HTML string. */
.info-tip { position: relative; display: inline-flex; align-items: center; vertical-align: -1px; margin-left: 4px; color: var(--ink-muted); cursor: help; }
.info-tip svg { width: 12px; height: 12px; }
.info-tip::after {
  content: attr(data-tip); position: absolute; bottom: calc(100% + 7px); left: 50%; transform: translateX(-50%);
  background: var(--ink); color: #fff; font-size: 11.5px; font-weight: 500; letter-spacing: 0; text-transform: none;
  line-height: 1.4; padding: 6px 9px; border-radius: 6px; white-space: nowrap; box-shadow: var(--shadow-md);
  opacity: 0; pointer-events: none; transition: opacity 0.12s ease; z-index: 60;
}
.info-tip::before {
  content: ''; position: absolute; bottom: calc(100% + 2px); left: 50%; transform: translateX(-50%);
  border: 5px solid transparent; border-top-color: var(--ink);
  opacity: 0; pointer-events: none; transition: opacity 0.12s ease; z-index: 60;
}
.info-tip:hover::after, .info-tip:hover::before { opacity: 1; }
/* Collapsible KPI header — desktop always shows the strip, so the toggle is
   hidden here and only appears in the mobile card layout. */
.kpi-toggle { display: none; }
.kpi-toggle-chevron { transition: transform 0.2s ease; }
#kpi-section.kpi-open .kpi-toggle-chevron { transform: rotate(180deg); }
.progress-track { height: 4px; background: var(--line-soft); border-radius: 2px; overflow: hidden; }
.progress-fill { height: 100%; background: var(--ink); border-radius: 2px; transition: width 0.4s ease; }
.progress-fill.brass { background: var(--brass); } .progress-fill.sage { background: var(--sage); } .progress-fill.rust { background: var(--rust); }
table.data-table { width: 100%; border-collapse: collapse; }
.data-table th { text-align: left; font-size: 10.5px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-muted); padding: 10px 12px; border-bottom: 1px solid var(--line); background: var(--paper-warm); }
.data-table td { padding: 14px 12px; border-bottom: 1px solid var(--line-soft); font-size: 13.5px; color: var(--ink-soft); }
@media (hover: hover) { .data-table tr:hover td { background: rgba(79,70,229,0.04); } }
.data-table tr:last-child td { border-bottom: none; }
.data-table tr.editable { cursor: pointer; }
/* Column totals — the rent-roll footer row. Reads as the "sum line" of a
   spreadsheet: separated by a full line, quiet background, no hover tint. */
.data-table tfoot td { padding: 11px 12px; border-top: 1px solid var(--line); border-bottom: none; background: var(--paper-warm); font-size: 12.5px; font-weight: 600; color: var(--ink); }
@media (hover: hover) { .data-table tfoot tr:hover td { background: var(--paper-warm); } }
/* Mobile counterpart of the tfoot totals: one summary block at the end of the
   unit-card list, same numbers in a compact grid. */
.uc-summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px 12px; padding: 12px 14px; background: var(--paper-warm); border-top: 1px solid var(--line); }
.uc-summary .kpi-label { font-size: 9.5px; }
.uc-summary .uc-sum-val { font-size: 14px; font-weight: 600; color: var(--ink); margin-top: 2px; font-variant-numeric: tabular-nums; }
/* Archived-lease history — a quiet, collapsed-by-default panel under the units table */
.lease-history { overflow: hidden; }
.lease-history-summary { display: flex; align-items: center; gap: 8px; padding: 13px 16px; cursor: pointer; font-size: 13px; font-weight: 600; color: var(--ink); list-style: none; user-select: none; }
.lease-history-summary::-webkit-details-marker { display: none; }
@media (hover: hover) { .lease-history-summary:hover { background: var(--paper-warm); } }
.lease-history-summary .chevron { color: var(--ink-muted); transition: transform 0.15s; }
.lease-history[open] > .lease-history-summary .chevron { transform: rotate(90deg); }
.lease-history[open] > .lease-history-summary { border-bottom: 1px solid var(--line); }
/* ===== Mobile rent roll (phone-only card list; hidden on desktop) ===== */
.units-mobile { display: none; }
.unit-card { padding: 12px 15px; border-bottom: 1px solid var(--line-soft); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.unit-card:last-child { border-bottom: none; }
.unit-card:active { background: var(--paper-warm); }
.unit-card-static { cursor: default; }
.unit-card-static:active { background: none; }
.uc-top { display: flex; align-items: baseline; gap: 10px; }
.uc-num { flex: 0 0 auto; min-width: 30px; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 12.5px; font-weight: 700; color: var(--ink); }
.uc-tenant { flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uc-tenant-wrap { flex: 1 1 auto; min-width: 0; display: flex; align-items: baseline; gap: 6px; overflow: hidden; }
.uc-tenant-wrap .uc-tenant { flex: 0 1 auto; }
.uc-rent { flex: 0 0 auto; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 13.5px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.uc-meta { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 3px; padding-left: 40px; }
.uc-meta-left { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uc-signal { flex: 0 0 auto; font-size: 12px; text-align: right; }
.uc-muted { color: var(--ink-muted); font-style: italic; font-weight: 500; }
.uc-chip { flex: 0 0 auto; display: inline-block; font-size: 10.5px; font-weight: 600; color: var(--ink-muted); background: var(--paper-warm); border: 1px solid var(--line); border-radius: 4px; padding: 0 5px; white-space: nowrap; }
/* ===== Mobile documents (phone-only card list; hidden on desktop) ===== */
.docs-mobile { display: none; }
.doc-card { display: block; padding: 12px 15px; border-bottom: 1px solid var(--line-soft); text-decoration: none; color: inherit; -webkit-tap-highlight-color: transparent; }
.doc-card:last-child { border-bottom: none; }
.doc-card:active { background: var(--paper-warm); }
.doc-card-static:active { background: none; }
.dc-top { display: flex; align-items: center; gap: 10px; }
.dc-icon { flex: 0 0 auto; width: 16px; height: 16px; color: var(--ink-muted); }
.dc-name-wrap { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; overflow: hidden; }
.dc-name { flex: 0 1 auto; min-width: 0; font-size: 14px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dc-tag { flex: 0 0 auto; font-size: 10.5px; font-weight: 600; color: var(--ink-muted); background: var(--paper-warm); border: 1px solid var(--line); border-radius: 4px; padding: 0 5px; }
.dc-open { flex: 0 0 auto; width: 15px; height: 15px; color: var(--ink-muted); }
.dc-meta { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 3px; padding-left: 26px; }
.dc-meta-left { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dc-exp { flex: 0 0 auto; font-size: 12px; font-weight: 500; }
.dc-up { flex: 0 0 auto; font-size: 12px; color: var(--ink-muted); }
/* ===== Document folders (collapsible, grouped by type) ===== */
.doc-folders { display: flex; flex-direction: column; gap: 10px; }
.doc-folder-head { display: flex; align-items: center; gap: 10px; width: 100%; padding: 13px 16px; background: none; border: none; cursor: pointer; text-align: left; font: inherit; color: var(--ink); -webkit-tap-highlight-color: transparent; }
@media (hover: hover) { .doc-folder-head:hover { background: var(--paper-warm); } }
.df-chev { flex: 0 0 auto; width: 15px; height: 15px; color: var(--ink-muted); transition: transform 0.15s; }
.doc-folder.open .df-chev { transform: rotate(90deg); }
.df-icon { flex: 0 0 auto; width: 17px; height: 17px; color: var(--brass-dark); }
.df-title { flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.df-count { flex: 0 0 auto; font-size: 11.5px; font-weight: 600; color: var(--ink-muted); background: var(--paper-warm); border: 1px solid var(--line); border-radius: 10px; min-width: 20px; text-align: center; padding: 0 6px; }
.df-alert { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; }
.doc-folder-body { display: none; border-top: 1px solid var(--line-soft); }
.doc-folder.open .doc-folder-body { display: block; }
.doc-folder.open .doc-folder-head { border-bottom: 1px solid transparent; }
/* Tenant table — expandable multi-unit groups */
.tenant-group-summary .chevron-toggle { display: inline-block; margin-right: 8px; padding: 2px 4px; color: var(--ink-muted); cursor: pointer; transition: transform 0.15s, color 0.15s; vertical-align: -2px; }
@media (hover: hover) { .tenant-group-summary .chevron-toggle:hover { color: var(--ink); } }
.tenant-group-summary.expanded .chevron-toggle { transform: rotate(90deg); }
.tenant-group-detail.hidden { display: none; }
.tenant-group-detail td { background: rgba(79,70,229,0.03); font-size: 12.5px; color: var(--ink-muted); }
.tenant-group-detail td:first-child { padding-left: 36px; }
/* Storage unit-mix — collapsible category bands (collapsed by default) */
.storage-cat-summary { cursor: pointer; }
.storage-cat-summary .chevron-toggle { display: inline-block; margin-right: 8px; padding: 2px 4px; color: var(--ink-muted); transition: transform 0.15s, color 0.15s; vertical-align: -2px; }
@media (hover: hover) { .storage-cat-summary:hover .chevron-toggle { color: var(--ink); } }
.storage-cat-summary.expanded .chevron-toggle { transform: rotate(90deg); }
.storage-cat-detail.hidden { display: none; }
/* Inline-editable rent + occupancy */
.storage-rent-edit { display: inline-flex; align-items: baseline; gap: 1px; }
.storage-rent-prefix { color: var(--ink-muted); }
.storage-rent-input, .storage-occ-input { font-family: inherit; font-size: 12px; color: var(--ink); background: var(--paper); border: 1px solid var(--line); border-radius: 4px; padding: 2px 4px; text-align: right; transition: border-color 0.15s, background 0.15s, box-shadow 0.15s; }
.storage-rent-input { width: 64px; }
.storage-occ-input { width: 44px; }
@media (hover: hover) { .storage-rent-input:hover, .storage-occ-input:hover { border-color: var(--ink-muted); } }
.storage-rent-input:focus, .storage-occ-input:focus { outline: none; border-color: var(--brass); background: white; box-shadow: 0 0 0 3px rgba(79,70,229,0.12); }
.storage-occ-input.has-vacancy { color: var(--rust); font-weight: 600; border-color: rgba(220,38,38,0.4); }
/* Actionable cue in the table meta line: reveals every category's editable rows in one click */
.storage-edit-hint { font: inherit; color: var(--brass); font-weight: 500; background: none; border: 0; padding: 0; cursor: pointer; }
@media (hover: hover) { .storage-edit-hint:hover { text-decoration: underline; } }
.kpi-sub { font-size: 11px; color: var(--ink-muted); margin-top: 2px; }
/* Access & Codes header: count on the left, Add-Code button on the right;
   the phone media query stacks them (button first, full-width). */
.access-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.access-add { flex: 0 0 auto; }
/* Code list: one row per code, scannable top-to-bottom. The value is the
   anchor — mono, ink, wide-tracked — so it's readable at a door on a phone. */
.code-list { overflow: hidden; }
.code-row { display: flex; align-items: center; gap: 14px; padding: 11px 14px; border-bottom: 1px solid var(--line); }
.code-row:last-child { border-bottom: 0; }
@media (hover: hover) { .code-row:hover { background: var(--paper-warm); } }
.code-row-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.code-row-label { font-size: 13.5px; font-weight: 500; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.code-row-notes { font-size: 11.5px; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* min-width keeps short and long codes on one aligned column (it grows for an
   unusually long code rather than clipping); user-select:all = one click grabs
   the whole code. */
.code-row-value { flex: 0 0 auto; min-width: 86px; text-align: center; font-family: 'JetBrains Mono', monospace; font-size: 14px; font-weight: 600; color: var(--ink); letter-spacing: 0.08em; background: var(--paper-warm); border: 1px solid var(--line); border-radius: 5px; padding: 4px 10px; user-select: all; }
/* Fixed width, not min-width: it must be wide enough for the longest "Rotated
   Sept 2026" or rows without a date knock the value column out of alignment. */
.code-row-rotated { flex: 0 0 auto; width: 106px; font-size: 11px; color: var(--ink-muted); white-space: nowrap; text-align: right; }
.code-row-copy { flex: 0 0 auto; }
.search-input { background: var(--paper-card); border: 1px solid var(--line); border-radius: 8px; padding: 7px 12px 7px 34px; font-size: 13px; width: 100%; transition: all 0.15s; }
.search-input:focus { outline: none; border-color: var(--brass); background: white; box-shadow: 0 0 0 3px rgba(79,70,229,0.12); }
/* Full-screen mobile search sheet (opened from the bottom tab bar; the tab
   bar itself only exists on phones, so these need no media query). z-index
   sits BELOW the tab bar (70) so Portfolio/Tasks/Search/More stay visible
   and tappable while searching; the results pad past the bar. */
.mobile-search-overlay { display: none; position: fixed; inset: 0; z-index: 60; background: var(--paper); flex-direction: column; }
.mobile-search-overlay.open { display: flex; }
.mobile-search-head {
  display: flex; align-items: center; gap: 8px; flex-shrink: 0;
  padding: calc(10px + env(safe-area-inset-top)) 12px 10px;
  background: var(--paper-card); border-bottom: 1px solid var(--line);
}
.mobile-search-results { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding-bottom: calc(64px + env(safe-area-inset-bottom)); }
.mobile-search-results .combo-group-label { padding: 12px 16px 5px; }
.mobile-search-row { padding: 11px 16px; border-bottom: 1px solid var(--line-soft); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.mobile-search-row:active { background: rgba(79,70,229,0.06); }
.mobile-search-hint { padding: 22px 16px; font-size: 13px; color: var(--ink-muted); text-align: center; }
/* Mobile "More" bottom sheet — slides up to sit flush on the tab bar (its
   `bottom` is set at open time to the bar's measured height). Backdrop and
   sheet both stay under the tab bar's z 70 so the bar remains usable. */
.mobile-more-backdrop { display: none; position: fixed; inset: 0; z-index: 55; background: rgba(15,23,42,0.42); }
.mobile-more-backdrop.open { display: block; }
.mobile-more-sheet {
  display: none; position: fixed; left: 0; right: 0; z-index: 62;
  background: var(--paper-card); border-radius: 16px 16px 0 0;
  box-shadow: var(--shadow-lg); padding: 14px 10px 12px;
}
.mobile-more-sheet.open { display: block; animation: sheet-up 0.18s ease-out; }
@keyframes sheet-up { from { transform: translateY(24px); opacity: 0.4; } to { transform: none; opacity: 1; } }
.mobile-more-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
.mobile-more-item {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 13px 4px 11px; background: none; border: 0; border-radius: 12px;
  font-size: 11px; font-weight: 500; color: var(--ink-soft); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.mobile-more-item:active { background: var(--paper-warm); }
.mobile-more-item svg { width: 22px; height: 22px; color: var(--ink-muted); }
@keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.fade-up { animation: fadeUp 0.4s ease-out both; }
.fade-up-1 { animation-delay: 0.05s; } .fade-up-2 { animation-delay: 0.1s; } .fade-up-3 { animation-delay: 0.15s; } .fade-up-4 { animation-delay: 0.2s; }
.kanban-col { background: var(--paper-warm); border: 1px solid var(--line); border-radius: 8px; padding: 12px; min-height: 400px; }
.kanban-card { background: var(--paper-card); border: 1px solid var(--line); border-left: 3px solid var(--ink); border-radius: 3px; padding: 10px 12px; margin-bottom: 8px; cursor: pointer; transition: all 0.15s; }
@media (hover: hover) { .kanban-card:hover { transform: translateY(-1px); box-shadow: 0 2px 8px rgba(15,23,42,0.06); } }
.kanban-card.priority-high { border-left-color: var(--rust); }
.kanban-card.priority-medium { border-left-color: var(--brass); }
.kanban-card.priority-low { border-left-color: var(--sage); }
/* Small status tag at the top of a kanban card. Reads quickly without
   fighting the title for attention. Per-status classes drive both
   background and text color so yellow doesn't get white text. */
.kanban-status-tag { display: inline-block; padding: 1px 7px; font-size: 9.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; border-radius: 2px; margin-bottom: 6px; }
.kanban-status-tag-on_track    { background: #16d093; color: #fff; }
.kanban-status-tag-in_progress { background: #fdab3d; color: #fff; }
.kanban-status-tag-waiting     { background: #a25ddc; color: #fff; }
.kanban-status-tag-stuck       { background: #e2445c; color: #fff; }
.kanban-status-tag-delayed     { background: #ff7043; color: #fff; }
.kanban-status-tag-abandoned   { background: #595959; color: #fff; }
.kanban-card-done { background: var(--paper-card); border: 1px solid var(--line); border-left: 3px solid var(--ink-muted); border-radius: 3px; padding: 10px 12px; margin-bottom: 8px; cursor: pointer; transition: all 0.15s; opacity: 0.78; }
@media (hover: hover) { .kanban-card-done:hover { transform: translateY(-1px); box-shadow: 0 2px 8px rgba(15,23,42,0.06); opacity: 1; } }
/* Slim "task in a list" row used by the project panel and other inline task lists. */
.task-list-row { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-bottom: 1px solid var(--line-soft); cursor: pointer; border-radius: 3px; }
@media (hover: hover) { .task-list-row:hover { background: var(--paper-warm); } }
.task-list-row:last-child { border-bottom: none; }

/* ============== MONDAY-STYLE TASK TABLE ============== */
/* Full-bleed colored status cells + chunky group bars + inline cell editing
   anchored to the cell (not modal). This is the primary Tasks surface. */

/* overflow-x: auto so the table never clips at narrow widths — Person
   column was getting trimmed by the parent container before. overflow-y
   stays visible so border-radius rounds cleanly. */
.task-board { background: var(--paper); border: 1px solid var(--line); border-radius: 6px; overflow-x: auto; overflow-y: visible; }
/* Mobile-only (see _taskCardHtml / the mobile media block). */
#task-fab { display: none; }

/* Column grid template — task title is flexible; the rest are fixed widths.
   Order: handle | title | status | priority | due | property | person.
   Repeating tasks render the schedule label as a small pill inline with
   the date, so the Due column is wider to keep everything on one line. */
.task-table-header,
.task-tr {
  display: grid;
  grid-template-columns: 28px minmax(220px, 1fr) 160px 100px 210px 180px 80px;
  align-items: center;
}
.task-table-header {
  background: var(--paper-warm);
  border-bottom: 1px solid var(--line);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.task-th { padding: 12px 18px; }
.task-th-handle { padding: 0; }

/* Group headers — Monday-style. Each status group reads as its own titled
   section: a tinted header band in the group's color, a bold colored title,
   and clear separation from the white task rows below. The color is derived
   from --accent (the status color) via color-mix so a single rule works for
   every status; darkened for text so even light accents stay readable. */
.task-group { border-bottom: 1px solid var(--line); }
.task-group:last-child { border-bottom: none; }
.task-group-bar {
  display: flex; align-items: center; gap: 9px;
  padding: 12px 16px;
  /* Fallbacks first for browsers without color-mix. */
  background: var(--paper-warm);
  background: color-mix(in srgb, var(--accent) 10%, var(--paper-card));
  border-bottom: 1px solid var(--line);
  border-bottom-color: color-mix(in srgb, var(--accent) 26%, var(--line));
  cursor: pointer;
  user-select: none;
  position: relative;
  transition: background 150ms ease-out;
}
@media (hover: hover) { .task-group-bar:hover { background: color-mix(in srgb, var(--accent) 16%, var(--paper-card)); } }
.task-group-bar::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 5px;
  background: var(--accent, var(--ink-muted));
}
.task-group-bar .chev {
  transition: transform 200ms ease-out;
  color: var(--ink-soft);
  color: color-mix(in srgb, var(--accent) 65%, #2a2a2a);
}
.task-group.collapsed .chev { transform: rotate(-90deg); }
.task-group.collapsed .task-tr,
.task-group.collapsed .task-card,
.task-group.collapsed .task-tr-add { display: none; }
.task-group-name {
  font-size: 14px; font-weight: 700; letter-spacing: -0.01em;
  color: var(--ink);
  color: color-mix(in srgb, var(--accent) 68%, #1c1c1c);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.task-group-count {
  font-size: 11.5px; font-family: 'JetBrains Mono', ui-monospace, monospace;
  color: var(--ink-muted);
  color: color-mix(in srgb, var(--accent) 62%, #1c1c1c);
  padding: 1px 8px; border-radius: 10px;
  background: var(--paper-card);
  background: color-mix(in srgb, var(--accent) 18%, white);
}

/* Rows */
.task-tr {
  background: var(--paper-card);
  border-bottom: 1px solid var(--line-soft);
  min-height: 50px;
  transition: background 120ms ease-out, transform 120ms ease-out;
  position: relative;
}
.task-tr:last-child { border-bottom: none; }
@media (hover: hover) { .task-tr:hover { background: var(--paper); } }
@media (hover: hover) { .task-tr:hover .task-row-handle i { opacity: 0.4; } }
.task-row-handle { display: flex; align-items: center; justify-content: center; height: 100%; cursor: grab; }
.task-row-handle i { opacity: 0; transition: opacity 120ms; color: var(--ink-muted); }
.task-tr[draggable="true"] { cursor: default; } /* row stays default; handle shows grab */
.task-tr.dragging { opacity: 0.4; }
.task-tr.dragging .task-row-handle { cursor: grabbing; }
/* Drop indicators — thin brass line above or below the target row. */
.task-tr.drop-above::before {
  content: ''; position: absolute; top: -1px; left: 0; right: 0; height: 2px;
  background: var(--brass); z-index: 10;
  box-shadow: 0 0 6px rgba(79,70,229,0.6);
}
.task-tr.drop-below::after {
  content: ''; position: absolute; bottom: -1px; left: 0; right: 0; height: 2px;
  background: var(--brass); z-index: 10;
  box-shadow: 0 0 6px rgba(79,70,229,0.6);
}
/* Group bar drop target — light up the accent strip & background. */
.task-group-bar.drop-into {
  background: rgba(79,70,229,0.10);
}
.task-group-bar.drop-into::before {
  width: 6px;
  box-shadow: 0 0 8px rgba(79,70,229,0.6);
}
/* "+ Add task" drop target — same brass line as a row drop-below */
.task-tr-add.drop-into {
  background: var(--paper-warm);
  position: relative;
}
.task-tr-add.drop-into::before {
  content: ''; position: absolute; top: -1px; left: 0; right: 0; height: 2px;
  background: var(--brass); z-index: 10;
  box-shadow: 0 0 6px rgba(79,70,229,0.6);
}

/* Title cell — clickable, opens the side panel. Wraps so long titles
   stay readable; the row's grid-row height grows to fit. */
.task-td-title {
  padding: 13px 18px;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--ink);
  cursor: pointer;
  min-width: 0;
  overflow-wrap: break-word;
  word-break: break-word;
  white-space: normal;
  border-right: 1px solid var(--line-soft);
}
@media (hover: hover) { .task-td-title:hover { color: var(--brass-dark); } }
.task-td-title.done { color: var(--ink-muted); text-decoration: line-through; }

/* All non-title cells separated by a faint vertical line */
.task-td { border-right: 1px solid var(--line-soft); min-width: 0; }
.task-td:last-child { border-right: none; }

/* Keyboard-focus ring on task table cells. Drawn as an inset shadow so it
   doesn't reflow the grid layout. */
.task-td-title:focus,
.task-td:focus {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--brass-dark);
}
.task-td-title:focus { background: rgba(79,70,229, 0.04); }

/* Status cell — the cell IS the color. Click for popover.
   Saturated Monday-palette hexes so cells pop at a glance; the rest of the
   app stays on our muted paper-warm brand. */
.task-cell-status {
  display: flex; align-items: center; justify-content: center;
  padding: 8px 12px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #fff;
  cursor: pointer;
  transition: filter 150ms ease-out, background-color 200ms ease-out;
  height: 100%;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (hover: hover) { .task-cell-status:hover { filter: brightness(1.06); } }
.task-cell-status.empty       { background: #c4c4c4; color: #fff; }
.task-cell-status-open        { background: #c4c4c4; color: #fff; }     /* Not Started — Monday gray */
.task-cell-status-on_track    { background: #16d093; color: #fff; }     /* On Track — bright teal-green */
.task-cell-status-in_progress { background: #fdab3d; color: #fff; }     /* Working on it — Monday orange */
.task-cell-status-waiting     { background: #a25ddc; color: #fff; }     /* Awaiting Response — purple */
.task-cell-status-stuck       { background: #e2445c; color: #fff; }     /* Stuck — Monday coral red */
.task-cell-status-delayed     { background: #ff7043; color: #fff; }     /* Delayed — peach-orange */
.task-cell-status-done        { background: #00c875; color: #fff; }     /* Done — Monday green */
.task-cell-status-abandoned   { background: #595959; color: #fff; }     /* Abandoned — dark gray */

/* Priority cell — saturated for high/urgent, muted for low/medium */
.task-cell-priority {
  display: flex; align-items: center; justify-content: center;
  padding: 8px 12px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: filter 150ms ease-out;
  height: 100%;
  text-align: center;
}
@media (hover: hover) { .task-cell-priority:hover { filter: brightness(1.05); } }
.task-cell-priority-low      { background: #eaeef2; color: #6b7280; }   /* Low — pale slate */
.task-cell-priority-medium   { background: #cbd2db; color: #444; }      /* Medium — slate */
.task-cell-priority-high     { background: #5559df; color: #fff; }      /* High — Monday indigo */
.task-cell-priority-urgent   { background: #bb3354; color: #fff; }      /* Urgent — deep red */

/* Due date cell — flex layout keeps the date and the recurrence pill on
   one row even when both are present. Color codes by urgency. */
.task-td-due {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 8px 10px;
  font-size: 12.5px;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background 120ms;
  overflow: hidden;
  white-space: nowrap;
  height: 100%;
}
@media (hover: hover) { .task-td-due:hover { background: var(--paper-warm); } }
.task-td-due.overdue { color: var(--rust); font-weight: 600; }
.task-td-due.today { color: var(--brass-dark); font-weight: 600; }
.task-td-due.empty { color: var(--ink-muted); font-style: italic; }
.task-td-due.has-time { font-size: 11.5px; }
.task-td-due .due-main { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* Quiet recurrence marker next to the date ("Weekly", "Every 3 weeks").
   Understated on purpose — no fill, muted text — so it reads as a footnote
   to the due date rather than competing with it. */
.due-repeat-pill {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ink-muted);
  background: transparent;
  padding: 0;
  border-radius: 0;
  flex-shrink: 0;
  text-transform: none;
}
.due-repeat-pill i { width: 10px; height: 10px; opacity: 0.65; }

/* Property cell — clickable, opens the property/group picker popover */
.task-td-property {
  padding: 8px 12px;
  font-size: 12.5px;
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
  transition: background 120ms;
  display: flex;
  align-items: center;
  gap: 5px;
  height: 100%;
}
@media (hover: hover) { .task-td-property:hover { background: var(--paper-warm); } }
.task-td-property.empty { color: var(--ink-muted); font-style: italic; }
.task-td-property .group-icon { color: var(--brass-dark); flex-shrink: 0; }

/* Property/Group picker popover */
.pp-search-wrap { padding: 8px 10px; border-bottom: 1px solid var(--line-soft); background: var(--paper-warm); }
.pp-search-wrap input {
  width: 100%; border: 1px solid var(--line); border-radius: 8px;
  padding: 6px 9px; font-size: 13px; outline: none; background: white;
  color: var(--ink);
}
.pp-search-wrap input:focus { border-color: var(--ink-soft); }
.pp-list { max-height: 380px; overflow-y: auto; }
.pp-section {
  padding: 7px 12px 5px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
  background: var(--paper-warm);
  border-top: 1px solid var(--line-soft);
}
.pp-section:first-child { border-top: none; }
/* A group shown purely as a heading for the buildings under it — reads like
   .pp-section but keeps the icon and building count, and is not clickable. */
.pp-group-title {
  display: flex; align-items: center; gap: 6px;
  padding: 7px 12px 5px; font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-muted); background: var(--paper-warm);
  border-top: 1px solid var(--line-soft); cursor: default;
}
.pp-group-title:first-child { border-top: none; }
.pp-group-title i { color: var(--brass-dark); opacity: 0.8; }
.pp-group-row { font-weight: 600; }
.pp-group-row i { color: var(--brass-dark); }
.pp-child-row { padding-left: 36px !important; font-size: 12.5px; color: var(--ink-soft); }
.pp-bldg-count {
  margin-left: auto; font-size: 9.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-muted);
  padding: 1px 6px; background: var(--paper-warm); border-radius: 8px;
}
.pp-empty { padding: 16px; text-align: center; color: var(--ink-muted); font-size: 12px; font-style: italic; }
/* Multi-select check column — sits at the left of each toggleable property row */
.pp-check {
  width: 16px; height: 16px;
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line);
  border-radius: 3px;
  background: white;
  color: white;
}
.pp-check.on { background: var(--brass-dark); border-color: var(--brass-dark); }
.pp-check.on i { display: block; }
.pp-child-row .pp-check { margin-right: 2px; }

/* Property display in the side panel — replaces the old Combo with a
   click-to-open trigger that mirrors the Monday table cell behavior. */
.task-property-trigger {
  display: flex; align-items: center; gap: 6px;
  padding: 7px 10px;
  background: white;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 120ms;
  min-height: 32px;
}
@media (hover: hover) { .task-property-trigger:hover { border-color: var(--ink-soft); } }
.task-property-trigger.empty { color: var(--ink-muted); font-style: italic; }
.task-property-trigger .group-icon { color: var(--brass-dark); }
.task-property-trigger .chev { margin-left: auto; color: var(--ink-muted); }

/* Person cell — avatar circle prominent */
.task-td-person {
  display: flex; align-items: center; justify-content: center;
  padding: 6px 8px;
  cursor: pointer;
  height: 100%;
  transition: background 120ms;
}
@media (hover: hover) { .task-td-person:hover { background: var(--paper-warm); } }
.task-td-person .avatar { width: 28px; height: 28px; font-size: 11px; }
.task-td-person .empty-avatar { width: 28px; height: 28px; border-radius: 50%; border: 1.5px dashed var(--line); display: flex; align-items: center; justify-content: center; color: var(--ink-muted); font-size: 11px; }

/* Inline "+ Add task" row */
.task-tr-add {
  display: grid;
  grid-template-columns: 28px 1fr;
  align-items: center;
  padding: 9px 12px;
  cursor: pointer;
  color: var(--ink-muted);
  font-size: 12.5px;
  background: var(--paper-card);
  border-top: 1px solid var(--line-soft);
  transition: background 120ms, color 120ms;
}
@media (hover: hover) { .task-tr-add:hover { background: var(--paper-warm); color: var(--ink); } }
.task-tr-add .add-icon { display: flex; align-items: center; justify-content: center; }
.task-tr-add input {
  background: transparent;
  border: none;
  outline: none;
  font-size: 13px;
  width: 100%;
  color: var(--ink);
  padding: 0;
}

/* Cell popover (status / priority / assignee picker) */
.cell-popover {
  position: fixed;
  z-index: 1300;
  background: white;
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: 0 12px 32px rgba(15,23,42,0.18);
  min-width: 200px;
  max-width: 320px;
  max-height: calc(100vh - 24px);
  overflow-y: auto;
  overflow-x: hidden;
  animation: cellPopoverIn 150ms ease-out;
}
@keyframes cellPopoverIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.cell-popover-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  cursor: pointer;
  font-size: 13px;
  transition: background 100ms;
}
@media (hover: hover) { .cell-popover-option:hover { background: var(--paper-warm); } }
.cell-popover-option.active { background: var(--paper-warm); font-weight: 600; }
/* Keyboard-driven highlight ring — paired with up/down nav inside any popover */
.cell-popover-option.keyboard-highlight { background: rgba(79,70,229, 0.12); box-shadow: inset 2px 0 0 var(--brass-dark); }
.cell-popover-option.keyboard-highlight.active { background: rgba(79,70,229, 0.18); }

/* Segmented date / time inputs in the due popover */
.date-time-segments {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  flex-wrap: nowrap;
}
.date-segment {
  width: 32px;
  text-align: center;
  padding: 6px 4px;
  border: 1px solid var(--line);
  border-radius: 3px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 14px;
  background: white;
  color: var(--ink);
  appearance: none;
}
#due-yyyy { width: 56px; }
/* Recurrence "Every N period" controls in the due popover. font-size lives
   here (not inline) so the mobile 16px anti-zoom list can override it. */
.rec-input { font-size: 13px; }
.date-segment::placeholder { color: var(--ink-muted); }
.date-segment:focus { outline: none; border-color: var(--ink); background: rgba(79,70,229, 0.06); }
.segment-sep { color: var(--ink-muted); font-weight: 600; font-size: 14px; padding: 0 1px; }
.segment-gap { width: 12px; }

/* Toggle button that opens / closes the inline calendar */
.cal-toggle-btn {
  display: flex; align-items: center; gap: 8px; justify-content: center;
  width: 100%;
  padding: 7px 12px;
  margin-top: 10px;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  background: var(--paper-warm);
  color: var(--ink-soft);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  outline: none;
}
@media (hover: hover) { .cal-toggle-btn:hover { background: white; border-color: var(--line); color: var(--ink); } }
.cal-toggle-btn:focus, .cal-toggle-btn.keyboard-highlight {
  background: rgba(79,70,229, 0.08);
  border-color: var(--brass-dark);
  color: var(--ink);
}
.cal-toggle-btn.open { background: white; color: var(--ink); }
.cal-toggle-btn i { color: var(--brass-dark); }

/* Inline month calendar inside the due popover */
.due-calendar {
  margin: 10px 0 2px;
  padding: 8px 6px 6px;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  background: var(--paper-warm);
  outline: none;
}
.due-calendar:focus { box-shadow: 0 0 0 2px rgba(79,70,229, 0.30); }
.cal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 2px 6px;
}
.cal-nav {
  width: 22px; height: 22px;
  border: 1px solid transparent; border-radius: 3px;
  background: transparent; color: var(--ink-soft);
  font-size: 15px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
@media (hover: hover) { .cal-nav:hover { border-color: var(--line); background: white; color: var(--ink); } }
.cal-title { font-size: 13px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.cal-weekdays {
  display: grid; grid-template-columns: repeat(7, 1fr);
  font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ink-muted); text-align: center; padding-bottom: 4px;
}
.cal-grid {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px;
}
.cal-day {
  aspect-ratio: 1;
  border: 1px solid transparent;
  border-radius: 3px;
  background: transparent;
  color: var(--ink);
  font-size: 12px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  cursor: pointer;
  line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
@media (hover: hover) { .cal-day:hover { background: white; border-color: var(--line); } }
.cal-day.other-month { color: var(--ink-muted); opacity: 0.5; }
.cal-day.today { font-weight: 700; color: var(--brass-dark); }
.cal-day.selected { background: var(--brass-dark); color: white; border-color: var(--brass-dark); }
.cal-day.kbd-focus { box-shadow: inset 0 0 0 2px var(--ink); }
.cal-day.selected.kbd-focus { box-shadow: inset 0 0 0 2px white; }
.cell-popover-swatch {
  width: 14px; height: 14px; border-radius: 3px; flex-shrink: 0;
}

/* View switcher (Table | Board) */
.view-switcher { display: inline-flex; background: var(--paper-warm); border: 1px solid var(--line); border-radius: 5px; padding: 2px; gap: 2px; }
.view-switcher button {
  background: transparent;
  border: none;
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-soft);
  cursor: pointer;
  border-radius: 3px;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: background 120ms, color 120ms;
}
@media (hover: hover) { .view-switcher button:hover { color: var(--ink); } }
.view-switcher button.active { background: var(--paper-card); color: var(--ink); box-shadow: 0 1px 2px rgba(15,23,42,0.05); }

/* Filter chip row — sits above the table/board, applies to both views. */
.filter-chips {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 12px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-soft);
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: 16px;
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
}
@media (hover: hover) { .filter-chip:hover { background: var(--paper-warm); color: var(--ink); } }
.filter-chip.active { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.filter-chip-count { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 11px; opacity: 0.7; }
.filter-chip.active .filter-chip-count { opacity: 0.8; }

/* Assignee bar — the primary "whose tasks" selector. A row of profile pills
   (avatar + first name + count), bracketed by Everyone / Unassigned. */
.assignee-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
}
.assignee-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 11px 4px 5px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-soft);
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: 20px;
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms, box-shadow 120ms;
}
@media (hover: hover) { .assignee-pill:hover { background: var(--paper-warm); color: var(--ink); border-color: var(--ink-soft); } }
.assignee-pill.active { background: var(--paper-card); color: var(--ink); border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); }
.assignee-pill .avatar { flex-shrink: 0; }
.assignee-pill-name { line-height: 1; }
.assignee-pill-you { font-size: 10.5px; color: var(--ink-muted); font-weight: 400; }
.assignee-pill-count {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  color: var(--ink-muted);
  background: var(--paper-warm);
  border-radius: 10px;
  padding: 1px 6px;
  min-width: 18px;
  text-align: center;
}
.assignee-pill.active .assignee-pill-count { background: var(--ink); color: var(--paper); }
.assignee-pill-icon,
.assignee-pill-empty {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  flex-shrink: 0;
}
.assignee-pill-icon { background: var(--paper-warm); color: var(--ink-soft); }
.assignee-pill-empty { border: 1.5px dashed var(--line-strong, var(--line)); color: var(--ink-muted); font-size: 13px; background: transparent; }

/* "Someone else" dropdown — a native select dressed up to match the pills.
   Keeps the bar compact when the team is large. */
.assignee-select-wrap { position: relative; display: inline-flex; align-items: center; }
.assignee-select {
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1;
  color: var(--ink-soft);
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 9px 30px 9px 14px;
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms, box-shadow 120ms;
}
@media (hover: hover) { .assignee-select:hover { background: var(--paper-warm); color: var(--ink); border-color: var(--ink-soft); } }
.assignee-select:focus { outline: none; border-color: var(--ink-soft); }
.assignee-select-wrap.active .assignee-select { color: var(--ink); border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); }
.assignee-select-chevron { position: absolute; right: 11px; color: var(--ink-muted); pointer-events: none; }

/* Pushes the Filter button to the right end of the assignee bar. */
.assignee-bar-spacer { flex: 1 1 auto; }
/* Filter button — opens the time-slice menu (All / Overdue / Today). */
.assignee-filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 13px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-soft);
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: 20px;
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms, box-shadow 120ms;
}
@media (hover: hover) { .assignee-filter-btn:hover { background: var(--paper-warm); color: var(--ink); border-color: var(--ink-soft); } }
.assignee-filter-btn.active { color: var(--ink); border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); }
.assignee-filter-btn i { color: var(--ink-muted); }
.assignee-filter-btn.active i { color: var(--ink); }
/* Count badge inside the filter menu rows. */
.filter-menu-count { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 11px; color: var(--ink-muted); }
/* Search box living inside the assignee bar (left of Filter). Pill-shaped to
   match the surrounding controls; cancels .filter-search's margin-left:auto
   since the bar spacer already pushes it right. */
.assignee-search { margin-left: 0; border-radius: 20px; padding: 7px 13px; min-width: 210px; }
/* Thin separator between the group-by toggle and the assignee pills. */
.assignee-bar-divider { width: 1px; align-self: stretch; min-height: 24px; background: var(--line); margin: 0 3px; }
.task-groupby button { display: inline-flex; align-items: center; gap: 5px; }
.task-groupby button i { width: 14px; height: 14px; }
/* By-property group headers: keep the property name in normal case (proper
   nouns), and give the building icon the header's accent tint. */
.task-group.by-property .task-group-name { text-transform: none; letter-spacing: -0.01em; }
/* A property revealed via "Add a property" has no tasks yet — quieted so it
   reads as a slot waiting for one rather than as content. */
.task-group.by-property.is-empty .task-group-name,
.task-group.by-property.is-empty .task-group-count { opacity: 0.55; }
.prop-reveal-btn { display: flex; align-items: center; gap: 6px; width: 100%; padding: 9px 14px; margin-top: 2px; background: transparent; border: none; border-top: 1px solid var(--line-soft); color: var(--ink-muted); font-family: 'Inter', sans-serif; font-size: 12.5px; cursor: pointer; text-align: left; }
.prop-reveal-btn i { opacity: 0.75; }
@media (hover: hover) { .prop-reveal-btn:hover { background: var(--paper-warm); color: var(--ink); } }
.task-group-prop-icon { color: color-mix(in srgb, var(--accent) 65%, #2a2a2a); flex-shrink: 0; }
.task-empty-prop { padding: 28px 16px; }

.filter-search {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 4px 10px;
  min-width: 200px;
  transition: border-color 120ms;
}
.filter-search:focus-within { border-color: var(--ink-soft); }
.filter-search input { flex: 1; border: none; outline: none; background: transparent; font-size: 13px; color: var(--ink); }
.filter-search input::placeholder { color: var(--ink-muted); }
.filter-search .lucide { color: var(--ink-muted); }

/* Confetti celebration on task done — twin-cannon burst from the bottom
   corners. Outer .confetti-piece handles translate (parabolic arc with
   gravity easing); inner .confetti-spinner handles rotation. Separating
   the two avoids the transform-clash that prevents combining two
   animations on a single element. Mixed shapes for visual variety. */
.confetti-burst { position: fixed; inset: 0; pointer-events: none; z-index: 5000; overflow: hidden; }
.confetti-piece {
  position: absolute;
  opacity: 0;
  will-change: transform, opacity;
  animation: confetti-fly var(--duration, 2s) forwards;
}
.confetti-spinner {
  background: var(--color);
  will-change: transform;
  animation: confetti-spin var(--spin-dur, 0.6s) linear infinite;
}
.confetti-spinner.shape-square { width: 9px;  height: 9px;  }
.confetti-spinner.shape-rect   { width: 6px;  height: 14px; }
.confetti-spinner.shape-ribbon { width: 4px;  height: 20px; border-radius: 2px; }
.confetti-spinner.shape-circle { width: 9px;  height: 9px;  border-radius: 50%; }
/* Parabolic arc — ease-out on the way up (decelerating against gravity),
   ease-in on the way down (accelerating under gravity), then a quick fade. */
@keyframes confetti-fly {
  0% {
    opacity: 1;
    transform: translate(0, 0);
    animation-timing-function: cubic-bezier(0.2, 0.6, 0.45, 1);
  }
  25% {
    opacity: 1;
    transform: translate(calc(var(--dx) * 0.4), var(--peak));
    animation-timing-function: cubic-bezier(0.55, 0, 0.85, 0.4);
  }
  92% {
    opacity: 1;
    transform: translate(calc(var(--dx) * 0.95), calc(var(--peak) + var(--fall) * 0.92));
  }
  100% {
    opacity: 0;
    transform: translate(var(--dx), calc(var(--peak) + var(--fall)));
  }
}
@keyframes confetti-spin {
  to { transform: rotate(var(--spin-turns, 720deg)); }
}
.label-divider { display: flex; align-items: center; gap: 12px; margin: 32px 0 16px; }
.label-divider::before, .label-divider::after { content: ''; flex: 1; height: 1px; background: var(--line); }
.label-divider-text { font-size: 10.5px; font-weight: 600; letter-spacing: 0.15em; text-transform: uppercase; color: var(--ink-muted); }
.photo-tile { aspect-ratio: 1; background-size: cover; background-position: center; border-radius: 3px; cursor: pointer; transition: all 0.2s; border: 1px solid var(--line); background-color: var(--paper-warm); }
@media (hover: hover) { .photo-tile:hover { transform: scale(1.02); border-color: var(--surge); } }
.photo-tile-wrap { position: relative; cursor: pointer; }
.photo-hero-badge { position: absolute; top: 6px; left: 6px; display: inline-flex; align-items: center; gap: 3px; padding: 2px 7px 2px 6px; border-radius: 4px; background: rgba(15,23,42,0.78); color: #fff; font-size: 10px; font-weight: 600; letter-spacing: 0.02em; pointer-events: none; }
.photo-hero-badge i { color: #fbbf24; }
/* Global photo library */
.photo-lib-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(208px, 1fr)); gap: 16px; }
.photo-lib-card { background: var(--paper-card); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; box-shadow: var(--shadow-sm); transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s; }
@media (hover: hover) { .photo-lib-card:hover { border-color: var(--brass-soft); box-shadow: var(--shadow-md); transform: translateY(-1px); } }
.photo-lib-card.selected { border-color: var(--brass); box-shadow: 0 0 0 1px var(--brass), var(--shadow-md); }
.photo-lib-thumb { position: relative; aspect-ratio: 4 / 3; background-size: cover; background-position: center; background-color: var(--paper-warm); cursor: pointer; }
.photo-lib-check { position: absolute; top: 8px; left: 8px; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: rgba(255,255,255,0.92); border: 1px solid rgba(15,23,42,0.18); color: transparent; cursor: pointer; transition: all 0.12s; box-shadow: var(--shadow-sm); }
@media (hover: hover) { .photo-lib-card:hover .photo-lib-check { border-color: var(--brass); } }
.photo-lib-check.on { background: var(--brass); border-color: var(--brass); color: #fff; }
.photo-lib-cat { position: absolute; bottom: 8px; left: 8px; padding: 2px 8px; border-radius: 4px; background: rgba(15,23,42,0.74); color: #fff; font-size: 10px; font-weight: 600; letter-spacing: 0.04em; text-transform: capitalize; pointer-events: none; }
.photo-lib-chips { display: flex; flex-wrap: wrap; gap: 4px; padding: 9px 10px; }
.photo-chip { display: inline-flex; align-items: center; gap: 3px; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; line-height: 1.5; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.photo-chip-property { background: var(--brass-soft); color: var(--brass-dark); }
.photo-chip-group { background: #ede9fe; color: var(--plum); }
.photo-chip-none { background: var(--paper-warm); color: var(--ink-muted); border: 1px dashed var(--line); }
.photo-chip-dataroom { background: #d1fae5; color: #047857; }
.photo-lib-actionbar { display: flex; align-items: center; gap: 8px; padding: 10px 14px; margin-bottom: 16px; background: var(--paper-card); border: 1px solid var(--brass-soft); border-radius: 10px; box-shadow: var(--shadow-sm); position: sticky; top: 0; z-index: 5; }
/* Segmented control + assignment checklist (upload & assign modals) */
.seg-control { display: inline-flex; gap: 2px; padding: 3px; background: var(--paper-warm); border-radius: 8px; }
.seg-btn { padding: 5px 12px; border-radius: 6px; font-size: 12.5px; font-weight: 500; color: var(--ink-muted); cursor: pointer; transition: all 0.12s; border: none; background: transparent; }
@media (hover: hover) { .seg-btn:hover { color: var(--ink); } }
.seg-btn.active { background: var(--paper-card); color: var(--ink); box-shadow: var(--shadow-sm); }
.assign-list { max-height: 260px; overflow-y: auto; border: 1px solid var(--line); border-radius: 8px; }
.assign-row { display: flex; align-items: center; gap: 10px; padding: 8px 11px; cursor: pointer; border-bottom: 1px solid var(--line-soft); transition: background 0.12s; }
.assign-row:last-child { border-bottom: none; }
@media (hover: hover) { .assign-row:hover { background: var(--paper-warm); } }
.assign-row.on { background: rgba(79,70,229,0.06); }
.assign-box { flex-shrink: 0; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; border: 1.5px solid var(--line); border-radius: 5px; color: #fff; background: var(--paper-card); transition: all 0.12s; }
.assign-box-radio { border-radius: 50%; }
.assign-box svg { opacity: 0; transition: opacity 0.12s; }
.assign-row.on .assign-box { background: var(--brass); border-color: var(--brass); }
.assign-row.on .assign-box svg { opacity: 1; }
.assign-row-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.assign-row-text > span:first-child { font-size: 13px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.assign-row-sub { font-size: 11px; color: var(--ink-muted); margin-top: 1px; }
/* Photo lightbox */
.pv-backdrop { position: fixed; inset: 0; z-index: 150; display: none; align-items: center; justify-content: center; background: rgba(15,23,42,0.86); opacity: 0; transition: opacity 0.18s; }
.pv-backdrop.show { display: flex; opacity: 1; }
.pv-img { max-width: min(92vw, 1200px); max-height: 84vh; object-fit: contain; border-radius: 6px; box-shadow: 0 16px 48px rgba(0,0,0,0.5); background: var(--ink); }
.pv-close { position: absolute; top: 18px; right: 18px; width: 38px; height: 38px; display: flex; align-items: center; justify-content: center; border-radius: 8px; background: rgba(255,255,255,0.1); color: #fff; border: none; cursor: pointer; transition: background 0.15s; }
@media (hover: hover) { .pv-close:hover { background: rgba(255,255,255,0.22); } }
.pv-arrow { position: absolute; top: 50%; transform: translateY(-50%); width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: rgba(255,255,255,0.1); color: #fff; border: none; cursor: pointer; transition: background 0.15s; }
@media (hover: hover) { .pv-arrow:hover { background: rgba(255,255,255,0.22); } }
.pv-arrow:disabled { opacity: 0; pointer-events: none; }
.pv-prev { left: 20px; }
.pv-next { right: 20px; }
.pv-bar { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 24px; background: linear-gradient(to top, rgba(15,23,42,0.72), transparent); }
.pv-meta { display: flex; align-items: center; gap: 12px; min-width: 0; color: #fff; }
.pv-count { font-size: 12px; font-weight: 600; color: rgba(255,255,255,0.7); white-space: nowrap; }
.pv-caption { font-size: 13px; color: rgba(255,255,255,0.92); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.pv-btn { display: inline-flex; align-items: center; gap: 5px; padding: 6px 12px; border-radius: 6px; background: rgba(255,255,255,0.12); color: #fff; border: 1px solid rgba(255,255,255,0.18); font-size: 12px; font-weight: 600; cursor: pointer; transition: background 0.15s, border-color 0.15s; }
@media (hover: hover) { .pv-btn:hover { background: rgba(255,255,255,0.24); } }
.pv-btn.active { background: #fbbf24; border-color: #fbbf24; color: var(--ink); }
@media (hover: hover) { .pv-btn.danger:hover { background: var(--rust); border-color: var(--rust); } }
.pv-dataroom { display: inline-flex; align-items: center; gap: 8px; padding-right: 10px; margin-right: 2px; border-right: 1px solid rgba(255,255,255,0.18); }
.pv-dr-label { font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: rgba(255,255,255,0.55); }
.pv-btn.pv-dr-btn.active { background: #10b981; border-color: #10b981; color: #fff; }
.cmd-key { font-family: 'JetBrains Mono', monospace; font-size: 10px; background: var(--paper-warm); border: 1px solid var(--line); border-radius: 3px; padding: 1px 5px; color: var(--ink-muted); }
.view { display: none; }
.view.active { display: block; }
.logo-mark { width: 32px; height: 32px; background: var(--ink); color: var(--paper); display: flex; align-items: center; justify-content: center; border-radius: 8px; font-family: 'Inter', sans-serif; font-weight: 700; font-size: 13px; letter-spacing: -0.03em; }
.surge-badge { background: var(--surge); color: white; font-size: 9px; font-weight: 700; letter-spacing: 0.1em; padding: 1px 5px; border-radius: 2px; text-transform: uppercase; }
.toast { position: fixed; bottom: 24px; right: 24px; background: var(--ink); color: var(--paper); padding: 12px 18px; border-radius: 8px; font-size: 13px; font-weight: 500; box-shadow: 0 8px 24px rgba(15,23,42,0.18); z-index: 200; opacity: 0; transform: translateY(8px); transition: all 0.2s; pointer-events: none; max-width: 320px; }
.toast.show { opacity: 1; transform: translateY(0); }
.conn-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--sage); box-shadow: 0 0 0 0 rgba(22,163,74,0.6); animation: pulseDot 2s infinite; flex-shrink: 0; }
.conn-dot.offline { background: var(--rust); animation: none; }
@keyframes pulseDot { 0%,100% { box-shadow: 0 0 0 0 rgba(22,163,74,0.4); } 50% { box-shadow: 0 0 0 4px rgba(22,163,74,0); } }
.modal-backdrop { position: fixed; inset: 0; background: rgba(15,23,42,0.5); display: none; align-items: center; justify-content: center; z-index: 100; padding: 20px; backdrop-filter: blur(2px); }
.modal-backdrop.show { display: flex; }
.modal-content { background: var(--paper-card); border: 1px solid var(--line); border-radius: 6px; max-width: 520px; width: 100%; padding: 24px; max-height: 90vh; overflow-y: auto; }
/* ---------- Units manager ---------- */
#units-manager-list { display: flex; flex-direction: column; gap: 8px; max-height: 52vh; overflow-y: auto; padding: 2px 2px 2px 0; }
.units-mgr-row { display: grid; grid-template-columns: minmax(78px, 1fr) 84px minmax(84px, 1.3fr) auto auto auto; align-items: center; gap: 10px; }
.units-mgr-row .input-field { padding: 7px 9px; font-size: 13px; }
.units-mgr-num { font-family: 'JetBrains Mono', monospace; font-weight: 600; }
.units-mgr-sqft { font-family: 'JetBrains Mono', monospace; }
.units-mgr-status { font-size: 12px; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.units-mgr-status.is-occupied { color: var(--ink-soft); font-weight: 500; }
.units-mgr-excl { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: var(--ink-muted); cursor: pointer; white-space: nowrap; }
.units-mgr-excl input { cursor: pointer; margin: 0; }
.units-mgr-del[disabled] { opacity: 0.32; cursor: not-allowed; }
@media (hover: hover) { .units-mgr-del:not([disabled]):hover { color: var(--rust); } }
.units-mgr-empty { font-size: 13px; color: var(--ink-muted); font-style: italic; padding: 14px 4px; }
.units-mgr-add { display: grid; grid-template-columns: minmax(78px, 1fr) 84px auto; gap: 10px; align-items: center; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
.input-field { width: 100%; background: white; border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px; font-size: 13.5px; font-family: 'Inter', sans-serif; }
.input-field:focus { outline: none; border-color: var(--brass); box-shadow: 0 0 0 3px rgba(79,70,229,0.12); }
select.input-field { background: white; }
/* Hide number-input spinner arrows app-wide - nobody uses the step buttons. */
.input-field[type=number]::-webkit-outer-spin-button,
.input-field[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.input-field[type=number] { -moz-appearance: textfield; appearance: textfield; }
@keyframes rowFlash { 0% { background: rgba(79,70,229,0.18); } 100% { background: transparent; } }
.row-flash { animation: rowFlash 1.4s ease-out; }
.empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 24px; color: var(--ink-muted); text-align: center; gap: 6px; }
.empty-state .empty-state-title { font-size: 13.5px; color: var(--ink-soft); font-weight: 500; }
.empty-state .empty-state-hint  { font-size: 12px;   color: var(--ink-muted); }
/* Compact variant for inline empty states inside panels, table bodies, etc. */
.empty-state-compact { padding: 14px 8px; font-style: italic; }
.empty-state-compact .empty-state-title { font-size: 12.5px; font-style: italic; font-weight: 400; }
.empty-state-compact .empty-state-hint  { display: none; }
.step-num { width: 24px; height: 24px; border-radius: 50%; background: var(--paper-warm); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 600; color: var(--ink-muted); transition: all 0.2s; }
.step-num.active { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.step-num.done { background: var(--sage); color: white; border-color: var(--sage); }
.review-row { display: flex; padding: 4px 0; }
.review-label { width: 130px; color: var(--ink-muted); font-size: 11px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; padding-top: 1px; }
.review-val { flex: 1; color: var(--ink); font-weight: 500; }
.image-drop { position: relative; border: 2px dashed var(--line); border-radius: 6px; padding: 32px 20px; text-align: center; cursor: pointer; background: var(--paper-warm); transition: all 0.15s; min-height: 140px; display: flex; align-items: center; justify-content: center; }
@media (hover: hover) { .image-drop:hover { border-color: var(--brass); background: rgba(79,70,229,0.04); } }
.image-drop.drag-over { border-color: var(--brass); background: rgba(79,70,229,0.08); }
.image-drop.has-image { padding: 0; border-style: solid; border-color: var(--line); }
.hidden-file { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
#image-drop-preview { aspect-ratio: 16/9; background-size: cover; background-position: center; }
.archived-banner { background: rgba(79,70,229,0.12); border: 1px solid var(--brass-soft); color: var(--brass-dark); padding: 10px 16px; border-radius: 8px; font-size: 13px; display: flex; align-items: center; gap: 8px; margin-bottom: 16px; }
/* searchable combobox */
.combo { position: relative; }
.combo-input { width: 100%; background: white; border: 1px solid var(--line); border-radius: 8px; padding: 8px 32px 8px 12px; font-size: 13.5px; font-family: 'Inter', sans-serif; cursor: pointer; }
.combo-input:focus { outline: none; border-color: var(--ink); }
.combo-chevron { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--ink-muted); }
.combo-panel { position: absolute; top: calc(100% + 4px); left: 0; right: 0; background: white; border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 8px 24px rgba(15,23,42,0.12); z-index: 1000; max-height: 280px; overflow-y: auto; display: none; }
.combo-panel.open { display: block; }
.combo-option { padding: 8px 12px; font-size: 13.5px; cursor: pointer; border-bottom: 1px solid var(--line-soft); transition: background 0.1s; }
.combo-option:last-child { border-bottom: none; }
@media (hover: hover) { .combo-option:hover, .combo-option.highlighted { background: var(--paper-warm); } }
.combo-option.selected { background: rgba(79,70,229,0.08); font-weight: 500; }
.combo-option .option-sub { font-size: 11.5px; color: var(--ink-muted); margin-top: 1px; }
.combo-option .option-create { color: var(--brass-dark); font-weight: 500; }
.combo-option .match { background: rgba(79,70,229,0.25); font-weight: 600; }
.combo-empty { padding: 14px 12px; font-size: 12.5px; color: var(--ink-muted); font-style: italic; text-align: center; }
.combo-group-label { padding: 10px 12px 4px; font-size: 10px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-muted); background: var(--paper-warm); border-bottom: 1px solid var(--line-soft); position: sticky; top: 0; }
/* task side panel */
.mobile-only { display: none; } /* inverse of .desktop-hide — see the mobile media block */
.panel-backdrop { position: fixed; inset: 0; background: rgba(15,23,42,0.45); display: none; z-index: 90; backdrop-filter: blur(1px); }
.panel-backdrop.show { display: block; }
.side-panel { position: fixed; top: 0; right: 0; height: 100vh; width: 580px; max-width: 100vw; background: var(--paper-card); border-left: 1px solid var(--line); transform: translateX(100%); transition: transform 0.25s cubic-bezier(0.4,0,0.2,1); z-index: 100; display: flex; flex-direction: column; }
/* Leads — monday-style status pills + clickable rows (app-leads.js) */
.lead-pill { display: inline-block; font-size: 11px; font-weight: 700; padding: 3px 11px; border-radius: 5px; color: #fff; letter-spacing: 0.02em; white-space: nowrap; }
.lead-row { cursor: pointer; }
.lead-row:hover td { background: var(--paper-warm); }

/* Lead panel — mirrors the task panel skeleton. */
.lead-ai-card { margin: 14px 24px 0; padding: 11px 14px 12px; border: 1px solid var(--brass-soft); background: rgba(199,210,254,0.14); border-radius: 10px; }
.lead-ai-card.empty { border-style: dashed; background: var(--paper-warm); border-color: var(--line); }
.lead-ai-head { display: flex; align-items: center; gap: 6px; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--brass-dark); margin-bottom: 5px; }
.lead-ai-card.empty .lead-ai-head { color: var(--ink-muted); }
.lead-ai-head .lead-ai-when { margin-left: auto; font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--ink-muted); font-size: 11px; }
.lead-ai-body { font-size: 13px; line-height: 1.55; color: var(--ink-soft); white-space: pre-wrap; }
.lead-ai-card.empty .lead-ai-body { color: var(--ink-muted); font-style: italic; }

/* Details grid — inline-editable fields, no Edit button. Inputs read as
   plain text until hover/focus. */
.lead-detail-grid { display: grid; grid-template-columns: 84px 1fr; column-gap: 14px; row-gap: 2px; align-items: center; }
.lead-detail-k { color: var(--ink-muted); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; }
.lead-field-wrap { display: flex; align-items: center; gap: 8px; min-width: 0; }
.lead-field { flex: 1; min-width: 0; font: inherit; font-size: 13px; color: var(--ink); background: transparent; border: 1px solid transparent; border-radius: 6px; padding: 5px 8px; outline: none; }
.lead-field::placeholder { color: var(--ink-muted); font-style: italic; }
@media (hover: hover) { .lead-field-wrap:hover .lead-field { border-color: var(--line); background: var(--paper-card); } }
.lead-field:focus { border-color: var(--brass); background: var(--paper-card); box-shadow: 0 0 0 2px rgba(79,70,229,0.18); }
.lead-field-select { appearance: none; cursor: pointer; flex: 0 1 auto; }
.lead-field-link { display: inline-flex; color: var(--brass-dark); flex-shrink: 0; padding: 4px; border-radius: 6px; }
@media (hover: hover) { .lead-field-link:hover { background: var(--paper-warm); } }
.lead-intake-note { margin-top: 10px; font-size: 12.5px; color: var(--ink-soft); background: var(--paper-warm); border: 1px solid var(--line); border-radius: 8px; padding: 9px 12px; white-space: pre-wrap; }

/* Quick actions — one-click touches. */
.lead-qa-hint { font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--ink-muted); font-size: 11px; margin-left: 6px; }
.lead-qa-row { display: flex; flex-wrap: wrap; gap: 8px; }
.lead-qa-btn { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; color: var(--ink-soft); background: var(--paper-card); border: 1px solid var(--line); border-radius: 8px; padding: 7px 12px; cursor: pointer; transition: border-color 0.12s, background 0.12s; }
@media (hover: hover) { .lead-qa-btn:hover { border-color: var(--brass); color: var(--brass-dark); background: rgba(199,210,254,0.12); } }
.lead-qa-btn:active { transform: scale(0.97); }

/* Composer staging — a pending status change rides above the textarea. */
.lead-staged-chip { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; color: var(--ink-soft); background: var(--paper-warm); border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px; margin-bottom: 8px; flex-wrap: wrap; }
.lead-staged-note { font-weight: 500; color: var(--ink-muted); font-size: 11.5px; }
.lead-quick-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--paper-warm); border: 1px solid var(--line); color: var(--ink-soft); }

/* Collapsed popup-event cluster in the lead timeline. */
.update-cluster { margin: 4px 0; }
.update-cluster-head {
  display: flex; align-items: center; gap: 7px; width: 100%; text-align: left;
  font-size: 12px; color: var(--ink-muted); background: none; border: 0;
  border-radius: 6px; padding: 5px 8px; cursor: pointer; font-family: inherit;
}
@media (hover: hover) { .update-cluster-head:hover { background: var(--paper-warm); color: var(--ink-soft); } }
.update-cluster-body { margin: 2px 0 6px 14px; padding-left: 10px; border-left: 1px solid var(--line); }
.side-panel.show { transform: translateX(0); box-shadow: -8px 0 32px rgba(15,23,42,0.12); }

/* ============== TASK PANEL — Monday-feel, Asana-skeleton ==============
   A 4px colored accent strip at the very top sets visual tone from the
   status. Header is a clean breadcrumb + close on top, then title + done
   toggle. Below the header sits a chunky chip row with Status / Priority /
   Due / Assignee / Property pills — each opens the same popover the
   Monday table uses. Below that, three clear sections with left-accent
   dividers: Description, Attachments, Activity. */
.task-status-strip {
  height: 4px;
  width: 100%;
  background: var(--ink-muted);
  transition: background 200ms ease-out;
  flex-shrink: 0;
}
.task-status-strip.status-open        { background: #c4c4c4; }
.task-status-strip.status-on_track    { background: #16d093; }
.task-status-strip.status-in_progress { background: #fdab3d; }
.task-status-strip.status-waiting     { background: #a25ddc; }
.task-status-strip.status-stuck       { background: #e2445c; }
.task-status-strip.status-delayed     { background: #ff7043; }
.task-status-strip.status-done        { background: #00c875; }
.task-status-strip.status-abandoned   { background: #595959; }

.task-panel-header { padding: 18px 22px 14px; border-bottom: 1px solid var(--line-soft); position: relative; }
/* padding-right keeps the title from running under the absolute X close. */
.task-panel-title-row { display: flex; align-items: flex-start; gap: 10px; padding-right: 34px; }
.task-done-circle {
  background: transparent; border: 2px solid var(--ink-muted);
  border-radius: 50%; width: 24px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; flex-shrink: 0; margin-top: 6px;
  transition: all 150ms ease-out;
}
@media (hover: hover) { .task-done-circle:hover { border-color: var(--sage); background: rgba(0,200,117,0.08); } }
.task-done-circle.done { background: #00c875; border-color: #00c875; }
.task-done-circle.done i { color: white; }
.task-done-circle i { color: transparent; transition: color 150ms; }
@media (hover: hover) { .task-done-circle:hover i { color: var(--sage); } }
@media (hover: hover) { .task-done-circle.done:hover i { color: white; } }

.task-title-input {
  flex: 1;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.2;
  background: transparent;
  border: 1px solid transparent;
  padding: 4px 8px;
  margin: -4px -8px;
  border-radius: 5px;
  color: var(--ink);
  width: 100%;
  resize: none;
  /* textarea — let long titles wrap; height is set via autoGrowTitle JS */
  overflow: hidden;
  overflow-wrap: break-word;
  word-break: break-word;
  white-space: pre-wrap;
  min-height: 32px;
}
@media (hover: hover) { .task-title-input:hover { border-color: var(--line-soft); } }
.task-title-input:focus { outline: none; border-color: var(--ink); background: white; }
.task-title-input.done { color: var(--ink-muted); text-decoration: line-through; }

/* Chip row — the Monday-style chunky pills under the title */
.task-chip-row {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 14px 22px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--paper-warm);
}
.task-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 11px;
  background: white;
  border: 1px solid var(--line);
  border-radius: 5px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 120ms, background 120ms, filter 150ms ease-out;
  min-height: 30px;
}
@media (hover: hover) { .task-chip:hover { border-color: var(--ink-soft); } }
.task-chip:focus, .task-chip:focus-visible { outline: none; border-color: var(--ink); box-shadow: 0 0 0 2px rgba(79,70,229, 0.30); }
.task-chip .chip-label { color: var(--ink-muted); font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; }
.task-chip .chip-value { color: var(--ink); font-weight: 600; }
.task-chip .chev { color: var(--ink-muted); opacity: 0.55; }

/* Status / priority chips are FULL-COLOR — same DNA as the Monday table cells */
.task-chip-color {
  border: none;
  color: #fff;
  padding: 6px 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
@media (hover: hover) { .task-chip-color:hover { filter: brightness(1.06); border: none; } }
.task-chip-color .chev { color: rgba(255,255,255,0.7); opacity: 1; }

.task-chip-status-open        { background: #c4c4c4; }
.task-chip-status-on_track    { background: #16d093; }
.task-chip-status-in_progress { background: #fdab3d; }
.task-chip-status-waiting     { background: #a25ddc; }
.task-chip-status-stuck       { background: #e2445c; }
.task-chip-status-delayed     { background: #ff7043; }
.task-chip-status-done        { background: #00c875; }
.task-chip-status-abandoned   { background: #595959; }
.task-chip-priority-low      { background: #eaeef2; color: #6b7280; }
.task-chip-priority-low .chev { color: rgba(107,114,128,0.7); }
.task-chip-priority-medium   { background: #cbd2db; color: #444; }
.task-chip-priority-medium .chev { color: rgba(68,68,68,0.7); }
.task-chip-priority-high     { background: #5559df; }
.task-chip-priority-urgent   { background: #bb3354; }

.task-chip-assignee .avatar { width: 22px; height: 22px; font-size: 9.5px; }
.task-chip-assignee .empty-avatar { width: 22px; height: 22px; border-radius: 50%; border: 1.5px dashed var(--line); display: flex; align-items: center; justify-content: center; color: var(--ink-muted); font-size: 11px; }

/* Stacked avatar group — up to 3 overlap, the rest collapses into a +N pill */
.avatar-stack { display: inline-flex; align-items: center; }
.avatar-stack .avatar-stack-item { display: inline-flex; }
.avatar-stack .avatar-stack-item + .avatar-stack-item { margin-left: -7px; }
.avatar-stack .avatar-stack-item .avatar { border: 2px solid var(--paper-card); }
.avatar-stack-sm .avatar-stack-item + .avatar-stack-item { margin-left: -6px; }
.avatar-stack-sm .avatar-stack-item .avatar { border-width: 1.5px; }
.avatar-stack-more {
  margin-left: -7px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--paper-warm);
  border: 2px solid var(--paper-card);
  color: var(--ink-soft);
  font-size: 10px;
  font-weight: 600;
}
.avatar-stack-sm .avatar-stack-more { width: 22px; height: 22px; font-size: 9.5px; border-width: 1.5px; margin-left: -6px; }
.task-chip-property .group-icon { color: var(--brass-dark); }
.task-chip-due.overdue { color: var(--rust); }

/* Sections — chunky left-accent dividers in the body */
.task-section { padding: 18px 22px; border-bottom: 1px solid var(--line-soft); }
.task-section:last-child { border-bottom: none; }
.task-section-header {
  display: flex; align-items: center;
  font-size: 11px; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ink-muted);
  margin-bottom: 12px;
  padding-left: 10px;
  position: relative;
}
.task-section-header::before {
  content: ''; position: absolute; left: 0; top: 1px; bottom: 1px; width: 3px;
  background: var(--brass); border-radius: 2px;
}
.task-section-header .section-action { margin-left: auto; }
.task-section-empty { padding: 14px 8px 8px; color: var(--ink-muted); font-size: 12.5px; font-style: italic; }

/* Subtasks list inside the task panel */
.subtask-list { display: flex; flex-direction: column; gap: 2px; margin: 4px 0 6px; }
/* ---- Threaded comments ---------------------------------------------
   Two levels only. Replies sit under their root behind a rule, so a thread
   reads as one exchange rather than a flat run of comments. */
.update-thread + .update-thread { margin-top: 14px; }
.update-replies {
  margin: 8px 0 0 14px; padding-left: 14px;
  border-left: 2px solid var(--line-soft);
  display: flex; flex-direction: column; gap: 10px;
}
.thread-reply-wrap { margin: 6px 0 0 38px; }
.thread-reply-btn {
  display: inline-flex; align-items: center; gap: 4px;
  background: none; border: none; padding: 2px 0; cursor: pointer;
  font-family: inherit; font-size: 11.5px; color: var(--ink-muted);
}
@media (hover: hover) { .thread-reply-btn:hover { color: var(--brass-dark); } }
.thread-reply-box[hidden] { display: none; }
.thread-reply-box { margin-top: 6px; }
.thread-reply-input {
  width: 100%; border: 1px solid var(--line); border-radius: 8px;
  padding: 7px 10px; font-family: 'Inter', sans-serif; font-size: 13px;
  line-height: 1.5; color: var(--ink); background: white; resize: vertical;
}
.thread-reply-input:focus { outline: none; border-color: var(--brass); }
.thread-reply-actions { display: flex; gap: 6px; margin-top: 6px; }
.thread-reply-send, .thread-reply-cancel {
  font-family: inherit; font-size: 12px; border-radius: 6px;
  padding: 5px 11px; cursor: pointer; border: 1px solid transparent;
}
.thread-reply-send { background: var(--ink); color: var(--paper); }
@media (hover: hover) { .thread-reply-send:hover { background: var(--ink-soft); } }
.thread-reply-cancel { background: transparent; color: var(--ink-muted); border-color: var(--line); }
@media (hover: hover) { .thread-reply-cancel:hover { color: var(--ink); } }

/* Sortable column headers on the tasks board. The caret only occupies space
   when a sort is active, so the header doesn't shift as you cycle columns. */
.task-th-sort { cursor: pointer; user-select: none; display: flex; align-items: center; gap: 3px; }
@media (hover: hover) { .task-th-sort:hover { color: var(--ink); } }
.task-th-sort:focus-visible { outline: 2px solid var(--brass); outline-offset: -2px; border-radius: 3px; }
.task-th-sort.active { color: var(--brass-dark); }
.task-sort-caret { font-size: 9px; line-height: 1; }

/* Opened by clicking the subtask in a task list — a brief tint so the click
   visibly resolves somewhere. Fades to nothing rather than leaving a state. */
.subtask-row.subtask-flash { animation: subtaskFlash 1.5s ease-out; }
@keyframes subtaskFlash {
  0%, 25% { background: var(--brass-soft); }
  100%    { background: transparent; }
}

/* A subtask row is a checklist line, not a table row: the due date and
   assignee are bare text/avatar rather than boxed chips, and the columns are
   fixed-width so every row's avatar and delete land on the same x. (Boxed
   chips on `auto` columns made each row a different width, and an empty due
   rendered as an em-dash in a box, which reads as a value — or worse, as a
   minus button — instead of "click to set".) */
.subtask-row {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) 66px 44px 20px;
  align-items: center;
  gap: 9px;
  padding: 3px 4px;
  border-radius: 6px;
  min-height: 32px;
}
@media (hover: hover) { .subtask-row:hover { background: var(--paper-warm); } }
.subtask-check {
  width: 17px; height: 17px;
  border: 1.5px solid var(--line);
  border-radius: 50%;          /* round reads as a to-do tick, not a checkbox field */
  background: white;
  color: white;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
}
@media (hover: hover) { .subtask-check:hover { border-color: var(--sage); } }
.subtask-check.done { background: var(--sage); border-color: var(--sage); }
.subtask-title-input {
  border: 1px solid transparent;
  background: transparent;
  padding: 3px 5px;
  border-radius: 4px;
  font-size: 13px;
  color: var(--ink);
  min-width: 0;
  width: 100%;
}
@media (hover: hover) { .subtask-title-input:hover { border-color: var(--line-soft); background: white; } }
.subtask-title-input:focus { outline: none; border-color: var(--brass); background: white; }
.subtask-title-input.done { color: var(--ink-muted); text-decoration: line-through; }
.subtask-due, .subtask-assignee, .subtask-delete {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--ink-muted); font-family: inherit;
  display: flex; align-items: center;
}
.subtask-due { font-size: 11.5px; white-space: nowrap; justify-content: flex-end; }
.subtask-due.overdue { color: var(--rust); font-weight: 600; }
.subtask-due.today { color: var(--brass-dark); font-weight: 600; }
.subtask-assignee { justify-content: center; }
.subtask-delete { font-size: 16px; line-height: 1; justify-content: center; opacity: 0.35; }
/* Unset due/assignee are faint icons — an affordance, not a value. */
.subtask-due.unset, .subtask-assignee.unset { opacity: 0.38; }
@media (hover: hover) {
  .subtask-row:hover .subtask-delete { opacity: 0.7; }
  .subtask-delete:hover { opacity: 1; color: var(--rust); }
  .subtask-row:hover .subtask-due.unset,
  .subtask-row:hover .subtask-assignee.unset { opacity: 0.75; }
  .subtask-due.unset:hover, .subtask-assignee.unset:hover { opacity: 1; color: var(--brass-dark); }
}
/* Touch: nothing can be revealed on hover, so the quiet controls stay legible.
   The old delete was opacity:0 with a hover-only reveal — unreachable on a
   phone, which is half of why this row felt wrong. */
@media (hover: none) {
  .subtask-delete { opacity: 0.55; }
  .subtask-due.unset, .subtask-assignee.unset { opacity: 0.6; }
  /* Same hover-reveal problem as the subtask controls: invisible on touch. */
  .update-delete, .att-remove { opacity: 0.55; }
  /* The done circle's check only appeared on hover — give touch a faint
     always-on hint of what tapping the circle does. */
  .task-done-circle:not(.done) i { color: var(--line); }
}

/* "+ Add subtask" inline input below the list */
.subtask-add-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 4px;
  border-radius: 8px;
  margin-top: 2px;
  color: var(--ink-muted);
}
@media (hover: hover) { .subtask-add-row:hover { background: var(--paper-warm); } }
.subtask-add-row .add-icon { color: var(--brass-dark); }
.subtask-add-input {
  flex: 1;
  border: none;
  background: transparent;
  font-size: 13px;
  color: var(--ink);
  outline: none;
  padding: 4px 0;
}
.subtask-add-input::placeholder { color: var(--ink-muted); }

/* Subtask count badge on the kanban row title cell */
.task-td-title {
  display: flex; align-items: center; gap: 10px;
}
.task-td-title-text { flex: 1; min-width: 0; }
.subtask-badge {
  flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 6px;
  border-radius: 8px;
  background: var(--paper-warm);
  color: var(--ink-muted);
  font-size: 10.5px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 600;
  border: 1px solid var(--line-soft);
}
.subtask-badge.all-done { background: rgba(22,163,74,0.12); color: var(--sage); border-color: rgba(22,163,74,0.30); }
.subtask-badge i { width: 10px; height: 10px; }

/* Composer — rounded, padded, prominent Post button */
.panel-composer { border-top: 1px solid var(--line); padding: 14px 18px 16px; background: var(--paper-card); flex-shrink: 0; }
.composer-textarea {
  border-radius: 6px;
  padding: 10px 12px;
  transition: border-color 150ms;
}
.task-post-btn {
  padding: 8px 16px;
  font-weight: 600;
  border-radius: 5px;
  background: var(--ink);
  color: var(--paper);
  transition: filter 150ms, transform 80ms ease-out;
}
@media (hover: hover) { .task-post-btn:hover { filter: brightness(1.1); } }
.task-post-btn:active { transform: scale(0.97); }

/* Within the task panel only, the description textarea uses the section
   body styling — no inner border (the section header is the divider). */
#task-panel .panel-desc-input { border: 1px solid transparent; padding: 8px 10px; }
@media (hover: hover) { #task-panel .panel-desc-input:hover { border-color: var(--line-soft); } }
#task-panel .panel-desc-input:focus { border-color: var(--ink); background: white; outline: none; }

.panel-header { padding: 18px 22px 12px; border-bottom: 1px solid var(--line-soft); position: relative; }
.panel-close { position: absolute; top: 12px; right: 14px; }
.panel-meta { padding: 12px 22px; border-bottom: 1px solid var(--line-soft); background: var(--paper-warm); display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px 16px; }
.panel-meta-item { display: flex; flex-direction: column; gap: 4px; }
.panel-meta-item .kpi-label { font-size: 10px; }
.panel-meta-item .input-field { padding: 6px 10px; font-size: 12.5px; }
.panel-meta-item .combo-input { padding: 6px 26px 6px 10px; font-size: 12.5px; }
/* min-height: 0 lets the flex item actually shrink below its content height —
   without it, tall content pushes the pinned composer off the panel bottom. */
.panel-scroll { flex: 1; min-height: 0; overflow-y: auto; }
.panel-body { padding: 18px 22px 8px; }
.panel-composer { border-top: 1px solid var(--line); padding: 12px 18px 14px; background: var(--paper-card); flex-shrink: 0; }
.panel-title-input { width: 100%; font-family: 'Inter', system-ui, sans-serif; font-size: 20px; font-weight: 600; letter-spacing: -0.01em; background: transparent; border: 1px solid transparent; padding: 4px 6px; margin: -4px -6px; border-radius: 8px; color: var(--ink); }
@media (hover: hover) { .panel-title-input:hover { border-color: var(--line-soft); } }
.panel-title-input:focus { outline: none; border-color: var(--ink); background: white; }
.panel-desc-input { width: 100%; min-height: 60px; resize: vertical; font-family: 'Inter', sans-serif; font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); background: transparent; border: 1px solid transparent; padding: 8px 10px; border-radius: 8px; }
@media (hover: hover) { .panel-desc-input:hover { border-color: var(--line-soft); } }
.panel-desc-input:focus { outline: none; border-color: var(--ink); background: white; color: var(--ink); }
.update-list { display: flex; flex-direction: column; gap: 14px; padding-bottom: 6px; }
.update-item { display: flex; gap: 10px; align-items: flex-start; }
.update-avatar { width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; color: white; font-size: 10.5px; font-weight: 600; }
.update-bubble { flex: 1; min-width: 0; }
.update-meta { font-size: 11.5px; color: var(--ink-muted); margin-bottom: 3px; display: flex; align-items: center; gap: 6px; }
.update-author { color: var(--ink); font-weight: 600; }
/* Parent breadcrumb on an assigned subtask surfaced in a top-level list. */
.subtask-parent { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; color: var(--ink-muted); margin-right: 6px; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
.subtask-parent i { flex-shrink: 0; opacity: 0.7; }
.task-created-meta { font-size: 11.5px; color: var(--ink-muted); margin-bottom: 10px; }
.task-created-meta:empty { display: none; }
.update-via { display: inline-flex; align-items: center; gap: 3px; font-size: 10.5px; font-weight: 500; color: var(--ink-muted); background: var(--paper-warm); border: 1px solid var(--line-soft); border-radius: 3px; padding: 0 4px; line-height: 1.5; }
.update-via i { width: 10px; height: 10px; }
.update-body { font-size: 13.5px; color: var(--ink-soft); line-height: 1.55; white-space: pre-wrap; word-wrap: break-word; }
.update-delete { opacity: 0; transition: opacity 0.15s; background: transparent; border: none; color: var(--ink-muted); cursor: pointer; padding: 0 4px; font-size: 11px; }
@media (hover: hover) { .update-item:hover .update-delete { opacity: 1; } }
@media (hover: hover) { .update-delete:hover { color: var(--rust); } }
.update-system { font-size: 12px; color: var(--ink-muted); padding: 2px 0; display: flex; align-items: center; gap: 8px; }
.update-system i { color: var(--brass); flex-shrink: 0; }
.mention-pill { display: inline; background: rgba(79,70,229,0.15); color: var(--brass-dark); padding: 1px 5px; border-radius: 3px; font-weight: 500; }
/* ---- "Notifying" bar --------------------------------------------------
   Sits above the composer and names everyone the message will notify —
   including anyone the auto-@ guessed. Every chip clicks off, which also
   strips the "@" back out of the text. */
.mbar { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin-bottom: 7px; }
.mbar-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--ink-muted); }
.mbar-chip { display: inline-flex; align-items: center; gap: 5px; border: 1px solid rgba(79,70,229,0.3); background: rgba(79,70,229,0.08); color: var(--brass-dark); border-radius: 999px; font-family: inherit; font-size: 12px; font-weight: 500; padding: 2px 8px 2px 3px; cursor: pointer; }
@media (hover: hover) { .mbar-chip:hover { border-color: var(--rust); color: var(--rust); background: rgba(220,38,38,0.06); } }
.mbar-av { width: 17px; height: 17px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 8.5px; font-weight: 600; flex-shrink: 0; }
.mbar-x { font-size: 12px; opacity: 0.65; }
.thread-reply-box .mbar { margin: 6px 0 0; }
.composer-textarea { width: 100%; min-height: 44px; max-height: 140px; resize: none; border: 1px solid var(--line); border-radius: 8px; padding: 9px 12px; font-family: 'Inter', sans-serif; font-size: 13.5px; line-height: 1.5; background: white; color: var(--ink); }
.composer-textarea:focus { outline: none; border-color: var(--ink); }
.composer-bar { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; }
.mention-popup { position: absolute; background: white; border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 8px 24px rgba(15,23,42,0.14); z-index: 1200; max-height: 240px; overflow-y: auto; width: 260px; bottom: calc(100% + 6px); left: 0; }
.mention-popup .mp-option { padding: 7px 12px; cursor: pointer; font-size: 13px; display: flex; align-items: center; gap: 8px; border-bottom: 1px solid var(--line-soft); }
.mention-popup .mp-option:last-child { border-bottom: none; }
@media (hover: hover) { .mention-popup .mp-option:hover, .mention-popup .mp-option.highlighted { background: var(--paper-warm); } }
.mp-avatar { width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 10px; font-weight: 600; flex-shrink: 0; }
.attachments-strip { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.attachment-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; background: var(--paper-warm); border: 1px solid var(--line); border-radius: 8px; font-size: 12.5px; max-width: 260px; position: relative; }
@media (hover: hover) { .attachment-item:hover .att-remove { opacity: 1; } }
.attachment-item .att-info { flex: 1; min-width: 0; }
.attachment-item .att-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); font-weight: 500; display: block; }
.attachment-item .att-meta { color: var(--ink-muted); font-size: 11px; }
.attachment-thumb { width: 32px; height: 32px; border-radius: 3px; background-size: cover; background-position: center; background-color: var(--line-soft); flex-shrink: 0; display: flex; align-items: center; justify-content: center; color: var(--ink-muted); }
.att-remove { opacity: 0; transition: opacity 0.15s; background: transparent; border: none; color: var(--ink-muted); cursor: pointer; padding: 0 2px; }
@media (hover: hover) { .att-remove:hover { color: var(--rust); } }
.panel-dropzone { position: absolute; inset: 0; background: rgba(79,70,229,0.14); border: 2px dashed var(--brass); display: none; align-items: center; justify-content: center; color: var(--brass-dark); font-weight: 600; font-size: 14px; z-index: 5; pointer-events: none; gap: 8px; }
.side-panel.drag-over .panel-dropzone { display: flex; }
/* unit checklist (multi-unit lease) */
.unit-checklist { max-height: 220px; overflow-y: auto; border: 1px solid var(--line); border-radius: 8px; padding: 4px; background: var(--paper-card); }
.unit-check { display: grid; grid-template-columns: 16px 1fr auto auto; gap: 10px; align-items: center; padding: 6px 8px; border-radius: 3px; font-size: 13px; cursor: pointer; }
.unit-more-toggle { display: block; width: 100%; text-align: left; background: none; border: none; cursor: pointer; color: var(--brass-dark); font-size: 12px; font-weight: 500; padding: 6px 8px; margin-top: 2px; border-top: 1px solid var(--line); }
@media (hover: hover) { .unit-more-toggle:hover { color: var(--brass); } }
@media (hover: hover) { .unit-check:hover:not(.disabled) { background: var(--paper-warm); } }
.unit-check.disabled { opacity: 0.5; cursor: not-allowed; }
.unit-check input[type=checkbox] { margin: 0; }
.unit-check-num { color: var(--ink); font-weight: 500; }
.unit-check-sqft { font-family: 'JetBrains Mono', monospace; font-size: 11.5px; color: var(--ink-muted); }
.unit-check-status { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; padding: 1px 6px; border-radius: 2px; }
.unit-check-status.vacant { background: rgba(22,163,74,0.12); color: var(--sage); }
.unit-check-status.occupied { background: rgba(79,70,229,0.12); color: var(--brass-dark); }
.unit-check-status.current { background: rgba(79,70,229,0.18); color: var(--brass-dark); }
.unit-check-group-label { font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-muted); padding: 8px 8px 4px; border-top: 1px solid var(--line-soft); margin-top: 2px; }
.unit-check-group-label:first-child { border-top: none; margin-top: 0; padding-top: 4px; }
/* sublease rows (single line + expandable detail panel) */
.sublet-item { border: 1px solid transparent; border-radius: 8px; }
.sublet-item.open { border-color: var(--line); background: var(--paper-card); padding: 4px 6px 8px; }
.sublet-expand { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 28px; flex-shrink: 0; background: none; border: none; padding: 0; cursor: pointer; color: var(--ink-muted); transition: color 0.15s; }
@media (hover: hover) { .sublet-expand:hover { color: var(--brass-dark); } }
.sublet-expand i { transition: transform 0.15s; }
.sublet-item.open .sublet-expand i { transform: rotate(90deg); }
.sublet-detail { margin: 8px 0 2px; padding: 10px 12px; border-radius: 6px; background: var(--paper-warm); border: 1px solid var(--line-soft); }
.sublet-detail-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
.sublet-field { display: flex; flex-direction: column; gap: 3px; }
.sublet-field-label { font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted); }
.sublet-detail-hint { margin-top: 8px; font-size: 11px; color: var(--ink-muted); line-height: 1.4; }
.sublet-schedule-section { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line-soft); }
/* notifications */
.notif-row { display: flex; gap: 12px; align-items: flex-start; padding: 12px 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--paper-card); cursor: pointer; transition: all 0.15s; }
@media (hover: hover) { .notif-row:hover { border-color: var(--ink-soft); background: var(--paper-warm); } }
.notif-row.unread { background: rgba(79,70,229,0.06); border-left: 3px solid var(--brass); }
.notif-row.unread .notif-msg { color: var(--ink); font-weight: 500; }
.notif-row .notif-msg { color: var(--ink-soft); font-size: 13.5px; line-height: 1.45; }
.notif-row .notif-meta { font-size: 11.5px; color: var(--ink-muted); margin-top: 3px; }
.notif-row .notif-snippet { font-size: 12.5px; color: var(--ink-muted); margin-top: 6px; padding: 6px 9px; background: var(--paper-warm); border-radius: 3px; line-height: 1.45; max-width: 100%; overflow: hidden; }
.notif-avatar { width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; color: white; font-size: 11px; font-weight: 600; }
/* ===== Collapsible sidebar (desktop/tablet) ===== */
.dms-sidebar { transition: width 0.2s cubic-bezier(0.4,0,0.2,1); }
.dms-sidebar.collapsed { width: 60px !important; }
.dms-sidebar.collapsed .nav-item { font-size: 0; justify-content: center; padding-left: 0; padding-right: 0; gap: 0; }
.dms-sidebar.collapsed .nav-item > span { display: none; }
.dms-sidebar.collapsed .nav-section-label,
.dms-sidebar.collapsed #property-nav-list,
.dms-sidebar.collapsed [data-collapse-hide] { display: none !important; }
.dms-sidebar.collapsed .sidebar-header-row { justify-content: center; }
/* Sidebar brand logo: bigger when expanded, scales to fit the rail when collapsed */
.sidebar-logo { display: block; height: 44px; width: auto; max-width: 100%; }
.dms-sidebar.collapsed .sidebar-logo { height: auto; width: 100%; }
.dms-sidebar.collapsed .sidebar-conn { justify-content: center; }
.dms-sidebar.collapsed .px-5 { padding-left: 6px; padding-right: 6px; }
.dms-sidebar.collapsed .px-3 { padding-left: 6px; padding-right: 6px; }
.sidebar-collapse-btn { display: flex; align-items: center; gap: 8px; width: 100%; padding: 7px 12px; border: none; background: transparent; color: var(--ink-muted); font-size: 12px; cursor: pointer; border-radius: 8px; transition: background 0.15s; }
@media (hover: hover) { .sidebar-collapse-btn:hover { background: var(--paper-card); color: var(--ink-soft); } }
.dms-sidebar.collapsed .sidebar-collapse-btn { justify-content: center; padding: 7px 0; }
.dms-sidebar.collapsed .sidebar-collapse-btn span { display: none; }
/* ===== Mobile responsive ===== */
.sidebar-backdrop { position: fixed; inset: 0; background: rgba(15,23,42,0.45); z-index: 75; opacity: 0; pointer-events: none; transition: opacity 0.2s ease; }
.sidebar-backdrop.open { opacity: 1; pointer-events: auto; }
.sidebar-toggle-btn { display: none; }
/* Mobile bottom tab bar is a phones-only component; hidden by default. */
.mobile-tabbar { display: none; }
/* "Mobile" is width < 768px OR a touch device in landscape (a phone rotated
   to landscape reports a wide CSS width — >767px — but keeps a short viewport
   and a coarse pointer; without this it would fall back to the desktop layout).
   The desktop query is the exact negation so the two never both apply. */
@media (min-width: 768px) and (not ((pointer: coarse) and (max-height: 500px))) {
  .sidebar-backdrop { display: none !important; }
  /* Symmetric partner to .mobile-hide below: hide on desktop, show on mobile.
     Used by the portfolio's mobile-only "+ Add" trigger (desktop creates from
     the top-bar "+", which is itself hidden on phones). */
  .desktop-hide { display: none !important; }
}
@media (max-width: 767px), (pointer: coarse) and (max-height: 500px) {
  .sidebar-toggle-btn { display: inline-flex; }
  .dms-sidebar { position: fixed; top: 0; bottom: 0; left: 0; z-index: 80; transform: translateX(-100%); transition: transform 0.25s cubic-bezier(0.4,0,0.2,1); }
  .dms-sidebar.open { transform: translateX(0); box-shadow: 4px 0 24px rgba(15,23,42,0.18); }
  /* Full-screen on phones, and it arrives from the BOTTOM: a full-width sheet
     sliding in from the right reads as a desktop drawer that swallowed the
     screen. Up-from-the-bottom matches every other sheet in the app. */
  /* Pinned to both edges rather than width:100vw — 100vw ignores a scrollbar
     gutter and leaves the panel hanging off one side. height uses dvh: 100vh
     is the LARGE viewport on iOS Safari, which parked the pinned composer
     (and its Post update button) under the browser toolbar. */
  .side-panel {
    left: 0; right: 0; width: auto !important; max-width: none;
    height: 100dvh;
    border-left: none;
    transform: translateY(100%);
  }
  .side-panel.show { transform: translateY(0); }
  .mobile-only { display: inline-flex; }
  /* ===== Task panel: native phone layout ===== */
  /* One inline header row: back chevron · done circle · title. The panel
     lives outside <main>, so it needs its own notch inset. */
  .task-panel-header { padding: calc(10px + env(safe-area-inset-top)) 16px 12px 8px; }
  /* flex-start + margins that center every control on the title's FIRST line
     (back 40px, circle 30px, 20px title ≈ 32px line box), so a long title
     wraps below while the controls stay pinned to the top row. */
  .task-panel-title-row { gap: 8px; padding-right: 0; }
  .panel-back { flex-shrink: 0; margin-top: -4px; }
  /* The X is redundant once there's a back chevron. */
  .task-panel-header .panel-close { display: none; }
  .task-done-circle { width: 30px; height: 30px; margin-top: 1px; flex-shrink: 0; }
  /* Chips become real buttons: taller, bigger type, press feedback. */
  .task-chip-row { padding: 14px 16px; }
  .task-chip {
    min-height: 42px; padding: 8px 14px; font-size: 14px; border-radius: 8px;
    -webkit-tap-highlight-color: transparent;
  }
  .task-chip:active { filter: brightness(0.94); }
  .task-section { padding: 16px; }
  /* Finger-sized subtask rows. */
  .subtask-row { min-height: 44px; padding: 6px 4px; }
  .subtask-check { width: 22px; height: 22px; }
  .panel-scroll { overscroll-behavior: contain; }
  /* Composer: clear the home indicator, and make Send the unmissable
     primary — it stretches to fill the row at full tap height. */
  .panel-composer { padding-bottom: calc(14px + env(safe-area-inset-bottom)); }
  .composer-bar > .flex.gap-2 { flex: 1; margin-left: 10px; }
  .task-post-btn { flex: 1; min-height: 44px; font-size: 15px; justify-content: center; display: inline-flex; align-items: center; gap: 6px; }
  /* ===== Data tables → stacked label/value cards (the native phone pattern) =====
     Each row becomes a card-like block inside the existing card; the column header
     is mirrored onto each cell as `data-label` (by setupDataTableLabeling() in app.js)
     and surfaced via td::before. No more sideways scroll hiding Status/Cost. */
  /* Units & Tenants and Documents swap their desktop tables for card lists. */
  .units-desktop, .docs-desktop { display: none; }
  .units-mobile, .docs-mobile { display: block; }
  /* Group summary popup does the same: each building's tenant table → cards. */
  .gsum-desktop { display: none; }
  .gsum-mobile { display: block; }
  table.data-table { min-width: 0; }
  .card.overflow-hidden:has(table.data-table) { overflow-x: visible; }
  .data-table thead { display: none; }
  .data-table, .data-table tbody { display: block; width: 100%; }
  .data-table tr { display: block; padding: 11px 15px; border-bottom: 1px solid var(--line); }
  .data-table tr:last-child { border-bottom: none; }
  .data-table td {
    display: flex; justify-content: space-between; align-items: baseline; gap: 14px;
    padding: 4px 0; border: none; font-size: 13.5px; text-align: right; min-width: 0;
  }
  .data-table td::before {
    content: attr(data-label);
    flex: 0 0 auto; text-align: left;
    font-size: 10.5px; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase;
    color: var(--ink-muted); white-space: nowrap;
  }
  .data-table td:first-child { font-weight: 600; color: var(--ink); }
  /* Empty-state rows (single colspan cell) span the whole card, no label. */
  .data-table td[colspan] { display: block; text-align: center; }
  .data-table td[colspan]::before { content: none; }
  /* Grouped/detail rows leave some cells blank; don't show a stray label for them. */
  .data-table td:empty { display: none; }
  .panel-meta { grid-template-columns: 1fr; }
  .sidebar-collapse-btn { display: none; }
  /* Phones scroll vertically only — nothing can drag the page sideways.
     Genuinely-wide content (data tables) still scrolls inside its own card.
     overscroll-behavior stops the rubber-band from chaining to the page. */
  /* Bottom padding clears the fixed tab bar so the last content isn't hidden. */
  .view { overflow-x: hidden; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; padding-bottom: calc(64px + env(safe-area-inset-bottom)); }
  /* Reclaim the desktop 32px page gutters that waste a phone's width. */
  .view.p-8 { padding: 20px 16px calc(64px + env(safe-area-inset-bottom)); }
  .view > .px-8 { padding: 20px 16px; }
  /* Page headers stack (title over actions) instead of overflowing one row. */
  .view .flex.items-end.justify-between { flex-wrap: wrap; align-items: flex-start; gap: 12px 10px; }
  .view .flex.items-end.justify-between > .flex { flex-wrap: wrap; }
  /* Dashboard KPI strips reflow to 2-up so labels aren't crushed/clipped. */
  #kpi-strip, #maint-kpi-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* An odd final KPI would sit alone leaving a blank cell — let it span the row. */
  #kpi-strip > div:last-child:nth-child(odd),
  #maint-kpi-strip > div:last-child:nth-child(odd) { grid-column: 1 / -1; }
  /* Portfolio KPIs collapse behind a tap on phones — they're reference metrics,
     not the reason you opened the app on a phone, so they start hidden. */
  .kpi-toggle {
    display: flex; align-items: center; justify-content: space-between; width: 100%;
    padding: 11px 14px; background: var(--paper-card); border: 1px solid var(--line);
    border-radius: 6px; font-size: 12px; font-weight: 600; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--ink-muted);
  }
  #kpi-strip { display: none; margin-top: 10px; }
  #kpi-section.kpi-open #kpi-strip { display: grid; }
  /* Generic phone-only hide (e.g. the rent-roll "Add Unit" action). */
  .mobile-hide { display: none !important; }
  /* Rent roll is read-only on phones: drop the per-row edit/floor-plan action
     column (tapping a lease opens a read-only summary instead). */
  .data-table td.cell-row-actions { display: none; }
  /* Tighten desktop-scale vertical rhythm: 40px section gap is dead space on a phone. */
  .view .mt-10 { margin-top: 24px; }
  /* ===== Touch & viewport ergonomics ===== */
  /* Shell fits the actually-visible viewport — no content cut off behind the
     browser's address/tab bar the way 100vh does on mobile. */
  .h-screen { height: 100dvh; }
  /* 16px form controls stop iOS Safari from auto-zooming when a field is
     focused. Class selectors beat the bare element ones regardless of this
     media query, so every field whose BASE font-size comes from a class must
     be listed here explicitly — a missing one zooms (the description did). */
  input, select, textarea,
  .input-field, .search-input, .combo-input,
  .task-title-input, .subtask-title-input, .subtask-add-input,
  .panel-desc-input, .date-segment, .rec-input,
  .composer-textarea, .filter-search input, .pp-search-wrap input { font-size: 16px; }
  /* 16px is a floor, not a target: the task title should still read as a
     title. Anything ≥16px is zoom-safe. (Placed after the list so it wins.) */
  .task-title-input { font-size: 20px; }
  /* Finger-friendly touch targets. */
  .btn-icon { width: 40px; height: 40px; }
  /* Text buttons render ~36px tall from their padding alone — below the 44px
     minimum tap target. min-height lifts the hit area without touching font
     size or horizontal padding (inline-flex just re-centers the label). */
  .btn-primary, .btn-secondary { min-height: 44px; }
  .nav-item { padding: 11px 12px; }
  /* ===== Bottom tab bar — the signature "it's an app" primary nav ===== */
  .mobile-tabbar {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
    background: var(--paper-card); border-top: 1px solid var(--line);
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: 0 -1px 12px rgba(15,23,42,0.06);
  }
  .mobile-tab {
    flex: 1; min-width: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 3px;
    padding: 8px 2px 7px; background: none; border: 0; cursor: pointer;
    color: var(--ink-muted); font-size: 10px; font-weight: 500; letter-spacing: 0.01em;
    white-space: nowrap; -webkit-tap-highlight-color: transparent; transition: color 0.15s;
  }
  .mobile-tab i, .mobile-tab svg { width: 22px; height: 22px; }
  .mobile-tab.active { color: var(--brass-dark); }
  .mobile-tab-icon-wrap { position: relative; display: inline-flex; }
  .mobile-tab-badge {
    position: absolute; top: -6px; right: -9px; min-width: 15px; height: 15px;
    padding: 0 4px; border-radius: 8px; background: var(--rust); color: #fff;
    font-size: 9px; font-weight: 700; line-height: 15px; text-align: center;
  }
  /* ===== Safe-area insets (notch / Dynamic Island / home indicator) ===== */
  /* viewport-fit=cover lets content fill the screen edge-to-edge; these pad it
     back out of the unsafe zones. env() is 0 on non-notched devices, so this is
     a no-op everywhere else. The tab bar/views already pad the bottom inset. */
  /* Top inset only — leave the header's Tailwind px-3 horizontal padding alone
     (landscape left/right insets are an edge case for this portrait-first app). */
  /* The top bar (search, AI, +Task, notifications, help) is desktop-oriented
     clutter on a phone — hidden entirely. Navigation lives in the bottom tab
     bar, so nothing here is load-bearing. Its notch inset moves to <main> so
     page content still clears the status bar. */
  .app-topbar { display: none; }
  main { padding-top: env(safe-area-inset-top); }
  /* Hide the portfolio header actions (Export / Group Buildings / Add Property)
     on phones — these are desktop-workflow controls; the mobile header stays lean. */
  #portfolio-actions { display: none; }
  .dms-sidebar { padding-top: env(safe-area-inset-top); }
  .mobile-tabbar { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }
  /* ===== Property detail: reflow dense desktop grids for phones ===== */
  /* Stat grids (hero/secondary specs, safety…) go 2-up instead of 3/4-up so the
     big display numbers aren't crushed into ~80px columns. */
  #view-property .grid-cols-4,
  #view-property .grid-cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 16px; }
  /* The page-layout grid (main col-span-2 + sidebar) stacks into one column.
     More specific than the rule above, so it wins for this grid only. */
  #view-property .grid-cols-3:has(> .col-span-2) { grid-template-columns: 1fr; }
  #view-property .grid-cols-3:has(> .col-span-2) > .col-span-2 { grid-column: auto; }

  /* Hero overlay + the stats band use bare px-8 (32px) gutters; the tab strip and
     tab content already drop to px-4 on phones. Only literal `px-8` elements match,
     so this trims just those two bands back to the 16px page gutter. */
  #view-property .px-8 { padding-left: 16px; padding-right: 16px; }
  /* Stats band: 6 headline figures reflow 3-up (a 6-wide row crushed them into
     ~50px columns), with the display numbers eased down so large values don't clip.
     The Photos tab's 6-up thumbnail grid rides the same rule — 3 larger tiles per
     row reads far better on a phone than 6 fingernail-sized ones. */
  #view-property .grid-cols-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px 12px; }
  #view-property .grid-cols-6 .font-display { font-size: 20px; }
  /* That band justifies the stats against the management buttons (Data Room / Group
     / Edit) in one row that overflowed sideways on a phone. Stack it: stats on top,
     the button cluster below, wrapping rather than forcing a horizontal scroll. */
  #view-property .flex.items-start.justify-between { flex-direction: column; gap: 14px; }
  #view-property .flex.items-start.justify-between > .flex.items-center { flex-wrap: wrap; }
  /* The Group / Edit Property controls are desktop admin actions — drop them from
     the phone stats band so its action row is just the Data Room control. */
  #view-property .prop-admin-action { display: none; }
  /* Data Rooms moves up into the hero (top-right, mirroring the Back pill) on
     phones, so drop the stats-band copy entirely — the band becomes pure KPIs. */
  #view-property .deck-btn { display: none; }
  #view-property .hero-share { display: inline-flex; }
  /* Detail-tab content cards carry desktop p-5/p-6 (20–24px) padding that eats a
     phone's width; tighten them to a uniform 16px. Table cards use a bare `card`
     (no padding utility) so they're untouched and stay edge-to-edge. */
  #view-property .card.p-6, #view-property .card.p-5 { padding: 16px; }
  /* Section tab strip: 24px inter-tab gaps make the scroll row sprawl — pull them
     in so more of Overview / Tasks / Units… reads at a glance. nowrap keeps each
     label on a single line (e.g. "Units & Tenants") so the row scrolls cleanly
     instead of letting a label wrap to two lines and bloat the strip height. */
  #view-property .tab { margin-right: 18px; white-space: nowrap; }
  /* Swap the horizontal tab scroll for the native section picker on phones. */
  #view-property .tabs-desktop { display: none; }
  #view-property .tabs-mobile { display: block; }
  /* Access & Codes on phones: stack the header — the Add-Code button comes
     first as a full-width indigo CTA, the count sits above the list. Rows
     drop the "Rotated" date (the code and its label are what you're at the
     door for) and grow their tap targets. */
  #view-property .access-head { flex-direction: column; align-items: stretch; gap: 10px; }
  #view-property .access-add { order: 1; width: 100%; justify-content: center; padding: 11px; font-size: 14px; background: var(--brass); border-color: var(--brass); color: #fff; }
  #view-property .code-row { padding: 13px 12px; gap: 10px; }
  #view-property .code-row-rotated { display: none; }
  #view-property .code-row-value { font-size: 15px; padding: 5px 11px; }

  /* Property type filters (All Types / Charter School / Class A Office…): on phones
     they wrapped to several rows and pushed the grid down. Make them a single
     horizontally-scrolling row — the familiar mobile chip carousel. id selector
     (1,0,0) beats Tailwind's `flex-wrap` (0,1,0). The strip scrolls within the
     content padding, so no page-level horizontal scroll is introduced. */
  #type-filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;            /* Firefox */
    /* Pad the trailing edge a touch so the last chip doesn't kiss the viewport. */
    padding-right: 2px;
  }
  #type-filters::-webkit-scrollbar { display: none; }  /* WebKit/Safari */
  /* Keep each chip at its natural width — scroll past them, never squeeze them. */
  #type-filters > .btn-secondary { flex: 0 0 auto; }

  /* Modals → bottom sheets (native phone pattern): dock to the bottom edge,
     full-width, rounded top, slide up, with a grab handle. !important beats the
     inline max-width overrides on a few modals (property 640px, signlease 560px…). */
  .modal-backdrop { align-items: flex-end; padding: 0; }
  .modal-content {
    width: 100%; max-width: 100% !important;
    max-height: 92vh;
    border-radius: 16px 16px 0 0;
    border-bottom: none;
    padding: 20px 18px calc(20px + env(safe-area-inset-bottom));
    animation: sheetUp 0.28s cubic-bezier(0.4, 0, 0.2, 1);
    /* Scrolling to the end of a sheet must not start scrolling the page. */
    overscroll-behavior: contain;
  }
  .modal-content::before {
    content: ''; display: block;
    width: 36px; height: 4px; border-radius: 2px;
    background: var(--line); margin: -4px auto 14px;
  }

  /* ===== Tasks: filter chip row (replaces the wrapping desktop bar) =====
     One horizontally scrolling line: group-by · whose tasks · slice · search. */
  .tfilter-row {
    display: flex; gap: 8px; overflow-x: auto; margin-bottom: 12px;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .tfilter-row::-webkit-scrollbar { display: none; }
  .tfilter-chip {
    flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
    height: 38px; padding: 0 13px; border-radius: 19px;
    background: var(--paper-card); border: 1px solid var(--line);
    font-size: 13px; font-weight: 500; color: var(--ink-soft);
    white-space: nowrap; max-width: 60vw; overflow: hidden; text-overflow: ellipsis;
    -webkit-tap-highlight-color: transparent;
  }
  .tfilter-chip i, .tfilter-chip svg { flex: 0 0 auto; color: var(--ink-muted); }
  .tfilter-chip:active { background: var(--paper-warm); }
  .tfilter-chip.primary { border-color: var(--ink); background: var(--ink); color: #fff; }
  .tfilter-chip.primary i, .tfilter-chip.primary svg { color: rgba(255,255,255,0.75); }
  .tfilter-chip.active { border-color: var(--brass); color: var(--brass-dark); background: rgba(79,70,229,0.06); }
  .tfilter-chip.active i, .tfilter-chip.active svg { color: var(--brass-dark); }
  .tfilter-count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px;
    background: rgba(15,23,42,0.08); font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums;
  }
  .task-chip.primary .tfilter-count { background: rgba(255,255,255,0.22); }
  .task-search-row { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
  .task-search-row input { flex: 1; min-width: 0; }

  /* ===== Tasks: card list (replaces the 978px desktop grid on phones) =====
     Built by _taskCardHtml. Two lines: complete circle | title + meta |
     status pill + avatars. Mirrors the .unit-card rent-roll pattern. */
  .task-board { overflow-x: hidden; border-radius: 0; border-left: none; border-right: none; }
  .task-card {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 11px 14px 11px 4px;
    border-bottom: 1px solid var(--line-soft);
    background: var(--paper-card);
    border-left: 3px solid var(--accent, var(--line));
  }
  .task-card:active { background: var(--paper-warm); }
  .task-card:last-of-type { border-bottom: none; }
  /* 44px tap target around a 22px circle — the whole left gutter completes. */
  .tc-check {
    flex: 0 0 auto; width: 44px; min-height: 44px; margin: -4px 0;
    display: flex; align-items: center; justify-content: center;
    background: none; border: 0; cursor: pointer; -webkit-tap-highlight-color: transparent;
  }
  .tc-check-circle {
    width: 22px; height: 22px; border-radius: 50%;
    border: 1.5px solid var(--line); background: var(--paper-card);
    display: flex; align-items: center; justify-content: center; color: #fff;
    transition: background 120ms ease-out, border-color 120ms ease-out;
  }
  .task-card.done .tc-check-circle { background: var(--sage); border-color: var(--sage); }
  .tc-body { flex: 1; min-width: 0; padding: 2px 0; }
  .tc-parent {
    display: flex; align-items: center; gap: 3px;
    font-size: 11px; color: var(--ink-muted); margin-bottom: 2px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .tc-title {
    font-size: 14.5px; font-weight: 500; color: var(--ink); line-height: 1.35;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .task-card.done .tc-title { text-decoration: line-through; color: var(--ink-muted); }
  .tc-meta {
    display: flex; align-items: center; flex-wrap: wrap; gap: 5px;
    margin-top: 4px; font-size: 11.5px; color: var(--ink-muted);
  }
  .tc-dot { color: var(--line); }
  .tc-due.overdue { color: var(--rust); font-weight: 600; }
  .tc-due.today { color: var(--amber); font-weight: 600; }
  .tc-sub.all-done { color: var(--sage); }
  .tc-right { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
  .tc-status {
    border: 0; border-radius: 5px; cursor: pointer; -webkit-tap-highlight-color: transparent;
    padding: 5px 9px; min-height: 30px;
    font-size: 11px; font-weight: 600; letter-spacing: 0.02em; white-space: nowrap;
    color: #fff; background: var(--tc-accent, var(--ink-muted));
  }
  .tc-status:active { filter: brightness(0.92); }

  /* Floating "new task" button — the topbar + is hidden on phones. Under the
     tab bar (z 70) and any sheet, clear of the home indicator. */
  #task-fab {
    position: fixed; right: 16px; bottom: calc(76px + env(safe-area-inset-bottom));
    z-index: 65; width: 54px; height: 54px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--brass); color: #fff; border: 0;
    box-shadow: 0 6px 20px rgba(79,70,229,0.4);
    -webkit-tap-highlight-color: transparent;
  }
  #task-fab i, #task-fab svg { width: 24px; height: 24px; }
  #task-fab:active { transform: scale(0.94); background: var(--brass-dark); }

  /* Cell pickers (status / priority / due / assignee / property / task filter)
     → bottom sheets, same as modals. An anchored dropdown next to a 44px row
     lands under the thumb and clips against the keyboard. CellPopover.open()
     adds .cell-popover-sheet on phones; every caller gets this for free.
     z-index clears the side panel (100) so the task-panel chips work too. */
  .cell-popover-sheet-backdrop { position: fixed; inset: 0; z-index: 1299; background: rgba(15,23,42,0.42); }
  .cell-popover.cell-popover-sheet {
    left: 0 !important; right: 0; top: auto !important; bottom: 0;
    width: 100%; min-width: 0; max-width: 100%;
    max-height: 78dvh;
    border-radius: 16px 16px 0 0; border-bottom: none;
    padding-bottom: env(safe-area-inset-bottom);
    animation: sheetUp 0.28s cubic-bezier(0.4, 0, 0.2, 1);
    overscroll-behavior: contain;
  }
  .cell-popover-sheet::before {
    content: ''; display: block;
    width: 36px; height: 4px; border-radius: 2px;
    background: var(--line); margin: 8px auto 6px;
  }
  /* Finger-sized rows — the desktop list is built for a mouse. */
  .cell-popover-sheet .cell-popover-option { padding: 13px 16px; font-size: 15px; }
  .cell-popover-sheet .pp-search-wrap { padding: 8px 14px; }
  /* Dense 3-up form rows (City/State/Zip, Block/Lot/Zoning…) are too cramped at
     390px once the modal is a full-width sheet. Reflow to 2-up. Scoped with
     :has(.input-field) so it only hits FORM grids, never stat-tile grids (e.g. the
     Sqft/Units/Occupancy cards). gap-y stays generous so labels breathe. */
  .modal-content .grid-cols-3:has(.input-field) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px 12px;
  }
}

/* ============== EMAIL UI ============== */
/* Intent badges — one color per email intent classification */
.intent-badge { display: inline-flex; align-items: center; padding: 2px 7px; font-size: 10.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; border-radius: 2px; border: 1px solid transparent; white-space: nowrap; }
.intent-lease       { background: rgba(79,70,229,0.12);  color: var(--brass-dark); border-color: rgba(79,70,229,0.25); }
.intent-ar          { background: rgba(22,163,74,0.12);  color: var(--sage);       border-color: rgba(22,163,74,0.25); }
.intent-ap          { background: rgba(220,38,38,0.10);   color: var(--rust);       border-color: rgba(220,38,38,0.25); }
.intent-maintenance { background: rgba(234,88,12,0.10);   color: var(--surge);      border-color: rgba(234,88,12,0.25); }
.intent-deal        { background: rgba(124,58,237,0.10);  color: var(--plum);       border-color: rgba(124,58,237,0.25); }
.intent-vendor      { background: var(--paper-warm);      color: var(--ink-soft);   border-color: var(--line); }
.intent-legal       { background: rgba(15,23,42,0.06);    color: var(--ink);        border-color: var(--line); }
.intent-prospecting { background: rgba(79,70,229,0.06);  color: var(--brass-dark); border-color: var(--line-soft); }
.intent-admin       { background: var(--paper-warm);      color: var(--ink-muted);  border-color: var(--line-soft); }
.intent-personal    { background: rgba(124,58,237,0.06);  color: var(--plum);       border-color: var(--line-soft); }
.intent-general     { background: var(--paper-warm);      color: var(--ink-muted);  border-color: var(--line-soft); }

/* Urgency: dots */
.urgency-dots { display: inline-flex; gap: 2px; }
.urgency-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--line); }
.urgency-dot.on-1 { background: var(--ink-muted); }
.urgency-dot.on-2 { background: var(--brass); }
.urgency-dot.on-3 { background: var(--brass-dark); }
.urgency-dot.on-4 { background: var(--rust); }
.urgency-dot.on-5 { background: var(--surge); }

/* Email row */
.email-row { cursor: pointer; }
.email-row td.email-subject { color: var(--ink); font-weight: 500; }
.email-row.unread td.email-subject { font-weight: 600; }
.email-row .email-no-subject { color: var(--ink-muted); font-style: italic; font-weight: 400; }

/* Linked-entity chip (used in inbox + email panel) */
.entity-chip { display: inline-flex; align-items: center; gap: 4px; padding: 1px 7px; border-radius: 2px; font-size: 11px; background: var(--paper-warm); color: var(--ink-soft); border: 1px solid var(--line); cursor: pointer; transition: all 0.15s; }
@media (hover: hover) { .entity-chip:hover { background: var(--paper-card); border-color: var(--ink-soft); } }
.entity-chip .entity-chip-type { font-size: 9.5px; font-weight: 600; color: var(--ink-muted); text-transform: uppercase; letter-spacing: 0.06em; }

/* Attention card — for clarifications / inconsistencies / suggested actions */
.attention-card { background: var(--paper-card); border: 1px solid var(--line); border-left: 3px solid var(--ink-muted); border-radius: 8px; padding: 16px 18px; transition: all 0.15s; }
@media (hover: hover) { .attention-card:hover { border-color: var(--ink-soft); } }
.attention-card.kind-inconsistency { border-left-color: var(--rust); }
.attention-card.kind-clarification { border-left-color: var(--brass); }
.attention-card.kind-suggested-action { border-left-color: var(--sage); }
.attention-kind-label { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }
.attention-kind-label.kind-inconsistency { color: var(--rust); }
.attention-kind-label.kind-clarification { color: var(--brass-dark); }
.attention-kind-label.kind-suggested-action { color: var(--sage); }
.attention-card .att-question { font-size: 14px; color: var(--ink); line-height: 1.45; margin: 6px 0 12px; }
.attention-card .att-source { font-size: 11.5px; color: var(--ink-muted); margin-bottom: 12px; }
.attention-card .att-source a { color: var(--brass-dark); }
@media (hover: hover) { .attention-card .att-source a:hover { text-decoration: underline; } }
.attention-card.resolved { opacity: 0.6; border-left-color: var(--sage); }

/* Option button — for clarification resolve choices */
.option-btn { display: inline-flex; align-items: center; gap: 6px; background: var(--paper-card); color: var(--ink); border: 1px solid var(--line); border-radius: 8px; padding: 7px 12px; font-size: 12.5px; font-weight: 500; cursor: pointer; transition: all 0.15s; }
@media (hover: hover) { .option-btn:hover { background: var(--paper-warm); border-color: var(--ink-soft); } }
.option-btn.primary { background: var(--ink); color: var(--paper); border-color: var(--ink); }
@media (hover: hover) { .option-btn.primary:hover { background: var(--ink-soft); } }
.option-btn.danger { color: var(--rust); border-color: rgba(220,38,38,0.3); }
@media (hover: hover) { .option-btn.danger:hover { background: rgba(220,38,38,0.05); border-color: var(--rust); } }

/* Email detail panel */
#email-panel .panel-body { padding: 18px 22px 28px; }
.email-meta-row { display: flex; gap: 8px; font-size: 12.5px; padding: 3px 0; }
.email-meta-row .label { color: var(--ink-muted); min-width: 60px; }
.email-meta-row .val { color: var(--ink); flex: 1; word-break: break-word; }
.email-body-block { background: var(--paper-warm); border: 1px solid var(--line-soft); border-radius: 8px; padding: 14px 16px; font-size: 13px; line-height: 1.55; color: var(--ink-soft); max-height: 380px; overflow-y: auto; white-space: pre-wrap; }
.email-section-title { font-size: 10.5px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-muted); margin: 22px 0 8px; display: flex; align-items: center; gap: 8px; }
.email-section-title::after { content: ''; flex: 1; height: 1px; background: var(--line-soft); }
.key-fact-row { display: flex; gap: 10px; padding: 3px 0; font-size: 12.5px; }
.key-fact-row .kf-key { color: var(--ink-muted); min-width: 130px; font-weight: 500; }
.key-fact-row .kf-val { color: var(--ink); flex: 1; }
.attachment-item { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border: 1px solid var(--line-soft); border-radius: 3px; margin-bottom: 6px; font-size: 12.5px; }
.attachment-item .att-icon { width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; border-radius: 3px; background: var(--paper-warm); color: var(--ink-soft); }
.attachment-item .att-name { flex: 1; min-width: 0; }
.attachment-item .att-name-text { font-weight: 500; color: var(--ink); word-break: break-all; }
.attachment-item .att-meta { font-size: 10.5px; color: var(--ink-muted); margin-top: 2px; }
.attachment-item .att-status { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; padding: 1px 6px; border-radius: 2px; }
.att-status.completed { background: rgba(22,163,74,0.12); color: var(--sage); }
.att-status.pending   { background: var(--paper-warm); color: var(--ink-muted); border: 1px solid var(--line); }
.att-status.failed    { background: rgba(220,38,38,0.10); color: var(--rust); border: 1px solid rgba(220,38,38,0.3); }
.att-status.skipped   { background: var(--paper-warm); color: var(--ink-muted); }

/* ============== DENSITY TOGGLE ============== */
/* Base spacing is "comfortable". data-density="compact" (the default) tightens
   the data-heavy surfaces — tables, task rows, kanban cards — for more rows per
   screen. Only vertical padding/heights change, so column alignment is untouched. */
html[data-density="compact"] .data-table th { padding-top: 6px; padding-bottom: 6px; }
html[data-density="compact"] .data-table td { padding-top: 8px; padding-bottom: 8px; }
html[data-density="compact"] .task-tr { min-height: 44px; }
html[data-density="compact"] .task-td-title,
html[data-density="compact"] .task-cell-status,
html[data-density="compact"] .task-cell-priority,
html[data-density="compact"] .task-td-due,
html[data-density="compact"] .task-td-property,
html[data-density="compact"] .task-td-person { padding-top: 10px; padding-bottom: 10px; }
html[data-density="compact"] .kanban-card,
html[data-density="compact"] .kanban-card-done { padding-top: 7px; padding-bottom: 7px; }

/* ============== CLICK-TO-SORT TABLES ============== */
.data-table th.sortable { cursor: pointer; user-select: none; }
@media (hover: hover) { .data-table th.sortable:hover { color: var(--ink-soft); } }
.sort-caret { display: inline-block; width: 8px; margin-left: 4px; font-size: 9px; color: var(--brass-dark); }
