Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
aba871f
Replace native <select> with custom div-based dropdowns for Power BI …
vim-sroberge Mar 11, 2026
fa34d8c
Fix GPU picker scissor test using raw WebGL context
vim-sroberge Mar 17, 2026
c49cdc6
Refactor viewer components to expose API via forwardRef/useImperative…
vim-sroberge Mar 17, 2026
48b9477
Bump version to 1.0.0-alpha.6
vim-sroberge Mar 17, 2026
6049f0b
Add useSubscribe hook and refactor BimTree to forwardRef
vim-sroberge Mar 17, 2026
fcdd681
Update sandbox to use getVim() and add selection logging
vim-sroberge Mar 17, 2026
f60d087
Add elementUniqueId and filterByUniqueId subset support
vim-sroberge Mar 18, 2026
e122b76
Fix flushSync warning by making createViewer async
vim-sroberge Mar 18, 2026
545af9d
Add primitive component library and migrate call sites
vim-sroberge Mar 18, 2026
bb42fb5
Refactor viewer internals: refs, customization, hooks cleanup
vim-sroberge Mar 18, 2026
b63132a
Remove embedded worktree repos from index
vim-sroberge Mar 18, 2026
5319b82
Remove flushSync from createWebglViewer using async callback ref pattern
vim-sroberge Mar 18, 2026
15e91a9
Fix Ultra loading progress fraction and reduce outline thickness default
vim-sroberge Mar 19, 2026
3baee54
Expand generic panel components with new entry types and layout fixes
vim-sroberge Mar 19, 2026
f8625a0
Replace SettingsApi with plain settings objects and add localStorage …
vim-sroberge Mar 19, 2026
0a611fb
Rewrite BIM panel to use generic panel components
vim-sroberge Mar 19, 2026
febcfea
Simplify settings panel using generic entry components
vim-sroberge Mar 19, 2026
0781909
Wire initial settings through hooks and reorganize CSS
vim-sroberge Mar 19, 2026
2ad8d8f
Remove Tailwind CSS dependency
vim-sroberge Mar 20, 2026
07b4566
Fix axes gizmo drag, background color, and ghost opacity rounding
vim-sroberge Mar 20, 2026
878c544
Replace control bar style functions with data-attribute variants
vim-sroberge Mar 20, 2026
4568207
Remove Stack, Group, Divider components and migrate to semantic CSS
vim-sroberge Mar 20, 2026
39ddeb1
Migrate BIM panel to semantic CSS and add empty-search state
vim-sroberge Mar 20, 2026
96e7619
Migrate layout and panel components from Tailwind to semantic CSS
vim-sroberge Mar 20, 2026
3966895
Enhance settings and generic panels with section type and min/max info
vim-sroberge Mar 20, 2026
72049a5
Clean up viewer components and sandbox app
vim-sroberge Mar 20, 2026
60bc1c6
Rewrite style.css with design tokens and semantic CSS classes
vim-sroberge Mar 20, 2026
fd9f679
Add CSS review skill and update Claude settings
vim-sroberge Mar 20, 2026
0523630
Add getElementFromUniqueId, hasGeometry, and onGeometryLoaded
vim-sroberge Mar 20, 2026
19d7a85
Support useOnChange cleanup returns and refresh BIM tree on geometry …
vim-sroberge Mar 20, 2026
8090a46
Clean up sandbox: remove debug code and fix formatting
vim-sroberge Mar 20, 2026
e54269f
fix tree padding
vim-sroberge Mar 20, 2026
4bd935f
Remove StateRef.confirm() — unused after settings refactor
vim-sroberge Mar 23, 2026
defa7d0
Rename ultra renderer backgroundColor to background
vim-sroberge Mar 23, 2026
c78264e
Add reactive UiApi for runtime UI visibility control
vim-sroberge Mar 23, 2026
8d77a05
Update settings defaults and doc comments
vim-sroberge Mar 23, 2026
33365d2
Bump version to 1.0.0-alpha.9 and clean up sandbox
vim-sroberge Mar 23, 2026
a8afdce
Remove debug console.logs, TODOs, and unused params in ultra layer
vim-sroberge Mar 24, 2026
d3f9855
Fix camera lerp onProgress firing after completion
vim-sroberge Mar 24, 2026
758905a
Fix selection overlay opacity and enabled condition
vim-sroberge Mar 24, 2026
0c2e23c
Toggle axes gizmo canvas visibility via uiState
vim-sroberge Mar 24, 2026
e84c988
Bump version to 1.0.0-alpha.12 and add sandbox test helpers
vim-sroberge Mar 24, 2026
d524d98
Remove VimSettings.transparency — unused dead code
vim-sroberge Mar 24, 2026
d281600
Rename IsolationSettings.transparency to showTransparent
vim-sroberge Mar 24, 2026
061096c
Add configurable transparentOpacity to materials API
vim-sroberge Mar 24, 2026
003c8c1
Make vim.load() idempotent by clearing before rebuilding
vim-sroberge Mar 24, 2026
7b41a4b
Update sandbox to test double-load idempotency
vim-sroberge Mar 24, 2026
7462004
Remove react-tooltip dependency
vim-sroberge Mar 24, 2026
9a300df
Add portal-based TooltipZone component
vim-sroberge Mar 24, 2026
d30f96f
Add data-tip tooltips and reactive tips across all UI elements
vim-sroberge Mar 24, 2026
da13543
Replace re-resizable with native drag handle for side panel
vim-sroberge Mar 24, 2026
d07e170
Replace react-contextmenu with portal-based context menu
vim-sroberge Mar 24, 2026
e44d457
Remove re-resizable, react-contextmenu, ste-events deps and add --fon…
vim-sroberge Mar 24, 2026
9138983
Add headless-tree BIM tree implementation
vim-sroberge Mar 24, 2026
0d1f47f
Rewrite BIM tree: clean data model, extracted hooks, virtualization
vim-sroberge Mar 25, 2026
e676342
Cache BIM parameter columns for fast getBimParameters() lookups
vim-sroberge Mar 25, 2026
efb8149
Debounce BIM info panel updates and add selected+hover tree color
vim-sroberge Mar 25, 2026
ca87980
Add @tanstack/react-virtual, open local file button in sandbox
vim-sroberge Mar 25, 2026
69f97e3
Polish BIM tree: fix getRange perf, scroll reliability, search crash
vim-sroberge Mar 25, 2026
e829aa4
Enable prewarmBim in sandbox and unload existing vims on local file open
vim-sroberge Mar 25, 2026
b86384c
Upgrade to React 19 and remove react-complex-tree
vim-sroberge Mar 25, 2026
0363e82
Update all dependencies to latest compatible versions
vim-sroberge Mar 25, 2026
98cb070
Remove ESLint, Prettier, and all lint/format tooling
vim-sroberge Mar 25, 2026
eebefca
Update vim-format to 1.0.16-dev.5
vim-sroberge Mar 25, 2026
b8d0c85
Remove @tailwind directives and update CLAUDE.md for current stack
vim-sroberge Mar 25, 2026
e6a86aa
Add exports field to package.json
vim-sroberge Mar 25, 2026
b74a0de
Replace deprecated MutableRefObject with RefObject for React 19
vim-sroberge Mar 26, 2026
5472c72
Refactor isolation: extract render settings from IsolationApi
vim-sroberge Mar 26, 2026
6774ddc
Wire render settings into viewer components and settings panels
vim-sroberge Mar 26, 2026
1f43073
Bump version to 1.0.0-alpha.14 and misc fixes
vim-sroberge Mar 26, 2026
42f2455
Fix selection fill mode, render settings, and vite externals
vim-sroberge Mar 26, 2026
25b4f5f
Reduce redundant renders on selection change
vim-sroberge Mar 26, 2026
bc6d5fe
Pre-index family elements and parameters for instant getBimParameters
vim-sroberge Mar 26, 2026
c8e6b53
Remove selection performance timing instrumentation
vim-sroberge Mar 26, 2026
3703942
Bump version to 1.0.0-beta.1 and add release notes
vim-sroberge Mar 26, 2026
3907eec
Add migration guide from 0.5 to 1.0.0-beta.1
vim-sroberge Mar 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"permissions": {
"allow": [
"Bash(npm run:*)",
"Skill(review-react)",
"Skill(review-react:*)",
"Bash(python3 reorganize_css.py)",
"Bash(find d:DriveVimvim-websrc -type f \\\\\\(-name *.css -o -name *.scss \\\\\\))",
"Bash(npx tsc:*)",
"Bash(npm ls:*)",
"Bash(npm view:*)",
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(d.get\\(''''homepage'''',''''no homepage''''\\)\\)\")",
"Bash(npm search:*)",
"Bash(python3 -c \":*)",
"Bash(npm install:*)",
"Bash(npm uninstall:*)",
"Bash(npm outdated:*)",
"Bash(node -e \"const vf = require\\(''vim-format''\\); console.log\\(''Import OK''\\); console.log\\(''Exports:'', Object.keys\\(vf\\).slice\\(0, 10\\).join\\('', ''\\), ''...''\\)\")",
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(''''main:'''', d.get\\(''''main''''\\)\\); print\\(''''module:'''', d.get\\(''''module''''\\)\\); print\\(''''types:'''', d.get\\(''''types''''\\)\\); print\\(''''exports:'''', json.dumps\\(d.get\\(''''exports'''',''''none''''\\), indent=2\\)\\)\")",
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(''''type:'''', d.get\\(''''type''''\\)\\); print\\(''''module:'''', d.get\\(''''module''''\\)\\); print\\(''''main:'''', d.get\\(''''main''''\\)\\); print\\(''''types:'''', d.get\\(''''types''''\\)\\)\")"
],
"additionalDirectories": [
"d:\\Drive\\Vim\\vim-web\\.claude\\skills"
]
}
}
284 changes: 284 additions & 0 deletions .claude/skills/css/skill.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
---
name: css
description: CSS best practices reference for writing and reviewing CSS/Tailwind. Covers general patterns, AI-friendliness, modern features, performance, accessibility, and this project's conventions. Use when writing, reviewing, or refactoring CSS.
allowed-tools: Read, Grep, Glob, Edit, Write, Agent
---

# CSS Best Practices

Reference guide for writing, reviewing, and refactoring CSS in this project. Apply these rules when touching `style.css`, Tailwind classes in TSX files, or CSS custom properties.

---

## Project-Specific Conventions

This project uses **Tailwind CSS v3** with the `vc-` prefix, CSS custom properties with `--c-` prefix, and a single `style.css` file for global styles + tokens.

> **Full styling reference**: See [STYLING.md](../../docs/STYLING.md) for the complete token system, panel architecture, `vim-hidden` pattern, third-party override conventions, and code style rules.

### Token Hierarchy
```
Primitives (--c-primary, --c-dark-gray, --gap-xs, --z-ui …)
→ used directly in style.css rules and Tailwind config
```

### Token Rules
- All Tailwind classes MUST use the `vc-` prefix: `vc-flex`, `vc-p-4`, `hover:vc-bg-blue-500`
- Never mix prefixed and non-prefixed Tailwind classes
- CSS custom properties use `--c-` prefix for colors: `--c-primary`, `--c-dark-gray-cool`
- Responsive/state variants go before the prefix: `sm:vc-flex`, `hover:vc-opacity-100`
- Inline Tailwind classes in TSX are preferred over @apply for component-specific styles
- Extract React components instead of creating @apply abstractions
- **Zero values**: always bare `0`, never `0px` — the unit is ignored on zero and `0px` is inconsistent
- **Gap values**: use `var(--gap-xs)` (4px) or `var(--gap-sm)` (10px) — never raw `4px`, `8px`, `0.25rem`, `0.5rem`
- **Magic numbers**: add an inline comment when a value isn't self-evident (e.g. `/* chevron size */`, `/* 33% label / 67% value split */`)

---

## 1. AI-Friendly CSS Patterns

LLMs cannot render CSS — they infer visual outcomes. Structure CSS to minimize ambiguity.

### Do
- **Colocate styles with components** — Tailwind inline classes keep full context in one file
- **Use flat, single-class selectors** — each class does one thing, no cascade surprises
- **Use constrained vocabularies** — Tailwind utilities are a predictable API
- **Make cascade explicit** — use `@layer` declarations to spell out priority order
- **One styling approach per component** — don't mix inline styles, CSS classes, and Tailwind
- **Use semantic token names** — `--c-primary` not `--c-blue-hex`

### Don't
- **Rely on implicit inheritance chains** — `.form .input .label` requires tracing up the DOM
- **Use ambiguous class names** — `.container`, `.wrapper`, `.inner` mean nothing to an LLM
- **Scatter related styles across files** — forces massive context to reason about a single component
- **Use deeply nested selectors** — `.a .b .c .d .e` is unpredictable

### Why This Matters
- Utility-first is the most AI-friendly approach: full context in one file, constrained vocabulary, no cascade
- CSS Modules are second-best: scoped by default, standard CSS syntax, no global side effects
- Global CSS files are worst: require cross-file context, implicit cascade, naming ambiguity

---

## 2. Specificity Management

### Cascade Layers (`@layer`)
Layers define explicit precedence that overrides specificity entirely.

```css
@layer reset, base, tokens, components, utilities, overrides;

@layer components {
.card { padding: 1rem; }
}
@layer utilities {
.hidden { display: none; } /* always beats .card even though same specificity */
}
```

### Rules
- Keep all selectors at the same specificity level (single class = `0,1,0`)
- Never use IDs for styling
- Never use `!important` except in utility layers (and even then, sparingly)
- Avoid deeply nested selectors — if you need nesting, limit to 2–3 levels max

---

## 3. CSS Custom Properties

### Three-Tier Token Pattern
```css
/* Tier 1: Primitive tokens */
:root { --color-blue-600: #0052CC; }

/* Tier 2: Semantic tokens */
:root { --c-interactive: var(--color-blue-600); }

/* Tier 3: Component tokens (private, --_ prefix) */
.button { --_button-bg: var(--c-interactive); background: var(--_button-bg); }
```

### Rules
- Never use raw hex/rgb values in component CSS — always go through tokens
- Set at `:root` for global scope, on selectors for scoped overrides
- Use `--_` prefix for private/internal component tokens
- Theme switching should only redefine primitive tokens

---

## 4. Layout

### Grid vs Flexbox
- **Grid**: page/section-level 2D layouts (dashboards, page structures)
- **Flexbox**: component-level 1D alignment (toolbars, button groups, centering)
- Combine them: Grid for structure, Flexbox inside grid cells for alignment

### Responsive Patterns
```css
/* Fluid typography */
font-size: clamp(1rem, 2vw + 0.5rem, 1.5rem);

/* Breakpoint-less grid */
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));

/* Container queries > media queries for components */
.card-container { container-type: inline-size; }
@container (min-width: 400px) {
.card { display: grid; grid-template-columns: 1fr 2fr; }
}
```

### Logical Properties
Prefer `margin-inline`, `padding-block` over directional properties for i18n support.

---

## 5. Performance

### Critical Rules
- **Animate only compositor properties**: `transform`, `opacity`, `filter`, `clip-path` — GPU-accelerated, no layout/paint
- **Never animate**: `width`, `height`, `margin`, `padding`, `top`, `left` — trigger full layout recalculation
- **Use `contain`** on independent sections:
```css
.sidebar { contain: layout; } /* 50-70% layout calc improvement */
.card { contain: paint; } /* reduces paint areas up to 80% */
.widget { contain: content; } /* layout + paint */
```
- **Use `will-change` sparingly** — promotes to GPU layer, remove after animation completes
- **Avoid layout thrashing** in JS — batch DOM reads before writes

### Animation Guidelines
- CSS transitions/animations over JavaScript when possible
- Keep animations 200–500ms for micro-interactions
- Use `ease-out` for entries, `ease-in` for exits
- Always provide `prefers-reduced-motion` alternatives

---

## 6. Accessibility

### Focus
```css
:focus-visible {
outline: 2px solid var(--c-primary);
outline-offset: 2px;
}
:focus:not(:focus-visible) {
outline: none;
}
```

### Motion
```css
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
```

### General
- Minimum touch target: 44x44px
- Use `rem`/`em` for font sizes, not `px`
- Color contrast: WCAG AA = 4.5:1 for text, 3:1 for large text
- Focus indicators need 3:1 contrast against background

---

## 7. Dark Mode

### Recommended: Data Attribute + CSS Variables
```css
:root, [data-theme="light"] { --c-bg: #ffffff; --c-text: #111; }
[data-theme="dark"] { --c-bg: #111; --c-text: #eee; }
```

### Rules
- Never mix hardcoded colors with tokens — use variables everywhere
- Set `color-scheme: light dark` for native element adaptation (scrollbars, form inputs)
- The new `light-dark()` function is another option:
```css
:root { color-scheme: light dark; }
body { background: light-dark(#fff, #111); }
```

---

## 8. Modern CSS Features to Adopt

### Container Queries (90%+ support)
Component-level responsiveness based on container width, not viewport.
```css
.panel { container-type: inline-size; }
@container (min-width: 400px) { .panel-content { flex-direction: row; } }
```

### `:has()` Selector (95%+ support)
Style parents based on child state — replaces many JS-driven conditional classes.
```css
.form-group:has(:focus-visible) { outline: 2px solid var(--c-primary); }
label:has(input:checked) { font-weight: bold; }
```

### Native CSS Nesting (96%+ support)
```css
.card {
padding: 1rem;
& .title { font-size: 1.25rem; }
&:hover { box-shadow: 0 4px 12px rgb(0 0 0 / 0.1); }
@media (min-width: 768px) { padding: 2rem; }
}
```
- `&` is mandatory (unlike Sass bare nesting)
- No suffix concatenation (`&-modifier` doesn't work)
- Limit to 2–3 levels

### `color-mix()` (92%+ support)
Runtime color manipulation without preprocessors.
```css
.button:hover { background: color-mix(in oklch, var(--c-primary) 80%, white); }
```

### Cascade Layers (all modern browsers)
See section 2 above.

### Subgrid (97%+ support)
Align children across sibling grid items (e.g., card grids with aligned titles/footers).

---

## 9. Tailwind-Specific Best Practices

### @apply vs Inline
- **Prefer inline classes** in TSX — keeps context colocated, no file switching, no naming
- **@apply only for**: tiny, highly-reused patterns like input resets, AND only when component extraction feels too heavy
- **In React**: extract a component (`<Button>`) over creating a `.btn` @apply class

### Class Organization in TSX
Group logically: layout → sizing → spacing → typography → colors → effects
```tsx
className="vc-flex vc-items-center vc-gap-2 vc-px-4 vc-py-2 vc-text-sm vc-text-white vc-bg-blue-600 vc-rounded hover:vc-bg-blue-700"
```

### Prefix Consistency
- Every Tailwind class must have `vc-` prefix — no exceptions
- Variants go before prefix: `sm:vc-flex`, `dark:vc-bg-gray-900`, `group-hover:vc-opacity-100`
- Use complete class strings in markup for PurgeCSS to detect them — never construct class names dynamically with string interpolation

---

## 10. Review Checklist

When reviewing CSS changes, check for:

1. **Specificity conflicts** — are new selectors at the same specificity level as existing ones?
2. **Unused styles** — did the change orphan any CSS rules?
3. **Token usage** — are raw color/spacing values used instead of tokens?
4. **Prefix compliance** — are all Tailwind classes using `vc-`?
5. **Performance** — are `width`/`height`/`margin` being animated?
6. **Accessibility** — do interactive elements have focus styles? Touch targets >= 44px?
7. **Reduced motion** — do new animations respect `prefers-reduced-motion`?
8. **Cascade safety** — could the new rule unintentionally affect other components?
9. **AI friendliness** — are styles colocated? Are selectors flat and unambiguous?
10. **Consistency** — does the pattern match existing conventions in the codebase?
41 changes: 0 additions & 41 deletions .eslintrc.js

This file was deleted.

2 changes: 0 additions & 2 deletions .prettierignore

This file was deleted.

Loading