Skip to content

Commit 26a32fe

Browse files
JSv4claude
andcommitted
Add premium polish: layered shadows, frosted glass, and micro-interactions
Phase 2 - Premium polish refinements: - Enhance shadow tokens with multi-layer depth (sm, md, lg, xl) - Add inner shadow token for tactile input depth - Add accent-tinted shadow tokens for primary elements - Add frosted glass backdrop-filter effect to modal overlay - Add hover lift effect to primary buttons with accent glow - Add spring easing for interactive card press states - Enhance input focus with glow effect (ring + outer glow) - Add premium polish utility classes (oc-frosted, oc-lift, oc-press) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent c9e457c commit 26a32fe

7 files changed

Lines changed: 91 additions & 13 deletions

File tree

src/Button/Button.styles.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,20 @@ export const buttonStyles = `
4343
.oc-button--primary {
4444
background: linear-gradient(135deg, var(--oc-accent, #E85A4F) 0%, var(--oc-accent-hover, #D64A3F) 100%);
4545
color: white;
46-
box-shadow: var(--oc-shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.04));
46+
box-shadow: var(--oc-shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 1px rgba(0, 0, 0, 0.03)),
47+
var(--oc-shadow-accent, 0 2px 8px rgba(232, 90, 79, 0.15), 0 4px 16px rgba(232, 90, 79, 0.1));
4748
}
4849
4950
.oc-button--primary:hover:not(:disabled):not(.oc-button--loading) {
5051
background: linear-gradient(135deg, var(--oc-accent-hover, #D64A3F) 0%, var(--oc-accent-active, #C43A2F) 100%);
51-
box-shadow: var(--oc-shadow-md, 0 2px 8px rgba(0, 0, 0, 0.05));
52+
box-shadow: var(--oc-shadow-md, 0 1px 2px rgba(0, 0, 0, 0.04), 0 2px 4px rgba(0, 0, 0, 0.04), 0 4px 8px rgba(0, 0, 0, 0.03)),
53+
var(--oc-shadow-accent-lg, 0 4px 12px rgba(232, 90, 79, 0.2), 0 8px 24px rgba(232, 90, 79, 0.15));
54+
transform: translateY(-1px);
5255
}
5356
5457
.oc-button--primary:active:not(:disabled):not(.oc-button--loading) {
5558
transform: translateY(1px);
59+
box-shadow: var(--oc-shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 1px rgba(0, 0, 0, 0.03));
5660
}
5761
5862
/* Secondary variant */

src/Card/Card.styles.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const cardStyles = `
88
99
/* Variants */
1010
.oc-card--elevated {
11-
box-shadow: var(--oc-shadow-md, 0 2px 8px rgba(0, 0, 0, 0.05));
11+
box-shadow: var(--oc-shadow-md, 0 1px 2px rgba(0, 0, 0, 0.04), 0 2px 4px rgba(0, 0, 0, 0.04), 0 4px 8px rgba(0, 0, 0, 0.03));
1212
}
1313
1414
.oc-card--flat {
@@ -40,15 +40,18 @@ export const cardStyles = `
4040
/* Interactive */
4141
.oc-card--interactive {
4242
cursor: pointer;
43-
transition: box-shadow 0.15s ease, transform 0.15s ease;
43+
transition: box-shadow var(--oc-duration-fast, 0.15s) var(--oc-easing-default, cubic-bezier(0.4, 0, 0.2, 1)),
44+
transform var(--oc-duration-fast, 0.15s) var(--oc-easing-default, cubic-bezier(0.4, 0, 0.2, 1));
4445
}
4546
4647
.oc-card--interactive:hover {
47-
box-shadow: var(--oc-shadow-lg, 0 4px 16px rgba(0, 0, 0, 0.05));
48+
box-shadow: var(--oc-shadow-lg, 0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 8px rgba(0, 0, 0, 0.04), 0 8px 16px rgba(0, 0, 0, 0.04));
49+
transform: translateY(-2px);
4850
}
4951
5052
.oc-card--interactive:active {
51-
transform: scale(0.995);
53+
transform: translateY(0) scale(0.995);
54+
transition-timing-function: var(--oc-easing-spring, cubic-bezier(0.34, 1.56, 0.64, 1));
5255
}
5356
5457
/* Card Header */

src/Input/Input.styles.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@ export const inputStyles = `
2424
background: var(--oc-bg-canvas, #FFFFFF);
2525
border: 1px solid var(--oc-border-default, #E5E5E5);
2626
border-radius: var(--oc-radius-md, 8px);
27+
box-shadow: var(--oc-shadow-inner, inset 0 1px 2px rgba(0, 0, 0, 0.04));
2728
transition: border-color var(--oc-duration-fast, 0.15s) var(--oc-easing-default, cubic-bezier(0.4, 0, 0.2, 1)),
2829
box-shadow var(--oc-duration-fast, 0.15s) var(--oc-easing-default, cubic-bezier(0.4, 0, 0.2, 1));
2930
overflow: hidden;
3031
}
3132
3233
.oc-input-container:focus-within {
3334
border-color: var(--oc-accent, #E85A4F);
34-
box-shadow: 0 0 0 3px rgba(232, 90, 79, 0.1);
35+
box-shadow: var(--oc-shadow-inner, inset 0 1px 2px rgba(0, 0, 0, 0.04)),
36+
0 0 0 3px rgba(232, 90, 79, 0.1),
37+
0 0 12px rgba(232, 90, 79, 0.08);
3538
}
3639
3740
.oc-input-container--error {

src/Modal/Modal.styles.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ export const modalStyles = `
33
.oc-modal-overlay {
44
position: fixed;
55
inset: 0;
6-
background: rgba(0, 0, 0, var(--oc-opacity-overlay, 0.5));
6+
background: rgba(0, 0, 0, 0.3);
7+
backdrop-filter: blur(4px);
8+
-webkit-backdrop-filter: blur(4px);
79
display: flex;
810
align-items: center;
911
justify-content: center;
@@ -16,7 +18,7 @@ export const modalStyles = `
1618
.oc-modal {
1719
background: var(--oc-bg-canvas, #FFFFFF);
1820
border-radius: var(--oc-radius-lg, 12px);
19-
box-shadow: var(--oc-shadow-lg, 0 4px 16px rgba(0, 0, 0, 0.05)), 0 25px 50px -12px rgba(0, 0, 0, 0.25);
21+
box-shadow: var(--oc-shadow-xl, 0 2px 4px rgba(0, 0, 0, 0.04), 0 8px 16px rgba(0, 0, 0, 0.04), 0 16px 32px rgba(0, 0, 0, 0.05));
2022
max-height: calc(100vh - 32px);
2123
display: flex;
2224
flex-direction: column;

src/SearchInput/SearchInput.styles.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ export const searchInputStyles = `
2626
2727
.oc-search-input-container--focused {
2828
border-color: var(--oc-accent, #E85A4F);
29-
box-shadow: 0 0 0 3px rgba(232, 90, 79, 0.1);
29+
box-shadow: var(--oc-shadow-inner, inset 0 1px 2px rgba(0, 0, 0, 0.04)),
30+
0 0 0 3px rgba(232, 90, 79, 0.1),
31+
0 0 12px rgba(232, 90, 79, 0.08);
3032
}
3133
3234
/* Search icon */

src/tokens.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ export interface ShadowScale {
4747
sm: string;
4848
md: string;
4949
lg: string;
50+
xl: string;
51+
inner: string;
52+
accent: string;
53+
accentLg: string;
5054
}
5155

5256
export interface FontSizeScale {
@@ -150,9 +154,16 @@ export const tokens: Tokens = {
150154
full: '9999px',
151155
},
152156
shadows: {
153-
sm: '0 1px 2px rgba(0, 0, 0, 0.04)',
154-
md: '0 2px 8px rgba(0, 0, 0, 0.05)',
155-
lg: '0 4px 16px rgba(0, 0, 0, 0.05)',
157+
// Layered shadows for realistic depth
158+
sm: '0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 1px rgba(0, 0, 0, 0.03)',
159+
md: '0 1px 2px rgba(0, 0, 0, 0.04), 0 2px 4px rgba(0, 0, 0, 0.04), 0 4px 8px rgba(0, 0, 0, 0.03)',
160+
lg: '0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 8px rgba(0, 0, 0, 0.04), 0 8px 16px rgba(0, 0, 0, 0.04)',
161+
xl: '0 2px 4px rgba(0, 0, 0, 0.04), 0 8px 16px rgba(0, 0, 0, 0.04), 0 16px 32px rgba(0, 0, 0, 0.05)',
162+
// Inner shadow for depth in inputs
163+
inner: 'inset 0 1px 2px rgba(0, 0, 0, 0.04)',
164+
// Accent-tinted shadows for primary elements
165+
accent: '0 2px 8px rgba(232, 90, 79, 0.15), 0 4px 16px rgba(232, 90, 79, 0.1)',
166+
accentLg: '0 4px 12px rgba(232, 90, 79, 0.2), 0 8px 24px rgba(232, 90, 79, 0.15)',
156167
},
157168
fontSizes: {
158169
xs: '12px',

src/utilities.styles.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ export const utilitiesStyles = `
4747
--oc-breakpoint-md: 768px;
4848
--oc-breakpoint-lg: 1024px;
4949
--oc-breakpoint-xl: 1280px;
50+
51+
/* Enhanced layered shadows */
52+
--oc-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 1px rgba(0, 0, 0, 0.03);
53+
--oc-shadow-md: 0 1px 2px rgba(0, 0, 0, 0.04), 0 2px 4px rgba(0, 0, 0, 0.04), 0 4px 8px rgba(0, 0, 0, 0.03);
54+
--oc-shadow-lg: 0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 8px rgba(0, 0, 0, 0.04), 0 8px 16px rgba(0, 0, 0, 0.04);
55+
--oc-shadow-xl: 0 2px 4px rgba(0, 0, 0, 0.04), 0 8px 16px rgba(0, 0, 0, 0.04), 0 16px 32px rgba(0, 0, 0, 0.05);
56+
--oc-shadow-inner: inset 0 1px 2px rgba(0, 0, 0, 0.04);
57+
--oc-shadow-accent: 0 2px 8px rgba(232, 90, 79, 0.15), 0 4px 16px rgba(232, 90, 79, 0.1);
58+
--oc-shadow-accent-lg: 0 4px 12px rgba(232, 90, 79, 0.2), 0 8px 24px rgba(232, 90, 79, 0.15);
5059
}
5160
5261
/* ============================================
@@ -259,4 +268,48 @@ export const utilitiesStyles = `
259268
white-space: nowrap;
260269
border-width: 0;
261270
}
271+
272+
/* ============================================
273+
Premium Polish Effects
274+
============================================ */
275+
276+
/* Frosted glass overlay effect */
277+
.oc-frosted {
278+
backdrop-filter: blur(8px);
279+
-webkit-backdrop-filter: blur(8px);
280+
}
281+
282+
.oc-frosted-light {
283+
backdrop-filter: blur(4px);
284+
-webkit-backdrop-filter: blur(4px);
285+
}
286+
287+
/* Interactive lift effect on hover */
288+
.oc-lift {
289+
transition: transform var(--oc-duration-fast, 0.15s) var(--oc-easing-default, cubic-bezier(0.4, 0, 0.2, 1)),
290+
box-shadow var(--oc-duration-fast, 0.15s) var(--oc-easing-default, cubic-bezier(0.4, 0, 0.2, 1));
291+
}
292+
293+
.oc-lift:hover {
294+
transform: translateY(-2px);
295+
}
296+
297+
/* Press effect */
298+
.oc-press:active {
299+
transform: translateY(1px);
300+
}
301+
302+
/* Focus glow effect for inputs */
303+
.oc-focus-glow-input:focus-within {
304+
box-shadow: var(--oc-shadow-inner, inset 0 1px 2px rgba(0, 0, 0, 0.04)),
305+
0 0 0 3px rgba(232, 90, 79, 0.1),
306+
0 0 12px rgba(232, 90, 79, 0.08);
307+
}
308+
309+
/* Smooth color transitions */
310+
.oc-color-transition {
311+
transition: color var(--oc-duration-fast, 0.15s) var(--oc-easing-default, cubic-bezier(0.4, 0, 0.2, 1)),
312+
background-color var(--oc-duration-fast, 0.15s) var(--oc-easing-default, cubic-bezier(0.4, 0, 0.2, 1)),
313+
border-color var(--oc-duration-fast, 0.15s) var(--oc-easing-default, cubic-bezier(0.4, 0, 0.2, 1));
314+
}
262315
`;

0 commit comments

Comments
 (0)