:root {
  --bg: #f6f5f2;
  --panel: #ffffff;
  --border: #e3e0d8;
  --text: #2b2a27;
  --text-muted: #77746c;
  --accent: #b5674a;
  --accent-dark: #96543b;
  --accent-soft: #f3e2da;
  --green: #4c7a5e;
  --amber: #b58a3f;
  --red: #b5473f;
  --radius: 10px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
}

/* Wider than the original 1100px column — HomePilot's reference layout uses
   most of the desktop viewport instead of a narrow centered column. Still
   capped (not 100%) so it doesn't stretch into unreadably long line lengths
   on very large monitors. */
#app { max-width: 1600px; margin: 0 auto; padding: 16px; }

/* ---------- Auth screen ---------- */
.auth-wrap {
  max-width: 380px;
  margin: 10vh auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px;
}
.auth-wrap h1 { margin-top: 0; font-size: 22px; }
.auth-tabs { display: flex; gap: 8px; margin-bottom: 16px; }
.auth-tabs button {
  flex: 1; padding: 8px; border: 1px solid var(--border);
  background: var(--bg); border-radius: 8px; cursor: pointer;
}
.auth-tabs button.active { background: var(--accent); color: white; border-color: var(--accent); }

/* ---------- Layout ---------- */
/* Matches the reference layout: the gold bar's edges line up exactly with
   the panels below it (it does NOT stretch to the browser's viewport
   edges) — it's a normal block inside #app, so it automatically inherits
   the same width/alignment as everything else on the page. An earlier
   "full-bleed" version (100vw + left:50%/translateX(-50%)) caused both a
   stray rendering seam above the bar and an oversized gap above it; a
   plain block avoids both.
   Uses TopHeaderBar-tile.png — a crop of the user-provided TopHeaderBar.png
   with its top 6px removed. Those 6px turned out to be fully transparent
   (not black, despite how they looked when sampled without alpha), which
   let the background-color show through as a lighter band above the brown
   stripe; cropping them out so the stripe is the very first row fixes that.
   Tiled horizontally, scaled to half native size (background-size) so both
   the grain and the stripe read finer, matching the reference. No separate
   CSS border-top: that doubled up with the image's own baked-in stripe and
   made the line look thicker than intended. */
/* Mirrors .layout's column widths exactly (280px sidebar + 20px gap) so
   .topbar-right — and the top-nav inside it — starts at the same x
   position as .main below it, instead of floating independently. */
/* No vertical padding here — that space is pushed onto .topbar-left/
   .user-pill individually instead, so the active nav item's diagonal cut
   (which stretches full-height with zero padding of its own) actually
   touches the bar's true top/bottom edges rather than sitting in a gap
   inset from them, which is what made it read as a button/pill instead
   of a cut through the bar. */
header.topbar {
  display: flex; align-items: stretch; gap: 20px;
  padding: 0 16px; margin: -8px 0 20px;
  background-color: #8f7232;
  background-image: url("TopHeaderBar-tile.png");
  background-repeat: repeat-x;
  background-position: top left;
  background-size: 71px auto;
  color: #fff;
}
header.topbar h1 { font-size: 32px; font-weight: 800; margin: 0; letter-spacing: -.01em; }
.topbar-left { width: 280px; flex-shrink: 0; display: flex; align-items: center; padding: 14px 0; }
.topbar-right { flex: 1; min-width: 0; display: flex; align-items: stretch; justify-content: space-between; }
.topbar-brand { display: flex; align-items: center; gap: 10px; }
.topbar-home-icon { flex-shrink: 0; }

/* Simplified — just a status dot + name; sign-out collapses to a small
   icon-only glyph rather than a separate labeled button. */
.user-pill {
  font-size: 14px; font-weight: 600; color: #fff;
  display: flex; align-items: center; gap: 8px; padding: 14px 0;
}
.user-dot {
  width: 8px; height: 8px; border-radius: 50%; background: #6ECD49;
  display: inline-block;
}
.user-pill #signout-btn {
  background: none; border: none; color: rgba(255,255,255,.7);
  font-size: 16px; cursor: pointer; padding: 2px 4px; border-radius: 6px; line-height: 1;
}
.user-pill #signout-btn:hover { color: #fff; background: rgba(255,255,255,.15); }

/* Property selector now lives at the top of the sidebar's Projects panel
   (not the top-bar) — a dark band "encompassing" the Projects band below
   it, so the two read as one nested container: Property > Projects. */
.sidebar-property-band { background: #4F3426; padding: 6px 16px; flex-shrink: 0; }
select.property-header-select {
  width: 100%; border: none; background: none; padding: 0;
  font-size: 17px; font-weight: 700; color: #fff; cursor: pointer; border-radius: 6px;
}
select.property-header-select:hover { opacity: .85; }

/* Diagonal "corner-joint" cut for the active nav item — a white
   parallelogram (mitered like a reno corner joint) cut into the brown
   bar, holding the active label italicized (same font family/size as the
   rest, just italic — not a different typeface). Inactive items are
   plain bold white text with no background, so the active one is the
   only thing that visually "pops" off the bar. All items stretch to the
   bar's full height so the cut is a clean single edge top-to-bottom
   rather than one item taller than its neighbors. */
.top-nav { display: flex; align-items: stretch; gap: 0; }
.top-nav button {
  display: flex; align-items: center;
  padding: 0 22px; border: none; background: none; cursor: pointer;
  font-size: 17px; font-weight: 700; color: #fff;
  letter-spacing: .01em;
}
.top-nav button:hover:not(.active) { color: #fff3e6; }
.top-nav button.active {
  color: var(--accent-dark); background: #fff;
  font-style: italic; font-weight: 700;
  padding: 0 34px;
  clip-path: polygon(14% 0, 100% 0, 86% 100%, 0% 100%);
}

.layout { display: flex; gap: 20px; align-items: flex-start; }
/* Height-bound to the viewport and sticky, so the sidebar (including the
   Projects panel's tail and the Dashboard/Calendar buttons below it)
   always stays fully visible regardless of project-list length or
   window height — #project-list is the only part that scrolls
   internally (see below), rather than letting the whole sidebar grow
   taller than the screen and push its own footer out of view.
   max-height is set precisely from JS (see adjustSidebarHeight in
   app.js) — a plain calc(100vh - Npx) can't know the header's actual
   rendered height, and guessing it produced a sidebar taller than the
   visible viewport, pushing Dashboard/Calendar back off-screen at the
   bottom (the exact bug this was meant to fix). The value here is just
   a same-ballpark fallback before that JS runs. */
.sidebar {
  width: 280px; flex-shrink: 0;
  position: sticky; top: 16px;
  max-height: calc(100vh - 100px);
  display: flex; flex-direction: column;
}
.main { flex: 1; min-width: 0; }

@media (max-width: 760px) {
  .layout { flex-direction: column; }
  /* Sticky height-constraining is a poor fit once the layout stacks
     vertically — back to normal in-flow, full-height placement. */
  .sidebar { width: 100%; position: static; max-height: none; }
}

/* ---------- Cards / panels ---------- */
.panel {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px; margin-bottom: 16px;
}
.panel h2 { margin-top: 0; font-size: 16px; }
.panel h3 { font-size: 14px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }

/* Sidebar "Projects" panel gets a solid colored header band (title + "+" on
   the left, status filter on the right) instead of a plain heading, so it
   reads as a distinct block above the flush list below. */
/* flex column, shrinkable (min-height:0) so #project-list — the only
   scrolling part — can be squeezed to whatever room is actually left
   inside the sticky, viewport-height-bound .sidebar above, instead of
   the panel just growing as tall as its content wants. */
.sidebar .panel {
  padding: 0; overflow: hidden;
  display: flex; flex-direction: column; min-height: 0; flex-shrink: 1;
}
.sidebar .panel h2 {
  margin: 0; padding: 14px 16px; background: #d38c00;
  color: #fff; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  flex-shrink: 0;
}
/* The one scrolling region — grows to fill whatever space is left in the
   panel and scrolls internally past that, so the tail band below it
   (and everything after the panel) never gets pushed off-screen. */
#project-list { padding: 6px 0; flex: 1; min-height: 60px; overflow-y: auto; }

/* Footer band matching the header's color, so the sidebar panel reads as
   one colored-bookends block. Houses the sort button. */
.sidebar-tail {
  background: #d38c00; padding: 10px 16px; flex-shrink: 0;
  display: flex; justify-content: space-between; align-items: center;
}
.project-count-label { color: #fff; font-size: 12px; font-weight: 700; }

/* Below the Projects panel's tail — used only for the guided-wizard/
   quick-entry toggle (see .entry-mode-toggle below). Dashboard/Calendar
   used to live here as their own buttons; they moved into the top bar's
   nav next to People, so this is just a plain strip on the page's
   off-white background now, not a boxed nav item list. flex-shrink:0 so
   it can't get squeezed by #project-list's flex:1 inside the sticky,
   height-bound .sidebar (see .sidebar above). */
.sidebar-nav { flex-shrink: 0; width: 100%; margin-top: 10px; }

/* Plain "+" trigger next to a heading (e.g. "Projects +") — no button box,
   just a glyph, colored to match whatever it's sitting on. */
.new-project-plus {
  cursor: pointer; font-weight: 700; font-size: 18px; margin-left: 2px;
}
.new-project-plus:hover { opacity: .8; }

/* Toggle between the guided wizard and the quick "pro" form — only shown
   once a user has created enough projects that the choice is relevant
   (see renderProjectList). Sits alone in its own strip below the
   Projects panel's tail (see .sidebar-nav above) rather than crammed
   next to "Projects +", where it read as cluttered. Plain small
   underlined text, not a full button, since it's a low-stakes
   preference, not a primary action. */
.entry-mode-toggle {
  display: block; cursor: pointer; font-size: 12px; font-weight: 600;
  text-decoration: underline; color: var(--text-muted); text-align: center;
}
.entry-mode-toggle:hover { color: var(--accent); }

/* Status filter chip — funnel icon + native select, styled as one pill so
   it reads as a single filter control rather than a plain dropdown. */
.project-filter {
  display: flex; align-items: center; gap: 4px; background: rgba(255,255,255,.2);
  border-radius: 999px; padding: 3px 10px 3px 8px; flex-shrink: 0;
}
.project-filter .filter-icon { color: #fff; flex-shrink: 0; }
.project-filter select {
  width: auto; border: none; background: none; color: #fff;
  font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  padding: 2px 2px; cursor: pointer;
}
.project-filter select option { color: var(--text); }

/* Sort cycle button — click advances through Status → Property → Start
   date → Manager, current mode shown as a short label next to the icon
   (and as the title tooltip for anyone hovering). */
.project-sort-btn {
  display: flex; align-items: center; gap: 4px; background: rgba(255,255,255,.2);
  border: none; border-radius: 999px; padding: 4px 10px; flex-shrink: 0;
  color: #fff; font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .03em; cursor: pointer;
}
.project-sort-btn:hover { background: rgba(255,255,255,.3); }

/* Filter pill picks up the same colors as the status badges once a specific
   status is chosen, so it visually matches what it's filtering for. */
.project-filter.status-ideation { background: #e1eefa; }
.project-filter.status-ideation .filter-icon, .project-filter.status-ideation select { color: #1d5f9e; }
.project-filter.status-planned { background: #e5e1f5; }
.project-filter.status-planned .filter-icon, .project-filter.status-planned select { color: #4b3f8f; }
.project-filter.status-in_progress { background: #d9ead9; }
.project-filter.status-in_progress .filter-icon, .project-filter.status-in_progress select { color: var(--green); }
.project-filter.status-on_hold { background: #fff3c4; }
.project-filter.status-on_hold .filter-icon, .project-filter.status-on_hold select { color: #8a6d00; }
.project-filter.status-completed { background: #f3dede; }
.project-filter.status-completed .filter-icon, .project-filter.status-completed select { color: #7a1f1f; }

/* Property/Status/Manager fields in the project header — a plain value with
   the native dropdown arrow, no visible box/border around it. */
select.select-plain {
  border: none; background: transparent; padding: 4px 18px 4px 2px;
}

/* No boxed card — a flush, full-bleed row with a bottom divider instead of
   a bordered, rounded container. The selected/hover tint then spans the
   whole sidebar width edge-to-edge, with a left accent stripe marking the
   active one. */
.project-card {
  padding: 12px 16px; margin: 0; cursor: pointer;
  border-bottom: 1px solid var(--border);
  border-left: 3px solid transparent;
}
.project-card:hover { background: var(--bg); }
.project-card.selected { background: #fbf1ec; border-left-color: var(--accent); }
.project-card .pc-row1 { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
/* Unselected rows show the name and manager in the accent brown, so the
   list reads with some color; the selected row switches both to plain dark
   text so it stands out as "the one you're looking at" instead of blending
   into the same brown as everything else. */
.project-card .name { font-weight: 600; color: var(--accent); }
.project-card.selected .name { color: var(--text); }
.project-card .pc-manager { color: var(--accent); font-weight: 600; }
.project-card.selected .pc-manager { color: var(--text); }
.project-card .meta { font-size: 12px; color: var(--text-muted); margin-top: 4px; display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.project-card .pc-dates { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

/* Thumbnail — the latest Before/After photo (Reference photos excluded on
   purpose, see loadProjectThumbnails) sits to the left of the card's text,
   same layout as the reference mockup. Cards without an eligible photo
   just skip it entirely rather than showing an empty placeholder. */
.pc-card-row { display: flex; gap: 10px; align-items: flex-start; }
.pc-thumb-col { display: flex; flex-direction: column; align-items: center; gap: 3px; flex-shrink: 0; width: 56px; }
/* Always reserves the photo's footprint, even with no photo, so the Type
   label underneath sits at a consistent height (level with the progress
   bar on the right) instead of collapsing upward when there's no image. */
.pc-thumb-slot { width: 56px; height: 56px; flex-shrink: 0; }
/* Not clickable on purpose — the card itself already selects/highlights
   on click and opens edit on double-click, so a click target here would
   just conflict with that instead of adding a useful upload shortcut. */
.pc-thumb-placeholder {
  width: 56px; height: 56px; border-radius: 6px;
  background: var(--bg); border: 1px dashed var(--border);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted); font-size: 20px;
}
.pc-thumb { width: 56px; height: 56px; border-radius: 6px; object-fit: cover; display: block; }
.pc-thumb-type { font-size: 12px; font-weight: 600; line-height: 1.2; color: var(--accent); text-align: center; }
.pc-card-body { flex: 1; min-width: 0; }

/* Per-project task-completion progress bar, matching the reference
   mockup — a thin track + fill plus the percentage as plain text. */
.pc-progress-row { display: flex; align-items: center; gap: 6px; margin-top: 6px; }
.pc-progress-track { flex: 1; height: 5px; background: var(--border); border-radius: 3px; overflow: hidden; }
.pc-progress-fill { height: 100%; background: var(--accent); border-radius: 3px; }
.pc-progress-pct { font-size: 11px; color: var(--text-muted); flex-shrink: 0; }

/* ---------- Badges ---------- */
.badge {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 600; text-transform: uppercase;
}
.badge.ideation { background: #e1eefa; color: #1d5f9e; }
.badge.planned { background: #e5e1f5; color: #4b3f8f; }
.badge.in_progress { background: #d9ead9; color: var(--green); }
.badge.on_hold { background: #fff3c4; color: #8a6d00; }
.badge.completed { background: #f3dede; color: #7a1f1f; }
.badge.idea { background: #eee; color: #666; }
.badge.considering { background: #fdeecb; color: var(--amber); }
.badge.chosen { background: #d9ead9; color: var(--green); }
.badge.rejected { background: #f0ddd8; color: var(--red); }

/* Same status colors as the badges above, applied to a <select> itself (the
   project header's Status field, and task status dropdowns) so status
   reads consistently everywhere it appears, not just in the sidebar list.
   Font-size is repeated at the same specificity as table.schedule-table's
   own select rule (which otherwise wins and overrides this) — bold+uppercase
   was also dropped, since combined with that larger font it made the text
   read as noticeably bigger/heavier than the rest of the row. */
select.status-select {
  border: none; border-radius: 999px; padding: 3px 10px;
  font-size: 12px; cursor: pointer;
}
table.schedule-table select.status-select { font-size: 12px; }
select.status-select.not_started { background: #eee; color: #666; }
select.status-select.ideation { background: #e1eefa; color: #1d5f9e; }
select.status-select.planned { background: #e5e1f5; color: #4b3f8f; }
select.status-select.in_progress { background: #d9ead9; color: var(--green); }
select.status-select.on_hold { background: #fff3c4; color: #8a6d00; }
select.status-select.completed, select.status-select.done { background: #f3dede; color: #7a1f1f; }

/* ---------- Forms ---------- */
label { display: block; font-size: 13px; margin: 10px 0 4px; color: var(--text-muted); }
input, select, textarea {
  width: 100%; padding: 8px 10px; border: 1px solid var(--border);
  border-radius: 8px; font-size: 14px; font-family: inherit; background: white;
}
textarea { resize: vertical; min-height: 60px; font-family: inherit; }
input::placeholder, textarea::placeholder { font-style: italic; color: var(--text-muted); opacity: 0.7; }
#ph-notes { min-height: 100px; }
form .row { display: flex; gap: 12px; }
form .row > div { flex: 1; }

button.btn {
  padding: 9px 16px; border-radius: 8px; border: none;
  background: var(--accent); color: white; font-weight: 600;
  cursor: pointer; font-size: 14px;
}
button.btn:hover { background: var(--accent-dark); }
button.btn.secondary { background: var(--bg); color: var(--text); border: 1px solid var(--border); }
button.btn.danger { background: var(--red); }
button.btn.small { padding: 5px 10px; font-size: 12px; }

/* The Schedule tab's "Assigned" button reused the plain secondary button
   style (dark, bold text), which read as stark next to the rest of the row.
   Needs .btn.secondary.si-assignee-btn (three classes) to actually beat
   .btn.secondary's own color rule (two classes) — the earlier two-class
   attempt lost that specificity tie and never took effect. */
button.btn.secondary.si-assignee-btn { color: #d38c00; font-weight: 700; }

/* De-emphasized delete affordance — muted by default, red only on hover,
   so it doesn't visually compete with the row's actual content. */
button.icon-delete {
  background: none; border: none; color: var(--text-muted);
  cursor: pointer; font-size: 14px; padding: 4px 8px; border-radius: 6px;
}
button.icon-delete:hover { color: var(--red); background: var(--bg); }

/* Same muted look, for non-delete icon actions (e.g. "estimate material"). */
button.icon-btn {
  background: none; border: none; color: var(--text-muted);
  cursor: pointer; font-size: 14px; padding: 4px 8px; border-radius: 6px;
}
button.icon-btn:hover { color: var(--accent); background: var(--bg); }

/* ---------- Tabs within a project ---------- */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 14px; }
.tabs button {
  padding: 9px 16px; border: none; background: none; cursor: pointer;
  font-size: 14px; font-weight: 600; color: var(--text-muted); border-bottom: 3px solid transparent;
  border-radius: 6px 6px 0 0;
}
.tabs button:hover { color: var(--text); background: var(--bg); }
.tabs button.active {
  color: var(--accent-dark); border-bottom-color: var(--accent); font-weight: 700;
  background: var(--accent-soft);
}

/* ---------- Tables/lists ---------- */
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th, td { text-align: left; padding: 8px 6px; border-bottom: 1px solid var(--border); }
th { color: var(--text-muted); font-weight: 600; font-size: 12px; text-transform: uppercase; }
tr.est-row td { color: var(--text-muted); font-style: italic; }
tr.group-heading td { background: var(--bg); font-weight: 600; font-size: 13px; border-bottom: 1px solid var(--border); padding-top: 12px; }

/* 8 columns: bulk-checkbox, #, task, start, due, assigned, status, actions
   — the checkbox column is always rendered (blank for non-managers) so the
   column count never changes and these nth-child widths stay meaningful;
   a conditional 8th/9th column previously shifted everything by one and
   broke the whole table's alignment. */
table.schedule-table { table-layout: fixed; }
table.schedule-table th:nth-child(1), table.schedule-table td:nth-child(1) { width: 4%; }
table.schedule-table th:nth-child(2), table.schedule-table td:nth-child(2) { width: 5%; }
table.schedule-table th:nth-child(3), table.schedule-table td:nth-child(3) { width: 19%; }
table.schedule-table th:nth-child(4), table.schedule-table td:nth-child(4),
table.schedule-table th:nth-child(5), table.schedule-table td:nth-child(5) { width: 14%; }
table.schedule-table th:nth-child(6), table.schedule-table td:nth-child(6) { width: 15%; }
table.schedule-table th:nth-child(7), table.schedule-table td:nth-child(7) { width: 16%; }
table.schedule-table th:nth-child(8), table.schedule-table td:nth-child(8) { width: 13%; }
table.schedule-table td { padding: 6px 4px; }
table.schedule-table td.si-num { color: var(--text-muted); font-size: 12px; text-align: center; }
/* Two icon buttons now share the last column — tighter side padding so
   both fit on one line instead of the second one wrapping below. */
table.schedule-table td:last-child { white-space: nowrap; }
table.schedule-table td:last-child .icon-btn,
table.schedule-table td:last-child .icon-delete { padding: 4px 5px; }
table.schedule-table input[type="date"], table.schedule-table input[type="text"], table.schedule-table select {
  padding: 5px 4px; font-size: 13px;
}

.summary-grid { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.summary-box {
  flex: 1; min-width: 140px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; padding: 12px;
}
.summary-box .label { font-size: 12px; color: var(--text-muted); }
.summary-box .value { font-size: 20px; font-weight: 700; margin-top: 4px; }
.summary-box.over .value { color: var(--red); }
.summary-box.under .value { color: var(--green); }

/* Dashboard chart panels — birds-eye complement to the Upcoming tasks
   list, not a replacement for it. Side by side on wide screens, stacked
   on narrow ones (matches the .layout breakpoint elsewhere). */
.chart-grid { display: flex; gap: 16px; margin-bottom: 16px; }
.chart-grid .panel { flex: 1; min-width: 0; margin-bottom: 0; }
.chart-box { position: relative; height: 240px; }
@media (max-width: 760px) {
  .chart-grid { flex-direction: column; }
}

.empty-state { color: var(--text-muted); font-size: 14px; padding: 20px 0; text-align: center; }

.error-msg { color: var(--red); font-size: 13px; margin-top: 8px; }
.hint { color: var(--text-muted); font-size: 12px; margin-top: 4px; }

a { color: var(--accent); }

details.new-form summary { cursor: pointer; color: var(--accent); font-weight: 600; margin-bottom: 8px; }

/* ---------- Modal (task review popup) ---------- */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(30,28,24,.45);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000; padding: 16px;
}
/* Can be opened from within another already-open modal (e.g. "+ Create new
   type" or "Surface area" from inside the Estimate Material modal), so they
   must stack above the base z-index regardless of DOM order. */
#new-material-type-overlay, #surface-area-overlay { z-index: 1100; }
.modal-box {
  background: var(--panel); border-radius: var(--radius);
  padding: 22px; max-width: 640px; width: 100%;
  max-height: 85vh; overflow-y: auto;
  box-shadow: 0 12px 40px rgba(0,0,0,.25);
}
.modal-box h2 { margin-top: 0; }
.modal-actions { display: flex; gap: 8px; margin-top: 18px; align-items: center; }

/* Recap of choices already committed in earlier wizard steps (see
   renderWizardStep in app.js) — shown so the Property/Type/Name/Dates
   chain stays visible as you move forward, instead of losing track of
   what you picked once its own screen is behind you. */
.wizard-summary { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.wizard-summary-chip {
  background: var(--bg); border: 1px solid var(--border); border-radius: 999px;
  padding: 4px 10px; font-size: 12px; color: var(--text-muted);
}
.wizard-summary-chip strong { color: var(--text); font-weight: 600; }

/* Project Type type-ahead (see setupProjectTypeTypeahead in app.js) — a
   custom dropdown instead of a native <datalist>, since datalist's popup
   colors/position are entirely browser/OS-controlled (shows up black on
   a system in dark mode, and can misplace itself inside a scrolling
   modal) with no CSS hook to fix either. position:fixed, positioned from
   JS via the input's getBoundingClientRect(), so it isn't clipped by the
   modal's own overflow:auto. */
.type-ahead-dropdown {
  position: fixed; background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; max-height: 240px; overflow-y: auto;
  box-shadow: 0 8px 20px rgba(0,0,0,.18); z-index: 1200;
}
.type-ahead-option { padding: 8px 12px; font-size: 14px; cursor: pointer; color: var(--text); }
.type-ahead-option:hover, .type-ahead-option.active { background: var(--bg); }
/* Flags typed text that isn't in the curated list — see updateValidity
   in setupProjectTypeTypeahead. Submitting still gets rejected either
   way; this just makes that visible before you try. */
#np-type.type-ahead-input-invalid { border-color: #b5473f; }

/* Info/confirm dialog ("Can't do that" explanations and yes/no confirms —
   see showDialog) is a small popup anchored to the cursor (position set
   from JS) rather than centered like the other modals — no dimmed
   backdrop, so it reads as a popup, not a page-blocking form. Used in
   place of window.confirm() too, since native confirm boxes can't be
   repositioned or restyled (always grey, always centered). */
.info-dialog-overlay { background: transparent; align-items: flex-start; justify-content: flex-start; }
.info-dialog-box {
  position: fixed; background: var(--accent); color: #fff;
  box-shadow: 0 8px 24px rgba(0,0,0,.35);
}
.info-dialog-box h2 { color: #fff; }
.info-dialog-box #info-dialog-message { color: #fdf3ef; }
.info-dialog-box .btn { background: #fff; color: var(--accent-dark); }
.info-dialog-box .btn:hover { background: #fdf3ef; }
.info-dialog-box .info-dialog-cancel-btn {
  background: transparent; color: #fff; border: 1px solid rgba(255,255,255,.6);
}
.info-dialog-box .info-dialog-cancel-btn:hover { background: rgba(255,255,255,.15); }

/* ---------- Schedule tab: list + permanent Task Details column ---------- */
/* Task Details is always visible next to the list (not a popup/drawer) —
   defaults to the first task so it's never blank. Stacks vertically below
   760px, same breakpoint as the sidebar/main layout. */
.schedule-layout { display: flex; gap: 16px; align-items: flex-start; }
.schedule-list-col { flex: 1; min-width: 0; }
.schedule-detail-col { width: 360px; flex-shrink: 0; position: sticky; top: 16px; }
@media (max-width: 760px) {
  .schedule-layout { flex-direction: column; }
  .schedule-detail-col { width: 100%; position: static; }
}
tr.selected { background: #fbf1ec; }

/* Bulk actions toolbar — appears above the Schedule table once at least
   one task is checked. One row per action so it stays readable as more
   actions get added, rather than everything crammed onto one line. */
.bulk-toolbar {
  background: #fbf1ec; border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px; margin-bottom: 12px; font-size: 14px;
}
.bulk-toolbar-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 4px 0;
}
.bulk-toolbar-row select { width: auto; }
.bulk-toolbar-row + .bulk-toolbar-row { border-top: 1px solid rgba(0,0,0,.06); }
tr.si-row td.si-num { cursor: pointer; }
/* Flags a task's own date falling outside its project's date range — a
   soft warning (hover for detail), not a blocked save. */
.date-warn { color: var(--amber); margin-left: 4px; cursor: help; font-size: 13px; }
.date-warning-banner {
  background: #fff3c4; color: #8a6d00; border-radius: 8px;
  padding: 8px 10px; font-size: 13px; margin-top: 8px;
}
tr.si-row:hover:not(.selected) { background: var(--bg); }

/* ---------- Task checklist ---------- */
.checklist-item { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.checklist-item input[type="checkbox"] { width: auto; }
.checklist-item .label { flex: 1; font-size: 14px; }
.checklist-item.done .label { color: var(--text-muted); text-decoration: line-through; }

/* ---------- Task priority ---------- */
select.priority-select {
  border: none; border-radius: 999px; padding: 3px 10px; font-size: 12px; cursor: pointer;
}
select.priority-select.low { background: #d9ead9; color: var(--green); }
select.priority-select.medium { background: #fff3c4; color: #8a6d00; }
select.priority-select.high { background: #f3dede; color: #7a1f1f; }

/* ---------- Photos tab ---------- */
.photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; }
.photo-card { border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: var(--bg); }
.photo-card img { width: 100%; height: 140px; object-fit: cover; display: block; }
.photo-card-meta { padding: 8px; font-size: 13px; position: relative; }
.photo-card-meta .icon-delete { position: absolute; top: 4px; right: 4px; background: var(--panel); }

/* Ties the Calendar's header bar to the sidebar's brown active-nav
   highlight, so landing on Calendar reads as a continuation of that
   highlight rather than a visually disconnected page. */
.cal-toolbar { background: var(--accent); color: #fdf3ef; }
.cal-toolbar h2 { color: #fdf3ef; }
.cal-nav-btn { background: rgba(255,255,255,.15); color: #fdf3ef; border: none; }
.cal-nav-btn:hover { background: rgba(255,255,255,.25); }

/* ---------- Calendar month grid ---------- */
/* Each week is its own block: a row of day-number cells, then one 7-column
   row per "lane" of task bars (see renderCalendarView's lane-packing) — a
   task spanning several days renders as one bar with grid-column: span N,
   clipped to (and re-drawn on) each week row it touches, same convention
   Google Calendar uses for multi-day events. */
.cal-grid-header { display: grid; grid-template-columns: repeat(7, 1fr); border: 1px solid var(--border); border-bottom: none; border-radius: 8px 8px 0 0; overflow: hidden; }
.cal-weekday {
  background: var(--bg); color: var(--text-muted); font-size: 13px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em; padding: 8px 10px;
}
.cal-week { border: 1px solid var(--border); border-top: none; min-height: 60px; }
.cal-week:last-child { border-radius: 0 0 8px 8px; overflow: hidden; }
.cal-week-days { display: grid; grid-template-columns: repeat(7, 1fr); }
.cal-cell { background: var(--panel); min-height: 26px; padding: 5px 8px 0; }
.cal-cell-empty { background: var(--bg); }
.cal-cell-today { background: #fbf1ec; }
.cal-day-num { font-size: 14px; font-weight: 700; color: var(--text); }
.cal-cell-today .cal-day-num { color: var(--accent); }
.cal-holiday {
  font-size: 10px; font-style: italic; color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cal-bar-row { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; padding: 0 5px; margin-bottom: 3px; }
.cal-bar {
  padding: 3px 7px; font-size: 13px; font-weight: 600; border-radius: 4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;
}
.cal-bar:hover { filter: brightness(0.95); }
.cal-bar-unassigned { font-style: italic; color: var(--red); }
@media (max-width: 760px) {
  .cal-cell { min-height: 22px; }
  .cal-bar { font-size: 11px; }
  .cal-weekday { font-size: 10px; padding: 5px; }
}

.task-review-row {
  display: flex; gap: 8px; align-items: center; margin-bottom: 8px;
  padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.task-review-row .trm-title { flex: 2; min-width: 0; }
.task-review-row .trm-date { flex: 1; min-width: 0; }
.task-review-row .trm-remove {
  flex-shrink: 0; background: none; border: none; color: var(--text-muted);
  cursor: pointer; font-size: 16px; padding: 4px 8px;
}
.task-review-row .trm-remove:hover { color: var(--red); }
.task-review-row .trm-order { width: 20px; color: var(--text-muted); font-size: 12px; flex-shrink: 0; text-align: right; }

@media (max-width: 520px) {
  .task-review-row { flex-wrap: wrap; }
  .task-review-row .trm-title { flex: 1 1 100%; }
}
