333 lines
7.5 KiB
Markdown
333 lines
7.5 KiB
Markdown
# OpenSpec Spec: UI Polish Round — Config Sections, Home Paddings, Project Repos
|
|
|
|
## Change
|
|
`ui-polish-round-config-sections-home-projects`
|
|
|
|
## Parent Proposal
|
|
`openspec/proposals/ui-polish-round-config-sections-home-projects.md`
|
|
|
|
## Status
|
|
spec
|
|
|
|
---
|
|
|
|
## 1. Scope
|
|
|
|
This spec covers three UI polish fixes:
|
|
|
|
1. **Unify config sections** across Tool Workshop and Config Profiles.
|
|
2. **Restore paddings** on the Home page cards.
|
|
3. **Improve project repository layout** in the expandable project card.
|
|
|
|
---
|
|
|
|
## 2. Shared Config Section
|
|
|
|
### 2.1 New CSS classes
|
|
|
|
Add to `apps/web/src/styles/global.css`:
|
|
|
|
```css
|
|
.config-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-3);
|
|
padding: var(--space-4);
|
|
background: var(--panel);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
}
|
|
|
|
.config-section-title {
|
|
margin: 0 0 var(--space-1);
|
|
font-size: var(--font-size-base);
|
|
font-weight: 600;
|
|
line-height: var(--line-height-tight);
|
|
color: var(--ink);
|
|
}
|
|
|
|
.config-section-subtitle {
|
|
margin: calc(var(--space-1) * -1) 0 var(--space-2);
|
|
font-size: var(--font-size-sm);
|
|
color: var(--muted);
|
|
line-height: var(--line-height-normal);
|
|
}
|
|
|
|
.config-section > .config-section-title + .config-section-subtitle {
|
|
margin-top: calc(var(--space-2) * -1);
|
|
}
|
|
```
|
|
|
|
### 2.2 Tool Workshop migration
|
|
|
|
In `apps/web/src/components/features/tool/manifest-editor.tsx`:
|
|
|
|
- Replace every occurrence of:
|
|
```tsx
|
|
<div className="card-md stack stack-md">
|
|
<h4 className="m-0">Title</h4>
|
|
...
|
|
</div>
|
|
```
|
|
with:
|
|
```tsx
|
|
<section className="config-section">
|
|
<h4 className="config-section-title">Title</h4>
|
|
...
|
|
</section>
|
|
```
|
|
|
|
- Keep `.card-md` on the preview block if it is not a config section.
|
|
|
|
### 2.3 Config Profiles migration
|
|
|
|
In `apps/web/src/components/features/config-profiles/ConfigProfileEditorPanel.tsx`:
|
|
|
|
- Replace every occurrence of:
|
|
```tsx
|
|
<div className="form-section">
|
|
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "0.75rem" }}>
|
|
<h4 style={{ margin: 0 }}>Title</h4>
|
|
...
|
|
</div>
|
|
...
|
|
</div>
|
|
```
|
|
with:
|
|
```tsx
|
|
<section className="config-section">
|
|
<div className="config-section-header">
|
|
<div>
|
|
<h4 className="config-section-title">Title</h4>
|
|
{subtitle && <p className="config-section-subtitle">{subtitle}</p>}
|
|
</div>
|
|
...actions...
|
|
</div>
|
|
...
|
|
</section>
|
|
```
|
|
|
|
- Add `.config-section-header` CSS:
|
|
```css
|
|
.config-section-header {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: var(--space-3);
|
|
margin-bottom: var(--space-2);
|
|
}
|
|
|
|
.config-section-header .config-section-title {
|
|
margin-bottom: 0;
|
|
}
|
|
```
|
|
|
|
### 2.4 Backward compatibility
|
|
|
|
Keep `.form-section` defined as an alias so existing consumers outside Config Profiles are not broken.
|
|
|
|
---
|
|
|
|
## 3. Home Page Padding
|
|
|
|
### 3.1 Target classes
|
|
|
|
In `apps/web/src/styles/global.css`:
|
|
|
|
```css
|
|
.home-hero {
|
|
padding: var(--space-4);
|
|
}
|
|
|
|
.home-summary-card {
|
|
padding: var(--space-4);
|
|
}
|
|
|
|
.home-section {
|
|
padding: var(--space-4);
|
|
}
|
|
```
|
|
|
|
If `.home-hero` already has padding from a previous rule, override/ensure it uses `--space-4`.
|
|
|
|
### 3.2 Mobile adjustments
|
|
|
|
At `max-width: 767px`, reduce padding to `--space-3`:
|
|
|
|
```css
|
|
@media (max-width: 767px) {
|
|
.home-hero,
|
|
.home-summary-card,
|
|
.home-section {
|
|
padding: var(--space-3);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Project Repository Layout
|
|
|
|
### 4.1 Component markup
|
|
|
|
In `apps/web/src/components/features/project/ProjectCard.tsx`:
|
|
|
|
Change the expanded detail block from:
|
|
|
|
```tsx
|
|
{expanded && (
|
|
<div className="project-detail">
|
|
{(project.repositories || []).length === 0 ? (
|
|
<p className="muted">No repositories yet.</p>
|
|
) : (
|
|
<div className="repo-list">...</div>
|
|
)}
|
|
{onAddRepository && (
|
|
<div className="project-add-repo">...</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
```
|
|
|
|
to:
|
|
|
|
```tsx
|
|
{expanded && (
|
|
<div className="project-detail">
|
|
<section className="project-repos">
|
|
<div className="project-repos-header">
|
|
<div>
|
|
<h4 className="config-section-title">Repositories</h4>
|
|
<p className="config-section-subtitle">
|
|
{project.repositories?.length ?? 0} repo
|
|
{(project.repositories?.length ?? 0) !== 1 ? "s" : ""}
|
|
</p>
|
|
</div>
|
|
{onAddRepository && (
|
|
<button
|
|
className="btn btn-sm btn-secondary"
|
|
onClick={onAddRepository}
|
|
type="button"
|
|
>
|
|
<Icon name="add" size="sm" /> Add Repository
|
|
</button>
|
|
)}
|
|
</div>
|
|
|
|
{(project.repositories || []).length === 0 ? (
|
|
<p className="muted">No repositories yet.</p>
|
|
) : (
|
|
<div className="repo-list">
|
|
{(project.repositories || []).map((repo) => (
|
|
<div key={repo.id} className="card card-md repo-block">
|
|
...
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</section>
|
|
</div>
|
|
)}
|
|
```
|
|
|
|
Remove the old `.project-add-repo` block.
|
|
|
|
### 4.2 CSS changes
|
|
|
|
In `apps/web/src/styles/pages/projects.css`:
|
|
|
|
```css
|
|
.project-detail {
|
|
margin-top: var(--space-4);
|
|
padding-top: var(--space-4);
|
|
border-top: 1px solid var(--border);
|
|
}
|
|
|
|
.project-repos {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-3);
|
|
}
|
|
|
|
.project-repos-header {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: var(--space-3);
|
|
}
|
|
|
|
.project-repos-header .config-section-title {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.repo-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-3);
|
|
}
|
|
|
|
.repo-block {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-3);
|
|
background: var(--bg);
|
|
}
|
|
|
|
.repo-block,
|
|
.repo-block.card-md {
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
}
|
|
|
|
/* Remove old .project-add-repo rules */
|
|
.project-add-repo {
|
|
display: none;
|
|
}
|
|
```
|
|
|
|
### 4.3 Mobile
|
|
|
|
At `max-width: 767px`, stack `.project-repos-header` vertically:
|
|
|
|
```css
|
|
@media (max-width: 767px) {
|
|
.project-repos-header {
|
|
flex-direction: column;
|
|
gap: var(--space-2);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Acceptance Criteria
|
|
|
|
- [ ] `.config-section`, `.config-section-title`, `.config-section-subtitle`, `.config-section-header` exist in `global.css`.
|
|
- [ ] `manifest-editor.tsx` uses `.config-section` for its grouped blocks.
|
|
- [ ] `ConfigProfileEditorPanel.tsx` uses `.config-section` for its grouped blocks.
|
|
- [ ] `.form-section` remains as a backward-compatible alias.
|
|
- [ ] `.home-hero`, `.home-summary-card`, and `.home-section` have `--space-4` padding (desktop) and `--space-3` padding (mobile).
|
|
- [ ] `ProjectCard.tsx` shows a "Repositories" header with repo count and an "Add Repository" button in the section header.
|
|
- [ ] Repository blocks are left-aligned under the project header and fill the available width.
|
|
- [ ] Old `.project-add-repo` standalone block is removed.
|
|
- [ ] `npm run typecheck` passes.
|
|
- [ ] `npm run lint` passes.
|
|
|
|
---
|
|
|
|
## 6. Verification Plan
|
|
|
|
1. Run `cd apps/web && npm run typecheck`.
|
|
2. Run `cd apps/web && npm run lint`.
|
|
3. Open Tool Workshop → create/edit a tool type → verify section styling matches Config Profiles.
|
|
4. Open Config Profiles → verify section headers and subtitles render correctly.
|
|
5. Open Home → verify hero, summary cards, and section cards have comfortable padding.
|
|
6. Open Projects → expand a project → verify repositories are left-aligned, have a "Repositories" header with count, and the "Add Repository" button is in the header.
|
|
7. Test project card on mobile viewport.
|
|
|
|
---
|
|
|
|
## 7. Next Phase
|
|
|
|
After approval, create tasks and delegate to `sdd-apply`.
|