/* ============================================================
   Client CRM — Apple-inspired design system
   Light mode · SF system stack · iOS blue accent · frosted glass
   ============================================================ */
:root {
  --blue: #007AFF;
  --blue-dark: #0062CC;
  --blue-light: #3D9BFF;
  --accent-rgb: 0, 122, 255;
  --bg: #F2F2F7;
  --card: #FFFFFF;
  --elevated: #FFFFFF;
  --label: #1C1C1E;
  --label-2: #3A3A3C;
  --label-3: #8E8E93;
  --separator: rgba(60, 60, 67, 0.12);
  --radius: 16px;
  --radius-s: 12px;
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 4px 16px rgba(0, 0, 0, 0.06);
  --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.14);
  --today-max-h: 336px; /* Home scroll-panel height cap (v86 Today brief + v87 Needs attention) — tunable */
  --header-blur: saturate(180%) blur(20px);
  /* Surface tokens (v90): every chrome surface routes through a variable
     so the dark palette only has to redefine this block. */
  --header-bg: rgba(255, 255, 255, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000)));
  --sidebar-bg: rgba(255, 255, 255, calc(0.82 * var(--glass-m, 1) + (1 - 0.82 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.82 * 1000)));
  --dock-bg: rgba(255, 255, 255, calc(0.55 * var(--glass-m, 1) + (1 - 0.55 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.55 * 1000)));
  --dock-border: rgba(255, 255, 255, 0.55);
  --login-card-bg: rgba(255, 255, 255, calc(0.82 * var(--glass-m, 1) + (1 - 0.82 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.82 * 1000)));
  --login-card-border: rgba(255, 255, 255, 0.6);
  --col-bg: rgba(255, 255, 255, 0.6);
  --input-bg: #FFFFFF;
  --check-bg: #FFFFFF;
  --check-border: #C7C7CC;
  --fill: rgba(120, 120, 128, 0.14);
  --fill-strong: rgba(120, 120, 128, 0.22);
  --bg-secondary: rgba(60, 60, 67, 0.06);
  --grabber: rgba(60, 60, 67, 0.25);
  /* Spring easings (v90, Apple doctrine — springs, not tweens):
     --spring is the standard interruptible iOS-style curve;
     --spring-bounce adds a gentle overshoot for the task check-off.
     v97 pacing pass (Nelson: animations liked, but too quick): motion
     durations scaled ~1.5x and the bounce overshoot softened 1.4 -> 1.25
     so springs settle more gently. Curves stay interruptible. */
  --spring: cubic-bezier(.32, .72, .24, 1);
  --spring-bounce: cubic-bezier(.34, 1.25, .64, 1);
  color-scheme: light;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
          "Helvetica Neue", "Segoe UI", Arial, sans-serif;
}

/* The `hidden` attribute must always win, even on elements that set
   their own display (flex/grid). Without this, login/app/sheet/modal
   can render stacked on top of each other. */
[hidden] { display: none !important; }

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0; padding: 0;
  font-family: var(--font);
  background: var(--bg);
  color: var(--label);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overscroll-behavior: none;
}

body { min-height: 100vh; min-height: 100dvh; touch-action: manipulation; }

/* ---------------- Login ---------------- */
.login-view {
  min-height: 100vh; min-height: 100dvh;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background:
    radial-gradient(1200px 600px at 20% -10%, rgba(var(--accent-rgb), 0.12), transparent 60%),
    radial-gradient(900px 500px at 90% 110%, rgba(175, 82, 222, 0.10), transparent 60%),
    var(--bg);
}
.login-card {
  width: 100%; max-width: 380px;
  background: var(--login-card-bg);
  -webkit-backdrop-filter: var(--header-blur); backdrop-filter: var(--header-blur);
  border: 1px solid var(--login-card-border);
  border-radius: 22px;
  box-shadow: var(--shadow-lg);
  padding: 36px 30px 30px;
  text-align: center;
}
.login-mark { margin-bottom: 14px; }
.login-card h1 { margin: 0 0 6px; font-size: 26px; font-weight: 700; letter-spacing: -0.4px; }
.login-sub { margin: 0 0 24px; color: var(--label-3); font-size: 14px; }
.field { display: block; text-align: left; margin-bottom: 14px; }
.field span { display: block; font-size: 13px; font-weight: 600; color: var(--label-2); margin-bottom: 6px; }
.field input {
  width: 100%; padding: 12px 14px;
  font: inherit; font-size: 16px;
  border: 1px solid var(--separator); border-radius: var(--radius-s);
  background: var(--input-bg); outline: none;
  transition: border-color .3s, box-shadow .3s;
}
.field input:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.15); }
.btn-primary {
  width: 100%; padding: 13px; margin-top: 6px;
  font: inherit; font-size: 16px; font-weight: 600; color: #fff;
  background: var(--blue); border: none; border-radius: var(--radius-s);
  cursor: pointer; transition: background .3s, transform .15s;
}
.btn-primary:hover { background: var(--blue-dark); }
.btn-primary:active { transform: scale(0.98); }
.btn-primary:disabled { opacity: 0.6; cursor: default; }
.login-error {
  color: #FF3B30; font-size: 13px; margin: 4px 0 10px;
  background: rgba(255, 59, 48, 0.08); border-radius: 8px; padding: 8px 10px;
}
.config-warning {
  margin-top: 16px; font-size: 12.5px; color: var(--label-3);
  background: rgba(255, 149, 0, 0.1); border-radius: 8px; padding: 8px 10px;
}
.config-warning code { font-family: ui-monospace, monospace; }

/* ---------------- App shell ---------------- */
.app { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; }

.app-header {
  position: sticky; top: 0; z-index: 40;
  background: var(--header-bg);
  -webkit-backdrop-filter: var(--header-blur); backdrop-filter: var(--header-blur);
  border-bottom: 1px solid var(--separator);
}
.header-row {
  display: flex; align-items: center; gap: 12px;
  padding: calc(10px + env(safe-area-inset-top)) 16px 10px;
  max-width: 1400px; margin: 0 auto; width: 100%;
}
.brand { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 17px; letter-spacing: -0.3px; white-space: nowrap; }
.header-stats { display: flex; gap: 8px; margin-left: auto; overflow-x: auto; scrollbar-width: none; }
.header-stats::-webkit-scrollbar { display: none; }
.stat-chip {
  flex: 0 0 auto; font-size: 12.5px; font-weight: 600;
  padding: 6px 10px; border-radius: 999px;
  background: rgba(var(--accent-rgb), 0.1); color: var(--blue);
  white-space: nowrap;
}
.stat-chip.warn { background: rgba(255, 59, 48, 0.1); color: #FF3B30; }
.stat-chip.ok { background: rgba(52, 199, 89, 0.12); color: #248A3D; }
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border: none; border-radius: 50%;
  background: transparent; color: var(--label-2); cursor: pointer;
  transition: background .3s;
}
.icon-btn:hover { background: rgba(60, 60, 67, 0.08); }
.icon-btn.on { color: var(--blue); }
.icon-btn.on svg { fill: rgba(var(--accent-rgb), 0.18); }

.views { flex: 1; width: 100%; max-width: 1400px; margin: 0 auto;
  padding: 20px 18px calc(128px + env(safe-area-inset-bottom)); }
.view h2.view-title { margin: 4px 0 14px; font-size: 32px; font-weight: 700; letter-spacing: -0.5px; }

/* ---------------- Liquid Glass bottom dock (iOS 26 style) ---------------- */
.toptabs {
  position: fixed; z-index: 50;
  left: 50%; transform: translateX(-50%);
  bottom: calc(10px + env(safe-area-inset-bottom));
  width: min(520px, calc(100% - 20px));
  display: flex; justify-content: space-around; align-items: center;
  padding: 8px 6px; margin: 0;
  background: var(--dock-bg);
  -webkit-backdrop-filter: blur(28px) saturate(180%);
  backdrop-filter: blur(28px) saturate(180%);
  border-radius: 30px;
  border: 1px solid var(--dock-border);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.65);
}
.toptabs::-webkit-scrollbar { display: none; }
/* v90: the ACTIVE tab is a labeled pill (icon + text); inactive tabs are
   icon-only. The label expands with a spring-timed max-width transition,
   which reads as the pill gliding open around the active tab. */
.toptabs .tab {
  flex: 0 0 auto; display: flex; flex-direction: row; align-items: center; justify-content: center;
  border: 0; cursor: pointer; font: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--label-3); background: transparent;
  padding: 8px 11px; border-radius: 999px;
  transition: background .45s var(--spring), color .3s, transform .38s var(--spring);
  -webkit-tap-highlight-color: transparent;
}
.toptabs .tab:active { transform: scale(0.92); }
.toptabs .tab svg { width: 23px; height: 23px; flex: 0 0 auto; }
.toptabs .tab span {
  max-width: 0; opacity: 0; overflow: hidden; white-space: nowrap;
  transition: max-width .55s var(--spring), opacity .33s ease, margin-left .55s var(--spring);
}
.toptabs .tab.active { background: rgba(var(--accent-rgb), 0.22); color: var(--blue); box-shadow: none; }
.toptabs .tab.active span { max-width: 76px; opacity: 1; margin-left: 6px; }

/* ---------------- Dashboard ---------------- */
.dash-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 720px) { .dash-grid { grid-template-columns: repeat(4, 1fr); } }
.dash-card {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 18px; cursor: pointer; position: relative;
  font: inherit; text-align: left; border: 0; color: inherit;
  transition: transform .38s var(--spring);
  -webkit-tap-highlight-color: transparent;
}
.dash-card:active { transform: scale(.96); }
.dash-card.alert { border-left: 4px solid #FF3B30; }
.dash-card .num { font-size: 30px; font-weight: 700; letter-spacing: -0.8px; }
.dash-card .lbl { font-size: 13px; color: var(--label-3); margin-top: 4px; font-weight: 500; padding-right: 14px; }
.dash-card.alert .num { color: #FF3B30; }
/* Reminders-style smart cards: colored icon badge + big count + label */
.smart-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 6px; }
@media (min-width: 720px) { .smart-grid { grid-template-columns: repeat(4, 1fr); } }
.smart-card { background: var(--card); border: 1px solid var(--separator);
  border-radius: 20px; padding: 14px; display: grid;
  grid-template-columns: auto 1fr; grid-template-areas: "icon num" "lbl lbl";
  gap: 2px 8px; align-items: center; box-shadow: var(--shadow);
  font: inherit; color: var(--label); cursor: pointer; text-align: left;
  transition: transform .38s var(--spring); -webkit-tap-highlight-color: transparent; }
.smart-card:active { transform: scale(0.96); }
.smart-icon { grid-area: icon; width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; color: #fff; }
.smart-icon svg { width: 17px; height: 17px; }
.smart-num { grid-area: num; justify-self: end; font-size: 30px; font-weight: 700; letter-spacing: -0.8px; }
.smart-card.alert .smart-num { color: #FF3B30; }
.smart-lbl { grid-area: lbl; font-size: 13px; color: var(--label-3); font-weight: 500; }
/* iOS Reminders-style round checkboxes */
.ios-check { -webkit-appearance: none; appearance: none; width: 23px; height: 23px;
  border-radius: 50%; border: 2px solid var(--check-border); background: var(--check-bg);
  cursor: pointer; flex: 0 0 auto; position: relative; margin: 0; padding: 0; }
.ios-check:checked { background: var(--blue); border-color: var(--blue); }
.ios-check:checked::after { content: ""; position: absolute; left: 6px; top: 2px;
  width: 5px; height: 10px; border: solid #fff; border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg); }
.task-check input[type="checkbox"] { -webkit-appearance: none; appearance: none; width: 23px; height: 23px;
  border-radius: 50%; border: 2px solid var(--check-border); background: var(--check-bg);
  cursor: pointer; flex: 0 0 auto; position: relative; margin: 1px 0 0; padding: 0; }
.task-check input[type="checkbox"]:checked { background: var(--blue); border-color: var(--blue); }
.task-check input[type="checkbox"]:checked::after { content: ""; position: absolute; left: 6px; top: 2px;
  width: 5px; height: 10px; border: solid #fff; border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg); }
.dash-go {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  font-size: 22px; font-weight: 600; color: var(--label-3); opacity: .7;
}
.filter-chip {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  border: 0; cursor: pointer; font: inherit; font-size: 13px; font-weight: 600;
  color: #fff; background: var(--blue); border-radius: 999px; padding: 8px 13px;
  -webkit-tap-highlight-color: transparent;
}
.filter-chip:active { transform: scale(.95); }
.count-badge {
  display: inline-block; min-width: 22px; text-align: center;
  background: var(--blue); color: #fff; font-size: 12px; font-weight: 700;
  border-radius: 999px; padding: 2px 7px; vertical-align: 2px; margin-left: 4px;
}
.mini-btn {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  border: 0; cursor: pointer; font: inherit; font-size: 13.5px; font-weight: 700;
  border-radius: 999px; padding: 9px 15px; text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.mini-btn.sms { background: #34C759; color: #fff; }
.mini-btn.sms:active { background: #2DA84A; }
.mini-btn.wa { background: #25D366; color: #fff; }
.mini-btn.wa:active { background: #1DA851; }
.mini-btn.ghost { background: var(--fill); color: var(--label-2); padding: 9px 12px; }
.mini-btn.ghost:active { transform: scale(.94); }
.section-title { font-size: 17px; font-weight: 700; margin: 26px 0 12px; letter-spacing: -0.3px; }
.focus-list { display: flex; flex-direction: column; gap: 10px; }

.views.no-dock-pad { padding-bottom: 0; }
#view-board.board-fit { display: flex; flex-direction: column; overflow: hidden; }
#view-board.board-fit .kanban { flex: 1 1 auto; min-height: 0; max-height: none; }
/* Last card in a column must scroll clear of the floating glass dock. */
#view-board.board-fit .col-body { padding-bottom: calc(110px + env(safe-area-inset-bottom)); }
/* ---------------- Kanban ---------------- */
.kanban {
  display: flex; gap: 14px; overflow-x: auto;
  padding: 4px 2px 16px;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}
/* While a card drag is active, scroll-snapping must be OFF: the snap
   logic re-pulls the offset to the nearest column on every programmatic
   scrollLeft step, which cancels the drag's edge auto-scroll (the board
   looks frozen no matter how the drivers tick). Snapping is only for
   free swipes. */
.kanban.snap-off { scroll-snap-type: none; }
.kanban-col {
  flex: 0 0 268px; max-width: 82vw;
  background: var(--col-bg);
  border-radius: var(--radius);
  display: flex; flex-direction: column;
  max-height: calc(100vh - 260px); min-height: 220px;
  transition: background .3s, box-shadow .3s;
  scroll-snap-align: start;
}
.kanban-col.drop-target { background: rgba(var(--accent-rgb), 0.1); box-shadow: inset 0 0 0 2px var(--blue); }
.col-empty {
  text-align: center; color: var(--label-3); font-size: 13px;
  padding: 22px 8px; border: 1.5px dashed rgba(120,120,128,.35); border-radius: var(--radius-s);
}
.col-muted .col-name { color: var(--label-3); }
.col-muted .kcard { opacity: .72; }
/* Apple News-style topic pills: free-floating white pills, horizontally scrollable */
.seg-toggle {
  display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none;
  padding: 4px 2px 12px; margin-bottom: 6px; -webkit-tap-highlight-color: transparent;
}
.seg-toggle::-webkit-scrollbar { display: none; }
.seg-btn {
  border: 0; background: var(--card); font: inherit; font-size: 14px; font-weight: 600;
  color: var(--label-2); padding: 10px 18px; border-radius: 999px; cursor: pointer;
  flex: 0 0 auto; white-space: nowrap; box-shadow: var(--shadow);
  transition: background .38s var(--spring), color .3s, transform .38s var(--spring);
  -webkit-tap-highlight-color: transparent;
}
.seg-btn:active { transform: scale(.95); }
/* v90: active segment is a filled accent pill (a sliding indicator isn't
   safe here — the buttons are variable-width inside a scrolling strip). */
.seg-btn.active { background: var(--blue); color: #fff; box-shadow: var(--shadow); }
.col-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 12px 8px;
  position: sticky; top: 0;
}
.col-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.col-name { font-size: 13.5px; font-weight: 700; letter-spacing: -0.2px; flex: 1; line-height: 1.25; }
.col-count {
  font-size: 12px; font-weight: 700; color: var(--label-3);
  background: var(--fill); border-radius: 999px; padding: 2px 8px;
}
.col-body { overflow-y: auto; padding: 4px 8px 12px; display: flex; flex-direction: column; gap: 8px; }
/* v118: per-stage mini search */
.col-search {
  display: flex; align-items: center; gap: 6px;
  margin: 0 10px 6px; padding: 5px 9px;
  background: var(--fill); border-radius: 10px; color: var(--label-3);
}
.col-search-input {
  flex: 1; min-width: 0; border: 0; background: transparent;
  font: inherit; font-size: 13.5px; color: var(--label); outline: none;
  -webkit-appearance: none; appearance: none;
}
.col-search-input::placeholder { color: var(--label-3); }
.col-search-clear {
  border: 0; background: rgba(120,120,128,.28); color: var(--label-2);
  width: 18px; height: 18px; border-radius: 50%; flex: 0 0 auto;
  font-size: 12px; line-height: 1; padding: 0; cursor: pointer;
}
.colq-hide { display: none !important; }
/* v119: Today page entry on Home + page sub-sections */
.today-head {
  display: flex; align-items: center; justify-content: space-between;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.see-all { color: var(--blue); font-size: 14px; font-weight: 600; padding: 6px 2px; }
.today-sub {
  font-size: 14.5px; font-weight: 700; letter-spacing: -0.2px;
  margin: 14px 2px 8px; display: flex; align-items: center; gap: 8px;
}
/* v126: per-message EN|ES switch on the client sheet */
.lang-row {
  display: flex; align-items: center; justify-content: space-between;
  margin: 2px 0 10px;
}
.lang-row-label { font-size: 13px; font-weight: 600; color: var(--label-2); }
.lang-seg {
  display: inline-flex; gap: 2px; padding: 2px;
  background: rgba(120,120,128,.14); border-radius: 9px;
}
.lang-seg-btn {
  border: 0; background: transparent; cursor: pointer; font: inherit;
  font-size: 13.5px; font-weight: 600; color: var(--label-2);
  padding: 5px 16px; border-radius: 7px;
  -webkit-tap-highlight-color: transparent;
}
.lang-seg-btn.on {
  background: var(--card); color: var(--label);
  box-shadow: 0 1px 4px rgba(0,0,0,.18);
}
/* v127: compact EN|ES switch on Follow-ups ready rows */
.fu-lang { margin-top: 7px; }
.lang-seg-btn.sm { font-size: 12px; padding: 3px 11px; border-radius: 6px; }
/* v123: Edit button on task rows */
.task-edit {
  color: var(--blue); background: rgba(var(--accent-rgb), .09);
  padding: 7px 13px; font-size: 13px; margin-left: auto;
}
.task-edit:active { opacity: .55; }
/* v121: back-to-Home button on the Today page */
.back-btn {
  display: inline-flex; align-items: center; gap: 1px;
  border: 0; background: none; cursor: pointer;
  color: var(--blue); font: inherit; font-size: 16px; font-weight: 600;
  padding: 6px 10px 6px 0; margin-bottom: 2px;
  -webkit-tap-highlight-color: transparent;
}
.back-btn:active { opacity: .55; }
.back-chev { font-size: 24px; line-height: 1; font-weight: 600; }

.kcard {
  background: var(--card); border-radius: var(--radius-s);
  box-shadow: var(--shadow);
  padding: 12px 14px;
  cursor: pointer;
  border-left: 4px solid var(--blue);
  transition: transform .38s var(--spring), box-shadow .3s;
  position: relative;
  touch-action: pan-x pan-y;
}
.kcard:active { transform: scale(.98); }
.kcard:hover { box-shadow: var(--shadow-lg); }
.kcard .kname { font-size: 14.5px; font-weight: 600; letter-spacing: -0.2px; padding-right: 26px; }
.kcard .kmeta { font-size: 12.5px; color: var(--label-3); margin-top: 3px; }
.kcard .krow { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; align-items: center; }
.drag-handle {
  position: absolute; top: 6px; right: 6px;
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  color: var(--label-3); cursor: grab;
  touch-action: none; border-radius: 8px;
}
.drag-handle:active { cursor: grabbing; background: rgba(60,60,67,.08); }
.drag-ghost {
  position: fixed; z-index: 100; pointer-events: none;
  opacity: 0.92; transform: rotate(2deg) scale(1.03);
  box-shadow: var(--shadow-lg);
  margin: 0;
}
.kcard.dragging-src { opacity: 0.35; }

.pill {
  display: inline-block; font-size: 11px; font-weight: 700;
  padding: 3px 8px; border-radius: 999px; letter-spacing: 0.1px;
  white-space: nowrap;
}
.pill.high { background: rgba(255, 59, 48, 0.12); color: #D70015; }
.pill.medium { background: rgba(255, 149, 0, 0.14); color: #B25E00; }
.pill.low { background: rgba(142, 142, 147, 0.16); color: #636366; }
.pill.pipeline { background: rgba(var(--accent-rgb), 0.1); color: var(--blue); font-weight: 600; }
.pill.overdue { background: #FF3B30; color: #fff; }
.pill.due-soon { background: rgba(255, 149, 0, 0.16); color: #B25E00; }

/* ---------------- Lists (clients / partners) ---------------- */
.toolbar { display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.toolbar .search { flex: 1 1 100%; }
/* iOS-style filter pills: compact horizontal scroll strip under the search */
.filter-pills { flex: 1 1 100%; display: flex; gap: 8px; overflow-x: auto;
  padding: 2px; margin: 0 -2px; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.filter-pills::-webkit-scrollbar { display: none; }
.filter-pills .select {
  flex: 0 0 auto;
  -webkit-appearance: none; appearance: none;
  font: inherit; font-size: 13.5px; font-weight: 600;
  padding: 8px 30px 8px 14px;
  border: 0; border-radius: 999px; cursor: pointer;
  color: var(--blue); background-color: rgba(var(--accent-rgb), 0.1);
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="%23007AFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>');
  background-repeat: no-repeat; background-position: right 11px center;
  box-shadow: none; max-width: 220px;
  text-overflow: ellipsis; overflow: hidden; white-space: nowrap;
}
.filter-pills .select.on {
  color: #fff; background-color: var(--blue);
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="%23ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>');
}
.filter-pills .filter-chip { flex: 0 0 auto; }
.search {
  flex: 1 1 200px; display: flex; align-items: center; gap: 8px;
  background: var(--card); border-radius: var(--radius-s);
  padding: 0 12px; box-shadow: var(--shadow);
}
.search svg { color: var(--label-3); flex: 0 0 auto; }
.search input { border: none; outline: none; background: none; font: inherit; font-size: 16px; padding: 11px 0; width: 100%; }
.select {
  font: inherit; font-size: 14px; padding: 10px 12px;
  border: none; border-radius: var(--radius-s); background: var(--card);
  box-shadow: var(--shadow); color: var(--label); cursor: pointer;
  max-width: 100%;
}
.list { display: flex; flex-direction: column; gap: 10px; }
.row-card {
  background: var(--card); border-radius: var(--radius-s); box-shadow: var(--shadow);
  padding: 14px 16px; cursor: pointer;
  display: flex; align-items: center; gap: 12px;
  transition: transform .38s var(--spring);
}
.row-card:active { transform: scale(0.98); }
.row-card .avatar {
  width: 42px; height: 42px; border-radius: 50%; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 16px; color: #fff;
  background: linear-gradient(135deg, var(--blue), #5AC8FA);
}
.row-card .rbody { flex: 1; min-width: 0; }
.row-card .rname { font-weight: 600; font-size: 15px; }
.row-card .rsub { font-size: 12.5px; color: var(--label-3); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row-card .chev { color: var(--label-3); flex: 0 0 auto; }
.empty { text-align: center; color: var(--label-3); padding: 40px 20px; font-size: 14px; }

/* ---------------- Detail sheet ---------------- */
.sheet-backdrop {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(0, 0, 0, 0.32);
  opacity: 1; transition: opacity .38s;
}
.sheet {
  position: fixed; z-index: 61;
  left: 0; right: 0; bottom: 0;
  max-height: 92vh;
  background: var(--bg);
  border-radius: 20px 20px 0 0;
  box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column;
  animation: sheetUp .55s var(--spring);
  padding-bottom: env(safe-area-inset-bottom);
  transition: transform .5s var(--spring);
}
@keyframes sheetUp { from { transform: translateY(40px); opacity: 0.6; } to { transform: none; opacity: 1; } }
@media (min-width: 720px) {
  .sheet { left: auto; right: 0; top: 0; bottom: 0; width: 420px; max-height: none; border-radius: 0; animation: sheetIn .5s var(--spring); }
  @keyframes sheetIn { from { transform: translateX(60px); opacity: 0.6; } to { transform: none; opacity: 1; } }
}
.sheet-swipe-zone { touch-action: none; cursor: grab; }
.sheet-grabber { width: 130px; margin: 0 auto; padding: 16px 0 12px; }
.sheet-grabber::before { content: ""; display: block; width: 42px; height: 5px; border-radius: 999px; background: var(--grabber); margin: 0 auto; }
.sheet.swiping { transition: none !important; }
@media (min-width: 720px) { .sheet-swipe-zone { display: none; } }
.sheet-close { position: absolute; top: 12px; right: 12px; background: var(--fill); z-index: 2; }
.sheet-body { overflow-y: auto; padding: 18px 20px 30px; }
.sheet-body h3 { margin: 0; font-size: 22px; font-weight: 700; letter-spacing: -0.4px; padding-right: 40px; }
.sheet-sub { color: var(--label-3); font-size: 13.5px; margin: 4px 0 14px; }
.contact-actions { display: flex; gap: 10px; margin-bottom: 16px; }
.contact-actions a {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px; border-radius: var(--radius-s);
  background: var(--blue); color: #fff; text-decoration: none;
  font-weight: 600; font-size: 15px;
  transition: background .3s;
}
.contact-actions a:hover { background: var(--blue-dark); }
.contact-actions a.secondary { background: rgba(var(--accent-rgb), 0.1); color: var(--blue); }
.contact-actions a.sms { background: #34C759; }
.contact-actions a.sms:hover { background: #2DA84A; }
.contact-actions a.wa { background: #25D366; }
.contact-actions a.wa:hover { background: #1DA851; }
.kv { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--separator); font-size: 14px; }
.kv .k { color: var(--label-3); flex: 0 0 auto; }
.kv .v { text-align: right; font-weight: 500; }
.notes-area {
  width: 100%; min-height: 110px; font: inherit; font-size: 14.5px;
  border: 1px solid var(--separator); border-radius: var(--radius-s);
  padding: 12px; background: var(--input-bg); resize: vertical; outline: none;
  transition: border-color .3s, box-shadow .3s;
}
.notes-area:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .14); }
.btn-row { display: flex; gap: 8px; margin-top: 10px; }
.btn-secondary {
  flex: 1; padding: 11px; font: inherit; font-size: 15px; font-weight: 600;
  border: none; border-radius: var(--radius-s); cursor: pointer;
  background: rgba(var(--accent-rgb), 0.1); color: var(--blue);
  transition: background .3s;
}
.btn-secondary:hover { background: rgba(var(--accent-rgb), 0.18); }
.task-check { display: flex; gap: 10px; align-items: flex-start; padding: 10px 0; border-bottom: 1px solid var(--separator); font-size: 14px; }
.task-check input[type="checkbox"] { width: 20px; height: 20px; margin-top: 1px; flex: 0 0 auto; cursor: pointer; }
.task-check.done .t { text-decoration: line-through; color: var(--label-3); }
.task-check .due { font-size: 12px; color: var(--label-3); }
.task-check .due.over { color: #FF3B30; font-weight: 700; }

/* ---------------- Partners ---------------- */
.partner-card { background: var(--card); border-radius: var(--radius-s); box-shadow: var(--shadow); padding: 14px 16px; }
.partner-head { display: flex; align-items: center; gap: 12px; cursor: pointer; }
.partner-head .avatar { width: 42px; height: 42px; border-radius: 50%; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; font-weight: 700; color: #fff; background: linear-gradient(135deg, var(--blue), #5AC8FA); }
.partner-head .pbody { flex: 1; min-width: 0; }
.partner-head .pname { font-weight: 600; font-size: 15px; }
.partner-head .psub { font-size: 12.5px; color: var(--label-3); margin-top: 2px; }
.star { color: #FF9500; flex: 0 0 auto; }
.partner-detail { margin-top: 10px; border-top: 1px solid var(--separator); padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.partner-detail label { font-size: 12.5px; font-weight: 600; color: var(--label-2); }
.partner-detail input[type="date"] { font: inherit; font-size: 16px; padding: 9px 10px; border: 1px solid var(--separator); border-radius: 8px; background: var(--input-bg); }
.mini-notes { width: 100%; min-height: 70px; font: inherit; font-size: 14px; border: 1px solid var(--separator); border-radius: 8px; padding: 10px; resize: vertical; outline: none; }
.mini-notes:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .14); }

/* ---------------- Toast ---------------- */
.toast-wrap { position: fixed; bottom: calc(112px + env(safe-area-inset-bottom)); left: 0; right: 0; z-index: 200; display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; }
.toast {
  background: rgba(28, 28, 30, 0.92); color: #fff;
  font-size: 14px; font-weight: 500;
  padding: 11px 18px; border-radius: 999px;
  box-shadow: var(--shadow-lg);
  animation: toastIn .38s ease-out;
  max-width: 90vw;
}
.toast.err { background: rgba(215, 0, 21, 0.94); }
@keyframes toastIn { from { transform: translateY(12px); opacity: 0; } to { transform: none; opacity: 1; } }

.spinner {
  width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid rgba(var(--accent-rgb), .2); border-top-color: var(--blue);
  animation: spin 0.8s linear infinite; margin: 60px auto;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (min-width: 720px) {
  .views { padding: 24px 24px 120px; }
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ---------------- Create modal + forms ---------------- */
.view-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 4px 0 14px; }
.view-head h2.view-title { margin: 0; }
.btn-add {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  background: var(--blue); color: #fff; border: 0; border-radius: 999px;
  font-size: 14px; font-weight: 600; padding: 8px 14px; cursor: pointer;
  transition: background .3s, transform .2s;
}
.btn-add:active { transform: scale(.96); }
@media (min-width: 720px) {
  .modal-sheet { left: 50%; right: auto; top: 50%; bottom: auto; transform: translate(-50%, -50%);
    width: 440px; max-width: calc(100vw - 40px); max-height: 88vh; border-radius: 20px;
    animation: modalIn .5s var(--spring); }
  @keyframes modalIn { from { transform: translate(-50%, -46%); opacity: .5; } to { transform: translate(-50%, -50%); opacity: 1; } }
}
.form-field { margin-bottom: 13px; }
.form-field > label { display: block; font-size: 13px; font-weight: 600; color: var(--label-2); margin-bottom: 6px; }
.form-field input, .form-field select, .form-field textarea {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 16px; color: var(--label);
  background: var(--bg-secondary); border: 1px solid transparent; border-radius: 12px;
  padding: 11px 13px; outline: none; transition: border-color .3s, background .3s;
  -webkit-appearance: none; appearance: none;
}
.form-field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238E8E93' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 13px center; padding-right: 36px;
}
.form-field input:focus, .form-field select:focus, .form-field textarea:focus {
  border-color: var(--blue); background: var(--bg, #fff);
}
.form-field .req { color: var(--red, #FF3B30); }

/* ---------------- Boot splash ---------------- */
.boot-splash {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg, #F2F2F7);
}
.boot-splash[hidden] { display: none; }
.boot-mark {
  width: 44px; height: 44px; border-radius: 14px; background: var(--blue, #007AFF);
  position: relative; animation: bootPulse 1.1s ease-in-out infinite;
}
.boot-mark::after {
  content: ""; position: absolute; inset: 12px;
  border: 3px solid rgba(255,255,255,.45); border-top-color: #fff; border-radius: 50%;
  animation: bootSpin .8s linear infinite;
}
@keyframes bootPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(.93); } }
@keyframes bootSpin { to { transform: rotate(360deg); } }

/* ---------------- Sync status dot ---------------- */
.sync-dot {
  width: 11px; height: 11px; border-radius: 50%; border: 0; padding: 0;
  margin-right: 2px; align-self: center; flex: 0 0 auto; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sync-dot.live { background: #34C759; }
.sync-dot.connecting { background: #8E8E93; animation: syncPulse 1.2s ease-in-out infinite; }
.sync-dot.offline { background: #FF9500; }
.sync-dot.error { background: #FF3B30; }
@keyframes syncPulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

/* ---------------- Manage Boards ---------------- */
.btn-small { flex: 0 0 auto; padding: 7px 14px; font-size: 13.5px; border-radius: 999px; }
.mb-pipeline { border: 1px solid var(--separator); border-radius: var(--radius-s); padding: 12px; margin-bottom: 12px; background: var(--card); }
.mb-pipeline-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.mb-pipeline-head strong { flex: 1; font-size: 16px; }
.mb-pipeline-head input[type="text"] { flex: 1; min-width: 0; font: inherit; font-size: 16px; padding: 7px 10px; border: 1px solid var(--blue); border-radius: 8px; outline: none; }
.mb-btn { border: 0; background: rgba(120,120,128,.14); color: var(--label); font: inherit; font-size: 12.5px; font-weight: 600; padding: 6px 11px; border-radius: 999px; cursor: pointer; flex: 0 0 auto; }
.mb-btn.danger { background: rgba(255,59,48,.1); color: #FF3B30; }
.mb-btn.confirm { background: #FF3B30; color: #fff; }
.mb-btn:disabled { opacity: .35; cursor: default; }
.mb-move { padding: 7px 10px; line-height: 0; }
.mb-col { display: flex; align-items: center; gap: 8px; padding: 9px 0; border-top: 1px solid var(--separator); }
.mb-col .col-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.mb-col-name { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mb-col select { font: inherit; font-size: 12px; padding: 6px 4px; border-radius: 8px; border: 1px solid var(--separator); background: var(--card); color: var(--label); max-width: 104px; flex: 0 0 auto; }
.mb-col input[type="text"] { flex: 1; min-width: 0; font: inherit; font-size: 16px; padding: 7px 10px; border: 1px solid var(--blue); border-radius: 8px; outline: none; }
.mb-add { margin-top: 10px; }
.mb-form { margin-top: 10px; padding-top: 4px; border-top: 1px dashed var(--separator); }
.mb-stages { max-height: 190px; overflow-y: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--separator); border-radius: 8px; padding: 4px 10px; }
.mb-stage { display: flex; align-items: center; gap: 9px; padding: 7px 0; font-size: 14px; border-bottom: 1px solid var(--separator); }
.mb-stage:last-child { border-bottom: 0; }
.mb-stage input { width: 19px; height: 19px; accent-color: var(--blue); flex: 0 0 auto; }
.mb-hint { font-size: 12.5px; color: var(--label-2); margin: 2px 0 14px; line-height: 1.45; }
.mb-new-pipeline-row { display: flex; gap: 8px; }
.mb-new-pipeline-row input { flex: 1; min-width: 0; }

/* ---------------- Global search ---------------- */
.global-search { position: relative; padding: 0 16px 10px; max-width: 1400px; margin: 0 auto; width: 100%; }
.global-search > svg { position: absolute; left: 28px; top: 10px; color: var(--label-3); pointer-events: none; }
#gq {
  width: 100%; font: inherit; font-size: 16px; color: var(--label);
  padding: 9px 12px 9px 36px; border: 0; border-radius: 12px;
  background: var(--fill); outline: none;
  -webkit-appearance: none; appearance: none;
}
#gq:focus { background: var(--fill-strong); }
.gq-results {
  position: absolute; left: 16px; right: 16px; top: calc(100% - 2px);
  background: var(--card); border-radius: 14px; box-shadow: var(--shadow-lg);
  z-index: 60; max-height: 340px; overflow-y: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--separator);
}
.gq-item { display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  padding: 10px 14px; border: 0; border-bottom: 1px solid var(--separator);
  background: transparent; font: inherit; cursor: pointer; color: var(--label); }
.gq-item:last-child { border-bottom: 0; }
.gq-item .avatar { width: 34px; height: 34px; border-radius: 50%; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; color: #fff; background: linear-gradient(135deg, var(--blue), var(--blue-light)); }
.gq-item .gq-name { font-size: 14.5px; font-weight: 600; }
.gq-item .gq-sub { font-size: 12.5px; color: var(--label-2); margin-top: 1px; }
.gq-item .gq-body { flex: 1; min-width: 0; overflow: hidden; }
.gq-item .gq-name, .gq-item .gq-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gq-empty { padding: 14px; font-size: 13.5px; color: var(--label-2); text-align: center; }
.gq-kind { flex: 0 0 auto; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px;
  color: var(--blue); background: rgba(var(--accent-rgb), 0.1); padding: 3px 8px; border-radius: 999px; }
.gq-flash { animation: gqFlash 1.6s ease; }
@keyframes gqFlash { 0%, 100% { box-shadow: var(--shadow); } 25%, 60% { box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.45); } }

/* ---------------- Note timeline ---------------- */
.note-timeline { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px;
  max-height: 320px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.note-bubble { background: var(--fill); border-radius: 14px; padding: 9px 12px; }
.note-text { font-size: 14.5px; line-height: 1.4; white-space: pre-wrap; word-break: break-word; }
.note-time { font-size: 11.5px; color: var(--label-2); margin-top: 5px; }
.note-input-row { display: flex; gap: 8px; margin-bottom: 6px; }
#sheet-note-input { flex: 1; min-width: 0; font: inherit; font-size: 16px; line-height: 1.45; color: var(--label);
  padding: 10px 12px; border: 1px solid var(--separator); border-radius: 12px;
  outline: none; background: var(--card); resize: none; overflow-y: auto; max-height: 140px; }
#sheet-note-input:focus { border-color: var(--blue); }

/* ---------------- Referred-by typeahead ---------------- */
.refby-wrap { position: relative; }
#sheet-referredby-input { width: 100%; box-sizing: border-box; font: inherit; font-size: 16px; color: var(--label);
  padding: 10px 36px 10px 12px; border: 1px solid var(--separator); border-radius: 12px;
  outline: none; background: var(--card); }
#sheet-referredby-input:focus { border-color: var(--blue); }
.refby-clear { position: absolute; right: 7px; top: 50%; transform: translateY(-50%);
  border: none; background: rgba(120, 120, 128, 0.18); color: var(--label);
  width: 24px; height: 24px; border-radius: 50%; font-size: 15px; line-height: 1; cursor: pointer; }
.refby-results { margin-top: 6px; border: 1px solid var(--separator); border-radius: 12px;
  overflow: hidden; background: var(--card); max-height: 264px; overflow-y: auto;
  -webkit-overflow-scrolling: touch; }
.refby-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 12px;
  border: none; background: none; font: inherit; color: var(--label); text-align: left; cursor: pointer; }
.refby-item:active { background: rgba(120, 120, 128, 0.14); }
.refby-empty { padding: 10px 12px; color: var(--label-2); font-size: 13.5px; }

/* ---------------- Notification inbox ---------------- */
#push-btn { position: relative; }
.push-badge { position: absolute; top: 1px; right: 1px; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 9px; background: #FF3B30; color: #fff;
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; }
.inbox-toolbar { display: flex; gap: 8px; margin-bottom: 6px; }
.inbox-list { display: flex; flex-direction: column; }
.inbox-foot { margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--separator);
  text-align: center; font-size: 11.5px; color: var(--label-3); }
.inbox-item { display: flex; gap: 12px; align-items: flex-start; width: 100%;
  padding: 12px 4px; border: none; border-bottom: 1px solid var(--separator);
  background: none; font: inherit; color: var(--label); text-align: left; cursor: pointer; }
.inbox-item:active { background: rgba(120, 120, 128, 0.1); }
.inbox-icon { font-size: 20px; line-height: 1.3; }
.inbox-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.inbox-title { font-weight: 600; font-size: 14.5px; }
.inbox-item.unread .inbox-title { font-weight: 700; }
.inbox-text { font-size: 13.5px; color: var(--label-2); display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.inbox-time { font-size: 11.5px; color: var(--label-2); }
.inbox-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--blue);
  margin-top: 7px; flex: 0 0 auto; }

/* ---------------- Duplicate detection ---------------- */
.dupe-warn { border: 1px solid rgba(255, 149, 0, 0.55); background: rgba(255, 149, 0, 0.08);
  border-radius: 12px; padding: 12px; margin-bottom: 12px; }
.dupe-warn-title { font-weight: 700; margin-bottom: 6px; }
.dupe-list { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.dupe-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 10px;
  border: 1px solid var(--separator); border-radius: 10px; background: var(--card);
  font: inherit; color: var(--label); text-align: left; cursor: pointer; }
.dupe-item:active { background: rgba(120, 120, 128, 0.12); }
.dupe-pairs { display: flex; flex-direction: column; gap: 12px; margin: 10px 0; }
.dupe-pair { border: 1px solid var(--separator); border-radius: 12px; padding: 12px; }
.dupe-why { font-size: 11.5px; font-weight: 700; color: #FF9500; text-transform: uppercase;
  letter-spacing: 0.4px; margin-bottom: 8px; }
.dupe-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 10px; }
.dupe-name { font-weight: 700; font-size: 14px; margin-bottom: 4px; }
.dupe-line { font-size: 12.5px; color: var(--label-2); word-break: break-word; }

/* ---------------- Merge dialog ---------------- */
.merge-opt { display: flex; gap: 10px; align-items: flex-start; padding: 11px 12px;
  border: 1px solid var(--separator); border-radius: 10px; margin-bottom: 8px;
  font-size: 14px; color: var(--label); cursor: pointer; }
.merge-opt input[type="checkbox"] { width: 20px; height: 20px; margin: 0; flex: 0 0 auto; accent-color: var(--blue); }

/* ---------------- Pipeline value dashboard ---------------- */
.value-hero { background: linear-gradient(135deg, var(--blue-dark), var(--blue) 58%, var(--blue-light)); border-radius: 20px;
  padding: 20px; margin-bottom: 16px; color: #fff; box-shadow: var(--shadow); }
.value-hero-num { font-size: 38px; font-weight: 800; letter-spacing: -0.5px; }
.value-hero-lbl { font-size: 12.5px; opacity: 0.85; margin-top: 4px; }
.value-pipes { display: flex; flex-direction: column; gap: 10px; margin-bottom: 6px; }
.value-pipe { display: block; width: 100%; text-align: left; font: inherit; color: var(--label);
  background: var(--card); border: 1px solid var(--separator); border-radius: 14px;
  padding: 12px 14px; cursor: pointer; }
.value-pipe:active { background: rgba(120, 120, 128, 0.12); }
.value-pipe-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 8px; }
.value-pipe-name { font-weight: 700; font-size: 15px; }
.value-pipe-total { font-weight: 800; font-size: 17px; color: var(--blue); }
.value-board { display: flex; align-items: center; gap: 8px; padding: 5px 0;
  border-top: 1px solid var(--separator); font-size: 13.5px; }
.value-board .dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.value-board-name { flex: 1; color: var(--label-2); }
.value-board-sum { font-weight: 700; }

/* Forgot password link on login */
.link-btn { background: none; border: none; padding: 10px; margin-top: 4px;
  color: var(--blue); font-size: 14px; font-weight: 600; cursor: pointer; width: 100%; }
.link-btn:active { opacity: 0.6; }

/* Tappable loan amount row + source note */
.kv-tap { display: flex; width: 100%; text-align: left; font: inherit; color: var(--label);
  background: none; border: none; padding: 7px 0; cursor: pointer; }
.kv-tap:active { opacity: 0.6; }
.kv-tap .chev { color: var(--label-2); font-weight: 700; }
.src-note { font-size: 11.5px; color: var(--label-2); padding: 0 0 6px; }

/* ---------------- Pie dashboard ---------------- */
.pie-wrap { display: flex; gap: 12px; align-items: center; background: var(--card);
  border: 1px solid var(--separator); border-radius: 18px; padding: 14px; margin-bottom: 4px; }
.pie { width: 124px; height: 124px; flex: 0 0 auto; }
.pie-legend { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.value-legend-row { display: flex; align-items: center; gap: 8px; background: none; border: none;
  font: inherit; color: var(--label); padding: 7px 2px; cursor: pointer; text-align: left; width: 100%; }
.value-legend-row:active { opacity: 0.6; }
.value-legend-row .dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.value-legend-name { flex: 1; font-size: 13.5px; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.value-legend-pct { font-size: 12.5px; color: var(--label-2); flex: 0 0 auto; }
.value-legend-sum { font-size: 13.5px; font-weight: 700; flex: 0 0 auto; }
.pie-cap { font-size: 12px; color: var(--label-2); margin: 8px 2px 10px; }
/* Two-pie layout: Pre-Qualifying + House Hunting side by side (stacked on phones) */
.pie-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 4px; }
@media (max-width: 600px) { .pie-cards { grid-template-columns: 1fr; } }
.pie-card { background: var(--card); border: 1px solid var(--separator);
  border-radius: 18px; padding: 14px; min-width: 0; }
.pie-card-head { display: flex; justify-content: space-between; align-items: baseline;
  margin: 0 2px 8px; font-weight: 700; font-size: 14px; }
.pie-card-head span:last-child { color: var(--blue); }
.pie-card .pie-wrap { background: none; border: none; padding: 0; margin: 0; }

/* Morning brief + missing documents (v52) */
.brief-rank { flex:0 0 auto; width:26px; height:26px; border-radius:50%; background:var(--blue); color:#fff; font-size:13px; font-weight:700; display:flex; align-items:center; justify-content:center; }
.brief-row { cursor:pointer; }
/* Home scroll panels (v86 Today brief / v87 Needs attention): long Home
   lists scroll inside a contained card so they can't take over the page.
   Section headers live in renderDashboard, outside the panels, so they
   never scroll away. Height cap via --today-max-h: ~4-5 rows visible,
   square-ish against phone width. One shared rule set: .today-scroll is
   the brief panel, .panel-scroll the Needs attention panel. */
.today-scroll, .panel-scroll { max-height: var(--today-max-h); overflow-y: auto;
  -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
  background: var(--card); border: 1px solid var(--separator);
  border-radius: 20px; box-shadow: var(--shadow);
  padding: 10px; margin-bottom: 6px; }
.today-scroll > *, .panel-scroll > * { flex: 0 0 auto; }
.doc-x { flex:0 0 auto; width:30px; height:30px; border-radius:50%; border:none; background:rgba(142,142,147,.16); color:var(--label-3); font-size:18px; line-height:1; cursor:pointer; }
.doc-x:active { transform:scale(.94); }

/* ---------------- Desktop layout (v63-v67, ≥1024px): sidebar nav, full-bleed filling grids ---------------- */
.dash-stats-title { display: none; }
@media (min-width: 1024px) {
  /* Sidebar replaces the floating bottom dock */
  .toptabs {
    left: 0; top: 0; bottom: 0;
    transform: none;
    width: 228px;
    flex-direction: column;
    justify-content: flex-start;
    align-items: stretch;
    gap: 4px;
    padding: 20px 12px;
    border-radius: 0;
    border: 0;
    border-right: 1px solid var(--separator);
    box-shadow: none;
  }
  /* v219: Nelson's call — the desktop sidebar carries the team
     brand, in solid deep navy for contrast on the glass rail
     (it still read "Client CRM" in the default text color) */
  .toptabs::before {
    content: "Team San Miguel CRM";
    font-size: 19px; font-weight: 800; letter-spacing: -0.4px;
    color: #0A2463;
    padding: 4px 14px 18px;
  }
  /* v221/v222: dark-theme overrides for this title live at the
     END of the stylesheet (top level) — see "Sidebar title
     themes" below. */
  .toptabs .tab {
    flex: 0 0 auto;
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    gap: 12px;
    font-size: 15px;
    padding: 11px 14px;
    border-radius: 12px;
  }
  .toptabs .tab svg { width: 22px; height: 22px; }
  .toptabs .tab:active { transform: none; }
  /* Full-bleed content: fills the space right of the sidebar, no dock clearance needed */
  .app-header { margin-left: 228px; }
  .header-row { max-width: none; }
  .views { width: auto; max-width: none; margin: 0;
    padding: 28px 40px 48px calc(228px + 40px); }
  .views.no-dock-pad { padding-bottom: 48px; }
  #view-board.board-fit .col-body { padding-bottom: 24px; }
  /* Home: two-column mid section (pies | stats) so the width gets used */
  .dash-mid { display: grid; grid-template-columns: 1.25fr 1fr; gap: 36px; align-items: start; }
  .dash-mid .section-title { margin-top: 0; }
  .dash-stats-title { display: block; }
  .dash-stats .smart-grid { grid-template-columns: 1fr 1fr; }
  /* Home lists fill the width in two columns */
  #view-dashboard .focus-list { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-items: start; }
  /* Client + partner lists become filling card grids */
  #view-clients .list, #view-partners .list {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 10px; }
  /* Wider board columns */
  .kanban { gap: 14px; }
  .kanban-col { flex-basis: 322px; }
  /* Denser lists */
  .col-body { gap: 6px; }
  .kcard { padding: 9px 12px; }
  .kcard .krow { margin-top: 6px; }
}

/* Very wide screens (v66-v67): scale the UI up so it fills the display instead of looking tiny */
@media (min-width: 1600px) {
  .view h2.view-title { font-size: 36px; }
  .section-title { font-size: 19px; }
  .smart-grid { gap: 14px; }
  .smart-card { padding: 17px; border-radius: 22px; }
  .smart-icon { width: 38px; height: 38px; }
  .smart-icon svg { width: 20px; height: 20px; }
  .smart-num { font-size: 37px; }
  .smart-lbl { font-size: 14px; }
  .pie-cards { gap: 14px; }
  .pie-card { padding: 18px; }
  .pie-card-head { font-size: 16px; }
  .kcard { padding: 12px 14px; }
  .kcard .kname { font-size: 16px; }
  .kcard .kmeta { font-size: 13.5px; }
  .kanban { gap: 16px; }
  .kanban-col { flex-basis: 344px; }
  .focus-list { gap: 10px; }
}
@media (min-width: 2000px) {
  .view h2.view-title { font-size: 40px; }
  .smart-card { padding: 20px; }
  .smart-num { font-size: 44px; }
  .smart-icon { width: 44px; height: 44px; }
  .smart-lbl { font-size: 15px; }
  .kcard .kname { font-size: 17px; }
  .kanban-col { flex-basis: 368px; }
}

/* ============================================================
   v90 — Dark mode, greeting + hero, spring motion
   ============================================================ */

/* Dark palette: applied when the user picks Dark, or picks System and
   the device is in dark mode. Light values live in the :root block at
   the top; only the tokens change — every surface reads variables. */
:root[data-theme='dark'] {
  --blue: #0A84FF;
  --blue-dark: #409CFF;
  --bg: #000000;
  --card: #1C1C1E;
  --elevated: #2C2C2E;
  --label: #F2F2F7;
  --label-2: rgba(235, 235, 245, 0.6);
  --label-3: rgba(235, 235, 245, 0.45);
  --separator: rgba(255, 255, 255, 0.12);
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.45), 0 4px 16px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.6);
  --header-bg: rgba(28, 28, 30, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000)));
  --sidebar-bg: rgba(28, 28, 30, calc(0.86 * var(--glass-m, 1) + (1 - 0.86 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.86 * 1000)));
  --dock-bg: rgba(28, 28, 30, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000)));
  --dock-border: rgba(255, 255, 255, 0.14);
  --login-card-bg: rgba(28, 28, 30, calc(0.82 * var(--glass-m, 1) + (1 - 0.82 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.82 * 1000)));
  --login-card-border: rgba(255, 255, 255, 0.12);
  --col-bg: rgba(28, 28, 30, 0.62);
  --input-bg: #2C2C2E;
  --check-bg: #1C1C1E;
  --check-border: rgba(255, 255, 255, 0.4);
  --fill: rgba(120, 120, 128, 0.28);
  --fill-strong: rgba(120, 120, 128, 0.4);
  --bg-secondary: rgba(118, 118, 128, 0.18);
  --grabber: rgba(255, 255, 255, 0.3);
  color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] {
    --blue: #0A84FF;
    --blue-dark: #409CFF;
    --bg: #000000;
    --card: #1C1C1E;
    --elevated: #2C2C2E;
    --label: #F2F2F7;
    --label-2: rgba(235, 235, 245, 0.6);
    --label-3: rgba(235, 235, 245, 0.45);
    --separator: rgba(255, 255, 255, 0.12);
    --shadow: 0 1px 3px rgba(0, 0, 0, 0.45), 0 4px 16px rgba(0, 0, 0, 0.35);
    --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.6);
    --header-bg: rgba(28, 28, 30, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000)));
    --sidebar-bg: rgba(28, 28, 30, calc(0.86 * var(--glass-m, 1) + (1 - 0.86 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.86 * 1000)));
    --dock-bg: rgba(28, 28, 30, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000)));
    --dock-border: rgba(255, 255, 255, 0.14);
    --login-card-bg: rgba(28, 28, 30, calc(0.82 * var(--glass-m, 1) + (1 - 0.82 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.82 * 1000)));
    --login-card-border: rgba(255, 255, 255, 0.12);
    --col-bg: rgba(28, 28, 30, 0.62);
    --input-bg: #2C2C2E;
    --check-bg: #1C1C1E;
    --check-border: rgba(255, 255, 255, 0.4);
    --fill: rgba(120, 120, 128, 0.28);
    --fill-strong: rgba(120, 120, 128, 0.4);
    --bg-secondary: rgba(118, 118, 128, 0.18);
    --grabber: rgba(255, 255, 255, 0.3);
    color-scheme: dark;
  }
}
/* The toast is a dark pill in light mode; in dark mode give it a hairline
   so it separates from the true-black page. */
:root[data-theme='dark'] .toast { border: 1px solid rgba(255, 255, 255, 0.16); }
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] .toast { border: 1px solid rgba(255, 255, 255, 0.16); }
}

/* ---------------- Home greeting + hero (v90) ---------------- */
.greet { margin: 8px 0 16px; }
.greet-title { margin: 0; font-size: 30px; font-weight: 800; letter-spacing: -0.6px; }
.greet-date { color: var(--label-3); font-size: 14px; font-weight: 500; margin-top: 3px; }

/* ---------------- Appearance (theme) segmented control ---------------- */
.theme-row { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 0 4px; }
.theme-lbl { font-size: 14px; font-weight: 600; color: var(--label-2); }
.theme-seg { display: flex; background: var(--fill); border-radius: 999px; padding: 3px; }
.theme-seg button {
  border: 0; background: transparent; font: inherit; font-size: 13px; font-weight: 600;
  color: var(--label-2); padding: 6px 13px; border-radius: 999px; cursor: pointer;
  transition: background .38s var(--spring), color .3s;
  -webkit-tap-highlight-color: transparent;
}
.theme-seg button.active { background: var(--elevated); color: var(--label); box-shadow: var(--shadow); }

/* ---------------- Settings sheet: Log out row (v100) ---------------- */
.settings-logout {
  display: block; width: 100%; margin-top: 16px; padding: 12px 14px;
  border: 1px solid var(--separator); border-radius: var(--radius-s);
  background: var(--card); color: #FF3B30;
  font: inherit; font-size: 15px; font-weight: 600; text-align: center;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.settings-logout:active { background: rgba(255, 59, 48, 0.10); }

/* ---------------- Spring motion (v90) ---------------- */
/* View transitions: the incoming view fades + rises a few px. The class
   is added by showView and removed shortly after so revisits re-animate. */
@keyframes viewIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.view-enter { animation: viewIn .5s var(--spring); }

/* Staggered entrances on Home + Tasks — v98: armed ONLY by the .anim-in
   class showView puts on the view for its entry render (stripped ~1s
   later). Snapshot-driven re-renders rebuild these lists without the
   class, so the entrance never replays mid-session (the replay was the
   "page refresh" feel). Scoped away from the Clients/Partners lists on
   purpose: those re-render per search keystroke, where a replaying
   entrance would jank. Board cards fade only (no transform) so
   entrance motion can never fight the drag ghost's positioning math. */
@keyframes riseIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
#view-dashboard.anim-in .focus-list > *, #view-dashboard.anim-in .smart-grid > *,
#view-dashboard.anim-in .pie-cards > *, #view-tasks.anim-in .list > * {
  animation: riseIn .55s var(--spring) both;
}
#view-dashboard.anim-in .focus-list > *:nth-child(2), #view-dashboard.anim-in .smart-grid > *:nth-child(2),
#view-dashboard.anim-in .pie-cards > *:nth-child(2), #view-tasks.anim-in .list > *:nth-child(2) { animation-delay: .06s; }
#view-dashboard.anim-in .focus-list > *:nth-child(3), #view-dashboard.anim-in .smart-grid > *:nth-child(3),
#view-dashboard.anim-in .pie-cards > *:nth-child(3), #view-tasks.anim-in .list > *:nth-child(3) { animation-delay: .1s; }
#view-dashboard.anim-in .focus-list > *:nth-child(4), #view-dashboard.anim-in .smart-grid > *:nth-child(4),
#view-dashboard.anim-in .pie-cards > *:nth-child(4), #view-tasks.anim-in .list > *:nth-child(4) { animation-delay: .18s; }
#view-dashboard.anim-in .focus-list > *:nth-child(5), #view-dashboard.anim-in .smart-grid > *:nth-child(5),
#view-dashboard.anim-in .pie-cards > *:nth-child(5), #view-tasks.anim-in .list > *:nth-child(5) { animation-delay: .2s; }
#view-dashboard.anim-in .focus-list > *:nth-child(6), #view-dashboard.anim-in .smart-grid > *:nth-child(6),
#view-dashboard.anim-in .pie-cards > *:nth-child(6), #view-tasks.anim-in .list > *:nth-child(6) { animation-delay: .30s; }
#view-dashboard.anim-in .focus-list > *:nth-child(7), #view-dashboard.anim-in .smart-grid > *:nth-child(7),
#view-dashboard.anim-in .pie-cards > *:nth-child(7), #view-tasks.anim-in .list > *:nth-child(7) { animation-delay: .3s; }
#view-dashboard.anim-in .focus-list > *:nth-child(n+8), #view-dashboard.anim-in .smart-grid > *:nth-child(n+8),
#view-dashboard.anim-in .pie-cards > *:nth-child(n+8), #view-tasks.anim-in .list > *:nth-child(n+8) { animation-delay: .35s; }
/* Board cards: same .anim-in arming as Home/Tasks (v101 — this rule
   shipped ungated in v90, so every board rebuild replayed the fade on
   every card; that replay is part of the "mini refresh" feel). */
#view-board.anim-in .col-body > .kcard { animation: fadeIn .45s ease both; }

/* Task check-off: the checkbox pops with a bounce spring; the row title
   strikes through and the row settles faded until the re-render lands it
   in Completed. Purely cosmetic — toggleTask's write fires immediately. */
@keyframes checkPop { 0% { transform: scale(1); } 40% { transform: scale(1.32); } 100% { transform: scale(1); } }
.check-pop { animation: checkPop .65s var(--spring-bounce); }
.task-done-anim { opacity: .55; transition: opacity .5s ease; }
.task-done-anim .rname, .task-done-anim .t {
  text-decoration: line-through; opacity: .5; transition: opacity .45s ease;
}
/* v98 task-row exit: collapseTaskRow pins the row's height inline, adds
   this class, then zeroes height/padding/opacity inline — this transition
   carries the row shut over ~.52s while the rows below glide up. */
.task-exit {
  overflow: hidden;
  transition: height .52s var(--spring), opacity .45s ease,
    padding-top .52s var(--spring), padding-bottom .52s var(--spring);
}

/* Pie entrance: the donut sweeps in with a spring rotate/scale. */
@keyframes pieIn { from { opacity: 0; transform: rotate(-24deg) scale(.86); } to { opacity: 1; transform: none; } }
.pie { transform-origin: 50% 50%; }
#view-dashboard.anim-in .pie { animation: pieIn 1.05s var(--spring) both; }

/* Desktop: the sidebar keeps every tab labeled (the icon-only rule is
   for the floating dock), its glass follows the theme token, and Home's
   mid grid keeps v89's visual column widths with the new DOM order
   (smart cards first, pies second). */
@media (min-width: 1024px) {
  .toptabs { background: var(--sidebar-bg); }
  .toptabs .tab span { max-width: none; opacity: 1; margin-left: 0; overflow: visible; }
  .dash-mid { grid-template-columns: 1fr 1.25fr; }
  .dash-mid .dash-stats { grid-column: 1; grid-row: 1; }
  .dash-mid .dash-pies { grid-column: 2; grid-row: 1; }
}

/* Reduced motion: kill the v90 motion layer outright (the global rule
   above already collapses durations; this removes the new keyframes so
   nothing replays at all). countUp() also jumps straight to final. */
@media (prefers-reduced-motion: reduce) {
  .view-enter, .pie, .check-pop,
  #view-dashboard.anim-in .focus-list > *, #view-dashboard.anim-in .smart-grid > *,
  #view-dashboard.anim-in .pie-cards > *, #view-tasks.anim-in .list > *,
  .col-body > .kcard { animation: none !important; }
  .toptabs .tab span { transition: none !important; }
  .task-done-anim, .task-done-anim .rname, .task-done-anim .t, .task-exit { transition: none !important; }
}

/* v120 (Nelson): Today page rows read bigger — more padding, larger
   names/detail text, larger checkboxes, pills and row buttons. Scoped
   to #view-today only; Home and the Tasks view keep their sizes. */
#view-today .row-card { padding: 19px 18px; gap: 14px; }
#view-today .row-card .rname { font-size: 17.5px; line-height: 1.3; }
#view-today .row-card .rsub { font-size: 14.5px; line-height: 1.4; margin-top: 3px; white-space: normal; }
#view-today .row-card .chev { font-size: 20px; }
#view-today .ios-check { width: 29px; height: 29px; }
#view-today .ios-check:checked::after { left: 8px; top: 3px; width: 6px; height: 12px; border-width: 0 3px 3px 0; }
#view-today .pill { font-size: 12.5px; padding: 4px 10px; }
#view-today .mini-btn { font-size: 15px; padding: 11px 17px; }
#view-today .brief-rank { width: 32px; height: 32px; font-size: 15px; }

/* ---------------- Activity view (2026-10-23) ---------------- */
.activity-people { margin-bottom: 10px; }
.fpill {
  flex: 0 0 auto; font: inherit; font-size: 13px; font-weight: 600;
  padding: 6px 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--separator); background: var(--card); color: var(--label-2);
}
.fpill.on { background: var(--blue); border-color: var(--blue); color: #fff; }
.activity-search-wrap { margin-bottom: 12px; }
.activity-search-wrap input {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 15px;
  padding: 10px 14px; border-radius: var(--radius-s);
  border: 1px solid var(--separator); background: var(--input-bg); color: var(--label);
}
.activity-row {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 12px 14px; margin-bottom: 10px;
}
.activity-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.activity-kind { font-size: 12px; font-weight: 600; color: var(--label-3); text-transform: uppercase; letter-spacing: 0.4px; }
.activity-name {
  font: inherit; font-size: 15px; font-weight: 700; color: var(--blue);
  background: none; border: none; padding: 0; cursor: pointer; text-align: left;
}
.activity-name.static { color: var(--label); cursor: default; }
.activity-when { margin-left: auto; font-size: 12.5px; color: var(--label-3); white-space: nowrap; }
.activity-actor { font-size: 13px; color: var(--label-2); margin-top: 3px; }
.activity-changes { margin: 8px 0 0; padding-left: 18px; font-size: 13px; color: var(--label-2); }
.activity-changes li { margin: 2px 0; overflow-wrap: anywhere; }
.activity-changes b { color: var(--label); }
.pill.act-create { background: rgba(52, 199, 89, 0.14); color: #1D7A37; }
.pill.act-update { background: rgba(var(--accent-rgb), 0.1); color: var(--blue); }
.pill.act-delete { background: rgba(255, 59, 48, 0.12); color: #D70015; }

/* ============================================================
   v134 — Liquid Glass Color (Nelson, 2026-10-25)
   Reference: "Glassy Dashboard V2" — frosted cards floating over a
   warm, colorful blurred backdrop, plus his follow-up: more color.
   Everything routes through the variables below so light / dark /
   system themes all get the glass; component rules are written once.
   Performance note: backdrop-filter is applied ONLY to chrome and
   dashboard surfaces (header, dock, Home cards, board columns,
   panels, sheet). Long-list rows (row-card, kcard) use translucent
   gradients without blur — 150+ live-blurred rows jank iPhone scroll.
   ============================================================ */
:root {
  --grad: linear-gradient(135deg, #0A6CFF 0%, #7D4AFF 52%, #00B4D8 100%);
  --grad-hero: linear-gradient(122deg, #0055D4 0%, #6A3DF0 52%, #00A8C5 108%);
  --aurora:
    radial-gradient(880px 600px at 10% -10%, rgba(125, 74, 255, 0.30), transparent 62%),
    radial-gradient(760px 540px at 94% -6%, rgba(0, 200, 215, 0.26), transparent 60%),
    radial-gradient(680px 520px at 88% 58%, rgba(255, 149, 0, 0.20), transparent 62%),
    radial-gradient(820px 640px at -8% 88%, rgba(var(--accent-rgb), 0.24), transparent 62%),
    radial-gradient(560px 460px at 58% 112%, rgba(255, 45, 120, 0.13), transparent 60%);
  --base-bg: #F3F1FA;
  --glass: linear-gradient(135deg, rgba(255, 255, 255, calc(0.78 * var(--glass-m, 1) + (1 - 0.78 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.78 * 1000))), rgba(255, 255, 255, calc(0.56 * var(--glass-m, 1) + (1 - 0.56 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.56 * 1000))));
  --glass-strong: linear-gradient(135deg, rgba(255, 255, 255, calc(0.88 * var(--glass-m, 1) + (1 - 0.88 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.88 * 1000))), rgba(255, 255, 255, calc(0.74 * var(--glass-m, 1) + (1 - 0.74 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.74 * 1000))));
  --glass-row: linear-gradient(135deg, rgba(255, 255, 255, calc(0.86 * var(--glass-m, 1) + (1 - 0.86 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.86 * 1000))), rgba(255, 255, 255, calc(0.68 * var(--glass-m, 1) + (1 - 0.68 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.68 * 1000))));
  --glass-ring: rgba(255, 255, 255, calc(0.75 * var(--glass-m, 1) + (1 - 0.75 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.75 * 1000)));
  --glass-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 0 0 1px rgba(255, 255, 255, 0.55),
    0 10px 32px rgba(83, 58, 183, 0.12), 0 2px 8px rgba(31, 38, 135, 0.06);
  --glass-shadow-sm: inset 0 1px 0 rgba(255, 255, 255, 0.85),
    inset 0 0 0 1px rgba(255, 255, 255, 0.45),
    0 6px 20px rgba(83, 58, 183, 0.09), 0 1px 5px rgba(31, 38, 135, 0.05);
  --glass-blur: blur(22px) saturate(190%);
  --sheet-bg: linear-gradient(180deg, rgba(255, 255, 255, calc(0.94 * var(--glass-m, 1) + (1 - 0.94 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.94 * 1000))), rgba(250, 249, 255, calc(0.97 * var(--glass-m, 1) + (1 - 0.97 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.97 * 1000))));
  --dock-glass: linear-gradient(135deg, rgba(255, 255, 255, 0.66), rgba(255, 255, 255, 0.44));
}
:root[data-theme='dark'] {
  --aurora:
    radial-gradient(880px 600px at 10% -10%, rgba(125, 74, 255, 0.34), transparent 62%),
    radial-gradient(760px 540px at 94% -6%, rgba(0, 200, 215, 0.22), transparent 60%),
    radial-gradient(680px 520px at 88% 58%, rgba(255, 149, 0, 0.16), transparent 62%),
    radial-gradient(820px 640px at -8% 88%, rgba(var(--accent-rgb), 0.26), transparent 62%),
    radial-gradient(560px 460px at 58% 112%, rgba(255, 45, 120, 0.16), transparent 60%);
  --base-bg: #060612;
  --glass: linear-gradient(135deg, rgba(52, 52, 64, calc(0.66 * var(--glass-m, 1) + (1 - 0.66 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.66 * 1000))), rgba(30, 30, 40, calc(0.52 * var(--glass-m, 1) + (1 - 0.52 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.52 * 1000))));
  --glass-strong: linear-gradient(135deg, rgba(56, 56, 68, calc(0.82 * var(--glass-m, 1) + (1 - 0.82 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.82 * 1000))), rgba(34, 34, 44, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000))));
  --glass-row: linear-gradient(135deg, rgba(50, 50, 62, calc(0.88 * var(--glass-m, 1) + (1 - 0.88 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.88 * 1000))), rgba(32, 32, 42, calc(0.78 * var(--glass-m, 1) + (1 - 0.78 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.78 * 1000))));
  --glass-ring: rgba(255, 255, 255, calc(0.16 * var(--glass-m, 1) + (1 - 0.16 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.16 * 1000)));
  --glass-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14),
    inset 0 0 0 1px rgba(255, 255, 255, 0.08),
    0 10px 32px rgba(0, 0, 0, 0.42), 0 2px 8px rgba(0, 0, 0, 0.3);
  --glass-shadow-sm: inset 0 1px 0 rgba(255, 255, 255, 0.12),
    inset 0 0 0 1px rgba(255, 255, 255, 0.07),
    0 6px 20px rgba(0, 0, 0, 0.36), 0 1px 5px rgba(0, 0, 0, 0.26);
  --sheet-bg: linear-gradient(180deg, rgba(34, 34, 44, calc(0.96 * var(--glass-m, 1) + (1 - 0.96 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.96 * 1000))), rgba(18, 18, 26, calc(0.98 * var(--glass-m, 1) + (1 - 0.98 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.98 * 1000))));
  --dock-glass: linear-gradient(135deg, rgba(52, 52, 64, 0.62), rgba(28, 28, 38, 0.5));
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] {
    --aurora:
      radial-gradient(880px 600px at 10% -10%, rgba(125, 74, 255, 0.34), transparent 62%),
      radial-gradient(760px 540px at 94% -6%, rgba(0, 200, 215, 0.22), transparent 60%),
      radial-gradient(680px 520px at 88% 58%, rgba(255, 149, 0, 0.16), transparent 62%),
      radial-gradient(820px 640px at -8% 88%, rgba(var(--accent-rgb), 0.26), transparent 62%),
      radial-gradient(560px 460px at 58% 112%, rgba(255, 45, 120, 0.16), transparent 60%);
    --base-bg: #060612;
    --glass: linear-gradient(135deg, rgba(52, 52, 64, calc(0.66 * var(--glass-m, 1) + (1 - 0.66 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.66 * 1000))), rgba(30, 30, 40, calc(0.52 * var(--glass-m, 1) + (1 - 0.52 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.52 * 1000))));
    --glass-strong: linear-gradient(135deg, rgba(56, 56, 68, calc(0.82 * var(--glass-m, 1) + (1 - 0.82 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.82 * 1000))), rgba(34, 34, 44, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000))));
    --glass-row: linear-gradient(135deg, rgba(50, 50, 62, calc(0.88 * var(--glass-m, 1) + (1 - 0.88 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.88 * 1000))), rgba(32, 32, 42, calc(0.78 * var(--glass-m, 1) + (1 - 0.78 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.78 * 1000))));
    --glass-ring: rgba(255, 255, 255, calc(0.16 * var(--glass-m, 1) + (1 - 0.16 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.16 * 1000)));
    --glass-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14),
      inset 0 0 0 1px rgba(255, 255, 255, 0.08),
      0 10px 32px rgba(0, 0, 0, 0.42), 0 2px 8px rgba(0, 0, 0, 0.3);
    --glass-shadow-sm: inset 0 1px 0 rgba(255, 255, 255, 0.12),
      inset 0 0 0 1px rgba(255, 255, 255, 0.07),
      0 6px 20px rgba(0, 0, 0, 0.36), 0 1px 5px rgba(0, 0, 0, 0.26);
    --sheet-bg: linear-gradient(180deg, rgba(34, 34, 44, calc(0.96 * var(--glass-m, 1) + (1 - 0.96 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.96 * 1000))), rgba(18, 18, 26, calc(0.98 * var(--glass-m, 1) + (1 - 0.98 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.98 * 1000))));
    --dock-glass: linear-gradient(135deg, rgba(52, 52, 64, 0.62), rgba(28, 28, 38, 0.5));
  }
}

/* Aurora backdrop: fixed layer behind everything; the glass above
   blurs against it. html keeps the flat base color for overscroll. */
html { background: var(--base-bg); }
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1;
  background-image: var(--aurora);
  background-color: var(--base-bg);
  pointer-events: none;
}
.boot-splash { background-color: var(--base-bg); background-image: var(--aurora); }
.boot-mark { background: var(--grad); box-shadow: 0 8px 24px rgba(109, 61, 240, 0.4); }

/* ---- Chrome: header + dock ---- */
.app-header {
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--glass-ring);
  box-shadow: 0 6px 24px rgba(83, 58, 183, 0.07);
}
/* v218: the wordmark no longer wears the accent gradient — over
   the bright lake sky its light end washed out (Nelson: "better
   contrast on the KeyPipeline name"). Solid deep navy + strong
   NAF blue, readable on any accent and any backdrop.
   v221/v222: the brand colors are theme-aware — the hardcoded
   navy vanished on dark glass ("barely seeable"), so dark
   themes flip to white + bright sky. (v221 briefly named the
   header the workspace; v222 restored KeyPipeline there per
   Nelson's photo correction — the workspace name lives ONLY
   in the desktop sidebar title.) */
.brand span { color: #0A2463; }
.brand span .brand-b { color: #1D4FA1; font-weight: 800; }
:root[data-theme='dark'] .brand span { color: #FFFFFF; }
:root[data-theme='dark'] .brand span .brand-b { color: #7DB8FF; }
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] .brand span { color: #FFFFFF; }
  :root[data-theme='system'] .brand span .brand-b { color: #7DB8FF; }
}
/* (v221's .powered-by login credit was removed in v222 —
   Nelson's photo correction: only the LEFT sidebar carries
   the workspace name; everything else is KeyPipeline.) */
/* v225: the header brand is viewport-split (Nelson, from his
   phone screenshot): on MOBILE the header names the TEAM —
   the workspace — because the workspace belongs to the team
   (and if the service is sold, that spot carries the buyer's
   name); on DESKTOP the header stays KeyPipeline, next to
   the sidebar's the workspace. */
.bn-desk { display: none; }
.bn-mob { display: inline; }
@media (min-width: 1024px) {
  .bn-desk { display: inline; }
  .bn-mob { display: none; }
}
.stat-chip {
  background: var(--glass-strong); border: 1px solid var(--glass-ring);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  box-shadow: var(--glass-shadow-sm);
}
.toptabs {
  background: var(--dock-glass);
  -webkit-backdrop-filter: blur(30px) saturate(200%); backdrop-filter: blur(30px) saturate(200%);
  border: 1px solid var(--glass-ring);
  box-shadow: 0 18px 44px rgba(64, 42, 160, 0.20), inset 0 1px 0 rgba(255, 255, 255, 0.65),
    inset 0 -1px 0 rgba(255, 255, 255, 0.2);
}
.toptabs .tab.active {
  background: var(--grad); color: #fff;
  box-shadow: 0 6px 18px rgba(109, 61, 240, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
@media (min-width: 1024px) {
  .toptabs {
    background: var(--dock-glass);
    -webkit-backdrop-filter: blur(30px) saturate(200%); backdrop-filter: blur(30px) saturate(200%);
    border-right: 1px solid var(--glass-ring);
    box-shadow: inset -1px 0 0 rgba(255, 255, 255, 0.25);
  }
  /* v223: this block used to re-skin the sidebar title with
     gradient-clipped text (text-fill-color: transparent) —
     that treatment, not the title's color, is what made
     "the workspace" blue-on-blue and barely visible on the
     dark rail. The title's paint is owned by its base rule
     (≥1024px block) + the v222/v223 theme rules at file end. */
}

/* ---- Glass card surfaces ---- */
.dash-card, .smart-card, .pie-wrap, .pie-card, .value-pipe, .today-scroll,
.panel-scroll, .search, .gq-results, .mb-pipeline {
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-ring);
  box-shadow: var(--glass-shadow);
}
.dash-card, .smart-card { border-radius: 22px; }
.pie-wrap, .pie-card { border-radius: 22px; }
.today-scroll, .panel-scroll { border-radius: 22px; }
.pie-card .pie-wrap {
  background: none; border: none; box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
/* Long-list rows: translucent glass look, no live blur (perf). */
.row-card, .activity-row, .partner-card {
  background: var(--glass-row);
  box-shadow: var(--glass-shadow-sm);
  border: 1px solid var(--glass-ring);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
.row-card { border-radius: 16px; }
.kcard {
  background: var(--glass-row);
  border: 1px solid var(--glass-ring); border-left: 4px solid var(--blue);
  border-radius: 14px;
  box-shadow: var(--glass-shadow-sm);
}
.search { border-radius: 14px; }
.select, .fpill {
  background: var(--glass-strong); border: 1px solid var(--glass-ring);
  box-shadow: var(--glass-shadow-sm);
}
.seg-btn {
  background: var(--glass-strong); border: 1px solid var(--glass-ring);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  box-shadow: var(--glass-shadow-sm);
}
.seg-btn.active {
  background: var(--grad); color: #fff; border-color: transparent;
  box-shadow: 0 6px 18px rgba(109, 61, 240, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

/* Board columns: tinted glass slabs the cards float inside. */
.kanban-col {
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-ring);
  border-radius: 20px;
  box-shadow: var(--glass-shadow);
}
.col-dot { box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.35), 0 0 10px rgba(83, 58, 183, 0.25); }
.col-count { background: var(--glass-strong); border: 1px solid var(--glass-ring); }

/* ---- Color: buttons, badges, checks ---- */
.btn-primary, .btn-add {
  background: var(--grad);
  box-shadow: 0 8px 22px rgba(109, 61, 240, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
.btn-primary:hover { background: var(--grad); filter: brightness(1.07); }
.btn-add:hover { filter: brightness(1.07); }
.filter-chip, .fpill.on {
  background: var(--grad); border-color: transparent;
  box-shadow: 0 5px 14px rgba(109, 61, 240, 0.3);
}
.count-badge { background: var(--grad); box-shadow: 0 3px 8px rgba(109, 61, 240, 0.35); }
.brief-rank { background: var(--grad); box-shadow: 0 4px 10px rgba(109, 61, 240, 0.35); }
.ios-check:checked, .task-check input[type="checkbox"]:checked {
  background: var(--grad); border-color: transparent;
  box-shadow: 0 3px 9px rgba(109, 61, 240, 0.35);
}
.filter-pills .select.on { background: var(--grad); background-color: transparent; }

/* Smart cards: tinted color washes (blue / violet / warm / teal),
   cycling by position — the "more colorful" on Home. */
.smart-card:nth-child(4n+1) { background-image: linear-gradient(135deg, rgba(10, 108, 255, 0.14), rgba(255, 255, 255, 0.1) 55%), var(--glass); }
.smart-card:nth-child(4n+2) { background-image: linear-gradient(135deg, rgba(125, 74, 255, 0.15), rgba(255, 255, 255, 0.1) 55%), var(--glass); }
.smart-card:nth-child(4n+3) { background-image: linear-gradient(135deg, rgba(255, 149, 0, 0.16), rgba(255, 255, 255, 0.1) 55%), var(--glass); }
.smart-card:nth-child(4n+4) { background-image: linear-gradient(135deg, rgba(0, 180, 216, 0.15), rgba(255, 255, 255, 0.1) 55%), var(--glass); }
.smart-icon {
  border-radius: 12px;
  background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0) 55%);
  box-shadow: 0 5px 14px rgba(31, 38, 135, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.45);
}

/* Avatars cycle five gradients by list position. */
.list > .row-card:nth-child(5n+1) .avatar, .focus-list > .row-card:nth-child(5n+1) .avatar { background: linear-gradient(135deg, #0A6CFF, #00B4D8); }
.list > .row-card:nth-child(5n+2) .avatar, .focus-list > .row-card:nth-child(5n+2) .avatar { background: linear-gradient(135deg, #7D4AFF, #FF5CA8); }
.list > .row-card:nth-child(5n+3) .avatar, .focus-list > .row-card:nth-child(5n+3) .avatar { background: linear-gradient(135deg, #FF9500, #FF3B30); }
.list > .row-card:nth-child(5n+4) .avatar, .focus-list > .row-card:nth-child(5n+4) .avatar { background: linear-gradient(135deg, #00B98A, #00B4D8); }
.list > .row-card:nth-child(5n+5) .avatar, .focus-list > .row-card:nth-child(5n+5) .avatar { background: linear-gradient(135deg, #5E5CE6, #0A6CFF); }
.row-card .avatar { box-shadow: 0 4px 12px rgba(31, 38, 135, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.4); }

/* Hero: richer multi-color gradient + soft glow, text stays on top. */
.value-hero {
  background: var(--grad-hero);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 24px;
  box-shadow: 0 16px 38px rgba(94, 61, 230, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.4);
  position: relative; overflow: hidden;
}
.value-hero::before {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(420px 240px at 88% -20%, rgba(255, 255, 255, 0.38), transparent 60%),
    radial-gradient(360px 260px at -10% 120%, rgba(0, 229, 255, 0.35), transparent 60%);
  pointer-events: none;
}
.value-hero > * { position: relative; z-index: 1; }

/* Sheet + login: glass, kept readable. */
.sheet {
  background: var(--sheet-bg);
  -webkit-backdrop-filter: blur(26px) saturate(180%); backdrop-filter: blur(26px) saturate(180%);
  border-top: 1px solid var(--glass-ring);
  border-radius: 26px 26px 0 0;
}
@media (min-width: 720px) { .sheet { border-radius: 0; border-top: none; border-left: 1px solid var(--glass-ring); } }
.login-view { background-image: var(--aurora); background-color: var(--base-bg); }
.login-card {
  background: var(--glass);
  -webkit-backdrop-filter: blur(28px) saturate(190%); backdrop-filter: blur(28px) saturate(190%);
  border: 1px solid var(--glass-ring);
  border-radius: 28px;
  box-shadow: var(--glass-shadow), 0 24px 60px rgba(83, 58, 183, 0.18);
}
.field input {
  background: var(--glass-strong); border: 1px solid var(--glass-ring);
}

/* Hover lift — non-draggable cards only, pointer devices only, so the
   lift can never fight the board drag or touch scrolling. */
@media (hover: hover) {
  .dash-card, .smart-card, .row-card, .partner-card, .pie-card, .value-pipe {
    transition: transform .45s var(--spring), box-shadow .35s ease;
  }
  .dash-card:hover, .smart-card:hover, .row-card:hover, .partner-card:hover,
  .pie-card:hover, .value-pipe:hover {
    transform: translateY(-3px);
    box-shadow: var(--glass-shadow), 0 18px 40px rgba(83, 58, 183, 0.16);
  }
}
@media (prefers-reduced-motion: reduce) {
  .dash-card:hover, .smart-card:hover, .row-card:hover, .partner-card:hover,
  .pie-card:hover, .value-pipe:hover { transform: none; }
}

/* ============================================================
   v135 — Glass+ (Nelson, 2026-10-25: "make it more glassy")
   Same system, pushed further: thinner fills so the aurora shows
   through, stronger blur + saturation, a diagonal sheen layer on
   the glass itself, brighter specular edges, richer aurora (more
   color for the glass to refract), and a very slow aurora drift.
   Variable overrides only — component rules above pick them up.
   ============================================================ */
:root {
  --glass-blur: blur(30px) saturate(215%);
  --aurora:
    radial-gradient(880px 600px at 10% -10%, rgba(125, 74, 255, 0.38), transparent 62%),
    radial-gradient(760px 540px at 94% -6%, rgba(0, 200, 215, 0.34), transparent 60%),
    radial-gradient(680px 520px at 88% 58%, rgba(255, 149, 0, 0.27), transparent 62%),
    radial-gradient(820px 640px at -8% 88%, rgba(var(--accent-rgb), 0.32), transparent 62%),
    radial-gradient(560px 460px at 58% 112%, rgba(255, 45, 120, 0.19), transparent 60%);
  --glass: linear-gradient(115deg, rgba(255, 255, 255, calc(0.5 * var(--glass-m, 1) + (1 - 0.5 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.5 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 42%),
    linear-gradient(135deg, rgba(255, 255, 255, calc(0.58 * var(--glass-m, 1) + (1 - 0.58 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.58 * 1000))), rgba(255, 255, 255, calc(0.32 * var(--glass-m, 1) + (1 - 0.32 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.32 * 1000))));
  --glass-strong: linear-gradient(115deg, rgba(255, 255, 255, calc(0.45 * var(--glass-m, 1) + (1 - 0.45 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.45 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%),
    linear-gradient(135deg, rgba(255, 255, 255, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000))), rgba(255, 255, 255, calc(0.5 * var(--glass-m, 1) + (1 - 0.5 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.5 * 1000))));
  --glass-row: linear-gradient(115deg, rgba(255, 255, 255, calc(0.4 * var(--glass-m, 1) + (1 - 0.4 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.4 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 48%),
    linear-gradient(135deg, rgba(255, 255, 255, calc(0.64 * var(--glass-m, 1) + (1 - 0.64 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.64 * 1000))), rgba(255, 255, 255, calc(0.44 * var(--glass-m, 1) + (1 - 0.44 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.44 * 1000))));
  --glass-ring: rgba(255, 255, 255, calc(0.85 * var(--glass-m, 1) + (1 - 0.85 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.85 * 1000)));
  --glass-shadow: inset 0 1px 0 #fff, inset 0 0 0 1px rgba(255, 255, 255, 0.55),
    0 14px 38px rgba(83, 58, 183, 0.15), 0 3px 10px rgba(31, 38, 135, 0.07);
  --glass-shadow-sm: inset 0 1px 0 rgba(255, 255, 255, 0.95), inset 0 0 0 1px rgba(255, 255, 255, 0.5),
    0 8px 22px rgba(83, 58, 183, 0.11), 0 2px 6px rgba(31, 38, 135, 0.06);
  --dock-glass: linear-gradient(115deg, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0.1) 55%),
    linear-gradient(135deg, rgba(255, 255, 255, 0.42), rgba(255, 255, 255, 0.24));
}
:root[data-theme='dark'] {
  --aurora:
    radial-gradient(880px 600px at 10% -10%, rgba(125, 74, 255, 0.42), transparent 62%),
    radial-gradient(760px 540px at 94% -6%, rgba(0, 200, 215, 0.28), transparent 60%),
    radial-gradient(680px 520px at 88% 58%, rgba(255, 149, 0, 0.2), transparent 62%),
    radial-gradient(820px 640px at -8% 88%, rgba(var(--accent-rgb), 0.34), transparent 62%),
    radial-gradient(560px 460px at 58% 112%, rgba(255, 45, 120, 0.2), transparent 60%);
  --glass: linear-gradient(115deg, rgba(255, 255, 255, calc(0.14 * var(--glass-m, 1) + (1 - 0.14 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.14 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 42%),
    linear-gradient(135deg, rgba(52, 52, 64, calc(0.5 * var(--glass-m, 1) + (1 - 0.5 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.5 * 1000))), rgba(30, 30, 40, calc(0.34 * var(--glass-m, 1) + (1 - 0.34 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.34 * 1000))));
  --glass-strong: linear-gradient(115deg, rgba(255, 255, 255, calc(0.12 * var(--glass-m, 1) + (1 - 0.12 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.12 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%),
    linear-gradient(135deg, rgba(56, 56, 68, calc(0.68 * var(--glass-m, 1) + (1 - 0.68 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.68 * 1000))), rgba(34, 34, 44, calc(0.5 * var(--glass-m, 1) + (1 - 0.5 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.5 * 1000))));
  --glass-row: linear-gradient(115deg, rgba(255, 255, 255, calc(0.1 * var(--glass-m, 1) + (1 - 0.1 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.1 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 48%),
    linear-gradient(135deg, rgba(50, 50, 62, calc(0.62 * var(--glass-m, 1) + (1 - 0.62 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.62 * 1000))), rgba(32, 32, 42, calc(0.5 * var(--glass-m, 1) + (1 - 0.5 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.5 * 1000))));
  --glass-ring: rgba(255, 255, 255, calc(0.22 * var(--glass-m, 1) + (1 - 0.22 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.22 * 1000)));
  --dock-glass: linear-gradient(115deg, rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0.03) 55%),
    linear-gradient(135deg, rgba(52, 52, 64, 0.48), rgba(28, 28, 38, 0.36));
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] {
    --aurora:
      radial-gradient(880px 600px at 10% -10%, rgba(125, 74, 255, 0.42), transparent 62%),
      radial-gradient(760px 540px at 94% -6%, rgba(0, 200, 215, 0.28), transparent 60%),
      radial-gradient(680px 520px at 88% 58%, rgba(255, 149, 0, 0.2), transparent 62%),
      radial-gradient(820px 640px at -8% 88%, rgba(var(--accent-rgb), 0.34), transparent 62%),
      radial-gradient(560px 460px at 58% 112%, rgba(255, 45, 120, 0.2), transparent 60%);
    --glass: linear-gradient(115deg, rgba(255, 255, 255, calc(0.14 * var(--glass-m, 1) + (1 - 0.14 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.14 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 42%),
      linear-gradient(135deg, rgba(52, 52, 64, calc(0.5 * var(--glass-m, 1) + (1 - 0.5 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.5 * 1000))), rgba(30, 30, 40, calc(0.34 * var(--glass-m, 1) + (1 - 0.34 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.34 * 1000))));
    --glass-strong: linear-gradient(115deg, rgba(255, 255, 255, calc(0.12 * var(--glass-m, 1) + (1 - 0.12 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.12 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%),
      linear-gradient(135deg, rgba(56, 56, 68, calc(0.68 * var(--glass-m, 1) + (1 - 0.68 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.68 * 1000))), rgba(34, 34, 44, calc(0.5 * var(--glass-m, 1) + (1 - 0.5 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.5 * 1000))));
    --glass-row: linear-gradient(115deg, rgba(255, 255, 255, calc(0.1 * var(--glass-m, 1) + (1 - 0.1 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.1 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 48%),
      linear-gradient(135deg, rgba(50, 50, 62, calc(0.62 * var(--glass-m, 1) + (1 - 0.62 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.62 * 1000))), rgba(32, 32, 42, calc(0.5 * var(--glass-m, 1) + (1 - 0.5 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.5 * 1000))));
    --glass-ring: rgba(255, 255, 255, calc(0.22 * var(--glass-m, 1) + (1 - 0.22 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.22 * 1000)));
    --dock-glass: linear-gradient(115deg, rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0.03) 55%),
      linear-gradient(135deg, rgba(52, 52, 64, 0.48), rgba(28, 28, 38, 0.36));
  }
}
/* Deeper frost on the big floating surfaces. */
.toptabs {
  -webkit-backdrop-filter: blur(40px) saturate(220%); backdrop-filter: blur(40px) saturate(220%);
}
.sheet {
  -webkit-backdrop-filter: blur(32px) saturate(200%); backdrop-filter: blur(32px) saturate(200%);
}
.login-card {
  -webkit-backdrop-filter: blur(34px) saturate(210%); backdrop-filter: blur(34px) saturate(210%);
}
/* Slow aurora drift — the glass subtly changes as the color moves
   beneath it. One fixed layer, transform-only, cheap on GPU; the
   global reduced-motion rule collapses it. */
@keyframes auroraDrift {
  from { transform: scale(1) translate(0, 0); }
  to { transform: scale(1.12) translate(-1.5%, 2%); }
}
body::before { animation: auroraDrift 30s ease-in-out infinite alternate; }

/* ============================================================
   v136 — NAF blue palette (Nelson, 2026-10-25: "more blue than
   violet, like NAF colors") + Activity owner-only.
   Palette anchored on NAF corporate: deep navy #091644, corporate
   blue #3B6CCF, off-white #F8F9FF. Violet/pink/orange leave the
   aurora; every gradient runs navy -> corporate blue -> sky.
   (The Activity gating itself lives in app.v5.js + firestore.rules.)
   ============================================================ */
:root {
  --grad: linear-gradient(135deg, #0B2A6B 0%, #3B6CCF 55%, #38B6E3 100%);
  --grad-hero: linear-gradient(122deg, #091644 0%, #1D4FA1 45%, #3B6CCF 78%, #38B6E3 108%);
  --base-bg: #F2F5FE;
  --aurora:
    radial-gradient(880px 600px at 10% -10%, rgba(27, 64, 150, 0.30), transparent 62%),
    radial-gradient(760px 540px at 94% -6%, rgba(59, 108, 207, 0.32), transparent 60%),
    radial-gradient(680px 520px at 88% 58%, rgba(56, 182, 227, 0.28), transparent 62%),
    radial-gradient(820px 640px at -8% 88%, rgba(0, 98, 204, 0.28), transparent 62%),
    radial-gradient(560px 460px at 58% 112%, rgba(9, 22, 68, 0.16), transparent 60%);
  --glass-shadow: inset 0 1px 0 #fff, inset 0 0 0 1px rgba(255, 255, 255, 0.55),
    0 14px 38px rgba(27, 58, 140, 0.15), 0 3px 10px rgba(23, 43, 99, 0.07);
  --glass-shadow-sm: inset 0 1px 0 rgba(255, 255, 255, 0.95), inset 0 0 0 1px rgba(255, 255, 255, 0.5),
    0 8px 22px rgba(27, 58, 140, 0.11), 0 2px 6px rgba(23, 43, 99, 0.06);
}
:root[data-theme='dark'] {
  --base-bg: #050A1E;
  --aurora:
    radial-gradient(880px 600px at 10% -10%, rgba(59, 108, 207, 0.40), transparent 62%),
    radial-gradient(760px 540px at 94% -6%, rgba(56, 182, 227, 0.26), transparent 60%),
    radial-gradient(680px 520px at 88% 58%, rgba(29, 79, 161, 0.3), transparent 62%),
    radial-gradient(820px 640px at -8% 88%, rgba(0, 98, 204, 0.32), transparent 62%),
    radial-gradient(560px 460px at 58% 112%, rgba(56, 182, 227, 0.16), transparent 60%);
  --glass-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14),
    inset 0 0 0 1px rgba(255, 255, 255, 0.08),
    0 10px 32px rgba(0, 0, 0, 0.42), 0 2px 8px rgba(0, 0, 0, 0.3);
  --glass-shadow-sm: inset 0 1px 0 rgba(255, 255, 255, 0.12),
    inset 0 0 0 1px rgba(255, 255, 255, 0.07),
    0 6px 20px rgba(0, 0, 0, 0.36), 0 1px 5px rgba(0, 0, 0, 0.26);
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] {
    --base-bg: #050A1E;
    --aurora:
      radial-gradient(880px 600px at 10% -10%, rgba(59, 108, 207, 0.40), transparent 62%),
      radial-gradient(760px 540px at 94% -6%, rgba(56, 182, 227, 0.26), transparent 60%),
      radial-gradient(680px 520px at 88% 58%, rgba(29, 79, 161, 0.3), transparent 62%),
      radial-gradient(820px 640px at -8% 88%, rgba(0, 98, 204, 0.32), transparent 62%),
      radial-gradient(560px 460px at 58% 112%, rgba(56, 182, 227, 0.16), transparent 60%);
    --glass-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14),
      inset 0 0 0 1px rgba(255, 255, 255, 0.08),
      0 10px 32px rgba(0, 0, 0, 0.42), 0 2px 8px rgba(0, 0, 0, 0.3);
    --glass-shadow-sm: inset 0 1px 0 rgba(255, 255, 255, 0.12),
      inset 0 0 0 1px rgba(255, 255, 255, 0.07),
      0 6px 20px rgba(0, 0, 0, 0.36), 0 1px 5px rgba(0, 0, 0, 0.26);
  }
}
/* Blue-tinted shadows where the violet ones were hard-coded. */
.toptabs { box-shadow: 0 18px 44px rgba(16, 42, 110, 0.22), inset 0 1px 0 rgba(255, 255, 255, 0.65),
  inset 0 -1px 0 rgba(255, 255, 255, 0.2); }
.toptabs .tab.active { box-shadow: 0 6px 18px rgba(29, 79, 161, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.35); }
.btn-primary, .btn-add { box-shadow: 0 8px 22px rgba(29, 79, 161, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.35); }
.seg-btn.active { box-shadow: 0 6px 18px rgba(29, 79, 161, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.35); }
.filter-chip, .fpill.on { box-shadow: 0 5px 14px rgba(29, 79, 161, 0.32); }
.count-badge { box-shadow: 0 3px 8px rgba(29, 79, 161, 0.35); }
.brief-rank { box-shadow: 0 4px 10px rgba(29, 79, 161, 0.35); }
.ios-check:checked, .task-check input[type="checkbox"]:checked { box-shadow: 0 3px 9px rgba(29, 79, 161, 0.35); }
.boot-mark { box-shadow: 0 8px 24px rgba(29, 79, 161, 0.42); }
.value-hero { box-shadow: 0 16px 38px rgba(13, 38, 102, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.4); }
.login-card { box-shadow: var(--glass-shadow), 0 24px 60px rgba(27, 58, 140, 0.18); }
.col-dot { box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.35), 0 0 10px rgba(27, 58, 140, 0.25); }
@media (hover: hover) {
  .dash-card:hover, .smart-card:hover, .row-card:hover, .partner-card:hover,
  .pie-card:hover, .value-pipe:hover {
    box-shadow: var(--glass-shadow), 0 18px 40px rgba(27, 58, 140, 0.16);
  }
}
/* Smart-card tints + avatars move into the blue family too. */
.smart-card:nth-child(4n+1) { background-image: linear-gradient(135deg, rgba(59, 108, 207, 0.16), rgba(255, 255, 255, 0.1) 55%), var(--glass); }
.smart-card:nth-child(4n+2) { background-image: linear-gradient(135deg, rgba(9, 22, 68, 0.13), rgba(255, 255, 255, 0.1) 55%), var(--glass); }
.smart-card:nth-child(4n+3) { background-image: linear-gradient(135deg, rgba(56, 182, 227, 0.17), rgba(255, 255, 255, 0.1) 55%), var(--glass); }
.smart-card:nth-child(4n+4) { background-image: linear-gradient(135deg, rgba(0, 150, 199, 0.15), rgba(255, 255, 255, 0.1) 55%), var(--glass); }
.list > .row-card:nth-child(5n+1) .avatar, .focus-list > .row-card:nth-child(5n+1) .avatar { background: linear-gradient(135deg, #0B2A6B, #3B6CCF); }
.list > .row-card:nth-child(5n+2) .avatar, .focus-list > .row-card:nth-child(5n+2) .avatar { background: linear-gradient(135deg, #3B6CCF, #38B6E3); }
.list > .row-card:nth-child(5n+3) .avatar, .focus-list > .row-card:nth-child(5n+3) .avatar { background: linear-gradient(135deg, #091644, #2E5FA3); }
.list > .row-card:nth-child(5n+4) .avatar, .focus-list > .row-card:nth-child(5n+4) .avatar { background: linear-gradient(135deg, var(--blue-dark), var(--blue-light)); }
.list > .row-card:nth-child(5n+5) .avatar, .focus-list > .row-card:nth-child(5n+5) .avatar { background: linear-gradient(135deg, #1D4FA1, #00A8C5); }

/* ============================================================
   v137 — See-through glass + celebrations (Nelson, 2026-10-25)
   "More glass that see the transparent from behind": fills drop
   to ~0.15-0.30 alpha and the blur lightens (16px) so the blue
   aurora reads THROUGH the cards, not just behind them; brighter
   rims + deeper float shadows keep the panes defined. The aurora
   gets more vivid — there has to be something to see through to.
   Plus the celebration layer for task completions / new notes.
   ============================================================ */
:root {
  --glass-blur: blur(16px) saturate(200%);
  --aurora:
    radial-gradient(880px 600px at 10% -10%, rgba(27, 64, 150, 0.38), transparent 62%),
    radial-gradient(760px 540px at 94% -6%, rgba(59, 108, 207, 0.42), transparent 60%),
    radial-gradient(680px 520px at 88% 58%, rgba(56, 182, 227, 0.4), transparent 62%),
    radial-gradient(820px 640px at -8% 88%, rgba(0, 98, 204, 0.36), transparent 62%),
    radial-gradient(560px 460px at 58% 112%, rgba(9, 22, 68, 0.22), transparent 60%);
  --glass: linear-gradient(115deg, rgba(255, 255, 255, calc(0.42 * var(--glass-m, 1) + (1 - 0.42 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.42 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%),
    linear-gradient(135deg, rgba(255, 255, 255, calc(0.3 * var(--glass-m, 1) + (1 - 0.3 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.3 * 1000))), rgba(255, 255, 255, calc(0.15 * var(--glass-m, 1) + (1 - 0.15 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.15 * 1000))));
  --glass-strong: linear-gradient(115deg, rgba(255, 255, 255, calc(0.4 * var(--glass-m, 1) + (1 - 0.4 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.4 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%),
    linear-gradient(135deg, rgba(255, 255, 255, calc(0.46 * var(--glass-m, 1) + (1 - 0.46 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.46 * 1000))), rgba(255, 255, 255, calc(0.28 * var(--glass-m, 1) + (1 - 0.28 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.28 * 1000))));
  --glass-row: linear-gradient(115deg, rgba(255, 255, 255, calc(0.36 * var(--glass-m, 1) + (1 - 0.36 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.36 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 48%),
    linear-gradient(135deg, rgba(255, 255, 255, calc(0.4 * var(--glass-m, 1) + (1 - 0.4 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.4 * 1000))), rgba(255, 255, 255, calc(0.24 * var(--glass-m, 1) + (1 - 0.24 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.24 * 1000))));
  --glass-ring: rgba(255, 255, 255, calc(0.95 * var(--glass-m, 1) + (1 - 0.95 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.95 * 1000)));
  --glass-shadow: inset 0 1px 0 #fff, inset 0 0 0 1px rgba(255, 255, 255, 0.6),
    inset 0 -1px 0 rgba(255, 255, 255, 0.35),
    0 16px 42px rgba(27, 58, 140, 0.18), 0 3px 10px rgba(23, 43, 99, 0.08);
  --glass-shadow-sm: inset 0 1px 0 #fff, inset 0 0 0 1px rgba(255, 255, 255, 0.55),
    inset 0 -1px 0 rgba(255, 255, 255, 0.3),
    0 9px 24px rgba(27, 58, 140, 0.13), 0 2px 6px rgba(23, 43, 99, 0.07);
  --dock-glass: linear-gradient(115deg, rgba(255, 255, 255, 0.45), rgba(255, 255, 255, 0.08) 55%),
    linear-gradient(135deg, rgba(255, 255, 255, 0.34), rgba(255, 255, 255, 0.18));
  --sheet-bg: linear-gradient(180deg, rgba(255, 255, 255, calc(0.88 * var(--glass-m, 1) + (1 - 0.88 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.88 * 1000))), rgba(248, 250, 255, calc(0.93 * var(--glass-m, 1) + (1 - 0.93 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.93 * 1000))));
}
:root[data-theme='dark'] {
  --aurora:
    radial-gradient(880px 600px at 10% -10%, rgba(59, 108, 207, 0.48), transparent 62%),
    radial-gradient(760px 540px at 94% -6%, rgba(56, 182, 227, 0.34), transparent 60%),
    radial-gradient(680px 520px at 88% 58%, rgba(29, 79, 161, 0.38), transparent 62%),
    radial-gradient(820px 640px at -8% 88%, rgba(0, 98, 204, 0.4), transparent 62%),
    radial-gradient(560px 460px at 58% 112%, rgba(56, 182, 227, 0.22), transparent 60%);
  --glass: linear-gradient(115deg, rgba(255, 255, 255, calc(0.13 * var(--glass-m, 1) + (1 - 0.13 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.13 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%),
    linear-gradient(135deg, rgba(52, 52, 64, calc(0.36 * var(--glass-m, 1) + (1 - 0.36 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.36 * 1000))), rgba(30, 30, 40, calc(0.22 * var(--glass-m, 1) + (1 - 0.22 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.22 * 1000))));
  --glass-strong: linear-gradient(115deg, rgba(255, 255, 255, calc(0.11 * var(--glass-m, 1) + (1 - 0.11 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.11 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%),
    linear-gradient(135deg, rgba(56, 56, 68, calc(0.5 * var(--glass-m, 1) + (1 - 0.5 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.5 * 1000))), rgba(34, 34, 44, calc(0.36 * var(--glass-m, 1) + (1 - 0.36 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.36 * 1000))));
  --glass-row: linear-gradient(115deg, rgba(255, 255, 255, calc(0.09 * var(--glass-m, 1) + (1 - 0.09 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.09 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 48%),
    linear-gradient(135deg, rgba(50, 50, 62, calc(0.48 * var(--glass-m, 1) + (1 - 0.48 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.48 * 1000))), rgba(32, 32, 42, calc(0.34 * var(--glass-m, 1) + (1 - 0.34 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.34 * 1000))));
  --sheet-bg: linear-gradient(180deg, rgba(34, 34, 44, calc(0.9 * var(--glass-m, 1) + (1 - 0.9 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.9 * 1000))), rgba(18, 18, 26, calc(0.94 * var(--glass-m, 1) + (1 - 0.94 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.94 * 1000))));
  --dock-glass: linear-gradient(115deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.02) 55%),
    linear-gradient(135deg, rgba(52, 52, 64, 0.36), rgba(28, 28, 38, 0.26));
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] {
    --aurora:
      radial-gradient(880px 600px at 10% -10%, rgba(59, 108, 207, 0.48), transparent 62%),
      radial-gradient(760px 540px at 94% -6%, rgba(56, 182, 227, 0.34), transparent 60%),
      radial-gradient(680px 520px at 88% 58%, rgba(29, 79, 161, 0.38), transparent 62%),
      radial-gradient(820px 640px at -8% 88%, rgba(0, 98, 204, 0.4), transparent 62%),
      radial-gradient(560px 460px at 58% 112%, rgba(56, 182, 227, 0.22), transparent 60%);
    --glass: linear-gradient(115deg, rgba(255, 255, 255, calc(0.13 * var(--glass-m, 1) + (1 - 0.13 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.13 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%),
      linear-gradient(135deg, rgba(52, 52, 64, calc(0.36 * var(--glass-m, 1) + (1 - 0.36 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.36 * 1000))), rgba(30, 30, 40, calc(0.22 * var(--glass-m, 1) + (1 - 0.22 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.22 * 1000))));
    --glass-strong: linear-gradient(115deg, rgba(255, 255, 255, calc(0.11 * var(--glass-m, 1) + (1 - 0.11 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.11 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%),
      linear-gradient(135deg, rgba(56, 56, 68, calc(0.5 * var(--glass-m, 1) + (1 - 0.5 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.5 * 1000))), rgba(34, 34, 44, calc(0.36 * var(--glass-m, 1) + (1 - 0.36 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.36 * 1000))));
    --glass-row: linear-gradient(115deg, rgba(255, 255, 255, calc(0.09 * var(--glass-m, 1) + (1 - 0.09 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.09 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 48%),
      linear-gradient(135deg, rgba(50, 50, 62, calc(0.48 * var(--glass-m, 1) + (1 - 0.48 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.48 * 1000))), rgba(32, 32, 42, calc(0.34 * var(--glass-m, 1) + (1 - 0.34 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.34 * 1000))));
    --sheet-bg: linear-gradient(180deg, rgba(34, 34, 44, calc(0.9 * var(--glass-m, 1) + (1 - 0.9 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.9 * 1000))), rgba(18, 18, 26, calc(0.94 * var(--glass-m, 1) + (1 - 0.94 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.94 * 1000))));
    --dock-glass: linear-gradient(115deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.02) 55%),
      linear-gradient(135deg, rgba(52, 52, 64, 0.36), rgba(28, 28, 38, 0.26));
  }
}
.toptabs {
  -webkit-backdrop-filter: blur(20px) saturate(210%); backdrop-filter: blur(20px) saturate(210%);
}
.sheet {
  -webkit-backdrop-filter: blur(24px) saturate(190%); backdrop-filter: blur(24px) saturate(190%);
}
.login-card {
  -webkit-backdrop-filter: blur(22px) saturate(200%); backdrop-filter: blur(22px) saturate(200%);
}

/* ---- Celebration layer (v137) ---- */
#celebrate-layer { position: fixed; inset: 0; z-index: 300; pointer-events: none; overflow: hidden; }
.cel-particle { position: fixed; border-radius: 50%; pointer-events: none; will-change: transform, opacity; }
.cel-particle.cel-square { border-radius: 3px; }
.cel-tick {
  position: fixed; pointer-events: none;
  font-size: 30px; font-weight: 800; color: #34C759;
  text-shadow: 0 2px 10px rgba(52, 199, 89, 0.45), 0 0 2px #fff;
  will-change: transform, opacity;
}
/* A freshly saved note springs in like the video's playful landing:
   rises, overshoots with a tiny tilt, settles. */
@keyframes noteIn {
  0% { opacity: 0; transform: translateY(16px) scale(0.9) rotate(-1.2deg); }
  55% { opacity: 1; transform: translateY(-3px) scale(1.03) rotate(0.6deg); }
  78% { transform: translateY(1px) scale(0.99) rotate(0deg); }
  100% { opacity: 1; transform: none; }
}
.note-bubble.note-pop-in { animation: noteIn 0.72s var(--spring-bounce) both; }

/* ============================================================
   v138 — Checkmark + close-button fix (Nelson, 2026-10-25)
   His screenshot: the completed-task check looked like "a square
   below a circle" — iOS Safari mis-clips the v134 GRADIENT fill on
   the round checkbox input (plus the legacy accent-color on the
   sheet rule invited a native square repaint; removed above).
   Checked boxes go back to a flat NAF blue fill, which clips to
   the circle reliably everywhere; gradients stay on buttons/pills.
   And the sheet's X becomes real glass so it blends with the page.
   ============================================================ */
.ios-check, .task-check input[type="checkbox"] {
  -webkit-appearance: none; appearance: none;
  border-radius: 50%; background-clip: padding-box;
}
.ios-check:checked, .task-check input[type="checkbox"]:checked {
  background: #1D4FA1; background-image: none;
  border-color: #1D4FA1;
  box-shadow: 0 3px 9px rgba(29, 79, 161, 0.35);
}
.sheet-close {
  background: var(--glass-strong);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-ring);
  box-shadow: var(--glass-shadow-sm);
  color: var(--label-2);
}
.doc-x {
  background: var(--glass-strong);
  border: 1px solid var(--glass-ring);
  box-shadow: var(--glass-shadow-sm);
}

/* ============================================================
   v139 — Peaceful backdrop (Nelson, 2026-10-25, Forest World
   reference): minimalist + calm, all the info kept. A serene
   photo — misty blue lake at dawn, generated for the app — now
   sits fixed behind everything, under a soft veil that protects
   text contrast. The glass (same recipe he approved on the
   boards) finally has something real to refract, which is the
   "correct glass effect + better contrast" he asked for. The
   aurora drift stops: peaceful means still. Login + boot get
   the photo too. Chrome quiets down (softer section titles,
   calmer chips, more air) — no information removed.
   ============================================================ */
:root {
  --veil: linear-gradient(180deg, rgba(246, 249, 255, 0.4), rgba(238, 244, 253, 0.52) 55%, rgba(233, 240, 251, 0.6));
}
:root[data-theme='dark'] {
  --veil: linear-gradient(180deg, rgba(5, 10, 30, 0.52), rgba(5, 10, 30, 0.64));
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] {
    --veil: linear-gradient(180deg, rgba(5, 10, 30, 0.52), rgba(5, 10, 30, 0.64));
  }
}
body::before {
  background-image: var(--veil), url('../img/peaceful-bg.jpg');
  background-size: cover, cover;
  background-position: center, center;
  animation: none;
}
.boot-splash, .login-view {
  background-image: var(--veil), url('../img/peaceful-bg.jpg');
  background-size: cover, cover;
  background-position: center, center;
  background-color: var(--base-bg);
}
/* Calmer chrome: softer section titles, quieter chips, more air. */
.views { padding-top: 26px; }
.section-title { font-weight: 600; color: var(--label-2); letter-spacing: -0.2px; margin-top: 30px; }
.stat-chip { box-shadow: none; }
.greet-date { color: var(--label-2); }

/* ============================================================
   v141 — The photo, actually visible + a real night version
   (Nelson, 2026-10-25: "I don't see the background" + "adapt it
   when is dark mode"). v139's veil was too heavy and the misty
   photo too pale — together they washed out to near-plain. The
   veil drops to a whisper in light mode so the lake/mountains
   read, and dark mode swaps the photo itself for a generated
   NIGHT version of the same scene (moonrise over the lake, deep
   navy) under a light veil — the backdrop adapts, not just dims.
   ============================================================ */
:root {
  --bg-photo: url('../img/peaceful-bg.jpg');
  --veil: linear-gradient(180deg, rgba(246, 249, 255, 0.16), rgba(240, 245, 253, 0.30) 55%, rgba(235, 242, 252, 0.42));
}
:root[data-theme='dark'] {
  --bg-photo: url('../img/peaceful-bg-night.jpg');
  --veil: linear-gradient(180deg, rgba(4, 8, 24, 0.16), rgba(4, 8, 24, 0.30));
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] {
    --bg-photo: url('../img/peaceful-bg-night.jpg');
    --veil: linear-gradient(180deg, rgba(4, 8, 24, 0.16), rgba(4, 8, 24, 0.30));
  }
}
body::before {
  background-image: var(--veil), var(--bg-photo);
  background-position: center, center 42%;
}
.boot-splash, .login-view {
  background-image: var(--veil), var(--bg-photo);
  background-position: center, center 42%;
}

/* ============================================================
   v142 — Richer backdrop + SUPER GLOSSY charts (Nelson,
   2026-10-25, from his own screenshot: "I dont see the
   background" + "the pipeline charts tab i want it glossy
   too... Super glossy and better design the charts"). The
   photo was recomposed: deeper, more saturated blues with the
   mountain/reflection band higher, so it reads through the
   glass instead of washing out. The veil thins again. Image
   URLs gain ?v=142 so no cache keeps the pale version.
   Charts: the donut gains a lacquer sheen (JS: gradient ring
   over the slices), a soft drop shadow, glossy legend dots,
   and the pie card itself turns thinner, shinier glass with a
   diagonal gloss sweep — the photo now visibly tints it.
   ============================================================ */
:root {
  --bg-photo: url('../img/peaceful-bg.jpg?v=142');
  --veil: linear-gradient(180deg, rgba(244, 248, 255, 0.07), rgba(240, 245, 253, 0.20) 55%, rgba(235, 242, 252, 0.32));
}
:root[data-theme='dark'] { --bg-photo: url('../img/peaceful-bg-night.jpg?v=142'); }
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] { --bg-photo: url('../img/peaceful-bg-night.jpg?v=142'); }
}
.pie-card {
  background: linear-gradient(120deg, rgba(255, 255, 255, calc(0.22 * var(--glass-m, 1) + (1 - 0.22 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.22 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%), rgba(255, 255, 255, calc(0.34 * var(--glass-m, 1) + (1 - 0.34 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.34 * 1000)));
  backdrop-filter: blur(20px) saturate(210%);
  -webkit-backdrop-filter: blur(20px) saturate(210%);
  box-shadow: var(--glass-shadow), inset 0 1px 0 rgba(255, 255, 255, 0.7), inset 0 -1px 0 rgba(255, 255, 255, 0.18);
}
:root[data-theme='dark'] .pie-card {
  background: linear-gradient(120deg, rgba(255, 255, 255, calc(0.10 * var(--glass-m, 1) + (1 - 0.10 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.10 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%), rgba(16, 28, 58, calc(0.40 * var(--glass-m, 1) + (1 - 0.40 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.40 * 1000)));
  box-shadow: var(--glass-shadow), inset 0 1px 0 rgba(190, 215, 255, 0.28);
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] .pie-card {
    background: linear-gradient(120deg, rgba(255, 255, 255, calc(0.10 * var(--glass-m, 1) + (1 - 0.10 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.10 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 45%), rgba(16, 28, 58, calc(0.40 * var(--glass-m, 1) + (1 - 0.40 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.40 * 1000)));
    box-shadow: var(--glass-shadow), inset 0 1px 0 rgba(190, 215, 255, 0.28);
  }
}
.pie { filter: drop-shadow(0 8px 14px rgba(9, 22, 68, 0.20)); }
.value-legend-row .dot {
  background-image: radial-gradient(circle at 32% 30%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0) 55%);
  box-shadow: inset 0 -2px 3px rgba(0, 0, 0, 0.20), 0 1px 3px rgba(9, 22, 68, 0.30);
}

/* ============================================================
   v143 — THE PHOTO LAYERING BUG + a real glass X (Nelson +
   checks, 2026-10-25). Root cause of "I don't see the
   background": the base rule paints a background on BOTH html
   and body, and body::before sits at z-index -1 — so the app's
   own plain background painted OVER the backdrop layer. The
   photo only ever showed where an element painted it itself
   (boot splash, login). Fix: the backdrop rises to z-index 0
   and .app lifts above it (position relative, z-index 1) —
   content floats over the scene, glass blurs the real photo.
   The sheet X also finally gets a defined tinted-glass disc
   (blue-tinted gradient, bright ring, soft shadow) — over the
   near-white sheet, untinted glass was invisible.
   ============================================================ */
body::before { z-index: 0; }
.app { position: relative; z-index: 1; }
/* The login view is a static sibling of .app — lift it too, or the
   raised backdrop paints over the sign-in form. */
.login-view { position: relative; z-index: 1; }
.sheet-close, .doc-x {
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.8), rgba(198, 222, 250, 0.55));
  border: 1px solid rgba(255, 255, 255, 0.95);
  box-shadow: 0 4px 14px rgba(9, 22, 68, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.95), inset 0 -1px 0 rgba(59, 108, 207, 0.12);
  color: #33507E;
  backdrop-filter: blur(14px) saturate(190%);
  -webkit-backdrop-filter: blur(14px) saturate(190%);
}
:root[data-theme='dark'] .sheet-close, :root[data-theme='dark'] .doc-x {
  background: linear-gradient(135deg, rgba(96, 132, 196, 0.5), rgba(28, 44, 88, 0.55));
  border-color: rgba(170, 200, 245, 0.4);
  box-shadow: 0 4px 14px rgba(0, 0, 10, 0.4), inset 0 1px 0 rgba(190, 215, 255, 0.3);
  color: #DCE9FD;
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] .sheet-close, :root[data-theme='system'] .doc-x {
    background: linear-gradient(135deg, rgba(96, 132, 196, 0.5), rgba(28, 44, 88, 0.55));
    border-color: rgba(170, 200, 245, 0.4);
    box-shadow: 0 4px 14px rgba(0, 0, 10, 0.4), inset 0 1px 0 rgba(190, 215, 255, 0.3);
    color: #DCE9FD;
  }
}

/* ============================================================
   v145 — The X, unmistakably glass (2026-10-25). v144's check
   confirmed the photo + glossy charts, but the sheet X still
   read plain: a near-white tint over the white sheet is
   invisible at 30px. The disc now carries a real NAF-blue tint
   (corporate blue at .28→.14) with a blue edge and navy glyph —
   readable as tinted glass at a glance. Legend dots get a
   stronger gloss highlight too (10px dots hid the v142 sheen).
   ============================================================ */
.sheet-close, .doc-x {
  background: linear-gradient(135deg, rgba(59, 108, 207, 0.30), rgba(59, 108, 207, 0.14));
  border: 1px solid rgba(59, 108, 207, 0.38);
  box-shadow: 0 4px 14px rgba(9, 22, 68, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.55), inset 0 -1px 0 rgba(59, 108, 207, 0.18);
  color: #1D4FA1;
}
:root[data-theme='dark'] .sheet-close, :root[data-theme='dark'] .doc-x {
  background: linear-gradient(135deg, rgba(120, 165, 235, 0.42), rgba(70, 110, 190, 0.28));
  border-color: rgba(170, 200, 245, 0.5);
  color: #EAF2FE;
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] .sheet-close, :root[data-theme='system'] .doc-x {
    background: linear-gradient(135deg, rgba(120, 165, 235, 0.42), rgba(70, 110, 190, 0.28));
    border-color: rgba(170, 200, 245, 0.5);
    color: #EAF2FE;
  }
}
.value-legend-row .dot {
  width: 11px; height: 11px;
  background-image: radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0) 58%);
  box-shadow: inset 0 -2px 4px rgba(0, 0, 0, 0.28), inset 0 1px 1px rgba(255, 255, 255, 0.5), 0 1px 3px rgba(9, 22, 68, 0.35);
}

/* ============================================================
   v146 — Contrast over the photo + donut fill-up (Nelson,
   2026-10-25, from his phone screenshot: the glass + photo
   read beautifully, but "make a better contrast, I don't see
   it quite well" — the small gray sub-text washed out over the
   bright reflection). Text-dense rows get a stronger frosted
   base (.78), the veil firms up a touch, and secondary gray
   deepens (#8E8E93 → #6B7A90). The glass look stays — text just
   sits on a calmer surface. Charts: the old rotate/scale pieIn
   retires; entering the page now runs the JS fill-up (slices
   sweep from 0 to full, staggered) with only a soft fade here.
   ============================================================ */
:root {
  --label-3: #6B7A90;
  --veil: linear-gradient(180deg, rgba(246, 249, 255, 0.14), rgba(242, 246, 253, 0.30) 55%, rgba(236, 242, 251, 0.44));
  --glass-row: linear-gradient(115deg, rgba(255, 255, 255, calc(0.5 * var(--glass-m, 1) + (1 - 0.5 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.5 * 1000))), rgba(255, 255, 255, calc(0 * var(--glass-m, 1) + (1 - 0 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0 * 1000))) 48%), rgba(250, 252, 255, calc(0.78 * var(--glass-m, 1) + (1 - 0.78 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.78 * 1000)));
}
.global-search { background: rgba(255, 255, 255, calc(0.55 * var(--glass-m, 1) + (1 - 0.55 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.55 * 1000))); }
@keyframes pieFade { from { opacity: 0; } to { opacity: 1; } }
#view-dashboard.anim-in .pie { animation: pieFade .45s ease both; }

/* ============================================================
   v147 — The X becomes a glossy blue disc (2026-10-25). Three
   tint attempts (v138/v143/v145) all read "plain pale" in
   checks: alpha tints over the white sheet wash out at 36px —
   at 30% the corporate blue composites to near-white. The disc
   is now SATURATED glossy blue (the same family as the active
   dock pill) with a white gloss sweep and a white glyph
   (currentColor), so it unmistakably belongs to the design.
   Applies to all .sheet-close buttons (client sheet, inbox,
   settings, modal). .doc-x keeps its v145 tinted glass.
   ============================================================ */
.sheet-close {
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.38), rgba(255, 255, 255, 0) 52%), linear-gradient(135deg, #4A7CD6, #2F5FB3);
  border: 1px solid rgba(255, 255, 255, 0.65);
  box-shadow: 0 4px 14px rgba(31, 79, 161, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.55), inset 0 -1px 0 rgba(9, 22, 68, 0.25);
  color: #FFFFFF;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* ============================================================
   v149 — Contrast round 2 (Nelson, 2026-10-25, from his Mac
   screenshots): the Clients filter pills were light-blue text
   on a 10% blue wash — invisible over the bright sky part of
   the photo. They become solid frosted pills with deep-blue
   text and a deep chevron; the header search firms up the
   same way; "See all" deepens to navy-blue. (The donut colors
   also returned to the original board colors — JS side.)
   ============================================================ */
.filter-pills .select {
  color: #1D4FA1;
  background-color: rgba(255, 255, 255, calc(0.78 * var(--glass-m, 1) + (1 - 0.78 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.78 * 1000)));
  border: 1px solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 2px 10px rgba(9, 22, 68, 0.12);
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="%231D4FA1" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>');
}
.global-search { background: rgba(255, 255, 255, calc(0.78 * var(--glass-m, 1) + (1 - 0.78 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.78 * 1000))); border: 1px solid rgba(255, 255, 255, calc(0.85 * var(--glass-m, 1) + (1 - 0.85 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.85 * 1000))); }
.see-all { color: #1D4FA1; }
:root[data-theme='dark'] .filter-pills .select {
  color: #BFD6F7; background-color: rgba(20, 34, 66, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000))); border-color: rgba(160, 190, 240, calc(0.35 * var(--glass-m, 1) + (1 - 0.35 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.35 * 1000)));
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="%23BFD6F7" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>');
}
:root[data-theme='dark'] .global-search { background: rgba(20, 34, 66, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000))); border-color: rgba(160, 190, 240, calc(0.35 * var(--glass-m, 1) + (1 - 0.35 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.35 * 1000))); }
:root[data-theme='dark'] .see-all { color: #8FC3EE; }
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] .filter-pills .select {
    color: #BFD6F7; background-color: rgba(20, 34, 66, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000))); border-color: rgba(160, 190, 240, calc(0.35 * var(--glass-m, 1) + (1 - 0.35 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.35 * 1000)));
    background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="%23BFD6F7" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>');
  }
  :root[data-theme='system'] .global-search { background: rgba(20, 34, 66, calc(0.72 * var(--glass-m, 1) + (1 - 0.72 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.72 * 1000))); border-color: rgba(160, 190, 240, calc(0.35 * var(--glass-m, 1) + (1 - 0.35 * var(--glass-m, 1)) * var(--glass-u, 0) * min(1, 0.35 * 1000))); }
  :root[data-theme='system'] .see-all { color: #8FC3EE; }
}

/* ============================================================
   v151 — Today page fits everything (Nelson, 2026-10-25: "the
   today tab i want all the information inside it without
   scrolling... make it fit perfectly"). The brief and the
   due-tasks lists on the Today page lived in capped panels
   with their own inner scrollbar (~4-5 rows, the rest hidden
   inside the box). On the Today page those panels now grow to
   their full height — every row visible, one natural page
   scroll, no trapped inner scrollers. Home keeps its compact
   panels (that page is a summary; this one is the full list).
   ============================================================ */
#view-today .today-scroll, #view-today .panel-scroll {
  max-height: none;
  overflow-y: visible;
}

/* ============================================================
   v152 — Home's Today panels fit too (Nelson, 2026-10-25: "i
   keep scrolling left to right in todays tab on the home
   page"). Same trapped-panel problem as the Today page, plus
   a desktop grid bug: on wide screens the Home lists become a
   2-column grid whose cells could be pushed wider than the
   panel by long content, forcing sideways scroll inside the
   capped panels. Fix: Home's brief + attention panels grow to
   full height like the Today page (no inner scroll at all),
   and the grid columns become minmax(0, 1fr) with min-width: 0
   children so nothing can push the layout sideways.
   ============================================================ */
#view-dashboard .today-scroll, #view-dashboard .panel-scroll {
  max-height: none;
  overflow-y: visible;
  overflow-x: hidden;
}
@media (min-width: 1024px) {
  #view-dashboard .focus-list { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  #view-dashboard .focus-list > * { min-width: 0; }
}

/* ============================================================
   v153 — Page-level fit guarantee (Nelson, 2026-10-25, video:
   the whole Home page ran wider than his Mac screen — cards
   and "See all" cut at the right edge, page sliding sideways).
   v152 fixed the list grid; this completes it: the pie grid
   gets the same minmax(0, 1fr) treatment, pie cards can shrink
   (min-width: 0), and .views clips horizontal overflow at the
   page level so no dashboard content can ever push the page
   sideways again. Inner scrollers (board columns) keep their
   own horizontal scroll — they're separate elements inside.
   ============================================================ */
.views { overflow-x: hidden; }
@media (min-width: 1024px) {
  #view-dashboard .pie-cards { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  #view-dashboard .pie-cards > *, #view-dashboard .smart-grid > * { min-width: 0; }
}
.pie-card { min-width: 0; }

/* ============================================================
   v154 — Compact again, still fitted (Nelson, 2026-10-25:
   "now the today tab is way longer and don't want it that
   long"). The full-height panels (v151/v152) overshot: his
   complaint was always the SIDEWAYS scroll, not the panel
   height. The original capped height returns on both the
   Today page and Home (panels scroll vertically inside, as
   designed), while every fit fix stays: no horizontal
   overflow anywhere (minmax grids, min-width: 0 children,
   page-level overflow-x clip, panel overflow-x hidden).
   ============================================================ */
#view-today .today-scroll, #view-today .panel-scroll,
#view-dashboard .today-scroll, #view-dashboard .panel-scroll {
  max-height: var(--today-max-h);
  overflow-y: auto;
  overflow-x: hidden;
}

/* ============================================================
   v156 — THE WOW PASS (Nelson, 2026-10-25: "more dramatic
   animations… everything… meaningful… wow, this is a well
   thought out CRM, great and fun to use"). One motion system:
   springy entrances everywhere a view opens, donuts that spin
   in while their totals count up and a shine sweeps the glass,
   legends that cascade, tabs that pop, buttons that press,
   cards that lift, a sync dot that celebrates connecting, and
   bigger celebration bursts with a shockwave ring. Motion is
   transform/opacity only, and the big choreography stays
   gated behind showView's .anim-in entry class so data
   repaints never replay it mid-session.
   ============================================================ */
/* Stronger keyframes (later definitions replace the earlier). */
@keyframes viewIn { from { opacity: 0; transform: translateY(16px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes riseIn { from { opacity: 0; transform: translateY(20px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes pieIn { from { opacity: 0; transform: rotate(-42deg) scale(.78); } to { opacity: 1; transform: none; } }
@keyframes sheetUp { from { transform: translateY(72px); opacity: .5; } to { transform: none; opacity: 1; } }
@keyframes sheetIn { from { transform: translateX(90px); opacity: .5; } to { transform: none; opacity: 1; } }
@keyframes toastIn { from { transform: translateY(16px) scale(.92); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes modalIn { from { transform: translate(-50%, -46%) scale(.92); opacity: .4; } to { transform: translate(-50%, -50%) scale(1); opacity: 1; } }
@keyframes tabPop { 0% { transform: scale(1); } 35% { transform: scale(1.28) translateY(-2px); } 65% { transform: scale(.94); } 100% { transform: scale(1); } }
@keyframes shinePass { from { background-position: 130% 0; } to { background-position: -130% 0; } }
@keyframes syncRing { 0% { box-shadow: 0 0 0 0 rgba(52, 199, 89, .45); } 100% { box-shadow: 0 0 0 9px rgba(52, 199, 89, 0); } }

/* Tab icons pop when their tab becomes active. */
.tab.active svg { animation: tabPop .5s cubic-bezier(.32, .72, .24, 1); }

/* Connected: the sync dot sends out two soft green rings. */
.sync-dot.live { animation: syncRing 1.1s ease-out 2; }

/* Donut shine: a light band sweeps the pie card once, just
   after the fill lands (anim-in is held ~2.3s in v156). */
.pie-card .pie-wrap { position: relative; overflow: hidden; }
.pie-card .pie-wrap::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 32%, rgba(255, 255, 255, .34) 50%, transparent 68%);
  background-size: 260% 100%; background-position: 130% 0;
}
#view-dashboard.anim-in .pie-wrap::after { animation: shinePass 1.15s ease 1s both; }

/* Legend rows cascade in behind the donut fill. */
#view-dashboard.anim-in .value-legend-row { animation: riseIn .55s var(--spring) both; animation-delay: .5s; }
#view-dashboard.anim-in .pie-legend .value-legend-row:nth-child(2) { animation-delay: .58s; }
#view-dashboard.anim-in .pie-legend .value-legend-row:nth-child(3) { animation-delay: .66s; }
#view-dashboard.anim-in .pie-legend .value-legend-row:nth-child(4) { animation-delay: .74s; }
#view-dashboard.anim-in .pie-legend .value-legend-row:nth-child(n+5) { animation-delay: .82s; }

/* Dashboard sections breathe in as whole blocks too. */
#view-dashboard.anim-in > section, #view-dashboard.anim-in > .today-head { animation: fadeIn .7s ease both; }

/* Today page: same staggered rise as Home. */
#view-today.anim-in > * { animation: riseIn .55s var(--spring) both; }
#view-today.anim-in > *:nth-child(2) { animation-delay: .06s; }
#view-today.anim-in > *:nth-child(3) { animation-delay: .12s; }
#view-today.anim-in > *:nth-child(n+4) { animation-delay: .18s; }

/* Board columns fade in left-to-right (fade only — transforms
   stay away from the board so drag math is never disturbed). */
#view-board.anim-in .kanban-col { animation: fadeIn .55s ease both; }
#view-board.anim-in .kanban-col:nth-child(2) { animation-delay: .06s; }
#view-board.anim-in .kanban-col:nth-child(3) { animation-delay: .12s; }
#view-board.anim-in .kanban-col:nth-child(4) { animation-delay: .18s; }
#view-board.anim-in .kanban-col:nth-child(5) { animation-delay: .24s; }
#view-board.anim-in .kanban-col:nth-child(n+6) { animation-delay: .3s; }

/* Press feedback: tappable things squash a touch, spring back. */
:is(.btn, .icon-btn, .tab, .smart-card, .value-legend-row, .see-all, .chip) {
  transition: transform .22s var(--spring);
}
:is(.btn, .icon-btn, .tab, .smart-card, .value-legend-row, .see-all, .chip):active {
  transform: scale(.95);
}

/* Desktop: cards lift toward the cursor. */
@media (hover: hover) and (pointer: fine) {
  .pie-card, .smart-card { transition: transform .3s var(--spring), box-shadow .3s ease; }
  .pie-card:hover, .smart-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 18px 42px rgba(9, 22, 68, .20);
  }
}

/* Celebration shockwave ring (celebrateAt, v156). */
.cel-ring {
  position: fixed; width: 58px; height: 58px; border-radius: 50%;
  border: 2.5px solid #FFD60A; pointer-events: none; will-change: transform, opacity;
}

/* ============================================================
   v157 — Board entrance: slide in from the right (Nelson,
   2026-10-25: "entering the page from the right and entering
   their correct position"). Columns glide in from the right
   and settle into place, staggered left-to-right; the cards
   inside each column follow with their own smaller slide and
   per-card stagger, so the whole board assembles itself.
   Entry-only (showView's .anim-in, stripped after ~2.3s);
   during the entrance the board scroller clips horizontally
   so the incoming columns never flash a scrollbar. Snapshot
   rebuilds carry no .anim-in, so nothing replays mid-work,
   and once the class strips, drag is exactly as before.
   ============================================================ */
@keyframes colIn { from { opacity: 0; transform: translateX(84px); } to { opacity: 1; transform: none; } }
@keyframes cardIn { from { opacity: 0; transform: translateX(48px); } to { opacity: 1; transform: none; } }
#view-board.anim-in .board-scroll { overflow-x: hidden; }
#view-board.anim-in .kanban-col { animation: colIn .7s var(--spring) both; }
#view-board.anim-in .kanban-col:nth-child(2) { animation-delay: .07s; }
#view-board.anim-in .kanban-col:nth-child(3) { animation-delay: .14s; }
#view-board.anim-in .kanban-col:nth-child(4) { animation-delay: .21s; }
#view-board.anim-in .kanban-col:nth-child(5) { animation-delay: .28s; }
#view-board.anim-in .kanban-col:nth-child(n+6) { animation-delay: .35s; }
#view-board.anim-in .col-body > .kcard { animation: cardIn .55s var(--spring) both; animation-delay: .18s; }
#view-board.anim-in .col-body > .kcard:nth-child(2) { animation-delay: .23s; }
#view-board.anim-in .col-body > .kcard:nth-child(3) { animation-delay: .28s; }
#view-board.anim-in .col-body > .kcard:nth-child(4) { animation-delay: .33s; }
#view-board.anim-in .col-body > .kcard:nth-child(5) { animation-delay: .38s; }
#view-board.anim-in .col-body > .kcard:nth-child(6) { animation-delay: .43s; }
#view-board.anim-in .col-body > .kcard:nth-child(7) { animation-delay: .48s; }
#view-board.anim-in .col-body > .kcard:nth-child(8) { animation-delay: .53s; }
#view-board.anim-in .col-body > .kcard:nth-child(n+9) { animation-delay: .58s; }

/* ============================================================
   v158 — Spring physics + directional pages (Nelson, 2026-10-25,
   from the "Dashboard V15" framer-motion reference he sent:
   cards that pop and SETTLE, pages that slide with direction,
   everything soft-spring). CSS can't run real spring physics,
   so the overshoot is baked into the keyframes themselves: each
   entrance passes its target by a hair at ~62% and settles —
   the eye reads it as a spring. View switches are directional:
   forward through the tabs slides in from the right, back from
   the left (showView tags .from-right/.from-left).
   ============================================================ */
@keyframes riseIn { 0% { opacity: 0; transform: translateY(22px) scale(.94); } 62% { opacity: 1; transform: translateY(-3px) scale(1.012); } 100% { opacity: 1; transform: none; } }
@keyframes viewIn { 0% { opacity: 0; transform: translateY(18px) scale(.985); } 62% { opacity: 1; transform: translateY(-2px) scale(1.002); } 100% { opacity: 1; transform: none; } }
@keyframes colIn { 0% { opacity: 0; transform: translateX(92px); } 62% { opacity: 1; transform: translateX(-5px); } 100% { opacity: 1; transform: none; } }
@keyframes cardIn { 0% { opacity: 0; transform: translateX(54px); } 62% { opacity: 1; transform: translateX(-3px); } 100% { opacity: 1; transform: none; } }
@keyframes pieIn { 0% { opacity: 0; transform: rotate(-46deg) scale(.74); } 62% { opacity: 1; transform: rotate(2.5deg) scale(1.015); } 100% { opacity: 1; transform: none; } }
@keyframes viewInR { 0% { opacity: 0; transform: translateX(64px); } 62% { opacity: 1; transform: translateX(-4px); } 100% { opacity: 1; transform: none; } }
@keyframes viewInL { 0% { opacity: 0; transform: translateX(-64px); } 62% { opacity: 1; transform: translateX(4px); } 100% { opacity: 1; transform: none; } }
.view-enter.from-right { animation: viewInR .6s var(--spring) both; }
.view-enter.from-left { animation: viewInL .6s var(--spring) both; }

/* Sheets and modals land on the bouncy spring too. */
.sheet { animation: sheetUp .62s cubic-bezier(.34, 1.4, .64, 1); }
@media (min-width: 720px) {
  .modal-sheet { animation: modalIn .55s cubic-bezier(.34, 1.4, .64, 1); }
}

/* Desktop hover life: rows lift, board cards glow, buttons warm. */
@media (hover: hover) and (pointer: fine) {
  .row-card { transition: transform .25s var(--spring), box-shadow .25s ease; }
  .row-card:hover { transform: translateY(-2px); box-shadow: 0 12px 30px rgba(9, 22, 68, .16); }
  .kcard { transition: box-shadow .25s ease; }
  .kcard:hover { box-shadow: 0 10px 26px rgba(9, 22, 68, .20); }
  .btn:hover { filter: brightness(1.07); }
}

/* ============================================================
   v159 — Shine correction (Nelson, 2026-10-25: "it needs to
   glow the whole tab, not a square"). The v156 shine lived on
   .pie-wrap — an inner box with square corners — so the sweep
   read as a glowing rectangle inside the card. The band now
   lives on the .pie-card itself: it covers the whole card
   (header + donut + legend) and the card's own overflow +
   22px radius clip it to the card's rounded shape.
   ============================================================ */
.pie-card { position: relative; overflow: hidden; }
.pie-card .pie-wrap { position: static; overflow: visible; }
.pie-card .pie-wrap::after { content: none; }
.pie-card::after {
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(115deg, transparent 32%, rgba(255, 255, 255, .30) 50%, transparent 68%);
  background-size: 260% 100%; background-position: 130% 0;
}
#view-dashboard.anim-in .pie-card::after { animation: shinePass 1.15s ease 1s both; }

/* ============================================================
   v160 — Search joins the header row (Nelson, 2026-10-25:
   "the search bar at the top is awkwardly positioned, it
   needs to integrate with the design"). The search lived on
   its own full-width row under the brand — worse, late rules
   had painted the whole row as a frosted slab with the pill
   floating inside it (a box in a box). The node now sits IN
   .header-row between the brand and the stats: one designed
   pill — 38px, fully rounded, bordered glass — vertically
   centered with the brand and icon buttons, growing to a
   520px cap. On phones it wraps to its own line inside the
   same header, same pill, no slab anywhere.
   ============================================================ */
.header-row { flex-wrap: wrap; }
.global-search {
  position: relative; flex: 1 1 auto; width: auto; min-width: 150px;
  max-width: 520px; margin: 0; padding: 0; background: none; border: 0;
}
:root[data-theme='dark'] .global-search { background: none; border: 0; }
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] .global-search { background: none; border: 0; }
}
.global-search > svg { left: 13px; top: 50%; transform: translateY(-50%); }
#gq {
  height: 38px; border-radius: 999px; padding: 0 14px 0 38px;
  background: var(--fill); border: 1px solid var(--separator);
}
#gq:focus { background: var(--fill-strong); border-color: var(--blue); }
.gq-results { left: 0; right: 0; top: calc(100% + 6px); }
@media (max-width: 1100px) {
  .global-search { max-width: 330px; }
}
@media (max-width: 760px) {
  .global-search { order: 5; flex: 1 1 100%; max-width: none; margin-top: 8px; }
  .header-row { padding-bottom: 12px; }
}

/* ============================================================
   v161 — Board entrance, take two (Nelson, 2026-10-25: "the
   animations of the board are awkward — make it better and
   like bouncing"). The awkwardness was compounding: columns
   slid AND the cards slid inside the moving columns, so
   everything wobbled on two clocks. Now the structure holds
   still — columns just fade in fast — and only the CARDS
   move: each one glides in from the right and lands with a
   decaying bounce (overshoot, small rebound, settle), dealt
   onto the board in a quick per-card cascade.
   ============================================================ */
@keyframes cardBounce {
  0% { opacity: 0; transform: translateX(64px) scale(.96); }
  55% { opacity: 1; transform: translateX(-9px) scale(1.005); }
  74% { transform: translateX(5px); }
  87% { transform: translateX(-2.5px); }
  100% { opacity: 1; transform: none; }
}
#view-board.anim-in .kanban-col { animation: fadeIn .35s ease both; animation-delay: 0s; }
#view-board.anim-in .col-body > .kcard {
  animation: cardBounce .8s cubic-bezier(.32, .72, .24, 1) both;
  animation-delay: .04s;
}
#view-board.anim-in .col-body > .kcard:nth-child(2) { animation-delay: .085s; }
#view-board.anim-in .col-body > .kcard:nth-child(3) { animation-delay: .13s; }
#view-board.anim-in .col-body > .kcard:nth-child(4) { animation-delay: .175s; }
#view-board.anim-in .col-body > .kcard:nth-child(5) { animation-delay: .22s; }
#view-board.anim-in .col-body > .kcard:nth-child(6) { animation-delay: .265s; }
#view-board.anim-in .col-body > .kcard:nth-child(7) { animation-delay: .31s; }
#view-board.anim-in .col-body > .kcard:nth-child(8) { animation-delay: .355s; }
#view-board.anim-in .col-body > .kcard:nth-child(n+9) { animation-delay: .4s; }

/* ============================================================
   v163 — Board bounce, physics pass (Nelson, 2026-10-25:
   "more pronounced and smooth — is not smooth"). The v161
   bounce was four keyframe joints with an ease on every joint,
   which reads as vibration, not physics. This replaces it
   with ONE continuous spring curve — a strong easeOutBack
   bezier on a single from→to animation: the card flies in
   120px, the curve itself carries it past its slot and pulls
   it back in one unbroken motion. Bigger travel (120px),
   longer glide (1.05s), a touch of scale, GPU layer hints
   while entering, and a slightly slower cascade.
   ============================================================ */
@keyframes cardSpring {
  from { opacity: 0; transform: translateX(120px) scale(.94); }
  to { opacity: 1; transform: translateX(0) scale(1); }
}
#view-board.anim-in .col-body > .kcard {
  animation: cardSpring 1.05s cubic-bezier(.3, 1.9, .45, 1) both;
  animation-delay: .06s; will-change: transform;
}
#view-board.anim-in .col-body > .kcard:nth-child(2) { animation-delay: .105s; }
#view-board.anim-in .col-body > .kcard:nth-child(3) { animation-delay: .16s; }
#view-board.anim-in .col-body > .kcard:nth-child(4) { animation-delay: .215s; }
#view-board.anim-in .col-body > .kcard:nth-child(5) { animation-delay: .27s; }
#view-board.anim-in .col-body > .kcard:nth-child(6) { animation-delay: .325s; }
#view-board.anim-in .col-body > .kcard:nth-child(7) { animation-delay: .38s; }
#view-board.anim-in .col-body > .kcard:nth-child(8) { animation-delay: .435s; }
#view-board.anim-in .col-body > .kcard:nth-child(n+9) { animation-delay: .49s; }

/* ============================================================
   v164 — Smooth task travel (Nelson, 2026-10-25: completions
   "disappear like a refresh" — make the transitions WAY
   smoother). Three parts: (1) the exit collapse eases on a
   soft in-out curve and the row's title gets a DRAWN strike
   line instead of a snap line-through; (2) collapseTaskRow
   cancels the flex gap it leaves behind (margin-top eased to
   -gap), so rows below glide up with no final hop; (3) the
   task ARRIVES in its new list — a gentle spring-in plus a
   tint flash (green into Completed, blue back into Open) —
   triggered by the snapshot diff, so it works whoever
   completed the task, on whichever device.
   ============================================================ */
.task-exit {
  transition: height .62s cubic-bezier(.45, 0, .25, 1), opacity .5s ease,
    padding-top .62s cubic-bezier(.45, 0, .25, 1),
    padding-bottom .62s cubic-bezier(.45, 0, .25, 1),
    margin-top .62s cubic-bezier(.45, 0, .25, 1);
}
.task-done-anim .rname, .task-done-anim .t {
  text-decoration: none; position: relative;
}
.task-done-anim .rname::after, .task-done-anim .t::after {
  content: ''; position: absolute; left: 0; top: 55%; height: 1.5px; width: 100%;
  background: currentColor; opacity: .55; border-radius: 2px;
  transform-origin: left center; transform: scaleX(0);
  animation: strikeDraw .35s ease .05s both;
}
@keyframes strikeDraw { from { transform: scaleX(0); } to { transform: scaleX(1); } }

@media (prefers-reduced-motion: no-preference) {
  .row-arrive { animation: rowArrive .55s cubic-bezier(.3, 1.35, .5, 1) both; }
  .row-arrive.arrive-done { animation: rowArrive .55s cubic-bezier(.3, 1.35, .5, 1) both, doneFlash 1.5s ease .1s both; }
  .row-arrive.arrive-open { animation: rowArrive .55s cubic-bezier(.3, 1.35, .5, 1) both, openFlash 1.5s ease .1s both; }
}
@keyframes rowArrive {
  from { opacity: 0; transform: translateX(-16px) scale(.98); }
  to { opacity: 1; transform: none; }
}
@keyframes doneFlash {
  0% { background-color: rgba(52, 199, 89, .20); }
  100% { background-color: transparent; }
}
@keyframes openFlash {
  0% { background-color: rgba(59, 108, 207, .16); }
  100% { background-color: transparent; }
}

/* ============================================================
   v165 — Completion choreography, take three (Nelson,
   2026-10-25: "when completed take it smoother, and the tab
   goes down to the completed tasks"). Everything slows a
   breath: the strike draws over .5s, the row waits 220ms on
   the burst before leaving, the collapse takes .85s — then
   the page itself glides down to the Completed heading
   (scrollIntoView smooth, fired by the settle repaint) where
   the task springs in softly with its tint flash. The
   arrival now plays exactly once (consumed at render).
   ============================================================ */
#tasks-completed-head { scroll-margin-top: 140px; }
.task-exit {
  transition: height .85s cubic-bezier(.45, 0, .25, 1), opacity .6s ease,
    padding-top .85s cubic-bezier(.45, 0, .25, 1),
    padding-bottom .85s cubic-bezier(.45, 0, .25, 1),
    margin-top .85s cubic-bezier(.45, 0, .25, 1);
}
@keyframes strikeDraw { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.task-done-anim .rname::after, .task-done-anim .t::after { animation-duration: .5s; }
@media (prefers-reduced-motion: no-preference) {
  .row-arrive { animation: rowArrive .8s cubic-bezier(.25, 1.05, .35, 1) both; }
  .row-arrive.arrive-done { animation: rowArrive .8s cubic-bezier(.25, 1.05, .35, 1) both, doneFlash 1.8s ease .1s both; }
  .row-arrive.arrive-open { animation: rowArrive .8s cubic-bezier(.25, 1.05, .35, 1) both, openFlash 1.8s ease .1s both; }
}
@keyframes rowArrive {
  from { opacity: 0; transform: translateX(-12px) scale(.985); }
  to { opacity: 1; transform: none; }
}
@keyframes doneFlash {
  0% { background-color: rgba(52, 199, 89, .16); }
  100% { background-color: transparent; }
}

/* ============================================================
   v167 — Symmetrical mini cards (Nelson, 2026-10-25, from his
   Mac photo: the Home Today cards were ragged). The desktop
   dashboard grid sized each card to its own content
   (align-items: start) and long titles wrapped to two lines,
   so every card had a different height. Now the grid
   stretches every card to its row's height, and inside the
   dashboard's mini cards the title and subtitle are clamped
   to one line with an ellipsis — every card the same height,
   a clean matrix. (The full Today page keeps wrapped titles;
   this is only the Home mini cards.)
   ============================================================ */
@media (min-width: 1024px) {
  #view-dashboard .focus-list { align-items: stretch; }
  #view-dashboard .focus-list > .row-card { height: 100%; align-items: center; }
  #view-dashboard .focus-list .rbody { min-width: 0; }
  #view-dashboard .focus-list .rname,
  #view-dashboard .focus-list .rsub {
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
}

/* ============================================================
   v168 — Color with meaning (Nelson, 2026-10-25: "more color…
   blue as the general color, but differentiate things with
   color too — while keeping it minimal and clean"). Blue
   stays the chrome; COLOR IS DATA: each brief card's rank
   badge and left edge take its KIND color (Docs red, New app
   blue, Follow-up orange, Task purple, Callback green); task
   rows get a left edge in their PRIORITY color (soft
   blue-grey when none); client rows print the stage name in
   its board color. Nothing else changes — the layout stays
   calm, the color does the talking.
   ============================================================ */
.brief-row { border-left: 3px solid var(--kind, var(--separator)); }
.brief-rank { background: var(--kind, var(--blue)); box-shadow: none; }
.row-card[data-task-toggle] { border-left: 3px solid var(--prio, #C7D3E8); }

/* ============================================================
   v169 — Pipeline flow river. Stage bands across Home, width
   ∝ √(dollars + count weight), one pleasant hue per stage on
   a blue-anchored palette, white text, counts + counting-up
   totals. Blocks pour in left→right on Home entry (anim-in).
   Side pools (Need Works, Lost) sit smaller and quieter in
   their own row. On phones the river wraps 2×2, arrows hide.
   ============================================================ */
.flow-row { display: flex; align-items: stretch; gap: 6px; }
.flow-row.sides { margin-top: 6px; }
.flow-block {
  flex: var(--grow) 1 0; min-width: 0; border-radius: 16px; padding: 12px 14px;
  color: #fff; background: linear-gradient(135deg, var(--fc), color-mix(in srgb, var(--fc) 72%, #0b1e4a));
  box-shadow: 0 8px 22px color-mix(in srgb, var(--fc) 34%, transparent);
  display: flex; flex-direction: column; gap: 1px; justify-content: center;
}
.flow-block.side { opacity: .82; padding: 9px 14px; }
.flow-label { font-size: 12px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase; opacity: .92; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.flow-n { font-size: 13px; font-weight: 600; opacity: .85; }
.flow-sum { font-size: clamp(17px, 2.4vw, 24px); font-weight: 800; letter-spacing: -.3px; }
.flow-block.side .flow-sum { font-size: 16px; }
.flow-arrow { align-self: center; font-size: 22px; font-weight: 800; color: var(--label-3); flex: 0 0 auto; }
@keyframes flowIn { from { opacity: 0; transform: translateX(-14px) scale(.9); } to { opacity: 1; transform: none; } }
#view-dashboard.anim-in .flow-block { animation: flowIn .8s var(--spring) both; }
@media (max-width: 760px) {
  .flow-row { flex-wrap: wrap; }
  .flow-block { flex: 1 1 42%; }
  .flow-arrow { display: none; }
}

/* ============================================================
   v170 — Movement this week. A horizontal strip of stage-move
   cards (arrow + color by direction: green forward/funded,
   orange back, red needs-work, grey out, blue sideways), count
   chips above, and the frozen files (14+ days unmoved) as
   compact tappable rows with red day badges.
   ============================================================ */
.move-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.move-chip { font-size: 12px; font-weight: 700; padding: 4px 10px; border-radius: 999px; background: rgba(59, 108, 207, .12); color: var(--blue); }
.move-chip.new { background: rgba(47, 191, 113, .14); color: #1E9E57; }
.move-chip.froze { background: rgba(229, 83, 75, .12); color: #D43A32; }
.move-strip { display: flex; gap: 10px; overflow-x: auto; padding: 2px 2px 10px; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; }
.move-card { flex: 0 0 228px; scroll-snap-align: start; background: var(--row); border: 1px solid var(--separator); border-left: 3px solid var(--mc); border-radius: 14px; padding: 10px 12px; cursor: pointer; }
.move-top { display: flex; align-items: center; gap: 7px; margin-bottom: 5px; }
.move-badge { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; background: var(--mc); color: #fff; font-size: 12px; font-weight: 800; display: flex; align-items: center; justify-content: center; }
.move-name { font-weight: 700; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.move-when { margin-left: auto; flex: 0 0 auto; font-size: 11.5px; color: var(--label-3); font-weight: 600; }
.move-path { font-size: 12.5px; color: var(--label-2); line-height: 1.45; }
.move-empty { font-size: 13.5px; color: var(--label-2); padding: 4px 0 10px; }
.frozen-head { font-size: 13px; font-weight: 700; color: #D43A32; margin: 4px 0 8px; }
.frozen-row { display: flex; align-items: center; gap: 9px; background: var(--row); border: 1px solid var(--separator); border-radius: 12px; padding: 8px 12px; margin-bottom: 6px; cursor: pointer; }
.frozen-days { flex: 0 0 auto; font-size: 12px; font-weight: 800; color: #fff; background: #E5534B; border-radius: 999px; padding: 2px 8px; }
.frozen-name { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.frozen-stage { margin-left: auto; flex: 0 0 auto; font-size: 12px; color: var(--label-3); font-weight: 600; }


/* ============================================================
   v173 — Pipeline picker + flow breathing room (Nelson, from
   his Mac photo: the two donuts crowded each other, the flow
   rows sat too tight, narrow blocks clipped their labels and
   totals). The value chart now shows ONE pipeline at a time
   behind selector pills; the donut grows into the space. The
   flow gets the same airy gaps as the rest of Home, a 150px
   minimum block width, and compact side pools that no longer
   stretch into slabs.
   ============================================================ */
.pie-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.pie-tab {
  border: 1px solid var(--separator); background: var(--row); color: var(--label);
  border-radius: 999px; padding: 6px 13px; font-size: 13px; font-weight: 700; cursor: pointer;
}
.pie-tab span { margin-left: 6px; font-weight: 600; color: var(--label-3); font-size: 12px; }
.pie-tab.on { background: var(--blue); border-color: transparent; color: #fff; box-shadow: 0 6px 16px rgba(29, 79, 161, .35); }
.pie-tab.on span { color: rgba(255, 255, 255, .78); }
.pie-tab:active { transform: scale(.96); }
.pie-cards.single { grid-template-columns: 1fr; max-width: 680px; margin: 0 auto 4px; }
.pie-cards.single .pie { width: 190px; height: 190px; }
.flow-row { gap: 10px; }
.flow-row.sides { margin-top: 10px; justify-content: flex-start; }
.flow-block { flex: var(--grow) 1 150px; min-height: 92px; }
.flow-block.side { flex: 1 1 0; max-width: 340px; min-height: 74px; }
.flow-label { font-size: 11px; letter-spacing: .2px; }
.flow-sum { font-size: clamp(16px, 2.2vw, 24px); }

/* v174 — Settings chips for the Home display choices. */
.settings-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.set-chip {
  border: 1px solid var(--separator); background: var(--row); color: var(--label-2);
  border-radius: 999px; padding: 6px 12px; font-size: 13px; font-weight: 600; cursor: pointer;
}
.set-chip.on { background: var(--blue); border-color: transparent; color: #fff; }
.set-chip:active { transform: scale(.96); }

/* ============================================================
   v175 — Flow shows boards per pipeline. Each chosen pipeline
   is a labeled row of its own board blocks, with real air
   between rows (Nelson's crowding note). Empty boards render
   muted so the stream reads honestly.
   ============================================================ */
.flow-pipe { margin-bottom: 16px; }
.flow-pipe:last-child { margin-bottom: 2px; }
.flow-pipe-head { display: flex; align-items: center; gap: 7px; font-weight: 800; font-size: 14px; margin-bottom: 7px; }
.flow-pipe-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.flow-pipe-total { margin-left: auto; font-size: 12.5px; color: var(--label-3); font-weight: 600; }
.flow-block.zero { opacity: .48; filter: saturate(.35); }

/* ============================================================
   v176 — Home visuals are doors (Nelson): flow blocks, flow
   pipeline names, pie titles and legend rows all jump to the
   Board view — the specific column scrolls into view and
   flashes. Board names in flow blocks may wrap to two lines
   instead of truncating (v175 check note). Plus the target
   column flash.
   ============================================================ */
.flow-block { cursor: pointer; }
.flow-block:active { transform: scale(.98); }
.flow-pipe-head[data-flow-tab] { cursor: pointer; }
.pie-card-head[data-vtab] { cursor: pointer; }
.flow-label { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-height: 1.25; }
@keyframes colFlash {
  0%, 55% { box-shadow: 0 0 0 3px var(--blue), 0 14px 34px rgba(29, 79, 161, .35); }
  100% { box-shadow: 0 0 0 0 transparent; }
}
.kanban-col.col-flash { animation: colFlash 1.6s ease both; border-radius: 16px; }

/* v177 — Settings visibility switches dim their chip groups. */
.settings-chips.off { opacity: .38; pointer-events: none; }

/* v179 — Accent color swatches in Settings. */
.accent-row { display: flex; gap: 10px; }
.accent-dot {
  width: 32px; height: 32px; border-radius: 50%; border: 2px solid transparent;
  background: var(--ac); cursor: pointer; padding: 0;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .35), 0 3px 8px rgba(0, 0, 0, .18);
}
.accent-dot.on { border-color: var(--label); transform: scale(1.08); }
.accent-dot:active { transform: scale(.94); }

/* v180 — Settings groups (collapsible, summarized) */
.set-group { border-top: 1px solid var(--separator); }
.set-group-head {
  width: 100%; display: flex; align-items: center; gap: 8px;
  background: none; border: none; padding: 14px 2px; cursor: pointer;
  font-size: 15.5px; font-weight: 600; color: var(--label); text-align: left;
}
.set-sum { margin-left: auto; font-size: 12.5px; font-weight: 500; color: var(--label-3); text-align: right; }
.set-chev { color: var(--label-3); font-size: 18px; transition: transform .25s; }
.set-group.open .set-chev { transform: rotate(90deg); }
.set-group-body { display: none; padding: 0 2px 16px; }
.set-group.open .set-group-body { display: block; }
.settings-logout { margin-top: 18px; }

/* v180 — Doc chase */
.greet-name { color: var(--blue); }
.chase-badge {
  display: inline-block; margin-left: 8px; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 700; vertical-align: 2px;
  background: rgba(var(--accent-rgb), .12); color: var(--blue);
}
.chase-badge.over { background: rgba(255, 59, 48, .12); color: #FF3B30; }
.chase-badge.decide { background: rgba(255, 149, 0, .16); color: #B25E00; }
.chase-ev { font-size: 12px; color: var(--label-3); margin-top: 3px; line-height: 1.45; }
.chase-oversight {
  margin: 14px 0 2px; padding: 10px 14px; border-radius: 14px;
  background: rgba(var(--accent-rgb), .07); border: 1px solid rgba(var(--accent-rgb), .16);
  font-size: 13.5px; color: var(--label-2);
}
.chase-oversight .over { color: #FF3B30; }
.chase-sched {
  margin-top: 10px; padding: 10px 14px; border-radius: 14px;
  background: var(--fill); font-size: 13px; color: var(--label-2); line-height: 1.5;
}

/* v182 — Doc chase lives in a glass panel like every other
   Home block; the oversight line and scheduled notes are
   strips INSIDE the card, never bare text on the background. */
.chase-panel {
  background: var(--card); border: 1px solid var(--separator);
  border-radius: 22px; padding: 6px 16px 12px; margin-bottom: 6px;
  box-shadow: 0 10px 28px rgba(31, 38, 135, 0.07);
}
.chase-panel .chase-oversight {
  margin: 0; padding: 10px 0; background: none; border: none; border-radius: 0;
  border-bottom: 1px solid var(--separator);
}
.chase-panel .chase-list { margin-top: 10px; }
.chase-panel .chase-sched {
  margin-top: 10px; padding: 10px 0 2px; background: none;
  border-top: 1px solid var(--separator); border-radius: 0;
}
.chase-panel .chase-oversight:only-child { border-bottom: none; }

/* v183 — Doc chase, interactive: tappable stat head, springy
   expand, hoverable rows — the same card language as Home's
   other tabs, with motion. */
#view-dashboard.anim-in .chase-panel { animation: riseIn .55s var(--spring) both; }
.chase-head {
  width: 100%; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  background: none; border: none; padding: 12px 0; cursor: pointer; text-align: left;
}
.chase-chip {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 5px 11px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
  background: rgba(var(--accent-rgb), .1); color: var(--blue);
  transition: transform .18s var(--spring), background .18s;
}
.chase-chip b { font-size: 14px; font-weight: 800; }
.chase-chip.over { background: rgba(255, 59, 48, .12); color: #D70015; }
.chase-chip.mute { background: var(--fill); color: var(--label-2); }
.chase-head:active .chase-chip { transform: scale(.95); }
.chase-chev { margin-left: auto; color: var(--label-3); font-size: 19px; transition: transform .35s var(--spring); }
.chase-panel.open .chase-chev { transform: rotate(90deg); }
.chase-detail { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows .5s var(--spring), opacity .3s ease; }
.chase-panel.open .chase-detail { grid-template-rows: 1fr; opacity: 1; }
.chase-detail-in { overflow: hidden; min-height: 0; }
.chase-detail .chase-list { margin: 2px 0 8px; }
.chase-panel .follow-row { transition: transform .18s var(--spring), box-shadow .18s; }
.chase-panel .follow-row:hover { transform: translateY(-1px); box-shadow: 0 8px 20px rgba(31, 38, 135, .1); }
.chase-panel .follow-row:active { transform: scale(.985); }
.chase-badge.held { background: rgba(52, 199, 89, .14); color: #1D7A37; }
.chase-row.held { opacity: .62; }
.chase-none { padding: 4px 0 10px; color: var(--label-3); font-size: 13.5px; }
.chase-mine-lbl { padding: 10px 0 0; font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--label-3); }
.chase-sched-row { display: flex; align-items: baseline; gap: 4px; cursor: pointer; padding: 6px 8px; margin: 0 -8px; border-radius: 10px; transition: background .18s, transform .18s var(--spring); }
.chase-sched-row:hover { background: rgba(var(--accent-rgb), .06); }
.chase-sched-row:active { transform: scale(.99); }
.chase-go { margin-left: auto; color: var(--label-3); font-size: 16px; }

/* v187 — Doc chase cards in the shared row-card language. */
.chase-card { cursor: pointer; align-items: center; }
.chase-card.scheduled { opacity: .78; }
.chase-badge.own { background: var(--fill); color: var(--label-2); }
.chase-open {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(var(--accent-rgb), .1); color: var(--blue);
}
.chase-card .chase-ev { margin-top: 2px; }

/* v189 — Follow-ups pager tabs. */
.fu-pager { display: flex; gap: 6px; justify-content: center; margin: 10px 0 2px; }
.fu-page-btn {
  min-width: 34px; height: 34px; padding: 0 10px; border-radius: 999px;
  border: 1px solid var(--separator); background: var(--card);
  color: var(--label-2); font-size: 13.5px; font-weight: 600; cursor: pointer;
  transition: transform .18s var(--spring), background .18s, color .18s;
}
.fu-page-btn.on { background: var(--blue); border-color: transparent; color: #fff; }
.fu-page-btn:active { transform: scale(.92); }

/* v191 — Follow-ups page transitions: directional slide + fade,
   staggered, on the app's spring curve. */
@keyframes fuSlideR { from { opacity: 0; transform: translateX(46px); } to { opacity: 1; transform: none; } }
@keyframes fuSlideL { from { opacity: 0; transform: translateX(-46px); } to { opacity: 1; transform: none; } }
#fu-section.fu-anim-next .focus-list > * { animation: fuSlideR .65s cubic-bezier(.3, 1.75, .4, 1) both; }
#fu-section.fu-anim-prev .focus-list > * { animation: fuSlideL .65s cubic-bezier(.3, 1.75, .4, 1) both; }
#fu-section.fu-anim-next .focus-list > *:nth-child(2), #fu-section.fu-anim-prev .focus-list > *:nth-child(2) { animation-delay: .06s; }
#fu-section.fu-anim-next .focus-list > *:nth-child(3), #fu-section.fu-anim-prev .focus-list > *:nth-child(3) { animation-delay: .12s; }
#fu-section.fu-anim-next .focus-list > *:nth-child(4), #fu-section.fu-anim-prev .focus-list > *:nth-child(4) { animation-delay: .18s; }
#fu-section.fu-anim-next .focus-list > *:nth-child(5), #fu-section.fu-anim-prev .focus-list > *:nth-child(5) { animation-delay: .24s; }
#fu-section.fu-anim-next .focus-list > *:nth-child(6), #fu-section.fu-anim-prev .focus-list > *:nth-child(6) { animation-delay: .3s; }

/* v193 — smart bundle: forecast, at-risk, scoreboard, NBA, loss reasons. */
.forecast-card {
  display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap;
  background: var(--card); border: 1px solid var(--separator); border-radius: 18px;
  padding: 14px 16px; margin: 26px 0 6px; box-shadow: var(--shadow);
}
.fc-lbl { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--label-2); }
.fc-num { font-size: 30px; font-weight: 800; letter-spacing: -.02em; margin: 2px 0; }
.fc-sub { font-size: 12.5px; color: var(--label-2); }
.fc-top { display: flex; gap: 6px; flex-wrap: wrap; }
.fc-chip {
  font-size: 12px; font-weight: 600; padding: 6px 10px; border-radius: 999px; cursor: pointer;
  background: color-mix(in srgb, var(--blue) 12%, transparent); color: var(--blue);
}
.fc-chip:active { transform: scale(.95); }
.count-badge.risk { background: #FF3B30; }
.risk-card { border-left: 4px solid #FF3B30; }
.risk-total { font-size: 12.5px; color: var(--label-2); margin: 2px 2px 6px; }
.score-row { cursor: default; }
.nba-card {
  border: 1px solid color-mix(in srgb, var(--blue) 35%, transparent);
  background: color-mix(in srgb, var(--blue) 7%, var(--card));
  border-radius: 16px; padding: 12px 14px; margin: 10px 0;
}
.nba-lbl { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .07em; color: var(--blue); }
.nba-title { font-size: 16.5px; font-weight: 700; margin: 3px 0; }
.nba-why { font-size: 13px; color: var(--label-2); line-height: 1.45; }
.nba-actions { display: flex; gap: 8px; margin-top: 9px; }
.lost-box { margin: 10px 0; }
.lost-lbl { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--label-2); margin-bottom: 7px; }
.lost-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.lost-summary {
  margin: 10px 2px; padding: 10px 14px; border-radius: 12px; font-size: 13px;
  background: var(--card); border: 1px solid var(--separator); color: var(--label);
}
.lost-missing { color: var(--label-2); }

/* v194 — Nova recommends (AI layer). */
.recs-host { margin-top: 2px; }
.rec-card { align-items: flex-start; }
.rec-draft { font-size: 12.5px; color: var(--label-2); font-style: italic; margin-top: 4px; line-height: 1.4; }
.rec-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.rec-ok {
  border: none; cursor: pointer; font-size: 12.5px; font-weight: 700;
  padding: 8px 12px; border-radius: 999px; color: #fff; background: var(--blue);
  transition: transform .15s var(--spring);
}
.rec-ok:active { transform: scale(.93); }
.rec-no {
  border: none; cursor: pointer; width: 30px; height: 30px; border-radius: 999px;
  background: color-mix(in srgb, var(--label-2) 14%, transparent); color: var(--label-2); font-size: 13px;
}
.rec-no:active { transform: scale(.9); }

/* v197 — action group tabs. */
.action-tabs { margin: 8px 0 12px; }
.action-tabs .seg-btn { font-size: 12.5px; padding: 7px 4px; }
.atab-n { opacity: .7; font-size: 11px; font-weight: 600; }
@keyframes actIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.action-host.act-anim .focus-list, .action-host.act-anim .recs-host { animation: actIn .32s var(--spring) both; }

/* v199 — action tabs in the app's own language: a section
   title above standard glass pills — no divider line, no
   foreign borders (Nelson). */
.action-tabs { margin: 10px 0 12px; padding: 2px; border-top: none; }
.action-tabs .atab-n {
  background: color-mix(in srgb, var(--label) 12%, transparent);
  border-radius: 999px; padding: 1px 6px; margin-left: 2px; font-size: 11px;
}
.action-tabs .seg-btn.active .atab-n { background: rgba(255, 255, 255, .25); }

/* v204: potential tag on follow-up rows */
.fu-tag { color: var(--blue-dark, #0062CC); font-weight: 600; }

/* ============================================================
   v207 — Pipeline flow portrayed cleanly on phones (Nelson:
   the proportional mosaic looked messy on the iPhone). The
   river keeps its dollar-proportional widths on desktop; on
   phones the blocks become an even 2-up layout — equal tiles,
   labels wrap to two lines instead of truncating mid-word,
   empty boards keep the same calm size, and a pipeline's odd
   last board stretches the row instead of leaving a hole.
   (The v173 rule "flex: var(--grow) 1 150px" silently overrode
   the old phone rule — this block sits last on purpose.)
   Home also gets bottom air so the floating dock never sits
   on the last section.
   ============================================================ */
@media (max-width: 760px) {
  .dash-flow .flow-row { flex-wrap: wrap; gap: 10px; }
  .dash-flow .flow-block { flex: 1 1 42%; min-height: 98px; padding: 13px 14px; }
  .dash-flow .flow-block.side { flex: 1 1 42%; max-width: none; min-height: 98px; }
  .dash-flow .flow-label { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; line-height: 1.3; font-size: 11.5px; }
  .dash-flow .flow-sum { font-size: 20px; }
  .dash-flow .flow-pipe { margin-bottom: 20px; }
}
#view-dashboard { padding-bottom: 132px; }

/* ============================================================
   v208 — Breathing room + pill-switch motion (Nelson).
   (1) The Today brief panel sat 6px above the At-a-glance
   tiles — "way too close". The panel now gets a real 24px
   bottom margin and the glance section its own top air.
   (2) Switching pills in "Who needs you" now glides: cards
   slide in from the direction of travel, staggered on the
   app's spring — the same recipe as the follow-ups pager.
   ============================================================ */
.today-scroll, .panel-scroll { margin-bottom: 24px; }
.dash-stats { margin-top: 8px; }
.action-tabs .seg-btn { transition: all .25s var(--spring); }
.action-tabs .seg-btn:active { transform: scale(.94); }
@keyframes actNext { from { opacity: 0; transform: translateX(46px); } to { opacity: 1; transform: none; } }
@keyframes actPrev { from { opacity: 0; transform: translateX(-46px); } to { opacity: 1; transform: none; } }
.action-host.act-next .focus-list > *, .action-host.act-next .risk-total { animation: actNext .65s cubic-bezier(.3, 1.75, .4, 1) both; }
.action-host.act-prev .focus-list > *, .action-host.act-prev .risk-total { animation: actPrev .65s cubic-bezier(.3, 1.75, .4, 1) both; }
.action-host.act-next .focus-list > *:nth-child(2), .action-host.act-prev .focus-list > *:nth-child(2) { animation-delay: .06s; }
.action-host.act-next .focus-list > *:nth-child(3), .action-host.act-prev .focus-list > *:nth-child(3) { animation-delay: .12s; }
.action-host.act-next .focus-list > *:nth-child(4), .action-host.act-prev .focus-list > *:nth-child(4) { animation-delay: .18s; }
.action-host.act-next .focus-list > *:nth-child(5), .action-host.act-prev .focus-list > *:nth-child(5) { animation-delay: .24s; }
.action-host.act-next .focus-list > *:nth-child(n+6), .action-host.act-prev .focus-list > *:nth-child(n+6) { animation-delay: .30s; }

/* ============================================================
   v210 — The pill highlight glides (Nelson). A thumb pill sits
   inside the action toggle strip and bounces across to the
   tapped pill on the v192 spring; the active button turns
   transparent so the thumb IS the highlight. Buttons keep
   their own active styling until the thumb is placed
   (.has-thumb), so a measurement failure never loses the
   selection state.
   ============================================================ */
.action-tabs { position: relative; }
.atab-thumb {
  position: absolute; left: 0; top: 0; z-index: 0; border-radius: 999px;
  background: var(--grad); opacity: 0; pointer-events: none; will-change: transform;
  box-shadow: 0 6px 18px rgba(109, 61, 240, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.35);
  transition: opacity .2s; /* v216: transform/width are driven per-frame by the spring integrator */
}
.atab-thumb.no-anim { transition: none; }
.action-tabs .seg-btn { position: relative; z-index: 1; }
.action-tabs.has-thumb .seg-btn.active { background: transparent; border-color: transparent; box-shadow: none; color: #fff; }

/* ============================================================
   v212 — Board pills glide too (Nelson). Same thumb + spring
   as Home's action tabs, plus the kanban columns cascade in
   from the direction of travel on a pipeline switch.
   ============================================================ */
.board-tabs { position: relative; }
.seg-thumb {
  position: absolute; left: 0; top: 0; z-index: 0; border-radius: 999px;
  background: var(--grad); opacity: 0; pointer-events: none; will-change: transform;
  box-shadow: 0 6px 18px rgba(109, 61, 240, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.35);
  transition: opacity .2s; /* v216: transform/width are driven per-frame by the spring integrator */
}
.seg-thumb.no-anim { transition: none; }
.board-tabs .seg-btn { position: relative; z-index: 1; }
.board-tabs.has-thumb .seg-btn.active { background: transparent; border-color: transparent; box-shadow: none; color: #fff; }
.board-body.act-next { animation: boardInNext .38s cubic-bezier(.25, .9, .3, 1) both; }
.board-body.act-prev { animation: boardInPrev .38s cubic-bezier(.25, .9, .3, 1) both; }
@keyframes boardInNext { from { opacity: 0; transform: translateX(26px); } to { opacity: 1; transform: translateX(0); } }
@keyframes boardInPrev { from { opacity: 0; transform: translateX(-26px); } to { opacity: 1; transform: translateX(0); } }

/* v214: the board's persistent structure — head stays mounted
   (the pill thumb is a real element now), the body carries the
   height the board-fit layout used to give .kanban directly. */
#view-board.board-fit .board-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.board-body { min-width: 0; }

/* ============================================================
   v215 — Soft rapid-switch animations. Fast repeat taps used
   to get NO panel animation at all (v213's anti-flicker skip),
   which reads as "the animations stopped". Rapid switches now
   get a short, shallow fade/slide — motion on every tap,
   without the strobe of restarting the full cascade.
   ============================================================ */
.board-body.act-next.soft { animation-name: boardInNextSoft; animation-duration: .22s; }
.board-body.act-prev.soft { animation-name: boardInPrevSoft; animation-duration: .22s; }
@keyframes boardInNextSoft { from { opacity: .45; transform: translateX(12px); } to { opacity: 1; transform: translateX(0); } }
@keyframes boardInPrevSoft { from { opacity: .45; transform: translateX(-12px); } to { opacity: 1; transform: translateX(0); } }
.action-host.act-next-soft > :last-child > *, .action-host.act-prev-soft > :last-child > * { animation: actSoftIn .22s ease-out both; }
.action-host.act-next-soft > :last-child > *:nth-child(2), .action-host.act-prev-soft > :last-child > *:nth-child(2) { animation-delay: .02s; }
.action-host.act-next-soft > :last-child > *:nth-child(3), .action-host.act-prev-soft > :last-child > *:nth-child(3) { animation-delay: .04s; }
.action-host.act-next-soft > :last-child > *:nth-child(n+4), .action-host.act-prev-soft > :last-child > *:nth-child(n+4) { animation-delay: .06s; }
@keyframes actSoftIn { from { opacity: .35; } to { opacity: 1; } }

/* ============================================================
   v216 — The KeyPipeline entrance (Nelson's reference videos).
   Boot: the mark draws itself stroke by stroke over the lake,
   the wordmark writes in letter by letter, the tagline fades
   up — then the splash zooms through into a rising glass login
   card. Sign In morphs into a spinner, then a green check, and
   Home's sections cascade in. All choreography is class-driven
   from app.v5.js (routeAfterBoot / onLogin / enterApp).
   ============================================================ */
.boot-splash { transition: opacity .5s ease; overflow: hidden; }
.boot-splash::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(620px 400px at 50% 26%, rgba(125, 184, 255, 0.38), transparent 65%);
  opacity: 0; animation: bootBloom 1.8s ease .2s both;
}
@keyframes bootBloom { to { opacity: 1; } }
.boot-inner {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; align-items: center;
  will-change: transform, opacity;
}
.boot-logo {
  width: 260px; height: 260px; /* v220: 208px; v224: bigger again — Nelson wants the mark to own the loading page */
  filter: drop-shadow(0 18px 38px rgba(5, 15, 45, 0.45));
  animation: bootTileIn .55s cubic-bezier(.2, .9, .3, 1.25) both;
}
/* v218: the completion glow fires when the load actually
   completes (JS adds .glow), not on a timer */
.boot-splash.glow .boot-logo { animation: bootGlow 1s ease both; }
@keyframes bootGlow {
  0% { filter: drop-shadow(0 18px 38px rgba(5, 15, 45, 0.45)); }
  45% { filter: drop-shadow(0 18px 46px rgba(94, 169, 248, 0.55)); }
  100% { filter: drop-shadow(0 18px 38px rgba(5, 15, 45, 0.45)); }
}
@keyframes bootTileIn { from { opacity: 0; transform: scale(.82) translateY(12px); } to { opacity: 1; transform: none; } }
/* v218: the draw is driven by JS from the REAL load progress
   (app.v5.js load engine) — stroke-dashoffset is set per frame;
   no CSS timeline, so the logo IS the progress meter. */
.boot-splash .bp { stroke-dasharray: 100; stroke-dashoffset: 100; }
.boot-word {
  margin-top: 26px; display: flex;
  font-size: 34px; font-weight: 800; letter-spacing: -.6px; color: #fff;
  text-shadow: 0 2px 18px rgba(5, 15, 45, 0.4);
}
/* v218: letter opacity/transform are set per frame by the load
   engine, in step with the draw */
.boot-word span { opacity: 0; transform: translateY(12px); }
.boot-word .bw-acc { color: #7DB8FF; }
.boot-tag {
  margin-top: 8px; font-size: 11.5px; font-weight: 700;
  letter-spacing: 3.5px; text-transform: uppercase; color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 1px 10px rgba(5, 15, 45, 0.35);
  opacity: 0; /* v218: faded in by the load engine near 100% */
}
@keyframes bwIn { to { opacity: 1; transform: none; } }
.boot-splash.leaving { opacity: 0; pointer-events: none; }
.boot-splash.leaving .boot-inner { animation: bootZoom .55s cubic-bezier(.5, 0, .75, .4) forwards; }
@keyframes bootZoom { to { transform: scale(1.85); opacity: 0; } }

/* Login: the glass card rises, its contents stagger up */
/* v224: while the boot splash is up, the login card is held
   invisible (its inputs are disabled by the load engine), so
   the browser's stored-credential prompt can only appear
   AFTER the logo finishes — never mid-draw (Nelson's ask) */
.login-view.boot-hold .login-card { opacity: 0 !important; }
.login-view.enter .login-card { animation: cardRise .65s cubic-bezier(.2, .9, .25, 1) both; }
.login-view.enter .login-card > * { animation: cardChildIn .5s ease both; }
.login-view.enter .login-card > :nth-child(1) { animation-delay: .10s; }
.login-view.enter .login-card > :nth-child(2) { animation-delay: .17s; }
.login-view.enter .login-card > :nth-child(3) { animation-delay: .22s; }
.login-view.enter .login-card > :nth-child(4) { animation-delay: .28s; }
.login-view.enter .login-card > :nth-child(5) { animation-delay: .36s; }
@keyframes cardRise { from { opacity: 0; transform: translateY(52px) scale(.975); } to { opacity: 1; transform: none; } }
@keyframes cardChildIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.login-card.shake { animation: cardShake .4s ease; }
@keyframes cardShake { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-9px); } 45% { transform: translateX(7px); } 70% { transform: translateX(-5px); } 88% { transform: translateX(3px); } }

/* Sign In morphs: pill -> spinner -> green check */
#login-btn { transition: background .3s, width .38s cubic-bezier(.3, 1.3, .4, 1), border-radius .38s, transform .15s, opacity .2s; }
#login-btn.busy, #login-btn.done {
  width: 54px; height: 50px; padding: 0; margin: 6px auto 0;
  border-radius: 999px; display: flex; align-items: center; justify-content: center;
}
#login-btn.busy:disabled, #login-btn.done:disabled { opacity: 1; }
#login-btn.done { background: #2FBF71; }
.btn-spin {
  width: 21px; height: 21px; border-radius: 50%;
  border: 2.6px solid rgba(255, 255, 255, 0.35); border-top-color: #fff;
  animation: bootSpin .7s linear infinite;
}
.btn-check { width: 24px; height: 24px; animation: checkPop .38s cubic-bezier(.3, 1.7, .4, 1) both; }
@keyframes checkPop { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* Home cascade on first entry */
#view-dashboard.entering > * { animation: cascadeUp .6s cubic-bezier(.2, .8, .25, 1) both; }
#view-dashboard.entering > :nth-child(2) { animation-delay: .06s; }
#view-dashboard.entering > :nth-child(3) { animation-delay: .12s; }
#view-dashboard.entering > :nth-child(4) { animation-delay: .18s; }
#view-dashboard.entering > :nth-child(5) { animation-delay: .24s; }
#view-dashboard.entering > :nth-child(6) { animation-delay: .30s; }
#view-dashboard.entering > :nth-child(n+7) { animation-delay: .36s; }
@keyframes cascadeUp { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .boot-splash .bp { stroke-dashoffset: 0; animation: none; }
  .boot-word span, .boot-tag, .boot-logo, .boot-splash::before { animation: none; opacity: 1; transform: none; }
  .boot-splash.leaving .boot-inner { animation: none; }
  .login-view.enter .login-card, .login-view.enter .login-card > *,
  #view-dashboard.entering > *, .login-card.shake { animation: none; }
}

/* ============================================================
   v222 — Sidebar title themes (TOP LEVEL on purpose).
   The desktop sidebar's "the workspace" title (a ::before in
   the ≥1024px block above) must be readable in every theme.
   v221 put its dark overrides NESTED inside that media block;
   on Nelson's Mac (system theme + dark macOS) the title still
   rendered blue-on-blue — barely seeable, his photo proved it.
   Top-level, high-specificity, and pure white + a soft shadow
   on dark glass so no engine quirk can mute it again.
   ============================================================ */
.toptabs::before { -webkit-text-fill-color: currentColor; }
:root[data-theme='dark'] .toptabs::before {
  color: #FFFFFF;
  -webkit-text-fill-color: #FFFFFF;
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.45);
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] .toptabs::before {
    color: #FFFFFF;
    -webkit-text-fill-color: #FFFFFF;
    text-shadow: 0 1px 14px rgba(0, 0, 0, 0.45);
  }
}

/* v233: Settings → Appearance → Glass slider row */
.glass-row { display: flex; align-items: center; gap: 10px; }
.glass-row input[type="range"] { flex: 1; accent-color: var(--blue); height: 28px; }
.glass-end { font-size: 11.5px; color: var(--label-3); white-space: nowrap; }

/* v234: Settings link rows (admin shortcuts) */
.set-link-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; width: 100%; margin-top: 14px; padding: 13px 14px; background: var(--glass-row); border: 1px solid var(--glass-ring); border-radius: 14px; font: inherit; font-size: 14.5px; font-weight: 600; color: var(--label); cursor: pointer; text-align: left; }
.set-link-row:active { transform: scale(.985); }

/* ============================================================
   v235 — Board borders blend in (Nelson, from his monitor photo:
   the bright white glass ring made the columns read as hard
   pasted-on frames over the photo). The board trades the ring
   for a soft blue-grey hairline and a calmer shadow; cards keep
   their stage-color bar (set inline) at 3px. Board-scoped: the
   rest of the app's glass system is untouched.
   ============================================================ */
:root { --col-ring: rgba(31, 68, 132, 0.16); }
:root[data-theme='dark'] { --col-ring: rgba(158, 190, 240, 0.18); }
@media (prefers-color-scheme: dark) {
  :root[data-theme='system'] { --col-ring: rgba(158, 190, 240, 0.18); }
}
#view-board .kanban-col { border-color: var(--col-ring); box-shadow: 0 12px 32px rgba(9, 22, 68, 0.10); }
#view-board .kcard { border-color: var(--col-ring); border-left-width: 3px; }
#view-board .col-count { border-color: var(--col-ring); }
/* v235: pill arrange mode (Board head → Order) */
.board-tabs.reordering .seg-btn { touch-action: none; cursor: grab; box-shadow: inset 0 0 0 2px rgba(0, 122, 255, 0.35), var(--glass-shadow-sm); transition: transform .18s ease; }
.board-tabs.reordering .seg-btn.dragging { position: relative; z-index: 4; transition: none; cursor: grabbing; box-shadow: 0 10px 24px rgba(9, 22, 68, 0.25), inset 0 0 0 2px var(--blue); }
.board-tabs.reordering .seg-thumb { opacity: 0 !important; }
.board-tabs.reordering .seg-btn.active { background: var(--grad); color: #fff; }

/* v236: board head actions travel together, grouped at the right. */
.view-head .head-actions { margin-left: auto; display: inline-flex; gap: 8px; align-items: center; }

/* v237: a pipeline pill lights up as a drop target during a card drag. */
.board-tabs .seg-btn.pill-drop { background: rgba(var(--accent-rgb), 0.16); box-shadow: inset 0 0 0 2px var(--blue); }

/* v239: on desktop the board view drops the last 48px of bottom
   padding too, so the columns run to the very bottom edge of the
   screen (fitBoard reads the computed padding, so it follows). */
@media (min-width: 1024px) {
  .views.no-dock-pad { padding-bottom: 0; }
}

/* v240: in board-fit the columns fill the kanban — the base
   max-height: calc(100vh - 260px) cap left them ending short of
   the screen bottom on tall windows. */
#view-board.board-fit .kanban-col { max-height: none; }

/* v241: columns stretch to fill the screen width — no empty band
   after the last column. Grow only (never shrink below the set
   basis, so overflow scrolling is unchanged), capped so a
   one-column pipeline does not stretch absurdly wide. */
#view-board .kanban-col { flex-grow: 1; }

/* v244: interactive closing forecast — the card invites a tap;
   the sheet lists every file behind the number with Add/Remove. */
.forecast-card { cursor: pointer; }
.fc-tap { font-size: 12px; font-weight: 600; color: var(--blue); margin-top: 5px; }
.fc-tot { display: flex; align-items: baseline; gap: 10px; padding: 4px 0 10px; }
.fc-tot-num { font-size: 26px; font-weight: 800; letter-spacing: -.02em; }
.fc-tot-sub { font-size: 12.5px; color: var(--label-2); }
.fc-sec { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--label-2); margin: 14px 0 6px; }
.fc-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--hair, rgba(120,140,180,.18)); }
.fc-row-main { flex: 1 1 auto; min-width: 0; }
.fc-name { font-size: 14.5px; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fc-meta { font-size: 12px; color: var(--label-2); margin-top: 1px; }
.fc-w { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }
.fc-btn { flex: 0 0 auto; border: 0; border-radius: 999px; padding: 7px 13px; font-size: 13px; font-weight: 700; background: var(--blue); color: #fff; cursor: pointer; }
.fc-btn.out { background: rgba(229, 83, 75, .14); color: #D63A30; }
.fc-empty { font-size: 13px; color: var(--label-2); padding: 6px 0 2px; }

/* v245: no scroll-snap on desktop. The phone-era 'x proximity' snap
   made the strip's end unreachable on wide screens: with only ~176px
   of overflow, the max scroll sits between two snap points and the
   strip springs back toward the start, so the last column never
   stays at the screen's edge (Nelson's 'horrible border'). */
@media (min-width: 1024px) { #view-board .kanban { scroll-snap-type: none; } }

/* v246: on desktop the columns share the strip and shrink to fit —
   every pipeline fits the screen exactly, like Needs Work already
   did (4 x 390, no scrollbar). The 344px no-shrink floor forced
   5- and 6-column pipelines to overflow, and the overflow strip
   never held its scroll end on Nelson's machine (snap-back, then
   repaint churn dragging it to 0) — the 'horrible border'. A 240px
   floor remains, so a very crowded pipeline can still scroll. */
@media (min-width: 1024px) {
  #view-board .kanban-col { flex: 1 1 0; min-width: 240px; }
}

/* ============================================================
   v247: board blend, second pass (Nelson, Oct 26: "the border on
   the left and right on the boards... looks horrible"). At full
   Solid glass the v235 hairline still traced a hard outline down
   both sides of every column. Columns now carry NO outline at
   all — a wide, faint shadow plus a top light line give them
   shape against the photo without a drawn border. The drag
   drop-target ring is functional and stays.
   ============================================================ */
#view-board .kanban-col { border-color: transparent; box-shadow: 0 18px 44px rgba(9, 22, 68, 0.07), inset 0 1px 0 rgba(255, 255, 255, 0.45); }
:root[data-theme='dark'] #view-board .kanban-col { box-shadow: 0 18px 44px rgba(2, 6, 20, 0.30), inset 0 1px 0 rgba(255, 255, 255, 0.10); }
#view-board .kanban-col.drop-target { box-shadow: inset 0 0 0 2px var(--blue); }

/* ============================================================
   v248: full-bleed board strip on phone/tablet (Nelson, Oct 26:
   "i want the board to go the whole way to either side of the
   screens when scrolling... i want the cut off be the screen
   itself"). The strip used to live inside the view's side
   padding, so columns were cut by an inner frame inset from
   each screen edge. Now the strip breaks out to the full screen
   width; its own end padding keeps the first/last columns
   inset at rest, and mid-scroll the SCREEN edge does the
   cutting. Desktop keeps its framed layout.
   ============================================================ */
@media (max-width: 719px) {
  #view-board .kanban { margin-left: -18px; margin-right: -18px; padding-left: 20px; padding-right: 20px; scroll-snap-type: none; }
}
@media (min-width: 720px) and (max-width: 1023px) {
  #view-board .kanban { margin-left: -24px; margin-right: -24px; padding-left: 26px; padding-right: 26px; scroll-snap-type: none; }
}

/* ============================================================
   v250: THE BOARD OWNS THE FULL WIDTH — structural fix (Nelson,
   Oct 26: "the same problem was on the computer and now on the
   phone... change to something more dynamic"). Instead of the
   strip fighting the page padding (v248's negative margins),
   the page drops its side padding while the Board is open
   (.views.board-open, toggled by showView); the board head and
   the strip's own end padding carry the insets. Result on every
   screen: the strip's scrollport IS the visible width — phone:
   the whole screen; desktop: sidebar edge to window edge — and
   the pipeline pills scroll edge-to-edge the same way.
   v248's strip margins are retired below.
   ============================================================ */
.views.board-open { padding-left: 0; padding-right: 0; }
.views.board-open .board-head { padding-left: 18px; padding-right: 18px; }
#view-board .kanban { margin-left: 0; margin-right: 0; padding-left: 20px; padding-right: 20px; }
.views.board-open .board-tabs { margin-left: -18px; margin-right: -18px; padding-left: 18px; padding-right: 18px; }
@media (min-width: 720px) {
  .views.board-open .board-head { padding-left: 24px; padding-right: 24px; }
  #view-board .kanban { padding-left: 26px; padding-right: 26px; }
  .views.board-open .board-tabs { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }
}
@media (min-width: 1024px) {
  .views.board-open { padding-left: 228px; }
  .views.board-open .board-head { padding-left: 40px; padding-right: 40px; }
  #view-board .kanban { padding-left: 40px; padding-right: 40px; }
  .views.board-open .board-tabs { margin-left: -40px; margin-right: -40px; padding-left: 40px; padding-right: 40px; }
}
