Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 10 additions & 10 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@
"esbenp.prettier-vscode",
"msjsdiag.vscode-react-native"
],
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
},
"lighthouse": {
"command": "npx",
"args": ["lighthouse-mcp"],
"disabled": false,
"autoApprove": []
"mcp": {
"servers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
},
"lighthouse": {
"command": "npx",
"args": ["lighthouse-mcp"]
}
}
}
}
Expand Down
23 changes: 21 additions & 2 deletions ACCESSIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ All colors tested on white background (#ffffff):
- **Warning** (#8a6b00): 5.02:1 contrast ratio ✓
- **Danger** (#d1242a): 5.25:1 contrast ratio ✓

### Button Contrast

- **Primary button gradient** (linear-gradient(135deg, #0073cc 0%, #cc4400 100%) on white text):
- Start color: 4.86:1 contrast ratio ✓
- End color: 4.78:1 contrast ratio ✓
- Minimum: 4.78:1 (exceeds WCAG AA)
- **Outline buttons**: Use solid primary color borders (4.86:1) for proper contrast

### Dark Mode Color Palette

All colors tested on dark background (#1d2026):
Expand All @@ -34,6 +42,12 @@ All colors tested on dark background (#1d2026):
- **Primary Light** (#66b3ff): 7.35:1 contrast ratio ✓
- **Primary Lighter** (#73baff): 7.92:1 contrast ratio ✓
- **Primary Lightest** (#99ccff): 9.66:1 contrast ratio ✓
- **Secondary text** (#d3d7e2): 11.34:1 contrast ratio ✓
- **White text** (#ffffff): 16.32:1 contrast ratio ✓

### Button Contrast in Dark Mode

- **Outline buttons**: Use primary-light color (#66b3ff) for borders (7.35:1 contrast ratio) ✓

### Requirements

Expand All @@ -57,7 +71,10 @@ All interactive elements are fully accessible via keyboard:
- Focus indicators use 3px solid outlines with 3px offset
- `:focus-visible` pseudo-class for keyboard-only focus states
- Mouse clicks don't show focus rings (better UX)
- Enhanced visibility in both light and dark modes
- Enhanced visibility in both light and dark modes:
- Light mode: Uses primary color (#0073cc) for focus outlines
- Dark mode: Uses primary-light color (#66b3ff) for better visibility
- Focus outlines are visible on all interactive elements

## Screen Reader Support

Expand Down Expand Up @@ -96,8 +113,10 @@ The theme respects `prefers-reduced-motion` settings:

The theme adapts to high contrast preferences:

- Darker primary colors in high contrast mode
- Enhanced primary colors in high contrast mode (#005299 for primary, #993300 for secondary)
- Solid backgrounds for gradient buttons to ensure maximum contrast
- Thicker focus outlines (4px instead of 3px)
- Thicker borders on outline buttons (3px instead of 2px)
- Enhanced borders for better element distinction
- Maintains usability for users with low vision

Expand Down
5 changes: 5 additions & 0 deletions packages/docs/src/pages/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
.swatch code {
font-family: var(--ifm-font-family-monospace);
font-size: 0.85rem;
color: var(--hk-color-dark);
}

[data-theme="dark"] .swatch code {
color: #fff;
}

.callout {
Expand Down
56 changes: 35 additions & 21 deletions packages/theme/src/styles/hoverkraft.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

--ifm-navbar-shadow: 0 1px 3px rgba(29, 32, 38, 0.1);
--ifm-button-border-radius: 8px;
--docusaurus-highlighted-code-line-bg: rgba(25, 152, 255, 0.1);
--docusaurus-highlighted-code-line-bg: rgba(0, 115, 204, 0.1);
}

[data-theme="dark"] {
Expand All @@ -58,7 +58,7 @@
--ifm-font-color-secondary: #d3d7e2;
--ifm-navbar-background-color: rgba(37, 40, 50, 0.95);
--ifm-navbar-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
--docusaurus-highlighted-code-line-bg: rgba(25, 152, 255, 0.2);
--docusaurus-highlighted-code-line-bg: rgba(77, 166, 255, 0.2);
}

html,
Expand All @@ -82,7 +82,8 @@ body {
}

[data-theme="dark"] :focus-visible {
outline: 3px solid var(--ifm-color-primary);
outline: 3px solid var(--ifm-color-primary-light);
outline-offset: 3px;
}

.navbar {
Expand Down Expand Up @@ -180,7 +181,7 @@ body {

.button.button--primary,
.button--primary {
background: linear-gradient(135deg, #1998ff 0%, #ff5a02 100%);
background: linear-gradient(135deg, #0073cc 0%, #cc4400 100%);
border: none;
border-radius: 999px;
color: #ffffff !important;
Expand All @@ -191,7 +192,7 @@ body {
padding: 0.875rem 2.25rem;
font-weight: 600;
text-decoration: none !important;
box-shadow: 0 8px 24px rgba(25, 152, 255, 0.35);
box-shadow: 0 8px 24px rgba(0, 115, 204, 0.35);
transition:
transform 0.2s ease,
box-shadow 0.2s ease,
Expand All @@ -201,21 +202,21 @@ body {
.button.button--primary:hover,
.button--primary:hover {
transform: translateY(-2px);
box-shadow: 0 14px 32px rgba(25, 152, 255, 0.45);
filter: brightness(1.03);
box-shadow: 0 14px 32px rgba(0, 115, 204, 0.45);
filter: brightness(1.1);
}

.button.button--primary:active,
.button--primary:active {
transform: translateY(0);
box-shadow: 0 6px 18px rgba(25, 152, 255, 0.4);
box-shadow: 0 6px 18px rgba(0, 115, 204, 0.4);
}

.button.button--primary:focus-visible,
.button--primary:focus-visible {
box-shadow:
0 0 0 4px rgba(25, 152, 255, 0.25),
0 12px 28px rgba(25, 152, 255, 0.45);
0 0 0 4px rgba(0, 115, 204, 0.25),
0 12px 28px rgba(0, 115, 204, 0.45);
}

.button.button--secondary,
Expand All @@ -224,7 +225,7 @@ body {
.button--outline {
background: transparent;
border-radius: 999px;
border: 2px solid rgba(25, 152, 255, 0.35);
border: 2px solid var(--hk-color-primary);
color: var(--hk-color-dark);
display: inline-flex;
align-items: center;
Expand All @@ -245,31 +246,31 @@ body {
[data-theme="dark"] .button.button--outline,
[data-theme="dark"] .button--outline {
color: #ffffff;
border-color: rgba(255, 255, 255, 0.4);
border-color: var(--ifm-color-primary);
}

.button.button--secondary:hover,
.button--secondary:hover,
.button.button--outline:hover,
.button--outline:hover {
transform: translateY(-2px);
background: rgba(25, 152, 255, 0.08);
border-color: rgba(25, 152, 255, 0.5);
background: rgba(0, 115, 204, 0.08);
border-color: var(--hk-color-primary);
}

[data-theme="dark"] .button.button--secondary:hover,
[data-theme="dark"] .button--secondary:hover,
[data-theme="dark"] .button.button--outline:hover,
[data-theme="dark"] .button--outline:hover {
background: rgba(255, 255, 255, 0.12);
border-color: rgba(255, 255, 255, 0.6);
background: rgba(77, 166, 255, 0.12);
border-color: var(--ifm-color-primary-light);
}

.button.button--secondary:focus-visible,
.button--secondary:focus-visible,
.button.button--outline:focus-visible,
.button--outline:focus-visible {
box-shadow: 0 0 0 4px rgba(25, 152, 255, 0.25);
box-shadow: 0 0 0 4px rgba(0, 115, 204, 0.25);
}

a {
Expand Down Expand Up @@ -350,18 +351,18 @@ a:hover {

.hero .button.button--primary,
.hero .button--primary {
box-shadow: 0 12px 30px rgba(25, 152, 255, 0.45);
box-shadow: 0 12px 30px rgba(0, 115, 204, 0.45);
}

.hero .button.button--primary:hover,
.hero .button--primary:hover {
box-shadow: 0 18px 40px rgba(25, 152, 255, 0.5);
box-shadow: 0 18px 40px rgba(0, 115, 204, 0.5);
}

@media (prefers-contrast: high) {
:root {
--hk-color-primary: #0056b3;
--hk-color-secondary: #b33d00;
--hk-color-primary: #005299;
--hk-color-secondary: #993300;
}

:focus-visible {
Expand All @@ -371,6 +372,19 @@ a:hover {
.navbar {
border-bottom: 2px solid currentColor;
}

.button.button--primary,
.button--primary {
background: #005299;
border: 2px solid #003d73;
}

.button.button--secondary,
.button--secondary,
.button.button--outline,
.button--outline {
border-width: 3px;
}
}

@media (prefers-reduced-motion: reduce) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
.highlight {
background: linear-gradient(45deg, #1998ff, #ff5a02);
background: linear-gradient(
45deg,
var(--hk-color-primary, #0073cc),
var(--hk-color-secondary, #cc4400)
);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
Expand Down
59 changes: 32 additions & 27 deletions packages/theme/src/theme/hoverscape/HoverkraftButton.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
}

.button:focus-visible {
outline: 3px solid rgba(25, 152, 255, 0.4);
outline: 3px solid var(--hk-color-primary, #0073cc);
outline-offset: 2px;
}

[data-theme="dark"] .button:focus-visible {
outline: 3px solid var(--ifm-color-primary-light, #66b3ff);
outline-offset: 2px;
}

Expand All @@ -43,70 +48,70 @@
}

.primary {
background: linear-gradient(135deg, #1998ff 0%, #ff5a02 100%);
box-shadow: 0 8px 24px rgba(25, 152, 255, 0.35);
background: linear-gradient(135deg, #0073cc 0%, #cc4400 100%);
box-shadow: 0 8px 24px rgba(0, 115, 204, 0.35);
}

.primary:hover {
transform: translateY(-2px);
box-shadow: 0 14px 32px rgba(25, 152, 255, 0.45);
filter: brightness(1.03);
box-shadow: 0 14px 32px rgba(0, 115, 204, 0.45);
filter: brightness(1.1);
color: #ffffff;
text-shadow: 0 3px 12px rgba(8, 43, 80, 0.35);
text-shadow: 0 3px 12px rgba(0, 0, 0, 0.35);
}

.primary:active {
transform: translateY(0);
box-shadow: 0 6px 18px rgba(25, 152, 255, 0.35);
box-shadow: 0 6px 18px rgba(0, 115, 204, 0.35);
}

.secondary {
background: rgba(25, 152, 255, 0.15);
border: 2px solid rgba(25, 152, 255, 0.5);
background: rgba(0, 115, 204, 0.15);
border: 2px solid var(--hk-color-primary, #0073cc);
color: var(--hk-color-dark, #1d2026);
box-shadow: 0 2px 8px rgba(25, 152, 255, 0.15);
box-shadow: 0 2px 8px rgba(0, 115, 204, 0.15);
}

.secondary:hover {
transform: translateY(-2px);
background: rgba(25, 152, 255, 0.22);
border-color: rgba(25, 152, 255, 0.65);
box-shadow: 0 4px 12px rgba(25, 152, 255, 0.25);
text-shadow: 0 3px 12px rgba(8, 43, 80, 0.35);
background: rgba(0, 115, 204, 0.22);
border-color: var(--hk-color-primary-dark, #0066b8);
box-shadow: 0 4px 12px rgba(0, 115, 204, 0.25);
text-shadow: 0 3px 12px rgba(0, 0, 0, 0.35);
}

.outline {
background: transparent;
border: 2px solid rgba(25, 152, 255, 0.35);
border: 2px solid var(--hk-color-primary, #0073cc);
color: var(--hk-color-dark, #1d2026);
}

.outline:hover {
transform: translateY(-2px);
background: rgba(25, 152, 255, 0.08);
border-color: rgba(25, 152, 255, 0.5);
text-shadow: 0 3px 12px rgba(8, 43, 80, 0.35);
background: rgba(0, 115, 204, 0.08);
border-color: var(--hk-color-primary, #0073cc);
text-shadow: 0 3px 12px rgba(0, 0, 0, 0.35);
}

[data-theme="dark"] .secondary {
background: rgba(25, 152, 255, 0.25);
border-color: rgba(25, 152, 255, 0.6);
background: rgba(77, 166, 255, 0.25);
border-color: var(--ifm-color-primary, #4da6ff);
color: #ffffff;
box-shadow: 0 2px 8px rgba(25, 152, 255, 0.2);
box-shadow: 0 2px 8px rgba(77, 166, 255, 0.2);
}

[data-theme="dark"] .secondary:hover {
background: rgba(25, 152, 255, 0.35);
border-color: rgba(25, 152, 255, 0.75);
box-shadow: 0 4px 12px rgba(25, 152, 255, 0.3);
background: rgba(77, 166, 255, 0.35);
border-color: var(--ifm-color-primary-light, #66b3ff);
box-shadow: 0 4px 12px rgba(77, 166, 255, 0.3);
}

[data-theme="dark"] .outline {
color: #ffffff;
border-color: rgba(255, 255, 255, 0.4);
border-color: var(--ifm-color-primary-light, #66b3ff);
}

[data-theme="dark"] .outline:hover {
background: rgba(255, 255, 255, 0.12);
border-color: rgba(255, 255, 255, 0.6);
background: rgba(77, 166, 255, 0.12);
border-color: var(--ifm-color-primary-light, #66b3ff);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@

.featureCard:hover {
transform: translateY(-4px);
box-shadow: 0 16px 30px rgba(25, 152, 255, 0.2);
border-color: #1998ff;
box-shadow: 0 16px 30px rgba(0, 115, 204, 0.2);
border-color: var(--hk-color-primary, #0073cc);
}

[data-theme="dark"] .featureCard {
Expand Down
Loading
Loading