My styling conventions
Skill AGilbertDev/agilbertdev-recipes/skills/my-styling-conventions
My reusable coding-agent conventions and a curated skill set, pulled into any project like a versioned package.
npx -y skills add AGilbertDev/agilbertdev-recipes --skill my-styling-conventionsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
AGilbertDev's styling conventions and visual identity for Nuxt/Tailwind projects — semantic-token theming, Hanken Grotesk type, fluid clamp() sizing, dark mode, and accessible Nuxt UI components. Use when styling components or pages, building responsive layouts, matching the brand, or setting up a theme. Pairs with my-frontend-conventions.
SKILL.md
8.0 KB, as published. Nobody here has run it
Styling conventions (Tailwind / Nuxt UI)
The visual identity shared across AGilbertDev's Nuxt projects (portfolio, time-tracking, resume). Starting defaults, adjust per project. Pairs with my-frontend-conventions for component choices and icons.
Stack & foundation
- Tailwind v4 + Nuxt UI v4.
main.cssis just@import "tailwindcss"; @import "@nuxt/ui";plus a small@theme staticblock. - Utility-first. Avoid custom CSS files. When custom CSS is unavoidable, keep it in
main.css(font var, palette ramps, base tweaks), not scattered across components. - Self-host fonts through
@nuxt/fonts: declare the family in@theme static, no manual<link>.
Brand & color
- Brand sans is Hanken Grotesk (set as
--font-sansin@theme static). Lato is the old print-only font, not for web. - Personal/portfolio palette is teal primary on dark navy, inspired by Nuxt's own system. Product apps pick their own primary.
- One primary + one neutral, themed through Nuxt UI. Set them in
app.config.ts(ui.colors.primary,neutral); never hardcode a second palette. - Define the palette in ONE place: color ramps in
main.css@theme static, semantic mapping inapp.config.ts. A palette change is one edit, not many. - Reserve status colors (
success/info/warning/error) as fixed Nuxt UI colors so they always read the same, never recolored by the active theme. - Derive on-brand accents from the primary with oklch relative color (
oklch(from var(--ui-primary) l c calc(h + 25))to shift the hue toward cyan,calc(l * 1.1)to lighten) rather than hardcoding a second hue, so accents track a retheme.
Semantic tokens, never raw color
- Style with Nuxt UI semantic classes:
bg-default/bg-muted/bg-elevated,text-highlighted/text-muted/text-dimmed/text-primary,ring-default/border-default. In raw CSS use the vars (--ui-text,--ui-primary,--ui-bg,--ui-border). - A hardcoded hex is acceptable only for a one-off decorative surface (for example a fixed image backdrop), never for text or UI chrome.
Theming & atmospheres (optional, advanced)
- For multi-theme apps, define each theme as a
[data-theme="x"]block inmain.cssthat overrides the--ui-color-primary-*and--ui-color-neutral-*50–950 ramps. Nuxt UI derives every surface, border, text, and hover shade from those. - Drive it from a
useThemecomposable: independent light and dark picks persisted in separate cookies, applied to<html data-theme>, with a synchronous no-flash inline script inapp.vueso the correct theme paints first.
Dark mode
- Every project supports light + dark via
useColorMode. Design both, not just one. - Logos: either swap two SVGs (
dark:hidden/hidden dark:block) or use one inline SVG colored withvar(--ui-text)/var(--ui-primary)so it adapts to theme and mode with no extra files. - Guard color-mode-dependent UI with
<ClientOnly>and a sized fallback to avoid a hydration mismatch. - On very dark canvases, lift
--ui-bordertoward neutral-600 so nav, footer, and card separators stay visible.
Typography
- Larger base text:
body { font-size: var(--text-lg) }, and default Nuxt UI components tosize: 'md'(withtext-md) inapp.config.tsso the whole UI scales up together. - Big titles:
font-extrabold tracking-tight. Section titles:font-semibold. Small eyebrow/label text:uppercase tracking-wideortracking-widest, oftentext-primary. - Body paragraphs:
text-justifyandhyphens-none. Never break a word with a hyphen anywhere on the site. Applies to prose and descriptions, not to centered headings or short subtitles.
Fluid, single-viewport sizing (signature)
- Pages are built to fit one viewport without scrolling on desktop: wrap content in
min-h-full flex items-centerand let it scale to fit. - Scale type, spacing, gaps, and image sizes with
clamp()rather than fixedsm:/lg:steps. Pattern:text-[clamp(1.5rem,1.6vw+0.5rem,3.5rem)],gap-[clamp(0.75rem,2vh,1.5rem)],size-[clamp(10rem,28vw,16rem)]— a mobile minimum, a fluid middle, a large-screen maximum. - Mobile-first otherwise: use
min-h-dvh(notmin-h-screen), and step padding and margin up atsm:andlg:.
Layout
- Build the shell from Nuxt UI Pro layout components:
UHeader+UMain+UFooter; pages withUPage/UPageBody/UPageHeader/UPageHero; nav viaUNavigationMenu; dividers viaUSeparator. - Horizontal padding scale:
px-6 sm:px-6 lg:px-8(a touch more on mobile). Set it once globally throughui.containerinapp.config.tsso every section agrees. - Space stacked sections with fluid vertical padding, for example
py-[clamp(4rem,10vh,8rem)]. - Container widths step up:
lg:max-w-5xl xl:max-w-6xl 2xl:max-w-7xlfor wide layouts,max-w-2xlfor prose,lg:max-w-mdfor forms. Center withmx-auto.
Components
- Buttons:
UButtonwithcolor+variant. Primary action is solid primary, often with a leadingiconand a bold trailing arrow (trailingIcon="i-ph-arrow-right-bold"). Secondary iscolor="neutral" variant="outline". Icon-only (social links, toggles) isvariant="ghost"plus anaria-label. Register custom sizes inapp.config.tsfor oversized CTAs (for example a2xl); make oversized buttons scale down on mobile (text-base ... sm:text-xl) and stack full width so long labels never truncate. - Cards:
rounded-2xl bg-default ring ring-default(a ring, not a border),hover:ring-primary; on media,group-hover:scale-105withtransition. - Round media (avatars, portraits): size by width with
aspect-square(w-fullinside a width-bounded wrapper), never by height withw-auto. Height-driven sizing stretches into an oval the moment a narrow column constrains the width. It must always be a perfect circle. - Tags:
UBadge color="neutral" variant="subtle" size="sm". - Forms:
UForm+UFormField+UInput/UTextarea(class="w-full"),space-y-4, avalidatefunction returning an errors array, realautocompletevalues, a right-aligned submit button with a:loadingstate, andUAlert variant="subtle"for success and error.
Accessibility (non-negotiable)
- Skip-to-content link:
sr-only focus:not-sr-only, targeting atabindex="-1"UMain#main-content. - Focus ring on every interactive element:
focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary. aria-labelon every icon-only button and link.- Lean on semantic tokens so contrast holds in both light and dark.
Motion
- Subtle and purposeful only (a card hover scale, a flip on the locale toggle). Always gate transitions behind
@media (prefers-reduced-motion: reduce).
Signature glow (optional, on-brand)
- A slow spinning gradient border is the signature accent. Implement it once as a
.btn-glowutility inmain.css: an absolutely-positioned::beforewithborder-radius: inherit, aconic-gradientmasked into a thin ring (mask+mask-composite: exclude), an animatable--btn-anglethrough CSS@propertyspinning slowly (about 7s), and a softbox-shadowglow. Reveal it on:hover; a.glow-onmodifier keeps it lit permanently (used around the portrait). Gate the spin behindprefers-reduced-motion. Put the ring::beforeabove the content (z-index: 1) so it shows over media that reaches the edge. - Keep the ring on-brand and legible on any button color: sweep between the brand colors (teal and a hue-shifted cyan) with a lighter glint, all derived from the primary via oklch relative color so nothing hardcodes a second hue.
- A faint page-level glow (a large, low-opacity radial of the primary, hue-shifted) anchored top-right and bled down through the first sections adds depth. Keep it fainter on the dark canvas so it never muddies the navy.