Architecture - create a solid-style package
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 146
- Forks
- 21
- PR merge metrics
- No merged PRs in 30d
Description
solid-style Package - Implementation Plan
Version: 1.0
Date: January 20, 2026
Status: Proposal
Executive Summary
Create a new solid-style package to centralize all styling and theming for the SolidOS ecosystem. This package will be a foundational dependency alongside rdflib and solid-logic, providing CSS variables, themes, and utilities to all packages.
Key Benefits:
- Single source of truth for styling
- Independent versioning from solid-ui
- Testable in isolation
- Reusable across all panes and apps
- Future-ready for Phase 2 CSS architecture
1. Package Architecture
1.1 Repository Structure
solid-style/
├── package.json
├── README.md
├── LICENSE.md
├── CHANGELOG.md
├── .gitignore
├── .npmignore
├── babel.config.mjs
├── webpack.config.mjs
├── tsconfig.json
│
├── src/
│ ├── index.ts # Main entry point
│ ├── themeLoader.js # Dynamic theme loader (from solid-ui)
│ │
│ ├── themes/
│ │ ├── foundation/
│ │ │ ├── variables.css # Base CSS variables
│ │ │ └── accessibility.css # WCAG compliance styles
│ │ │
│ │ └── presets/
│ │ ├── classic.css # Default SolidOS theme
│ │ ├── default.css # Modern purple gradient
│ │ ├── wave.css # Blue wave theme
│ │ ├── telegram.css # Telegram-inspired
│ │ └── signal.css # Signal-inspired
│ │
│ └── utilities/ # Future: Phase 2 utility classes
│ ├── layout.css
│ ├── spacing.css
│ ├── typography.css
│ └── index.css
│
├── dist/ # Build output
│ ├── solid-style.js # UMD bundle
│ ├── solid-style.min.js # Minified UMD
│ ├── solid-style.esm.js # ES module
│ ├── solid-style.esm.min.js # Minified ES module
│ ├── theme-variables.css # Flattened foundation
│ ├── theme-accessibility.css # Flattened foundation
│ ├── theme-classic.css # Flattened presets
│ ├── theme-default.css
│ ├── theme-wave.css
│ ├── theme-telegram.css
│ └── theme-signal.css
│
└── test/
├── themeLoader.test.js
└── themes/
└── variables.test.js
1.2 Package Metadata
package.json:
{
"name": "solid-style",
"version": "1.0.0",
"description": "Styling and theming system for SolidOS",
"main": "dist/solid-style.js",
"module": "dist/solid-style.esm.js",
"types": "dist/index.d.ts",
"files": [
"dist/",
"README.md",
"LICENSE.md"
],
"sideEffects": [
"*.css"
],
"exports": {
".": {
"import": "./dist/solid-style.esm.js",
"require": "./dist/solid-style.js",
"types": "./dist/index.d.ts"
},
"./themes/*": "./dist/theme-*.css",
"./package.json": "./package.json"
},
"keywords": [
"solid",
"solidos",
"css",
"themes",
"styling",
"wcag",
"accessibility"
],
"peerDependencies": {},
"devDependencies": {
"@babel/cli": "^7.28.0",
"@babel/core": "^7.28.0",
"copy-webpack-plugin": "^13.0.0",
"css-loader": "^7.1.2",
"jest": "^30.0.0",
"typescript": "^5.9.2",
"webpack": "^5.101.0",
"webpack-cli": "^6.0.1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/solidos/solid-style.git"
},
"bugs": {
"url": "https://github.com/solidos/solid-style/issues"
},
"homepage": "https://github.com/solidos/solid-style",
"license": "MIT"
}
2. CSS Variable Naming Convention
2.1 Adopt mashlib newStyle Convention
Decision: Use mashlib's --color-* / --spacing-* convention as the standard.
Rationale:
- More semantic than
--sui-*prefix - Already implemented in mashlib newStyle and profile-pane html5
- Clearer for developers (e.g.,
--color-primaryvs--sui-primary) - Aligns with CSS custom property best practices
2.2 Variable Categories
/* Colors */
--color-primary
--color-secondary
--color-accent
--color-background
--color-text
--color-text-secondary
--color-border
--color-error
--color-success
--color-warning
/* Spacing */
--spacing-xs
--spacing-sm
--spacing-md
--spacing-lg
--spacing-xl
--spacing-2xl
/* Typography */
--font-family-base
--font-family-mono
--font-size-base
--font-size-sm
--font-size-lg
--line-height-base
/* Layout */
--border-radius-base
--border-width-thin
--box-shadow
--max-width-readable
/* Accessibility */
--min-touch-target
--focus-ring-width
--animation-duration
2.3 Backward Compatibility
For Phase 1, provide aliases in solid-ui:
/* solid-ui/src/index.css or compatibility layer */
:root {
/* Aliases for backward compatibility */
--sui-primary: var(--color-primary);
--sui-bg: var(--color-background);
--sui-text: var(--color-text);
--sui-space-md: var(--spacing-md);
/* ... etc */
}
This allows existing code using --sui-* to continue working during migration.
3. Migration Strategy
3.1 Phase 1: Create Package (Week 1-2)
Actions:
- Create GitHub repository:
github.com/solidos/solid-style - Copy theme files from solid-ui:
src/themeLoader.js→solid-style/src/themeLoader.jssrc/themes/→solid-style/src/themes/
- Update
themeLoader.js:- Change
STORAGE_KEYto'solid-style-theme' - Update script detection to look for
solid-style.js
- Change
- Set up build configuration:
- Webpack config for UMD + ESM bundles
- CopyPlugin for flattening theme CSS files
- TypeScript declarations
- Write initial tests
- Publish
solid-style@1.0.0to npm
Deliverables:
- ✅ Published npm package:
solid-style@1.0.0 - ✅ GitHub repository with CI/CD
- ✅ README with usage examples
- ✅ Working theme loader and 5 themes
3.2 Phase 2: Update solid-ui (Week 2-3)
Actions:
- Add
solid-styleas dependency insolid-ui/package.json - Remove theme files from solid-ui:
- Delete
src/themeLoader.js - Delete
src/themes/
- Delete
- Update
solid-ui/src/index.ts:import { themeLoader } from 'solid-style' export const UI = { // ... existing exports themeLoader // Re-export for compatibility } - Update webpack config to remove theme file copying
- Add CSS compatibility layer with
--sui-*aliases - Update tests to import from
solid-style - Publish
solid-ui@3.1.0(minor bump - additive change)
Breaking Changes: None (re-exports maintain compatibility)
Deliverables:
- ✅ solid-ui@3.1.0 depends on solid-style
- ✅ All tests passing
- ✅ Theme loader still accessible via
UI.themeLoader
3.3 Phase 3: Update Panes (Week 3-4)
Actions:
- Update each pane's
package.json:{ "peerDependencies": { "solid-style": "^1.0.0" } } - For panes using themes in tests/dev:
import { themeLoader } from 'solid-style' // or import 'solid-style/dist/theme-classic.css' - Update profile-pane html5 to use
solid-stylevariables directly - Publish updated pane versions
Panes to Update:
- chat-pane
- profile-pane
- folder-pane
- source-pane
- contacts-pane
- issue-pane
- meeting-pane
- activitystreams-pane
Deliverables:
- ✅ All panes declare solid-style peer dependency
- ✅ Tests can load themes independently
3.4 Phase 4: Update solid-panes (Week 4)
Actions:
- Add
solid-styleto dependencies - Update aggregated exports if needed
- Update tests
- Publish
solid-panes@4.1.0
Deliverables:
- ✅ solid-panes@4.1.0 with solid-style dependency
3.5 Phase 5: Update mashlib (Week 4-5)
Actions:
- Add
solid-styleto dependencies - Update
src/index.ts:import { themeLoader } from 'solid-style' // Auto-detect base path if (!global.solid) global.solid = {} const scripts = document.getElementsByTagName('script') for (const script of scripts) { if (script.src && script.src.includes('solid-style')) { global.solid.basePath = script.src.substring(0, script.src.lastIndexOf('/') + 1) break } } // Initialize theme system await themeLoader.init() - Update webpack to copy solid-style themes
- Remove custom mashlib theme code if superseded
- Publish
mashlib@2.1.0
Deliverables:
- ✅ mashlib@2.1.0 uses solid-style
- ✅ Themes work at any URL path
4. Dependency Graph
4.1 Current Architecture
rdflib (standalone)
↓
solid-logic (depends: rdflib)
↓
solid-ui (depends: solid-logic, rdflib)
├── themeLoader ❌ (embedded)
└── themes/ ❌ (embedded)
↓
panes (depend: solid-ui, solid-logic, rdflib)
↓
mashlib (depends: solid-ui, solid-panes, solid-logic, rdflib)
4.2 New Architecture
rdflib (standalone)
↓
solid-logic (depends: rdflib)
↓
solid-style (standalone) ✨ NEW
├── themeLoader.js
└── themes/
↓
solid-ui (depends: solid-logic, rdflib, solid-style)
↓
panes (depend: solid-ui, solid-logic, rdflib, solid-style)
↓
mashlib (depends: solid-ui, solid-panes, solid-logic, rdflib, solid-style)
4.3 Benefits
- Parallel Development: solid-style can be updated independently
- Smaller Bundles: Apps only needing themes don't need full solid-ui
- Testing: Each package tests themes in isolation
- Reusability: Browser apps can use solid-style directly
5. themeLoader API
5.1 Current API (solid-ui)
import { themeLoader } from 'solid-ui'
// Initialize (auto-runs on load, but can be called manually)
await themeLoader.init()
// Get available themes
const themes = themeLoader.getAvailableThemes()
// Returns: [{ name: 'classic', label: 'Classic' }, ...]
// Get current theme
const current = themeLoader.getCurrentTheme() // 'classic'
// Load a theme
await themeLoader.loadTheme('wave')
// Listen for theme changes
window.addEventListener('solid-ui-theme-change', (e) => {
console.log('Theme changed to:', e.detail.theme)
})
5.2 New API (solid-style)
Same interface, new event name:
import { themeLoader } from 'solid-style'
// Same methods
await themeLoader.init()
const themes = themeLoader.getAvailableThemes()
const current = themeLoader.getCurrentTheme()
await themeLoader.loadTheme('wave')
// New event name
window.addEventListener('solid-style-theme-change', (e) => {
console.log('Theme changed to:', e.detail.theme)
})
5.3 Path Resolution
Priority order in resolveThemePath():
__webpack_public_path__(if set by bundler)window.solid.basePath(set by mashlib)- Script tag detection (
solid-style.jslocation) - Origin root fallback
Configuration option for multi-tenant:
// Set before themeLoader.init()
window.solid = window.solid || {}
window.solid.basePath = 'https://localhost:3000/alice/'
6. CSS Variables - Complete List
6.1 Foundation Variables (from mashlib light.css)
:root {
/* === PRIMARY COLORS === */
--color-primary: #7C4DFF;
--color-primary-alpha: rgba(124, 77, 255, 0.25);
--color-primary-alpha-light: rgba(124, 77, 255, 0.1);
--color-secondary: #0077B6;
--color-accent: #FFD600;
/* === BACKGROUNDS === */
--color-background: white;
--color-card-bg: #FFFFFF;
--color-section-bg: #F5F5F5;
--color-zebra-stripe: rgba(0, 0, 0, 0.02);
--color-hover-bg: rgba(0, 0, 0, 0.05);
/* === TEXT === */
--color-text: #1A1A1A;
--color-text-secondary: #666;
--color-text-light: #aaa;
--color-text-muted: #444;
--color-text-link: #3B5998;
--color-text-link-visited: #3B5998;
--color-text-link-hover: #3B5998;
/* === BORDERS === */
--color-border: #ccc;
--color-border-dark: #777;
--color-border-darker: #444;
--color-border-light: #aaa;
--color-border-pale: #eee;
/* === STATUS === */
--color-error: #B00020;
--color-success: #00C853;
--color-success-alpha: rgba(0, 200, 83, 0.1);
--color-warning: red;
--color-selected-bg: #8F3;
/* === SPACING === */
--spacing-tiny: 0.05em;
--spacing-small: 0.1em;
--spacing-xs: 0.5rem;
--spacing-sm: 0.75em;
--spacing-base: 0.5em;
--spacing-md: 1em;
--spacing-lg: 1.5em;
--spacing-xl: 2em;
--spacing-2xl: 3em;
/* === TYPOGRAPHY === */
--font-family-base: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--font-family-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--font-size-base: 100%;
--font-size-sm: 0.875rem;
--font-size-lg: 1.125rem;
--font-size-xl: 1.25rem;
--font-size-strong: 120%;
--font-weight-normal: normal;
--font-weight-bold: bold;
--line-height-base: 1.5;
--line-height-tight: 1.4;
--line-height-loose: 1.6;
--letter-spacing-wide: 0.025em;
/* === LAYOUT === */
--border-width-thin: 1px;
--border-width-medium: 2px;
--border-width-bold: 5px;
--border-radius-base: 0.5em;
--border-radius-lg: 0.75em;
--border-radius-full: 1em;
--box-shadow: 0 2px 8px rgba(124,77,255,0.08);
--box-shadow-sm: 0 1px 4px rgba(124,77,255,0.12);
--max-width-readable: 65ch;
--max-width-readable-wide: 70ch;
/* === ACCESSIBILITY === */
--min-touch-target: 44px;
--focus-ring-width: 2px;
--focus-indicator-width: 3px;
--animation-duration: 0.2s;
--animation-duration-slow: 0.3s;
--min-font-size: 14px;
--min-line-height: 1.4;
--high-contrast-ratio: 7:1;
--outline-offset-sm: 2px;
--opacity-disabled: 0.6;
/* === Z-INDEX === */
--z-index-modal: 9999;
--z-index-skip-links: 1000;
/* === OVERLAY === */
--overlay-bg: rgba(0, 0, 0, 0.5);
}
6.2 solid-ui Compatibility Aliases
/* solid-ui/src/compatibility.css */
:root {
/* Map new names to old names for backward compatibility */
--sui-primary: var(--color-primary);
--sui-primary-dark: var(--color-primary);
--sui-primary-light: var(--color-primary-alpha-light);
--sui-accent: var(--color-accent);
--sui-bg: var(--color-background);
--sui-bg-panel: var(--color-card-bg);
--sui-bg-header: var(--color-background);
--sui-bg-hover: var(--color-hover-bg);
--sui-text: var(--color-text);
--sui-text-secondary: var(--color-text-secondary);
--sui-text-muted: var(--color-text-muted);
--sui-text-link: var(--color-text-link);
--sui-border-color: var(--color-border);
--sui-border-color-dark: var(--color-border-dark);
--sui-border-width: var(--border-width-thin);
--sui-border-radius: var(--border-radius-base);
--sui-border-radius-sm: var(--border-radius-base);
--sui-border-radius-lg: var(--border-radius-lg);
--sui-shadow: var(--box-shadow);
--sui-shadow-sm: var(--box-shadow-sm);
--sui-space-xs: var(--spacing-xs);
--sui-space-sm: var(--spacing-sm);
--sui-space-md: var(--spacing-md);
--sui-space-lg: var(--spacing-lg);
--sui-space-xl: var(--spacing-xl);
--sui-space-2xl: var(--spacing-2xl);
--sui-font-family: var(--font-family-base);
--sui-font-size-base: var(--font-size-base);
--sui-font-size-sm: var(--font-size-sm);
--sui-font-size-lg: var(--font-size-lg);
--sui-line-height: var(--line-height-base);
--sui-line-height-tight: var(--line-height-tight);
--sui-success: var(--color-success);
--sui-warning: var(--color-warning);
--sui-error: var(--color-error);
}
7. Testing Strategy
7.1 Unit Tests
// test/themeLoader.test.js
import { themeLoader } from '../src/themeLoader'
describe('ThemeLoader', () => {
test('initializes with default theme', async () => {
await themeLoader.init()
expect(themeLoader.getCurrentTheme()).toBe('classic')
})
test('loads available themes', () => {
const themes = themeLoader.getAvailableThemes()
expect(themes).toHaveLength(5)
expect(themes[0]).toHaveProperty('name')
expect(themes[0]).toHaveProperty('label')
})
test('switches themes', async () => {
await themeLoader.loadTheme('wave')
expect(themeLoader.getCurrentTheme()).toBe('wave')
})
test('persists theme to localStorage', async () => {
await themeLoader.loadTheme('telegram')
const saved = localStorage.getItem('solid-style-theme')
expect(saved).toBe('telegram')
})
})
7.2 Integration Tests
Test in each consuming package:
// solid-ui/test/integration/themes.test.js
import { UI } from '../../src'
describe('solid-ui theme integration', () => {
test('themeLoader is available via UI', () => {
expect(UI.themeLoader).toBeDefined()
expect(UI.themeLoader.getAvailableThemes).toBeDefined()
})
test('CSS variables are applied', async () => {
await UI.themeLoader.init()
const primary = getComputedStyle(document.documentElement)
.getPropertyValue('--color-primary')
expect(primary).toBeTruthy()
})
})
7.3 Visual Regression Tests
Consider adding visual tests for themes:
// test/visual/themes.visual.test.js
import { themeLoader } from '../src/themeLoader'
import { toMatchImageSnapshot } from 'jest-image-snapshot'
expect.extend({ toMatchImageSnapshot })
describe('Theme Visual Tests', () => {
test('classic theme snapshot', async () => {
await themeLoader.loadTheme('classic')
const screenshot = await page.screenshot()
expect(screenshot).toMatchImageSnapshot()
})
})
8. Documentation
8.1 README.md Structure
# solid-style
> Styling and theming system for SolidOS
## Installation
npm install solid-style
## Quick Start
### Basic Usage
import { themeLoader } from 'solid-style'
await themeLoader.init()
### Direct CSS Import
import 'solid-style/dist/theme-classic.css'
## Available Themes
- Classic - Default SolidOS theme
- Default - Modern purple gradient
- Wave - Blue wave theme
- Telegram - Telegram-inspired
- Signal - Signal-inspired
## API Reference
[Full API docs]
## CSS Variables
[Complete variable list]
## Configuration
[Multi-tenant setup]
## Contributing
[Guidelines]
8.2 Migration Guide
Create MIGRATION.md for package maintainers:
# Migration Guide: solid-ui themes → solid-style
## For Pane Developers
1. Add peer dependency:
"peerDependencies": {
"solid-style": "^1.0.0"
}
2. Import themes in tests:
import { themeLoader } from 'solid-style'
3. Update CSS variable names (optional):
--sui-primary → --color-primary
## For solid-ui Users
No changes required! solid-ui re-exports themeLoader.
## Breaking Changes
None - fully backward compatible.
9. Publishing & Release
9.1 Version Strategy
- solid-style: Start at
1.0.0 - solid-ui: Bump to
3.1.0(minor - additive) - panes: Bump patch versions (e.g.,
3.0.1) - solid-panes: Bump to
4.1.0(minor) - mashlib: Bump to
2.1.0(minor)
9.2 Publishing Order
solid-style@1.0.0(standalone, no deps)solid-ui@3.1.0(depends on solid-style)- Individual panes (with solid-style peer dep)
solid-panes@4.1.0(aggregates updated panes)mashlib@2.1.0(depends on everything)
9.3 Rollback Plan
If issues arise:
- solid-ui can temporarily vendor themes again
- Packages can pin to old versions
- No breaking changes allow gradual migration
10. Future Enhancements
10.1 Phase 2: Utility Classes
Add utility classes for rapid development:
/* solid-style/src/utilities/ */
.ss-flex { display: flex; }
.ss-grid { display: grid; }
.ss-gap-md { gap: var(--spacing-md); }
.ss-text-primary { color: var(--color-primary); }
.ss-bg-card { background: var(--color-card-bg); }
10.2 Theme Builder
Web-based theme customizer:
- Visual editor for CSS variables
- Preview changes live
- Export custom theme CSS
- Share theme configurations
10.3 Dark Mode
Proper dark theme support:
[data-theme="dark"] {
--color-background: #1a1a1a;
--color-text: #ffffff;
/* ... */
}
10.4 Custom Theme Registration
Allow apps to register custom themes:
themeLoader.registerTheme('mycorp', {
label: 'MyCorp Theme',
url: 'https://mycorp.com/solid-theme.css'
})
11. Success Criteria
11.1 Functional Requirements
- ✅ Theme loader works in all packages
- ✅ Themes load at any URL path
- ✅ localStorage persistence works
- ✅ Theme switching is instant
- ✅ All 5 themes available
- ✅ Backward compatibility maintained
11.2 Performance Requirements
- ✅ Theme files < 10KB each
- ✅ Total bundle increase < 50KB
- ✅ Theme switch < 100ms
- ✅ No blocking on page load
11.3 Quality Requirements
- ✅ 80%+ test coverage
- ✅ TypeScript declarations
- ✅ JSDoc comments
- ✅ README with examples
- ✅ No breaking changes
- ✅ CI/CD pipeline
12. Timeline
Total Duration: 5 weeks
| Phase | Duration | Deliverable |
|---|---|---|
| 1. Create solid-style | 1-2 weeks | npm package published |
| 2. Update solid-ui | 1 week | solid-ui@3.1.0 |
| 3. Update panes | 1 week | 8 panes updated |
| 4. Update solid-panes | 2-3 days | solid-panes@4.1.0 |
| 5. Update mashlib | 2-3 days | mashlib@2.1.0 |
| Testing & docs | Ongoing | Complete coverage |
13. Open Questions
13.1 Naming
- solid-style vs solid-themes vs solidos-style?
- Recommendation: solid-style (broader scope for future utilities)
13.2 Variable Prefixes
- Keep
--color-*or introduce--ss-*prefix?- Recommendation: Keep
--color-*(more semantic)
- Recommendation: Keep
13.3 Utilities Scope
- Include utilities in v1.0.0 or wait for Phase 2?
- Recommendation: Wait for Phase 2 (focus on themes first)
14. Risks & Mitigation
14.1 Risk: npm Package Size
Impact: Medium
Probability: Low
Mitigation:
- CSS files are small (~5KB each)
- Tree-shaking for JS
- Document CDN usage for browsers
14.2 Risk: Compatibility Issues
Impact: High
Probability: Low
Mitigation:
- Extensive testing before release
- Beta release period
- solid-ui re-exports maintain API
14.3 Risk: Multi-tenant Path Resolution
Impact: Medium
Probability: Medium
Mitigation:
- Multiple fallback strategies in resolveThemePath()
- Configuration option via window.solid.basePath
- Document common deployment scenarios
14.4 Risk: Adoption Resistance
Impact: Medium
Probability: Low
Mitigation:
- No breaking changes
- Gradual migration path
- Clear documentation and benefits
15. Stakeholders & Approval
- Tim Berners-Lee - Architecture review
- Timea - Implementation lead
- SolidOS Team - Review and approval
- Community - Feedback and testing
Appendix A: File Movement Checklist
From solid-ui to solid-style:
-
src/themeLoader.js→solid-style/src/themeLoader.js -
src/themes/foundation/variables.css→solid-style/src/themes/foundation/variables.css -
src/themes/foundation/accessibility.css→solid-style/src/themes/foundation/accessibility.css -
src/themes/presets/classic.css→solid-style/src/themes/presets/classic.css -
src/themes/presets/default.css→solid-style/src/themes/presets/default.css -
src/themes/presets/wave.css→solid-style/src/themes/presets/wave.css -
src/themes/presets/telegram.css→solid-style/src/themes/presets/telegram.css -
src/themes/presets/signal.css→solid-style/src/themes/presets/signal.css
Appendix B: Reference Links
- Current themes in solid-ui: https://github.com/SolidOS/solid-ui/tree/main/src/themes
- mashlib newStyle: https://github.com/SolidOS/mashlib/tree/newStyle
- profile-pane html5: https://github.com/SolidOS/profile-pane/tree/html5
- CSS Variables spec: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties
Document Status: Draft for review
Next Steps: Team review → Approval → Implementation
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by comparing the proposed solid-style/src/themeLoader.js, src/index.ts, theme files, and test files with their solid-ui counterparts, then review the package.json and build configuration requirements. Done means the standalone package, five themes, tests, build outputs, compatibility behavior, and documented migration deliverables are completed across the listed SolidOS packages.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, javascript, typescript, webpack
- Domain
- build-system, design, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100