Display

Gradient Icon Tile

A gradient icon tile whose whole colour pair is derived from a single hue angle: you cannot knock the gradient out of tune by picking colours by hand.

  • icontile
  • gradient
  • icon
  • hue

Preview

1440pxHost theme

Use it with AI

  1. 1. Copy the link.
  2. 2. Write to your agent in your own words and drop the link into the sentence.
  3. 3. The agent opens the link and installs the component from the registry.

put this in the header: https://vibeui.ru/c/icontile-002?lang=en

Show the full instructions

What the link says, spelled out. Use it when your agent cannot open links — paste this text instead.

# Install and place "icontile-002" (Gradient Icon Tile) from VibeUI

## 1. Install first — do not skip, do not recreate
Run this exact command before writing any code:
npx shadcn@latest add https://vibeui.ru/r/icontile-002.json

Registry item: https://vibeui.ru/r/icontile-002.json
Installs to: components/vibeui/icontile-002.tsx (the exact path follows this project's components.json aliases).
npm dependencies: none.
Registry dependencies: none.

Install it from the registry. Do not recreate it from the description,
do not substitute a similar component from another library, and do not
rewrite it to match the project's existing style.

## 2. What it is
A gradient icon tile whose whole colour pair is derived from a single hue angle: you cannot knock the gradient out of tune by picking colours by hand.

A gradient icon tile: both gradient stops are derived from hue and the size comes from one variable. Zero dependencies, one file, no client JS.

## 3. How to use it
import { Icontile002 } from "@/components/vibeui/icontile-002"

<Icontile002 glyph="◆" hue={262} size="md" label="Projects" />

Read the installed file for the full prop list.

## 4. Where to place it
This is a small inline component. Put it exactly where the user asked,
inside the existing markup. Do not create a new page, section or
wrapper for it. If a similar control already sits in that spot,
replace it instead of adding a second one.

Placement: ___
(The user fills this line in. If it is still blank, ask where to put it
instead of guessing.)

## 5. Keep exactly as installed
- the local --vibeui-icontile-002-* palette — do not swap it for your theme tokens
- deriving the second gradient stop from hue: hand-picked colours fall out of tune in the first row of tiles
- the inset shadow instead of a border — a border changes the tile size and breaks the icon grid
- the glyph size as a fraction of the tile: otherwise it hits the edges at sm and gets lost at lg
- aria-hidden without a label: a decorative tile must not be announced by a screen reader
- the light glyph over the gradient: a dark one loses contrast on a saturated fill

## 6. You may change
- the glyph inside the tile through glyph
- the tile colour through hue: one number moves the whole gradient
- the size through size: sm, md or lg
- the radius through the --vibeui-icontile-002-radius variable

## 7. Rules
- The glyph is a character, not an svg: drop your own element inside for an icon set.
- oklch and calc in colours need a current browser; older ones leave the tile without a fill.
- An over-long glyph spills outside: the tile is sized for one or two characters.
- Do not lift the CSS variables into globals.css: the component has to stay a single file.

## 8. Verify
- it renders with no console errors;
- it looks like the preview on the VibeUI page you copied this from;
- if it does not, you changed something listed in section 5 — put it back.

For developers

npx shadcn@latest add https://vibeui.ru/r/icontile-002.json
https://vibeui.ru/r/icontile-002.json

Серверный компонент, хуков нет. Оба края градиента выведены из переменной --vibeui-icontile-002-hue: второй берётся сдвигом на 32° по тому же кругу oklch, поэтому пара всегда согласована, а перекрасить плитку можно одним числом. Внутренняя светлая рамка сделана inset-тенью, а не border: border съедал бы размер плитки и сбивал сетку иконок. Размер задаётся data-size и одной переменной, от которой считаются радиус и кегль знака. Плитка декоративна: без label она получает aria-hidden, с label — role=img и доступное имя.

Component source

The same file your agent installs. Here in case you would rather copy it by hand.

import type { ComponentPropsWithoutRef, CSSProperties } from "react"

export type Icontile002Props = Omit<
  ComponentPropsWithoutRef<"span">,
  "children" | "color"
> & {
  glyph?: string
  hue?: number
  size?: "sm" | "md" | "lg"
  label?: string
}

// Идея компонента: градиентная плитка, у которой весь цвет считается от
// одного числа — угла оттенка. Второй край градиента берётся сдвигом на 32°
// по тому же кругу, поэтому пара всегда согласована и её нельзя испортить
// случайным подбором. Светлая рамка внутри (inset-тень) отделяет плитку от
// тёмного фона: без неё градиент на тёмной подложке теряет границу.
const STYLES = `
:where([data-vibeui-block="icontile-002"]){
--vibeui-icontile-002-hue:262;
--vibeui-icontile-002-size:2.75rem;
--vibeui-icontile-002-radius:0.875rem;
--vibeui-icontile-002-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}
/* Оба края градиента считаются от одного угла: пару нельзя рассогласовать. */
[data-vibeui-block="icontile-002"]{
display:inline-flex;align-items:center;justify-content:center;flex:none;
box-sizing:border-box;
width:var(--vibeui-icontile-002-size);height:var(--vibeui-icontile-002-size);
border-radius:var(--vibeui-icontile-002-radius);
background:linear-gradient(145deg,
oklch(0.72 0.17 var(--vibeui-icontile-002-hue)) 0%,
oklch(0.5 0.19 calc(var(--vibeui-icontile-002-hue) + 32)) 100%);
box-shadow:inset 0 0 0 1px oklch(1 0 0 / 28%);
color:oklch(0.99 0.01 var(--vibeui-icontile-002-hue));
font-family:var(--vibeui-icontile-002-font);
font-size:calc(var(--vibeui-icontile-002-size) * 0.42);
font-weight:650;line-height:1;
}
[data-vibeui-block="icontile-002"][data-size="sm"]{--vibeui-icontile-002-size:2rem;--vibeui-icontile-002-radius:0.625rem}
[data-vibeui-block="icontile-002"][data-size="lg"]{--vibeui-icontile-002-size:3.5rem;--vibeui-icontile-002-radius:1.125rem}
@media (prefers-reduced-motion:reduce){[data-vibeui-block="icontile-002"]{animation:none!important;transition:none!important}}
`

/**
 * Градиентная плитка под иконку: обе точки градиента считаются от hue.
 * Один файл, ноль зависимостей, собственная палитра.
 */
export function Icontile002({
  glyph = "◆",
  hue = 262,
  size = "md",
  label,
  className,
  style,
  ...props
}: Icontile002Props) {
  const palette = {
    "--vibeui-icontile-002-hue": hue,
    ...style,
  } as CSSProperties

  return (
    <>
      <style href="vibeui-icontile-002" precedence="medium">
        {STYLES}
      </style>
      <span
        {...props}
        data-vibeui-block="icontile-002"
        data-size={size}
        role={label ? "img" : undefined}
        aria-label={label}
        aria-hidden={label ? undefined : true}
        className={className}
        style={palette}
      >
        {glyph}
      </span>
    </>
  )
}