diff --git a/frontend/src/v2/__tests__/v2-layout-invariants.test.ts b/frontend/src/v2/__tests__/v2-layout-invariants.test.ts index f4279325a4..538a86d2d2 100644 --- a/frontend/src/v2/__tests__/v2-layout-invariants.test.ts +++ b/frontend/src/v2/__tests__/v2-layout-invariants.test.ts @@ -5041,16 +5041,28 @@ describe('task priority and lease signals (TASK-443)', () => { expect(badge).toContain('var(--v2-font-mono)'); expect(badge).toContain('border-radius: 4px'); expect(badge).toContain('background: none'); + expect(badge).toContain('color: var(--v2-prio-ink)'); + expect(badge).toContain('border: 1px solid var(--v2-prio-edge)'); + // P0 is the only filled badge: red fill, white label (B-lite, Sam 10-31). const urgent = ruleBody(css, '.v2-board__priority--p0'); - expect(urgent).toContain('border-color: var(--v2-text-primary)'); - expect(urgent).toContain('color: var(--v2-text-primary)'); - expect(urgent).not.toMatch(/background/); + expect(urgent).toContain('background: var(--v2-prio-p0-bg)'); + expect(urgent).toContain('color: var(--v2-prio-p0-fg)'); + // Status and priority colour are tokens, so the D215 colour choice is a value swap. + expect(css).toMatch(/--v2-prio-p0-bg:\s*#b42318/); + expect(css).toMatch(/--v2-prio-p2-fg:\s*#667085/); + expect(css).toMatch(/--v2-status-live:\s*var\(--v2-accent\)/); + expect(ruleBody(css, '.v2-board__priority--p2')).toContain('color: var(--v2-prio-p2-fg)'); + }); + test('blocked is red with a thin edge on blocked cards only', () => { + expect(css).toMatch(/--v2-status-blocked:\s*#d92d20/); + expect(ruleBody(css, '.v2-board__card--blocked')).toContain('box-shadow: inset 3px 0 0 var(--v2-status-blocked-edge)'); + expect(ruleBody(css, '.v2-board__col--blocked .v2-board__col-name')).toContain('color: var(--v2-status-blocked)'); }); test('live, unclaimed and expired ownership retain distinct dots', () => { - expect(ruleBody(css, '.v2-board__owner-dot--live')).toContain('background: var(--v2-accent)'); - expect(ruleBody(css, '.v2-board__owner-dot--not-claimed')).toContain('border: 1px dashed var(--v2-border-strong)'); + expect(ruleBody(css, '.v2-board__owner-dot--live')).toContain('background: var(--v2-status-live)'); + expect(ruleBody(css, '.v2-board__owner-dot--not-claimed')).toContain('border: 1px dashed var(--v2-status-pending)'); const expired = ruleBody(css, '.v2-board__owner-dot--expired'); - expect(expired).toContain('border: 1px solid var(--v2-border-strong)'); + expect(expired).toContain('border: 1px solid var(--v2-status-idle)'); expect(expired).toContain('background: none'); }); }); @@ -5212,3 +5224,26 @@ describe('v2 board on a phone (TASK-576)', () => { expect(page).toContain(''); }); }); + +describe('pod board column scroll (TASK-698)', () => { + const css = read('../v2.css'); + test('the board route scrolls inside its columns, not the page', () => { + // The feature body was the scroller and its legacy wrapper had auto height, so the + // columns' max-height:100% resolved to nothing (85.5x at 1440, measured 12f608b71). + const body = ruleBody(css, '.v2-feature--board .v2-feature__body'); + expect(body).toContain('display: flex'); + expect(body).toContain('overflow: hidden'); + const legacy = ruleBody(css, '.v2-feature--board .v2-feature__legacy'); + expect(legacy).toContain('width: 100%'); + expect(legacy).toContain('min-height: 0'); + expect(legacy).toContain('display: flex'); + expect(ruleBody(css, '.v2-feature--board .v2-board')).toContain('flex: 1 1 auto'); + expect(ruleBody(css, '.v2-board__col')).toContain('overflow-y: auto'); + expect(ruleBody(css, '.v2-board__col')).toContain('max-height: 100%'); + }); + test('a long focus list is bounded so the columns keep room below it', () => { + const focus = ruleBody(css, '.v2-board__focus'); + expect(focus).toContain('max-height: min(35vh, 260px)'); + expect(focus).toContain('overflow-y: auto'); + }); +}); diff --git a/frontend/src/v2/components/V2PodBoard.tsx b/frontend/src/v2/components/V2PodBoard.tsx index f9ac01575e..477e7a54fa 100644 --- a/frontend/src/v2/components/V2PodBoard.tsx +++ b/frontend/src/v2/components/V2PodBoard.tsx @@ -735,7 +735,7 @@ const V2PodBoard: React.FC = () => { {COLUMNS.map((col) => { const items = columnTasks.get(col.key) || []; return ( -
+
{t(col.labelKey)} {items.length} @@ -744,7 +744,7 @@ const V2PodBoard: React.FC = () => {
{t(col.emptyKey)}
)} {items.map((task) => ( -
+