Citrus Web Design Kit: 9 Fruit-Color Sections
Citrus web design layers saturated fruit colors — orange, lime, grapefruit — on cream, with each card's shadow tinted to match: the juice-bar site you
The full one-page landing built in this style sits below, live and scrollable. Open it, drag from the sticky nav down past the wave footer, and get the whole mood before reading a line of code. The trick behind the vivid palette turns out to be picking each card's brightness against a contrast number, not just picking pretty fruit colors — more on that in the color table below.
Nine pieces build that page, pulled apart into the grid below in the order a visitor's eye actually travels — get noticed, browse, check price, trust, act, sign up. Five of them (hero, card grid, feature list, CTA band, footer) carry the animation that shows what separates this look from soft pastel: droplet shapes instead of blurred mist, and shadows tinted to match.
Auto-plays · click a tile to jump to its section · all nine in one zip
- 01 Juice-splash hero
- 02 Citrus-slice indicator nav
- 03 Wedge-badge card grid
- 04 Squeeze-droplet icon list
- 05 Smoothie pricing
- 06 Droplet-bubble testimonial
- 07 Citrus-gradient CTA band
- 08 Wave-edge footer
- 09 Juicy buttons & inputs
The whole kit runs on nine colors, split into two jobs. Card surfaces get a lighter fruit tone chosen to clear contrast against the ink text; the deep, fully saturated version of each color is reserved for shadows, gradients, and small icon fills only.
| Role | Color | Contrast vs. ink | Where it goes |
|---|---|---|---|
| Cream | #fffaf0 |
9.83:1 | Page background |
| Orange (surface) | #ff9a52 |
4.87:1 | Hero badge, cards |
| Lime (surface) | #c8e84a |
7.35:1 | Cards, input focus ring |
| Grapefruit (surface) | #ff8fa3 |
4.73:1 | Cards, testimonial bubble shadow |
| Lemon (surface) | #ffe066 |
7.84:1 | Cards, pricing |
| Orange (deep) | #ff6a00 |
3.56:1 | Shadows, gradients, button fill only |
| Ink | #204a17 |
— | All text (10.23:1 on white) |
01Juice-splash hero
Three droplets — asymmetric border-radius shapes rotated 45 degrees, not blurred circles — bounce and swap places over the cream field while the white card in front presses in with every landing. Sharp droplets instead of soft mist is the first tell that separates this style from pastel candy.
.drop::before {
content: "";
width: 100%; height: 100%;
border-radius: 50% 50% 50% 4px; /* droplet shape */
transform: rotate(45deg);
}
@keyframes dropA {
0%, 100% { transform: translate(0, 0) scale(1) rotate(0deg); }
50% { transform: translate(8%, -10%) scale(1.15) rotate(-8deg); }
}
02Citrus-slice indicator nav
The lime wedge marking the active tab stretches mid-hop and springs back tight on arrival. Its width is a quarter of the track minus 4px of inset, so the travel distance needs the same 4px added back or the wedge drifts short with every hop.
.wedge {
width: calc(25% - 4px);
animation: wedgeWalk 2s cubic-bezier(.2,.8,.2,1) infinite;
}
@keyframes wedgeWalk {
0%, 24% { transform: translateX(0) scaleY(1); }
36%, 49% { transform: translateX(calc(100% + 4px)) scaleY(1); }
}
03Wedge-badge card grid
Each tile carries its own fruit tone — orange, lime, grapefruit, lemon — with a matching-family shadow and a wedge-shaped badge tucked in the corner. The four tiles pop up on a quarter-beat stagger, one after another.
.card { animation: cardPop 2s cubic-bezier(.2,.8,.2,1) infinite; }
.card--lim { background: #c8e84a; animation-delay: -500ms; }
@keyframes cardPop {
0%, 100% { transform: translateY(0) scale(1); }
30% { transform: translateY(-8px) scale(1.02); }
}
04Squeeze-droplet icon list
Each row is a white pill card holding a round icon drawn with repeating-conic-gradient to read as citrus pulp. Offsetting the start time per row makes the droplets squeeze to their own beat. This item moves the least pixel area of the nine — 2.4% — yet its intensity still measures 56.4, sharp enough to read clearly against the white card.
.drop {
background: repeating-conic-gradient(#ff9a52 0deg 45deg, #ffe066 45deg 90deg);
animation: dropSqueeze 2s cubic-bezier(.2,1.4,.4,1) infinite;
}
@keyframes dropSqueeze {
0%, 40%, 100% { transform: scale(1, 1); }
15% { transform: scale(1.18, .78); }
}
05Smoothie pricing
Three plans sit in lime, orange (the recommended tier), and grapefruit like smoothie cups. Only the recommended plan gets an orange-to-lemon gradient ring, a badge, extra size, and a slow jiggle — color and scale alone carry the hierarchy, no table needed.
.plan--pick {
flex: 1.2 1 0;
background: linear-gradient(135deg, #ff6a00, #ffe066);
animation: pickJiggle 2s cubic-bezier(.2,.8,.2,1) infinite;
}
@keyframes pickJiggle {
0%, 100% { transform: rotate(0deg) translateY(0); }
25% { transform: rotate(-1.6deg) translateY(-5px); }
}
06Droplet-bubble testimonial
The quote sits in a rounded bubble with a droplet-shaped tail, next to a citrus-pulp avatar. The bubble's height breathes in and out on a loop, giving the whole card the springy give of jelly held between chopsticks.
.bubble::before {
content: "";
width: 16px; height: 16px;
border-radius: 50% 50% 50% 4px; /* the tail is a droplet too */
background: #fff;
transform: rotate(45deg);
}
07Citrus-gradient CTA band
One band carries a gradient flowing orange to lemon to lime, its position drifting slowly, while the white button on top presses in and springs back. This section comes back in the trap section below — the first version put white text directly on the moving gradient and contrast collapsed at the lemon stop.
.ctacitrus {
background: linear-gradient(90deg, #ff6a00, #ffd400, #9ad200, #ffd400, #ff6a00);
background-size: 300% 100%;
animation: gradFlow 2s linear infinite;
}
@keyframes gradFlow {
0% { background-position: 0% 50%; }
100% { background-position: -300% 50%; }
}
08Wave-edge footer
The footer's top edge is a row of waves drawn by one repeating background, not one element per curve. The three columns beneath sit in orange, grapefruit, and lemon, lifting in sequence, while two droplet sparkles twinkle out of phase.
.wave {
height: 12px;
background-image: radial-gradient(circle at 50% 100%, #eef7d3 0 64%, transparent 66%);
background-size: 30px 15px;
background-repeat: repeat-x;
}
09Juicy buttons & inputs
The button's body and shadow sink together on press for tactile feedback, and the input grows a soft lime ring on focus. This one item bundles every hand-feel cue the kit uses elsewhere.
.btn { animation: citrusPress 2s cubic-bezier(.2,.8,.2,1) infinite; }
@keyframes citrusPress {
0%, 55%, 100% { transform: translateY(0) scaleY(1); }
65% { transform: translateY(4px) scaleY(.95); }
82% { transform: translateY(-3px); }
}
Custom tailwind.config
Four card-surface colors and their deep, shadow-only counterparts live in one place, so the landing page and all nine parts stay on the same contrast rule. The -deep suffix is a naming reminder: never put text on those.
theme: {
extend: {
colors: {
cream: "#fffaf0", orange: "#ff9a52", "orange-deep": "#ff6a00",
lime: "#c8e84a", grapefruit: "#ff8fa3", lemon: "#ffe066",
ink: "#204a17",
},
borderRadius: { citrus: "24px", control: "12px", pill: "999px" },
boxShadow: {
"citrus-orange": "0 10px 24px rgba(255,106,0,.4)",
"citrus-lime": "0 10px 24px rgba(200,232,74,.8)",
},
},
},
Vibe-Coding Prompt
Once the config is in your project, this is the whole instruction Claude Code or Cursor needs. Spelling out that higher saturation eats into contrast keeps the tool from grabbing a deep tone for a card surface and burying the text on it. The full eleven-rule prompt ships in the zip's prompt.md.
Unify the background on cream (#fffaf0). Give each card one surface tone —
orange, lime, grapefruit, or lemon (the deep versions are shadow/gradient
only, never a text background). Shadows match the card's color family, never
gray. Text is always ink (#204a17).
Applying that instruction to page/index.html and capturing the result at a 1280px viewport produced the screenshot below.

Where it breaks (the trap)
The first real break showed up at a 320px render: the hero card overflowed the frame. With three droplets hanging past the card's edges, the 480×300 stage looked fine, but shrinking to 320×200 pushed document.documentElement.scrollHeight to 213px against a 200px innerHeight. Trimming card padding, the title size, and the droplets' negative offsets together inside the phone media query brought it back to exactly 200px. Design-trend posts like this one sit outside the check.py BD9 gate, which only runs against the per-item collection format — so the 320px overflow had to be measured by hand with Playwright, checking both document.documentElement and document.body on width and height.
The second break was contrast on the CTA band. White text sitting directly on the orange-to-lemon-to-lime gradient measured 1.43:1 against the lemon stop (#ffd400) and 1.81:1 against the lime stop — both far under the WCAG 2.1 minimum of 4.5:1. Computing the numbers showed that a 65%-opacity ink scrim behind the text holds the worst case at 4.7:1 across every stop the gradient passes through, and that's the fix now live in the demo. Both fixes are baked into the files behind the password 52ppc9vv in the zip below.
All nine demos honor the query defined by MDN's prefers-reduced-motion guide: motion-sensitive visitors get every element frozen at its pre-animation rest state, so nothing moves but nothing disappears either.
Accessibility (accessibility)
Citrus hits the saturation problem before pastel ever does. Left at full saturation, a card surface drops ink-text contrast to 3.56:1 on deep orange or 2.98:1 on deep grapefruit — both under the 4.5:1 body-text floor. That's why this kit keeps four separate, lighter surface tones (4.73–7.84:1 against ink) for anything carrying text, and reserves the fully saturated colors for shadows, gradients, and small icon fills. Where white text has to sit on a moving gradient, as in section 07, the fix is the 65%-ink scrim described above. Colored shadows follow the standard MDN box-shadow syntax at 0.4–0.85 opacity, and keyboard focus gets its own :focus-visible ink outline rather than leaning on any shadow to show where the cursor is.
Looking for a different homepage trend? Browse the design trends category; the about page covers what this whole blog ships.
FAQ
How is citrus fresh different from pastel candy?
Pastel candy desaturates its palette — lavender, mint — and keeps shadows soft for a gentle mood. Citrus fresh keeps the fruit colors at near-full saturation but splits surface brightness from shadow brightness to protect contrast. Both use color-matched shadows; pastel goes soft, citrus goes vivid.
Why can't I use the deep, saturated color as a card background?
The deeper and more saturated a color gets, the closer its brightness sits to the ink text on top of it, and the ratio between them shrinks. This kit's deep orange (#ff6a00) measures 3.56:1 against ink — under the 4.5:1 body-text floor. Keep card surfaces on the lighter tone within that color family, and save the deep tone for shadows or gradients where no text sits directly on top.
What do I do when text has to sit on a gradient?
A moving gradient changes color under the text, so checking contrast at one frame isn't enough — a different stop will fail later. This kit's CTA band solves it with a semi-transparent dark scrim (65% ink) behind the text, which holds a safe contrast ratio across every stop the gradient passes through. Skipping the scrim and placing white text straight on the gradient will fail almost every time it crosses a light stop.