Skip to content

Commit 1875e1a

Browse files
jchrisAmberVioletMaclaude
authored
feat: Add design updates from Amber's branch (rebased) (#657)
## Summary - Add PNG icon assets (back, invite, logout, remix, settings) - Add colors.css with design token definitions - Redesign BrutalistCard component with updated styles - Redesign VibesButton with new variants (blue, red, yellow, green) and icon support - Redesign VibesPanel with LabelContainer and new styles - Update VibesSwitch styling - Update HiddenMenuWrapper and ImgGen.css styles - Update vibe-control-styles utility - Update NewSessionView to use new button variants - Add PNG type definitions for TypeScript - Update tsconfig files to support PNG imports ## Rebase Notes This PR is a rebase of #623 onto the latest main branch. The rebase resolved conflicts by: - Adjusting import paths for the flattened directory structure - Keeping the PR's CSS variables approach (cleaner than JS theme detection) - Merging all design updates successfully ## Changes vs Original PR - Import paths adjusted for flat component directory structure - Removed useThemeDetection hook in favor of CSS variables (better approach) - All design features preserved 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Amber Macias <arussek05@gmail.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent f72a94a commit 1875e1a

28 files changed

+1578
-1108
lines changed

pnpm-lock.yaml

Lines changed: 513 additions & 908 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

use-vibes/base/assets/back.png

3.32 KB
Loading

use-vibes/base/assets/invite.png

3.17 KB
Loading

use-vibes/base/assets/logout.png

3.47 KB
Loading

use-vibes/base/assets/remix.png

3.25 KB
Loading

use-vibes/base/assets/settings.png

4.63 KB
Loading

use-vibes/base/components/BrutalistCard/BrutalistCard.styles.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ export type BrutalistCardSize = 'sm' | 'md' | 'lg';
99
function getShadowColor(variant: BrutalistCardVariant): string {
1010
switch (variant) {
1111
case 'success':
12-
return '#51cf66'; // Green
12+
return 'var(--vibes-green)'; // Green
1313
case 'error':
14-
return '#DA291C'; // Red
14+
return 'var(--vibes-red-accent)'; // Red
1515
case 'warning':
16-
return '#FEDD00'; // Yellow
16+
return 'var(--vibes-yellow-accent)'; // Yellow
1717
case 'default':
1818
default:
19-
return '#1a1a1a'; // Dark gray
19+
return 'var(--vibes-shadow-color)'; // Dark gray (theme-aware)
2020
}
2121
}
2222

use-vibes/base/components/BrutalistCard/BrutalistCard.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { getBrutalistCardStyle } from './BrutalistCard.styles.js';
33
import type { BrutalistCardVariant, BrutalistCardSize } from './BrutalistCard.styles.js';
4-
import { useThemeDetection } from '../../hooks/useThemeDetection.js';
4+
import '../../styles/colors.css';
55

66
export interface BrutalistCardProps extends React.HTMLAttributes<HTMLDivElement> {
77
/** Content to render inside the card */
@@ -44,13 +44,11 @@ export const BrutalistCard = React.forwardRef<HTMLDivElement, BrutalistCardProps
4444
}: BrutalistCardProps,
4545
ref
4646
) => {
47-
const isDark = useThemeDetection();
48-
4947
const cardStyle = {
5048
...getBrutalistCardStyle(variant, size, messageType),
51-
background: isDark ? '#1a1a1a' : '#fff',
52-
color: isDark ? '#fff' : '#1a1a1a',
53-
border: isDark ? '3px solid #555' : '3px solid #1a1a1a',
49+
background: 'var(--vibes-card-bg)',
50+
color: 'var(--vibes-card-text)',
51+
border: '3px solid var(--vibes-card-border)',
5452
...style,
5553
} as React.CSSProperties;
5654

use-vibes/base/components/HiddenMenuWrapper/HiddenMenuWrapper.styles.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,39 @@ import type { CSSProperties } from 'react';
1717
* }
1818
*/
1919

20+
// Inject CSS variables for HiddenMenuWrapper component
21+
if (typeof document !== 'undefined') {
22+
const styleId = 'hidden-menu-wrapper-vars';
23+
if (!document.getElementById(styleId)) {
24+
const style = document.createElement('style');
25+
style.id = styleId;
26+
style.textContent = `
27+
:root {
28+
--hm-menu-bg: var(--vibes-gray-lightest);
29+
--hm-menu-text: var(--vibes-white);
30+
--hm-content-bg: #1e1e1e;
31+
--hm-shadow: rgba(0, 0, 0, 0.3);
32+
--hm-grid-line: rgba(255, 255, 255, 0.5);
33+
}
34+
35+
@media (prefers-color-scheme: dark) {
36+
:root {
37+
--hm-menu-bg: #2a2a2a;
38+
--hm-menu-text: var(--vibes-gray-ultralight);
39+
--hm-content-bg: var(--vibes-near-black);
40+
--hm-shadow: rgba(255, 255, 255, 0.1);
41+
}
42+
}
43+
`;
44+
document.head.appendChild(style);
45+
}
46+
}
47+
2048
// CSS Custom Properties (Variables) as JavaScript constants with fallbacks
2149
export const hiddenMenuTheme = {
2250
colors: {
23-
menuBg: 'var(--hm-menu-bg, #d4d4d4)',
24-
menuText: 'var(--hm-menu-text, white)',
51+
menuBg: 'var(--hm-menu-bg, var(--vibes-gray-lightest))',
52+
menuText: 'var(--hm-menu-text, var(--vibes-white))',
2553
contentBg: 'var(--hm-content-bg, #1e1e1e)',
2654
shadow: 'var(--hm-shadow, rgba(0, 0, 0, 0.3))',
2755
gridLineColor: 'var(--hm-grid-line, rgba(255, 255, 255, 0.5))',
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
import type React from 'react';
2+
3+
export function getContainerStyle(): React.CSSProperties {
4+
return {
5+
position: 'relative',
6+
display: 'inline-flex',
7+
alignItems: 'stretch',
8+
width: 'auto',
9+
marginBottom: '40px',
10+
};
11+
}
12+
13+
export function getLabelStyle(): React.CSSProperties {
14+
return {
15+
background: 'var(--vibes-card-bg)',
16+
border: '2px solid var(--vibes-card-border)',
17+
borderLeft: 'none',
18+
borderTopRightRadius: '8px',
19+
borderBottomRightRadius: '8px',
20+
padding: '12px 8px',
21+
fontWeight: 700,
22+
fontSize: '14px',
23+
textTransform: 'uppercase',
24+
letterSpacing: '1px',
25+
whiteSpace: 'nowrap',
26+
color: 'var(--vibes-card-text)',
27+
writingMode: 'vertical-rl',
28+
transform: 'rotate(180deg)',
29+
display: 'flex',
30+
alignItems: 'center',
31+
justifyContent: 'center',
32+
flexShrink: 0,
33+
margin: '32px 0px',
34+
};
35+
}
36+
37+
export function getButtonWrapperStyle(): React.CSSProperties {
38+
return {
39+
background: 'var(--vibes-card-bg)',
40+
border: '2px solid var(--vibes-card-border)',
41+
borderRadius: '8px',
42+
padding: '24px 24px 32px 24px',
43+
display: 'flex',
44+
alignItems: 'center',
45+
justifyContent: 'center',
46+
width: 'auto',
47+
};
48+
}
49+
50+
// Media query helpers (use window.matchMedia in component for responsive behavior)
51+
export function getResponsiveLabelStyle(isMobile: boolean, disappear = false): React.CSSProperties {
52+
if (isMobile) {
53+
if (disappear) {
54+
return {
55+
display: 'none',
56+
};
57+
}
58+
// When not disappearing on mobile, show label at top (horizontal)
59+
return {
60+
background: 'var(--vibes-card-bg)',
61+
border: '2px solid var(--vibes-card-border)',
62+
borderLeft: '2px solid var(--vibes-card-border)', // Explicitly set to override desktop style
63+
borderBottom: 'none',
64+
borderTopLeftRadius: '8px',
65+
borderTopRightRadius: '8px',
66+
borderBottomRightRadius: '0', // Explicitly reset desktop radius
67+
padding: '8px 12px',
68+
fontWeight: 700,
69+
fontSize: '14px',
70+
textTransform: 'uppercase',
71+
letterSpacing: '1px',
72+
whiteSpace: 'nowrap',
73+
color: 'var(--vibes-card-text)',
74+
writingMode: 'horizontal-tb', // Explicitly reset from vertical-rl
75+
transform: 'none', // Explicitly reset rotation
76+
display: 'flex',
77+
alignItems: 'center',
78+
justifyContent: 'center',
79+
flexShrink: 0,
80+
width: 'calc(100% - 64px)',
81+
margin: '0px 32px',
82+
};
83+
}
84+
// Desktop style - explicitly set all properties
85+
return {
86+
background: 'var(--vibes-card-bg)',
87+
border: '2px solid var(--vibes-card-border)',
88+
borderLeft: 'none',
89+
borderBottom: '2px solid var(--vibes-card-border)', // Explicitly set for desktop
90+
borderTopRightRadius: '8px',
91+
borderBottomRightRadius: '8px',
92+
borderTopLeftRadius: '0', // Explicitly set for desktop
93+
padding: '12px 8px',
94+
fontWeight: 700,
95+
fontSize: '14px',
96+
textTransform: 'uppercase',
97+
letterSpacing: '1px',
98+
whiteSpace: 'nowrap',
99+
color: 'var(--vibes-card-text)',
100+
writingMode: 'vertical-rl',
101+
transform: 'rotate(180deg)',
102+
display: 'flex',
103+
alignItems: 'center',
104+
justifyContent: 'center',
105+
flexShrink: 0,
106+
margin: '32px 0px',
107+
width: 'auto', // Explicitly reset from mobile width
108+
};
109+
}
110+
111+
export function getResponsiveButtonWrapperStyle(
112+
isMobile: boolean,
113+
disappear = false
114+
): React.CSSProperties {
115+
if (isMobile && disappear) {
116+
return {
117+
background: 'transparent',
118+
border: 'none',
119+
borderRadius: '0', // Explicitly reset
120+
padding: '0',
121+
paddingBottom: '24px',
122+
display: 'flex',
123+
alignItems: 'center',
124+
justifyContent: 'center',
125+
width: 'auto',
126+
};
127+
}
128+
if (isMobile && !disappear) {
129+
// When not disappearing, keep the card styling but adjust for mobile
130+
return {
131+
background: 'var(--vibes-card-bg)',
132+
border: '2px solid var(--vibes-card-border)',
133+
borderRadius: '8px',
134+
padding: '24px 24px 32px 24px',
135+
display: 'flex',
136+
alignItems: 'center',
137+
justifyContent: 'center',
138+
width: '100%',
139+
};
140+
}
141+
// Desktop style - explicitly set all properties
142+
return {
143+
background: 'var(--vibes-card-bg)',
144+
border: '2px solid var(--vibes-card-border)',
145+
borderRadius: '8px',
146+
padding: '24px 24px 32px 24px',
147+
display: 'flex',
148+
alignItems: 'center',
149+
justifyContent: 'center',
150+
width: 'auto',
151+
};
152+
}
153+
154+
export function getResponsiveContainerStyle(isMobile: boolean): React.CSSProperties {
155+
if (isMobile) {
156+
return {
157+
position: 'relative',
158+
display: 'inline-flex',
159+
alignItems: 'stretch',
160+
flexDirection: 'column',
161+
width: '100%',
162+
marginBottom: '40px',
163+
};
164+
}
165+
// Desktop style - explicitly set all properties
166+
return {
167+
position: 'relative',
168+
display: 'inline-flex',
169+
alignItems: 'stretch',
170+
flexDirection: 'row', // Explicitly set to override mobile column
171+
width: 'auto',
172+
marginBottom: '40px',
173+
};
174+
}

0 commit comments

Comments
 (0)