mirror of
https://github.com/wshobson/agents.git
synced 2026-03-18 17:47:16 +00:00
fix(conductor): move plugin to plugins/ directory for proper discovery
Conductor plugin was at root level instead of plugins/ directory, causing slash commands to not be recognized by Claude Code.
This commit is contained in:
618
plugins/conductor/templates/code_styleguides/html-css.md
Normal file
618
plugins/conductor/templates/code_styleguides/html-css.md
Normal file
@@ -0,0 +1,618 @@
|
||||
# HTML & CSS Style Guide
|
||||
|
||||
Web standards for semantic markup, maintainable styling, and accessibility.
|
||||
|
||||
## Semantic HTML
|
||||
|
||||
### Document Structure
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Page description for SEO" />
|
||||
<title>Page Title | Site Name</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav aria-label="Main navigation">
|
||||
<!-- Navigation -->
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<article>
|
||||
<!-- Primary content -->
|
||||
</article>
|
||||
<aside>
|
||||
<!-- Supplementary content -->
|
||||
</aside>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<!-- Footer content -->
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### Semantic Elements
|
||||
|
||||
```html
|
||||
<!-- Use appropriate semantic elements -->
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav aria-label="Main navigation">
|
||||
<ul>
|
||||
<li><a href="/">Home</a></li>
|
||||
<li><a href="/about">About</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- Article with header and footer -->
|
||||
<article>
|
||||
<header>
|
||||
<h1>Article Title</h1>
|
||||
<time datetime="2024-01-15">January 15, 2024</time>
|
||||
</header>
|
||||
|
||||
<p>Article content...</p>
|
||||
|
||||
<footer>
|
||||
<p>Written by <address>Author Name</address></p>
|
||||
</footer>
|
||||
</article>
|
||||
|
||||
<!-- Sections with headings -->
|
||||
<section aria-labelledby="features-heading">
|
||||
<h2 id="features-heading">Features</h2>
|
||||
<p>Section content...</p>
|
||||
</section>
|
||||
|
||||
<!-- Figures with captions -->
|
||||
<figure>
|
||||
<img src="chart.png" alt="Sales data showing 20% growth">
|
||||
<figcaption>Q4 2024 Sales Performance</figcaption>
|
||||
</figure>
|
||||
|
||||
<!-- Definition lists -->
|
||||
<dl>
|
||||
<dt>HTML</dt>
|
||||
<dd>HyperText Markup Language</dd>
|
||||
<dt>CSS</dt>
|
||||
<dd>Cascading Style Sheets</dd>
|
||||
</dl>
|
||||
```
|
||||
|
||||
### Form Elements
|
||||
|
||||
```html
|
||||
<form action="/submit" method="POST">
|
||||
<!-- Text input with label -->
|
||||
<div class="form-group">
|
||||
<label for="email">Email Address</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
required
|
||||
autocomplete="email"
|
||||
aria-describedby="email-hint"
|
||||
/>
|
||||
<span id="email-hint" class="hint">We'll never share your email.</span>
|
||||
</div>
|
||||
|
||||
<!-- Select with label -->
|
||||
<div class="form-group">
|
||||
<label for="country">Country</label>
|
||||
<select id="country" name="country" required>
|
||||
<option value="">Select a country</option>
|
||||
<option value="us">United States</option>
|
||||
<option value="uk">United Kingdom</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Radio group with fieldset -->
|
||||
<fieldset>
|
||||
<legend>Preferred Contact Method</legend>
|
||||
<div>
|
||||
<input type="radio" id="contact-email" name="contact" value="email" />
|
||||
<label for="contact-email">Email</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" id="contact-phone" name="contact" value="phone" />
|
||||
<label for="contact-phone">Phone</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<!-- Submit button -->
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
## BEM Naming Convention
|
||||
|
||||
### Block, Element, Modifier
|
||||
|
||||
```css
|
||||
/* Block: Standalone component */
|
||||
.card {
|
||||
}
|
||||
|
||||
/* Element: Part of block (double underscore) */
|
||||
.card__header {
|
||||
}
|
||||
.card__body {
|
||||
}
|
||||
.card__footer {
|
||||
}
|
||||
|
||||
/* Modifier: Variation (double hyphen) */
|
||||
.card--featured {
|
||||
}
|
||||
.card--compact {
|
||||
}
|
||||
.card__header--centered {
|
||||
}
|
||||
```
|
||||
|
||||
### BEM Examples
|
||||
|
||||
```html
|
||||
<!-- Card component -->
|
||||
<article class="card card--featured">
|
||||
<header class="card__header">
|
||||
<h2 class="card__title">Card Title</h2>
|
||||
</header>
|
||||
<div class="card__body">
|
||||
<p class="card__text">Card content goes here.</p>
|
||||
</div>
|
||||
<footer class="card__footer">
|
||||
<button class="card__button card__button--primary">Action</button>
|
||||
</footer>
|
||||
</article>
|
||||
|
||||
<!-- Navigation component -->
|
||||
<nav class="nav nav--horizontal">
|
||||
<ul class="nav__list">
|
||||
<li class="nav__item nav__item--active">
|
||||
<a class="nav__link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav__item">
|
||||
<a class="nav__link" href="/about">About</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
```
|
||||
|
||||
### BEM Best Practices
|
||||
|
||||
```css
|
||||
/* Avoid deep nesting */
|
||||
/* Bad */
|
||||
.card__header__title__icon {
|
||||
}
|
||||
|
||||
/* Good - flatten structure */
|
||||
.card__title-icon {
|
||||
}
|
||||
|
||||
/* Avoid styling elements without class */
|
||||
/* Bad */
|
||||
.card h2 {
|
||||
}
|
||||
|
||||
/* Good */
|
||||
.card__title {
|
||||
}
|
||||
|
||||
/* Modifiers extend base styles */
|
||||
.button {
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.button--large {
|
||||
padding: 12px 24px;
|
||||
}
|
||||
|
||||
.button--primary {
|
||||
background: blue;
|
||||
color: white;
|
||||
}
|
||||
```
|
||||
|
||||
## Accessibility
|
||||
|
||||
### ARIA Attributes
|
||||
|
||||
```html
|
||||
<!-- Live regions for dynamic content -->
|
||||
<div aria-live="polite" aria-atomic="true">Status updates appear here</div>
|
||||
|
||||
<!-- Landmarks -->
|
||||
<nav aria-label="Main navigation"></nav>
|
||||
<nav aria-label="Footer navigation"></nav>
|
||||
|
||||
<!-- Current page in navigation -->
|
||||
<a href="/about" aria-current="page">About</a>
|
||||
|
||||
<!-- Expanded/collapsed state -->
|
||||
<button aria-expanded="false" aria-controls="menu">Toggle Menu</button>
|
||||
<div id="menu" hidden>Menu content</div>
|
||||
|
||||
<!-- Disabled vs aria-disabled -->
|
||||
<button disabled>Can't click (removed from tab order)</button>
|
||||
<button aria-disabled="true">Can't click (stays in tab order)</button>
|
||||
|
||||
<!-- Loading states -->
|
||||
<button aria-busy="true">
|
||||
<span aria-hidden="true">Loading...</span>
|
||||
<span class="visually-hidden">Please wait</span>
|
||||
</button>
|
||||
```
|
||||
|
||||
### Keyboard Navigation
|
||||
|
||||
```html
|
||||
<!-- Skip link -->
|
||||
<a href="#main-content" class="skip-link">Skip to main content</a>
|
||||
|
||||
<!-- Focusable elements should be obvious -->
|
||||
<style>
|
||||
:focus-visible {
|
||||
outline: 2px solid blue;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Tabindex usage -->
|
||||
<!-- tabindex="0": Add to tab order -->
|
||||
<div tabindex="0" role="button">Custom button</div>
|
||||
|
||||
<!-- tabindex="-1": Programmatically focusable only -->
|
||||
<div id="modal" tabindex="-1">Modal content</div>
|
||||
|
||||
<!-- Never use tabindex > 0 -->
|
||||
```
|
||||
|
||||
### Screen Reader Support
|
||||
|
||||
```css
|
||||
/* Visually hidden but accessible */
|
||||
.visually-hidden {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* Hide from screen readers */
|
||||
[aria-hidden="true"] {
|
||||
/* Decorative content */
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- Icon buttons need accessible names -->
|
||||
<button aria-label="Close dialog">
|
||||
<svg aria-hidden="true"><!-- icon --></svg>
|
||||
</button>
|
||||
|
||||
<!-- Decorative images -->
|
||||
<img src="decoration.png" alt="" role="presentation" />
|
||||
|
||||
<!-- Informative images -->
|
||||
<img src="chart.png" alt="Sales increased 20% in Q4 2024" />
|
||||
|
||||
<!-- Complex images -->
|
||||
<figure>
|
||||
<img
|
||||
src="flowchart.png"
|
||||
alt="User registration process"
|
||||
aria-describedby="flowchart-desc"
|
||||
/>
|
||||
<figcaption id="flowchart-desc">
|
||||
Step 1: Enter email. Step 2: Verify email. Step 3: Create password.
|
||||
</figcaption>
|
||||
</figure>
|
||||
```
|
||||
|
||||
## Responsive Design
|
||||
|
||||
### Mobile-First Approach
|
||||
|
||||
```css
|
||||
/* Base styles for mobile */
|
||||
.container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
/* Tablet and up */
|
||||
@media (min-width: 768px) {
|
||||
.container {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop and up */
|
||||
@media (min-width: 1024px) {
|
||||
.container {
|
||||
padding: 32px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Flexible Units
|
||||
|
||||
```css
|
||||
/* Use relative units */
|
||||
body {
|
||||
font-size: 16px; /* Base size */
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2rem; /* Relative to root */
|
||||
margin-bottom: 1em; /* Relative to element */
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 75ch; /* Character width for readability */
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
/* Fluid typography */
|
||||
h1 {
|
||||
font-size: clamp(1.5rem, 4vw, 3rem);
|
||||
}
|
||||
|
||||
/* Fluid spacing */
|
||||
.section {
|
||||
padding: clamp(2rem, 5vw, 4rem);
|
||||
}
|
||||
```
|
||||
|
||||
### Responsive Images
|
||||
|
||||
```html
|
||||
<!-- Responsive image with srcset -->
|
||||
<img
|
||||
src="image-800.jpg"
|
||||
srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w"
|
||||
sizes="(max-width: 600px) 100vw, 50vw"
|
||||
alt="Description"
|
||||
loading="lazy"
|
||||
/>
|
||||
|
||||
<!-- Art direction with picture -->
|
||||
<picture>
|
||||
<source media="(min-width: 1024px)" srcset="hero-desktop.jpg" />
|
||||
<source media="(min-width: 768px)" srcset="hero-tablet.jpg" />
|
||||
<img src="hero-mobile.jpg" alt="Hero image" />
|
||||
</picture>
|
||||
```
|
||||
|
||||
## CSS Best Practices
|
||||
|
||||
### Custom Properties (CSS Variables)
|
||||
|
||||
```css
|
||||
:root {
|
||||
/* Colors */
|
||||
--color-primary: #0066cc;
|
||||
--color-primary-dark: #004c99;
|
||||
--color-secondary: #6c757d;
|
||||
--color-success: #28a745;
|
||||
--color-error: #dc3545;
|
||||
|
||||
/* Typography */
|
||||
--font-family-base: system-ui, sans-serif;
|
||||
--font-family-mono: ui-monospace, monospace;
|
||||
--font-size-sm: 0.875rem;
|
||||
--font-size-base: 1rem;
|
||||
--font-size-lg: 1.25rem;
|
||||
|
||||
/* Spacing */
|
||||
--spacing-xs: 0.25rem;
|
||||
--spacing-sm: 0.5rem;
|
||||
--spacing-md: 1rem;
|
||||
--spacing-lg: 1.5rem;
|
||||
--spacing-xl: 2rem;
|
||||
|
||||
/* Borders */
|
||||
--border-radius: 4px;
|
||||
--border-color: #dee2e6;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Dark mode */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-primary: #4da6ff;
|
||||
--color-background: #1a1a1a;
|
||||
--color-text: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Usage */
|
||||
.button {
|
||||
background: var(--color-primary);
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
```
|
||||
|
||||
### Modern Layout
|
||||
|
||||
```css
|
||||
/* Flexbox for 1D layouts */
|
||||
.navbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--spacing-md);
|
||||
}
|
||||
|
||||
/* Grid for 2D layouts */
|
||||
.page-layout {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"header header"
|
||||
"sidebar main"
|
||||
"footer footer";
|
||||
grid-template-columns: 250px 1fr;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
grid-area: header;
|
||||
}
|
||||
.sidebar {
|
||||
grid-area: sidebar;
|
||||
}
|
||||
.main {
|
||||
grid-area: main;
|
||||
}
|
||||
.footer {
|
||||
grid-area: footer;
|
||||
}
|
||||
|
||||
/* Auto-fit grid */
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: var(--spacing-lg);
|
||||
}
|
||||
```
|
||||
|
||||
### Performance
|
||||
|
||||
```css
|
||||
/* Avoid expensive properties in animations */
|
||||
/* Bad - triggers layout */
|
||||
.animate-bad {
|
||||
animation: move 1s;
|
||||
}
|
||||
@keyframes move {
|
||||
to {
|
||||
left: 100px;
|
||||
top: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Good - uses transform */
|
||||
.animate-good {
|
||||
animation: move-optimized 1s;
|
||||
}
|
||||
@keyframes move-optimized {
|
||||
to {
|
||||
transform: translate(100px, 100px);
|
||||
}
|
||||
}
|
||||
|
||||
/* Use will-change sparingly */
|
||||
.will-animate {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
/* Contain for layout isolation */
|
||||
.card {
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
/* Content-visibility for off-screen content */
|
||||
.below-fold {
|
||||
content-visibility: auto;
|
||||
contain-intrinsic-size: 500px;
|
||||
}
|
||||
```
|
||||
|
||||
## HTML Best Practices
|
||||
|
||||
### Validation and Attributes
|
||||
|
||||
```html
|
||||
<!-- Use proper input types -->
|
||||
<input type="email" autocomplete="email" />
|
||||
<input type="tel" autocomplete="tel" />
|
||||
<input type="url" />
|
||||
<input type="number" min="0" max="100" step="1" />
|
||||
<input type="date" min="2024-01-01" />
|
||||
|
||||
<!-- Required and validation -->
|
||||
<input type="text" required minlength="2" maxlength="50" pattern="[A-Za-z]+" />
|
||||
|
||||
<!-- Autocomplete for better UX -->
|
||||
<input type="text" name="name" autocomplete="name" />
|
||||
<input type="text" name="address" autocomplete="street-address" />
|
||||
<input type="text" name="cc-number" autocomplete="cc-number" />
|
||||
```
|
||||
|
||||
### Performance Attributes
|
||||
|
||||
```html
|
||||
<!-- Lazy loading -->
|
||||
<img src="image.jpg" loading="lazy" alt="Description" />
|
||||
<iframe src="video.html" loading="lazy"></iframe>
|
||||
|
||||
<!-- Preload critical resources -->
|
||||
<link rel="preload" href="critical.css" as="style" />
|
||||
<link rel="preload" href="hero.jpg" as="image" />
|
||||
<link rel="preload" href="font.woff2" as="font" crossorigin />
|
||||
|
||||
<!-- Preconnect to origins -->
|
||||
<link rel="preconnect" href="https://api.example.com" />
|
||||
<link rel="dns-prefetch" href="https://analytics.example.com" />
|
||||
|
||||
<!-- Async/defer scripts -->
|
||||
<script src="analytics.js" async></script>
|
||||
<script src="app.js" defer></script>
|
||||
```
|
||||
|
||||
### Microdata and SEO
|
||||
|
||||
```html
|
||||
<!-- Schema.org markup -->
|
||||
<article itemscope itemtype="https://schema.org/Article">
|
||||
<h1 itemprop="headline">Article Title</h1>
|
||||
<time itemprop="datePublished" datetime="2024-01-15"> January 15, 2024 </time>
|
||||
<div itemprop="author" itemscope itemtype="https://schema.org/Person">
|
||||
<span itemprop="name">Author Name</span>
|
||||
</div>
|
||||
<div itemprop="articleBody">Article content...</div>
|
||||
</article>
|
||||
|
||||
<!-- Open Graph for social sharing -->
|
||||
<meta property="og:title" content="Page Title" />
|
||||
<meta property="og:description" content="Page description" />
|
||||
<meta property="og:image" content="https://example.com/image.jpg" />
|
||||
<meta property="og:url" content="https://example.com/page" />
|
||||
```
|
||||
Reference in New Issue
Block a user