The gate reported 14 conflicts across two files. Thirteen were false and it was blind to real ones, and both came from a single cause: it keyed a rule on the last class before the brace, so any qualified rule was filed under its own base rule. A dark-mode override, a .dsm-dark variant and a :host(:fullscreen) rule all merged into the unconditional rules they were meant to override, and the pair was then reported as the file disagreeing with itself. In every case both copies were identical and the code correct. Merging is last-write-wins, so the same bug also HID conflicts. Poisoning .dsm-root inset from 0 to 7px in the shadow copy produced no finding at all, because the fullscreen rule's own inset:0 was merged in afterwards and restored it. A property could be shared, genuinely divergent, and invisible. The key is now the full selector, and at-rules are part of it. The header already claimed media-query variants were treated as distinct rules; nothing implemented it, and PeopleGroupDetail's 18px name with a 16px @media override read as the file contradicting itself when the shadow copy simply has no mobile rule -- which this gate's own contract explicitly allows. At-rule bodies are brace-matched rather than regex-matched, since a lazy pattern stops at the first inner brace. The shadow literal is also sliced AFTER its opening backtick. Slicing from the anchor left useShadowStyles(` at the head of the CSS, which a full-selector pattern absorbs into the first rule -- .dsm-root was captured as "useShadowStyles(` .dsm-root" and silently dropped. That leaves one true finding, and it was real: .action-buttons padding-top was 12px as a Vue child and 4px in a shadow root. Both values date from the initial commit, so there is no later intent to infer; aligned to the shadow copy's 4px because that is the copy that reaches the shipped bundles, so it preserves what users have been seeing rather than changing it. check:synced-css:self-test poisons three properties in memory and requires each to be caught. inset is there deliberately -- it is the one the old implementation missed, so it is the case that proves the fix. Now in build:unlocked, which it could never be while it was red. |
||
|---|---|---|
| .. | ||
| charts | ||
| hints | ||
| legends | ||
| map-controls | ||
| poster | ||
| qa | ||
| search | ||
| tables | ||
| PeopleGroupDetail.vue | ||
| README.md | ||
| ResearchMapFilterPanel.vue | ||
| ResearchMapSideMenu.vue | ||
| SideMenuDrawer.vue | ||
| WARNING.md | ||
library/components/ — shared Vue components
The map UI, built from parameterized pieces every app-profile reuses. Fix one here and every map benefits — never edit a shared component to customize one map.
library/components/
┌───────────────────────────────────────────┐
│ legends/ map-controls/ poster/ │
│ charts/ tables/ │
│ PeopleGroupDetail.vue SideMenuDrawer.vue │
│ ResearchMapFilterPanel.vue …SideMenu.vue │
└───────────────────────────────────────────┘
reused by every app-profile via @map/components/…
legends/,map-controls/,poster/each have their own README.- Every component uses
<script setup>, callsuseShadowStyles(), and reaches stores viainject('mapStore' | 'uiStore' | 'dataStore')— never a direct store import.
Full catalog + conventions:
../../documentation/architecture/components.md ·
per-file roles: ../../documentation/reference.md.