Grove UI 25 components · rose + platform

Grove UI

Glass link cards, rose/coral profile aesthetic, pill buttons, and social icons — extracted from a mobile-first link-in-bio profile page. The glassmorphism link card is the hero component.

Colour

Two-mode system. Dark (profile) = rose background with glass cards. Light (platform) = warm off-white with clean surfaces. Both modes share the rose accent.

Profile (dark)

bg-page
#E37282
glass bg
rgba(255,255,255,0.10)
glass hover
rgba(255,255,255,0.18)
pill action
rgba(0,0,0,0.14)
text primary
#FFFFFF
text secondary
80% white

Platform (light)

bg-page
#EFF0EC
surface
#FFFFFF
accent
#E37282
text primary
#1A1A1A
text secondary
#78716C
text muted
#A8A29E
border
#E7E5E4

Typography

Inter for all body/UI text. Anton (free Google Fonts substitute for source commercial display font) at 60px for the profile name. Measured directly from source elements.

Profile Name
Hello, it's me. — 16px Inter 500
Link card title — 14px Inter 600
Link card description — 14px Inter 400
Meta / attribution text — 12px Inter 400
TokenValueUsage
--font-display'Anton', Impact, sans-serifProfile name h1
--font-body'Inter', system-uiAll UI text
--size-display60pxh1 — measured
--lh-display57pxh1 line-height — measured
--size-base16pxh2 / body — measured
--size-sm14pxCard text — measured
--size-xs12pxLinks / meta — measured

Spacing

4px base unit. Link card vertical padding 16px, horizontal 24px. Pill button height 48px, glass link card height 64px — all measured.

--space-1 · 4px
--space-2 · 8px
--space-4 · 16px — card v-padding
--space-6 · 24px — card h-padding
--space-8 · 32px
--pill-height · 48px — pill button
--card-height · 64px — glass link card
--card-height-lg · 127px — media card

Elevation

Very subtle shadows — the glass cards use near-invisible glow. Heavier shadows reserved for modals. Layered factorial shadow also detected.

shadow-xs
0px 0px 8px rgba(0,0,0,0.02)
Glass link card
shadow-md
6px 14px rgba(0,0,0,0.08)
Hover / cards
shadow-xl
24px 32px rgba(0,0,0,0.15)
Modals
shadow-layered
Factorial 2/4/8/16/32px
Soft depth card

Border radius

6
16
28
32
pill

Motion

Fast 75ms transitions on link cards. Spring easing (0.34, 1.56, 0.64, 1) detected. Four named link-card animations: wobble, pop, buzz, swipe.

Click a card to trigger its animation

TokenValue
--duration-fast75ms — link card transition
--duration-normal150ms
--duration-slow300ms
--ease-springcubic-bezier(0.34, 1.56, 0.64, 1)
--transition-cardtransform 75ms, box-shadow 75ms, background-color 75ms

Navigation

Profile page nav: logo icon + subscribe button + share icon. Platform view nav: wordmark + text links.

<nav class="grove-nav">
  <a href="#" class="grove-nav__wordmark">Brand</a>
  <ul class="grove-nav__links">
    <li><a href="#" class="grove-nav__link is-active">Links</a></li>
    <li><a href="#" class="grove-nav__link">Appearance</a></li>
  </ul>
</nav>

Profile hero

Full-width profile header with animated gradient background, profile name in chunky display type, bio line, and profile nav. On mobile this is ~70% of viewport height.

Profile Name

Short tagline or bio

Avatar

Measured at 142×142px with 5px border-radius (near-square). White ring variant also observed.

🎭
Default 142×142 br:5px
🎭
Circle + ring 96px
🎭
Small 60px

Ambient radial-blur backdrop

<!-- Default (near-square, measured) -->
<img class="grove-avatar" src="photo.jpg" alt="Profile photo" width="142" height="142">

<!-- Circle variant -->
<img class="grove-avatar grove-avatar--circle" src="photo.jpg" alt="Profile photo" width="96" height="96">

<!-- Circle with ring -->
<img class="grove-avatar grove-avatar--circle grove-avatar--ring" ...>

<!-- Ambient glow: blurred duplicate of the hero image, radial-masked.
     Place inside a position:relative parent, behind the avatar. -->
<div class="grove-ambient-blur" aria-hidden="true">
  <img src="photo.jpg" alt="">
</div>

Social icons

Bare 48×48px icon buttons (8px padding → 32px icon) with no background or border — just the icon tinted in the profile text colour. Hover scales to 107.5%. A flex-wrap row centred below the profile header. (Demo uses neutral emoji glyphs in place of platform logos.)

<div class="grove-social-row">
  <a href="https://instagram.com/…" class="grove-social-icon" aria-label="Instagram">
    <!-- SVG icon -->
  </a>
  <a href="https://tiktok.com/…" class="grove-social-icon" aria-label="TikTok">
    <!-- SVG icon -->
  </a>
</div>

Pill button

Action / donate / CTA button. 48px tall, pill radius, rgba(0,0,0,0.14) bg on rose — giving a deeper rose tint on hover to rgba(0,0,0,0.22). All values measured.

<button class="grove-btn-pill">Donate</button>
<button class="grove-btn-pill grove-btn-pill--sm">Follow</button>

<!-- Subscribe (white bg) -->
<button class="grove-btn-subscribe">🔔 Subscribe</button>

Icon button

40px glass icon button for share/action. Circular, rgba(255,255,255,0.20) background, appears in profile header.

<button class="grove-btn-icon" aria-label="Share">
  <svg …></svg>
</button>

Tabs

The profile's "Links / Shop" switcher. A 192px pill rail on a translucent black ground (rgba(0,0,0,0.4), darkening to 0.5 on hover) with 2px inset padding. Two 48px tab buttons split the width; a white pill slides behind the active tab (active label turns black, inactive stays white). Keyboard-navigable with arrow keys. All values measured.

<nav class="grove-tabnav" data-tabnav="demo" aria-label="Sections">
  <div class="grove-tabnav__list" role="tablist">
    <span class="grove-tabnav__pill" aria-hidden="true"></span>
    <button class="grove-tabnav__tab" role="tab" aria-selected="true">Links</button>
    <button class="grove-tabnav__tab" role="tab" aria-selected="false">Shop</button>
  </div>
</nav>

<!-- components.js sizes the pill (100/N %) and slides it on click/arrow keys.
     Optional: add data-tabpanel="demo" to panels to toggle them. -->

Text input

From the contact form modal. 48px tall, 16px radius, 1.5px border, rose focus ring at 20% opacity.

<input class="grove-input" type="text" placeholder="Your name">
<input class="grove-input grove-input--error" type="email" aria-invalid="true">

Select

Toggle

Enable notifications
Show email publicly
<label class="grove-toggle">
  <input type="checkbox">
  <span class="grove-toggle__track"></span>
</label>

Checkbox

Slider

This component was not present in the source site.

Badges

"NEW" sticker detected with a yellow-green (#C8F44E) rotated chip. Standard rose-accent badge also present. Pill variant and outline variant included.

Rose Pill Outline NEW
NEW Live Featured
<span class="grove-badge">Tag</span>
<span class="grove-badge grove-badge--pill">Pill</span>
<span class="grove-badge grove-badge--outline">Outline</span>
<span class="grove-badge grove-badge--star">NEW</span>

Card

Two card types: glass card (on rose, rgba white) and platform card (on white, border + shadow).

Platform card
White surface · border + shadow-sm · 24px radius

Stat

A 2-column grid of metric tiles (gap: 2px). Each tile is a 20px-radius rgba(0,0,0,0.05) card with a 32px icon, then the figure in Inter extrabold (800) at 36px with tracking-tight (−0.9px) and tabular-nums, and a 12px label beneath at 0.7 opacity. Measured directly — the figure is not the Anton display face.

40 Videos
90M Views
<div class="grove-stats-grid">
  <div class="grove-stat">
    <svg class="grove-stat__icon" …></svg>
    <span class="grove-stat__value">90M</span>
    <span class="grove-stat__label">Views</span>
  </div>
</div>

Code block

This component was not present in the source site.

Table

This component was not present in the source site.

Pricing

This component was not present in the source site.

Modal

Bottom-sheet style. Slides up with spring easing. White surface, 28px top radius, shadow-xl. Detected as privacy consent + subscribe modals.

<div id="modal-id" class="grove-modal-backdrop" role="dialog" aria-modal="true">
  <div class="grove-modal">
    <div class="grove-modal__header">
      <h2 class="grove-modal__title">Title</h2>
      <button class="grove-modal__close" data-modal-close aria-label="Close">✕</button>
    </div>
    <p class="grove-modal__body">Content</p>
    <div class="grove-modal__actions">
      <button class="grove-btn-pill">Confirm</button>
    </div>
  </div>
</div>

Progress

Poll vote result bars. Rose accent fill, 8px height, pill radius.

Option A72%
Option B28%
<div class="grove-progress">
  <div class="grove-progress__bar" data-progress="72"></div>
</div>

Skeleton

Shimmer loading state matching the glass card and text dimensions.

Toast

This component was not present in the source site.

Empty state

This component was not present in the source site.