📦 deps(thirdparty): update snapshots
This commit is contained in:
@@ -0,0 +1,309 @@
|
||||
---
|
||||
name: gradient-design
|
||||
description: Web and App implementation guide for Gradient Design. Trigger when user wants heavy gradient usage, vibrant transitions, and modern energetic feels.
|
||||
date_added: "2026-06-17"
|
||||
risk: safe
|
||||
source: self
|
||||
source_type: self
|
||||
---
|
||||
|
||||
# Gradient Design
|
||||
|
||||
> "Color in motion. Fluid transitions that add energy and depth to flat surfaces."
|
||||
|
||||
|
||||
## When to Use
|
||||
Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the `design-it` skill and is not meant to be triggered directly.
|
||||
|
||||
## Core Principles
|
||||
1. **Gradients are the Primary Visual**: Backgrounds, buttons, text, and borders all use gradients instead of solid colors.
|
||||
2. **Analogous or Complementary Blends**: Gradients must be carefully chosen so the transition colors don't become muddy (e.g., blending red to green creates a muddy brown in the middle. Blend red to yellow to green instead).
|
||||
3. **Subtle Animation**: Background gradients should slowly shift and rotate.
|
||||
|
||||
## Visual DNA
|
||||
- **Colors**: **Warm Tech** (blues to oranges) or create custom vibrant pairs (e.g., Purple to Coral, Deep Blue to Cyan).
|
||||
- **Typography**: Clean, heavy sans-serifs that can be easily masked with a gradient fill.
|
||||
- **Layout**: Keep the UI structure minimal (glass panels or white/black cards) to let the gradients breathe.
|
||||
|
||||
## Web Implementation
|
||||
- **CSS Example**:
|
||||
```css
|
||||
body {
|
||||
/* Complex mesh-like animated gradient */
|
||||
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
|
||||
background-size: 400% 400%;
|
||||
animation: gradientBG 15s ease infinite;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@keyframes gradientBG {
|
||||
0% { background-position: 0% 50%; }
|
||||
50% { background-position: 100% 50%; }
|
||||
100% { background-position: 0% 50%; }
|
||||
}
|
||||
|
||||
.gradient-text {
|
||||
background: linear-gradient(90deg, #F9D423 0%, #FF4E50 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
font-size: 4rem;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.gradient-border-card {
|
||||
background: #ffffff;
|
||||
color: #333;
|
||||
padding: 32px;
|
||||
border-radius: 12px;
|
||||
position: relative;
|
||||
/* Use a pseudo-element for the gradient border */
|
||||
}
|
||||
.gradient-border-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -3px; left: -3px; right: -3px; bottom: -3px;
|
||||
background: linear-gradient(90deg, #8A2387, #E94057, #F27121);
|
||||
z-index: -1;
|
||||
border-radius: 15px;
|
||||
}
|
||||
```
|
||||
|
||||
## App Implementation
|
||||
|
||||
### SwiftUI
|
||||
```swift
|
||||
struct GradientDesignView: View {
|
||||
@State private var animateGradient = false
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
// Animated Background Gradient
|
||||
LinearGradient(
|
||||
colors: [Color(hex: "ee7752"), Color(hex: "e73c7e"), Color(hex: "23a6d5"), Color(hex: "23d5ab")],
|
||||
startPoint: animateGradient ? .topLeading : .bottomLeading,
|
||||
endPoint: animateGradient ? .bottomTrailing : .topTrailing
|
||||
)
|
||||
.ignoresSafeArea()
|
||||
.onAppear {
|
||||
withAnimation(.linear(duration: 5.0).repeatForever(autoreverses: true)) {
|
||||
animateGradient.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
VStack(spacing: 40) {
|
||||
// Gradient Text
|
||||
Text("VIBRANT")
|
||||
.font(.system(size: 60, weight: .black))
|
||||
.foregroundStyle(
|
||||
LinearGradient(
|
||||
colors: [Color(hex: "F9D423"), Color(hex: "FF4E50")],
|
||||
startPoint: .leading,
|
||||
endPoint: .trailing
|
||||
)
|
||||
)
|
||||
|
||||
// Gradient Border Card
|
||||
Text("Gradient Border")
|
||||
.padding()
|
||||
.frame(width: 250, height: 150)
|
||||
.background(Color.white)
|
||||
.cornerRadius(12)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.stroke(
|
||||
LinearGradient(
|
||||
colors: [Color(hex: "8A2387"), Color(hex: "E94057"), Color(hex: "F27121")],
|
||||
startPoint: .leading, endPoint: .trailing
|
||||
),
|
||||
lineWidth: 3
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- `.foregroundStyle(LinearGradient(...))` makes gradient text incredibly easy in modern SwiftUI.
|
||||
- Use `.stroke(LinearGradient(...))` inside an `.overlay` to create gradient borders.
|
||||
|
||||
### Flutter
|
||||
```dart
|
||||
class GradientDesignScreen extends StatefulWidget {
|
||||
@override
|
||||
State<GradientDesignScreen> createState() => _GradientDesignScreenState();
|
||||
}
|
||||
|
||||
class _GradientDesignScreenState extends State<GradientDesignScreen> with SingleTickerProviderStateMixin {
|
||||
late AnimationController _controller;
|
||||
late Animation<Alignment> _topAlignment;
|
||||
late Animation<Alignment> _bottomAlignment;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = AnimationController(vsync: this, duration: const Duration(seconds: 5))..repeat(reverse: true);
|
||||
_topAlignment = TweenSequence<Alignment>([
|
||||
TweenSequenceItem(tween: AlignmentTween(begin: Alignment.topLeft, end: Alignment.topRight), weight: 1),
|
||||
]).animate(_controller);
|
||||
_bottomAlignment = TweenSequence<Alignment>([
|
||||
TweenSequenceItem(tween: AlignmentTween(begin: Alignment.bottomRight, end: Alignment.bottomLeft), weight: 1),
|
||||
]).animate(_controller);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: AnimatedBuilder(
|
||||
animation: _controller,
|
||||
builder: (context, _) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
// Animated Background Gradient
|
||||
gradient: LinearGradient(
|
||||
begin: _topAlignment.value,
|
||||
end: _bottomAlignment.value,
|
||||
colors: const [Color(0xFFee7752), Color(0xFFe73c7e), Color(0xFF23a6d5), Color(0xFF23d5ab)],
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// Gradient Text
|
||||
ShaderMask(
|
||||
blendMode: BlendMode.srcIn,
|
||||
shaderCallback: (bounds) => const LinearGradient(
|
||||
colors: [Color(0xFFF9D423), Color(0xFFFF4E50)],
|
||||
).createShader(Rect.fromLTWH(0, 0, bounds.width, bounds.height)),
|
||||
child: const Text('VIBRANT', style: TextStyle(fontSize: 60, fontWeight: FontWeight.w900, color: Colors.white)),
|
||||
),
|
||||
const SizedBox(height: 40),
|
||||
// Gradient Border Card
|
||||
Container(
|
||||
width: 250, height: 150,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
gradient: const LinearGradient(colors: [Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121)]),
|
||||
),
|
||||
padding: const EdgeInsets.all(3), // Border width
|
||||
child: Container(
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(12)),
|
||||
alignment: Alignment.center,
|
||||
child: const Text('Gradient Border'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
- Flutter text gradients require `ShaderMask` with `BlendMode.srcIn`.
|
||||
- To animate a gradient background, animate the `Alignment` values of the `LinearGradient`.
|
||||
|
||||
### React Native
|
||||
```jsx
|
||||
// REQUIRES: expo-linear-gradient OR react-native-linear-gradient
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import MaskedView from '@react-native-masked-view/masked-view';
|
||||
|
||||
const GradientDesignScreen = () => {
|
||||
return (
|
||||
<LinearGradient
|
||||
colors={['#ee7752', '#e73c7e', '#23a6d5', '#23d5ab']}
|
||||
start={{ x: 0, y: 0 }} end={{ x: 1, y: 1 }}
|
||||
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}
|
||||
>
|
||||
{/* Gradient Text */}
|
||||
<MaskedView
|
||||
style={{ height: 80, width: '100%', flexDirection: 'row' }}
|
||||
maskElement={
|
||||
<View style={{ backgroundColor: 'transparent', flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
||||
<Text style={{ fontSize: 60, fontWeight: '900', color: 'black' }}>VIBRANT</Text>
|
||||
</View>
|
||||
}
|
||||
>
|
||||
<LinearGradient
|
||||
colors={['#F9D423', '#FF4E50']}
|
||||
start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
</MaskedView>
|
||||
|
||||
<View style={{ marginTop: 40 }}>
|
||||
{/* Gradient Border Card */}
|
||||
<LinearGradient
|
||||
colors={['#8A2387', '#E94057', '#F27121']}
|
||||
start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }}
|
||||
style={{ padding: 3, borderRadius: 15 }}
|
||||
>
|
||||
<View style={{ backgroundColor: '#FFF', width: 250, height: 150, borderRadius: 12, justifyContent: 'center', alignItems: 'center' }}>
|
||||
<Text>Gradient Border</Text>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
);
|
||||
};
|
||||
```
|
||||
- Gradient text in React Native is notoriously annoying. You must use `@react-native-masked-view/masked-view` to mask a `LinearGradient` with a `<Text>` node.
|
||||
- Gradient borders are achieved by nesting a solid view inside a `LinearGradient` with a small padding (e.g., `padding: 3`).
|
||||
|
||||
### Jetpack Compose
|
||||
```kotlin
|
||||
@Composable
|
||||
fun GradientDesignScreen() {
|
||||
// Animated Background
|
||||
val infiniteTransition = rememberInfiniteTransition()
|
||||
val offset by infiniteTransition.animateFloat(
|
||||
initialValue = 0f, targetValue = 1000f,
|
||||
animationSpec = infiniteRepeatable(tween(5000, easing = LinearEasing), RepeatMode.Reverse)
|
||||
)
|
||||
|
||||
val bgBrush = Brush.linearGradient(
|
||||
colors = listOf(Color(0xFFee7752), Color(0xFFe73c7e), Color(0xFF23a6d5), Color(0xFF23d5ab)),
|
||||
start = Offset(offset, 0f), end = Offset(offset + 500f, 1000f)
|
||||
)
|
||||
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize().background(bgBrush),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
// Gradient Text
|
||||
val textBrush = Brush.horizontalGradient(listOf(Color(0xFFF9D423), Color(0xFFFF4E50)))
|
||||
Text(
|
||||
text = "VIBRANT",
|
||||
style = TextStyle(brush = textBrush, fontSize = 60.sp, fontWeight = FontWeight.Black)
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(40.dp))
|
||||
|
||||
// Gradient Border Card
|
||||
val borderBrush = Brush.horizontalGradient(listOf(Color(0xFF8A2387), Color(0xFFE94057), Color(0xFFF27121)))
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(250.dp, 150.dp)
|
||||
.border(3.dp, borderBrush, RoundedCornerShape(12.dp))
|
||||
.background(Color.White, RoundedCornerShape(12.dp)),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text("Gradient Border")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- Compose handles gradients beautifully via `Brush`.
|
||||
- You can pass a `Brush` directly into a `TextStyle` for gradient text, or into a `Modifier.border()` for gradient borders.
|
||||
|
||||
## Do's and Don'ts
|
||||
- **DO**: Use multi-stop gradients (3 or 4 colors) rather than just simple A-to-B gradients for a more modern, rich look.
|
||||
- **DON'T**: Apply gradients to tiny text or thin icons, they will lose legibility immediately.
|
||||
|
||||
## Limitations
|
||||
- This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review.
|
||||
- Ensure appropriate contrast ratios and responsive behaviors are verified separately.
|
||||
Reference in New Issue
Block a user