diff --git a/frontend/src/v2/__tests__/v2-layout-invariants.test.ts b/frontend/src/v2/__tests__/v2-layout-invariants.test.ts index 734d1ea94..b6b539f85 100644 --- a/frontend/src/v2/__tests__/v2-layout-invariants.test.ts +++ b/frontend/src/v2/__tests__/v2-layout-invariants.test.ts @@ -2086,6 +2086,41 @@ describe('v2 layout invariants (CSS rule presence)', () => { expect(connectorCss).not.toContain('v2-connector-row--dead):not(.v2-connector-row--not-enabled) .v2-connector-row__detail'); }); + it('connector refusal links keep the in-text link treatment in the parsed stylesheet', () => { + const style = document.createElement('style'); + style.textContent = v2; + document.head.appendChild(style); + + try { + const sheet = style.sheet; + expect(sheet).not.toBeNull(); + const rules = Array.from(sheet!.cssRules); + + // This covers links in any refusal slot. Parsing before these assertions + // catches malformed CSS without pinning unrelated stylesheet size/tail. + + const styleRules = rules.filter((rule) => rule.type === CSSRule.STYLE_RULE) as CSSStyleRule[]; + const linkRules = styleRules.filter((rule) => { + const selectors = rule.selectorText.split(',').map((selector) => selector.trim()); + return selectors.includes('.v2-connector-row__refusal a') + && selectors.includes('.v2-connector-aside__refusal a'); + }); + expect(linkRules).toHaveLength(1); + expect(linkRules[0].selectorText.split(',').map((selector) => selector.trim())).toEqual([ + '.v2-connector-row__refusal a', + '.v2-connector-aside__refusal a', + ]); + expect(linkRules[0].style.getPropertyValue('color')).toBe('var(--v2-accent-text)'); + expect(linkRules[0].style.getPropertyValue('text-decoration')).toBe('underline'); + + const resetIndex = styleRules.findIndex((rule) => rule.selectorText === '.v2-root a'); + const linkIndex = styleRules.indexOf(linkRules[0]); + expect(linkIndex).toBeGreaterThan(resetIndex); + } finally { + style.remove(); + } + }); + describe('TASK-122 Phase A — the ruled restyle (Sam, 2026-09-03; spec on TASK-122)', () => { const v2Root = ruleBody(v2, '.v2-root'); diff --git a/frontend/src/v2/v2.css b/frontend/src/v2/v2.css index 03520d6d2..ab1326a4c 100644 --- a/frontend/src/v2/v2.css +++ b/frontend/src/v2/v2.css @@ -10090,6 +10090,8 @@ body.modern-ui.v2-canvas { .v2-connector-code code { overflow-wrap: anywhere; color: var(--v2-on-ink); font-family: var(--v2-font-mono); font-size: 14px; line-height: 20px; } .v2-root button.v2-connector-code__copy { min-height: 30px; padding: 5px 9px; border: 1px solid var(--v2-accent); border-radius: var(--v2-radius-sm); background: var(--v2-accent); color: var(--v2-on-ink); font: 600 12px/16px var(--v2-font); cursor: pointer; } .v2-connector-row__refusal { grid-column: 1 / -1; margin: 10px 0 0; padding: 8px 10px; border: 1px solid var(--v2-border); border-radius: var(--v2-radius-sm); background: var(--v2-surface-tint); color: var(--v2-ink); font-size: 13px; line-height: 18px; overflow-wrap: anywhere; } +.v2-connector-row__refusal a, +.v2-connector-aside__refusal a { color: var(--v2-accent-text); text-decoration: underline; } .v2-connectors__error { padding: 10px 12px; border: 1px solid var(--v2-border); border-radius: var(--v2-radius-sm); color: var(--v2-ink); font-size: 13px; } .v2-connector-aside__note { margin-top: 12px !important; color: var(--v2-text-tertiary) !important; font-size: 12px !important; }