/* Sacred Command Center · projects module styles. Owned by the new-modules agent. Semantic tokens only: no hex, no rgba (tests/static.mjs S-a2).
   No colored side stripes and no status dots: a state is a word, lateness is a crimson icon plus the word (.late), and the one accent
   marks the bar that needs attention. The board and the record page reuse the Leads classes (css/modules/leads.css). */

/* ── Cells ─────────────────────────────────────────────────────────────────────────────── */
.pj-prog { display: inline-flex; align-items: center; gap: var(--s-2); min-width: 0; }
.pj-pct { min-width: 3.2ch; font-weight: 700; color: var(--text); }
.pj-prog .bar { width: 48px; flex: none; }
.module--projects .rp-id { flex: 0 1 17rem; }
.module--projects .rp-facts { flex: 1 1 26rem; gap: var(--s-2) var(--s-4); }
.module--projects .rs-grid:empty { display: none; }
.pj-note { padding: var(--s-1) 0; }
.view:has(.module--projects .rp .lv-main) { height: auto; overflow: visible; display: block; }

/* ── Timeline: one bar per project, start to finish-by ─────────────────────────────────── */
.pj-tl { display: flex; flex-direction: column; gap: var(--s-3); min-width: 0; height: 100%; overflow: auto; padding-bottom: var(--s-3); }
.pj-tl-legend { padding: 0 var(--s-1); }
.pj-tl-grid { display: flex; flex-direction: column; min-width: 44rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); }
.pj-tl-axis, .pj-tl-row { display: grid; grid-template-columns: 15rem minmax(24rem, 1fr) 6.5rem; align-items: center; column-gap: var(--s-3); padding: 0 var(--s-3); }
.pj-tl-axis { position: sticky; top: 0; z-index: 1; min-height: 32px; background: var(--surface); border-bottom: 1px solid var(--line); border-radius: var(--r-card) var(--r-card) 0 0; }
.pj-tl-h { font-size: var(--fs-caption); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-3); }
.pj-tl-row { min-height: calc(var(--row-h) + 8px); border-bottom: 1px solid var(--line); }
.pj-tl-row:last-child { border-bottom: 0; }
.pj-tl-name { display: flex; flex-direction: column; min-width: 0; text-decoration: none; color: var(--text); }
.pj-tl-name b { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pj-tl-name .caption { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pj-tl-row:hover { background: var(--hover); }
.pj-tl-track { position: relative; align-self: stretch; min-width: 0; }
.pj-tl-ticks { min-height: 32px; }
.pj-tick { position: absolute; top: 50%; transform: translate(-50%, -50%); font-size: var(--fs-caption); font-weight: 600; color: var(--text-3); white-space: nowrap; font-variant-numeric: tabular-nums; }
.pj-grid { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--chart-grid); }
.pj-bar { position: absolute; top: 50%; height: 14px; transform: translateY(-50%); overflow: hidden; background: var(--chart-track); box-shadow: inset 0 0 0 1px var(--line-strong); border-radius: var(--r-button); }
.pj-bar-fill { position: absolute; inset: 0 auto 0 0; background: var(--chart-2); }
.pj-bar.is-risk { box-shadow: inset 0 0 0 1px var(--chart-focal); }
.pj-bar.is-risk .pj-bar-fill { background: var(--chart-focal); }
.pj-bar.is-done .pj-bar-fill { background: var(--chart-3); }
.pj-mark { position: absolute; top: 50%; width: 10px; height: 10px; transform: translate(-50%, -50%) rotate(45deg); box-shadow: inset 0 0 0 2px var(--text-2); }
.pj-today { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--text-2); }
.pj-tl-end { text-align: right; white-space: nowrap; }
.pj-tl-undated { display: flex; flex-direction: column; gap: var(--s-2); padding: 0 var(--s-1); }
.pj-tl-undated .chips { list-style: none; margin: 0; padding: 0; }
.pj-tl-list { overflow: auto; height: 100%; }
@media (max-width: 719px) { .pj-tl { height: auto; overflow: visible; } }

/* ── Split by client ───────────────────────────────────────────────────────────────────── */
.pj-split { display: flex; flex-direction: column; gap: var(--s-3); height: 100%; overflow: auto; padding-bottom: var(--s-3); }
.pj-split .ctr .table-wrap { border: 0; border-radius: 0; height: auto; }
@media (max-width: 719px) { .pj-split { height: auto; overflow: visible; } }

/* ── How these are counted ─────────────────────────────────────────────────────────────── */
.hc-list { grid-template-columns: minmax(6.5rem, max-content) minmax(0, 1fr); gap: var(--s-3) var(--s-4); }
.hc-list dd { max-width: var(--measure); color: var(--text-2); }
.hc-list dt { font-weight: 700; color: var(--text); font-size: var(--fs-cell); }
@media (max-width: 519px) { .hc-list { grid-template-columns: minmax(0, 1fr); gap: var(--s-1); } .hc-list dd { margin-bottom: var(--s-2); } }

/* A list over a source that is not there says so in its count line instead of "0 projects". The marker is rendered beside the list while the source answers needs-yes. */
.module:has(> .lv-off-mark) .lv-count, .module:has(.lv-off-mark) .lv-count { font-size: 0; }
.module:has(.lv-off-mark) .lv-count::after { content: "Not connected"; font-size: var(--fs-caption); font-weight: 600; letter-spacing: var(--caption-ls); color: var(--text-3); }

/* On a wide page the list's tools row (Filter, Sort, Columns, the count, the pager) used to share the first three head columns with the title, and four record views and Create make the right column too wide for that: the count and the pager wrapped to two lines.
   The row takes the whole width instead and keeps clear of the Updated line, which sits over its right end. */
@media (min-width: 768px) {
  .module.module--projects:has(.wide-flag.is-wide) .lv-bar:not(.lv-bar--mass), .module.module--productions:has(.wide-flag.is-wide) .lv-bar:not(.lv-bar--mass) { grid-column: 1 / -1; padding-right: 252px; }
  .module.module--projects:has(.wide-flag.is-wide) .page-meta, .module.module--productions:has(.wide-flag.is-wide) .page-meta { position: relative; z-index: 6; }
  .module--projects .lv-count, .module--productions .lv-count, .module--projects .lv-pager, .module--productions .lv-pager { white-space: nowrap; flex-wrap: nowrap; }
}

/* ── Phone ─────────────────────────────────────────────────────────────────────────────── */
/* The record switcher is icon-only except for the view in use (kit.css), so four views fit a phone without hiding the icons. */
.pj-tl-list .row-main { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; text-decoration: none; color: var(--text); }
.pj-tl-list .row-t { text-decoration: none; font-weight: 700; }

/* A record page's primary action can carry a long stage name ("Move to Credentials", "Copy package path"): on the narrowest phones it wraps its words instead of running past the edge. */
@media (max-width: 479px) {
  .module--projects .rp-acts, .module--productions .rp-acts, .module--invoices .rp-acts, .module--documents .rp-acts { flex-wrap: nowrap; min-width: 0; max-width: 100%; }
  .module--projects .rp-acts .btn--primary, .module--productions .rp-acts .btn--primary, .module--invoices .rp-acts .btn--primary, .module--documents .rp-acts .btn--primary { min-width: 0; flex: 0 1 auto; white-space: normal; text-align: left; line-height: 1.25; padding-top: var(--s-2); padding-bottom: var(--s-2); }
}

/* A board card with no badge lets its third line run under the owner mark, so "At risk · 29 points behind" is not cut ("owner" sits on the second line). */
.pj-board .kcard:not(:has(.kcard-badge)) .kcard-next, .inv-board .kcard:not(:has(.kcard-badge)) .kcard-next { grid-column: 1 / -1; }
