Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/dyed-in-the-wool/llms.txt
Use this file to discover all available pages before exploring further.
Dyed in the Wool’s visual identity is built around the metaphor of fabric and dye — organic, saturated, and slightly unpredictable. Tailwind CSS provides the structural utility layer, while a set of custom dye-* color tokens, SVG noise filters, and CSS mix-blend-mode properties combine to produce the handcrafted look.
The dye-* Color System
All brand colors are defined as custom Tailwind tokens and used throughout the app via text-dye-*, bg-dye-*, and border-dye-* utilities. The compiled CSS confirms the following resolved values:
| Token | Hex value | RGB | Role |
|---|
dye-primary | #0d9488 | rgb(13 148 136) | Primary teal — buttons, accents, glows |
dye-light | #2dd4bf | rgb(45 212 191) | Light teal — active nav indicator, hover states |
dye-magenta | #db2777 | rgb(219 39 119) | Hot pink — accent color, hover overlays, selection highlight |
dye-indigo | #1e3a8a | rgb(30 58 138) | Deep indigo — headings, body text default, buttons |
dye-ocean | #0369a1 | rgb(3 105 161) | Ocean blue — background blob accent |
dye-dark | #0f766e | rgb(15 118 110) | Dark teal — body text, muted content |
dye-fabric | #fafaf9 | rgb(250 250 249) | Off-white / warm stone — page background |
dye-pattern | — | — | Special gradient-clip text class (see below) |
dye-fabric is used as the body background color and also the border-dye-fabric scrollbar track color, keeping the scrollbar seamlessly integrated into the page background.
text-dye-pattern — Gradient Clip Text
dye-pattern is not a simple color token. It is a composite CSS class that applies a noisy gradient to text using SVG background, background-clip: text, and -webkit-text-fill-color: transparent. The effect makes the text look like it has been dye-printed onto fabric.
.text-dye-pattern {
background-image: url("data:image/svg+xml, <SVG feTurbulence noise filter />");
background-color: #0d9488; /* dye-primary as base tint */
background-blend-mode: overlay; /* blend noise over the teal */
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
color: transparent;
}
It is used on the “THE WOOL” portion of the hero headline for a mottled, printed-fabric appearance.
Typography
Two Google Fonts families are loaded via @import in the compiled CSS:
| Tailwind class | Font family | Usage |
|---|
font-display | Caveat Brush, cursive | All h1–h6 headings — the bold, handwritten display style |
font-sans | DM Sans, sans-serif | Body text, nav labels, captions, form inputs |
The global CSS applies font-family: Caveat Brush, cursive to every heading element by default, so any <h1> through <h6> automatically renders in the display typeface without an explicit class. Display headings are rendered in bold, uppercase all-caps with wide letter-spacing (tracking-widest, tracking-[0.3em]) to evoke screen-printed fabric labels.
SVG Texture Effects: feTurbulence + feDisplacementMap
The most distinctive visual effect in the portfolio is the tie-dye texture on project cards and the Skills page canvas. This is achieved entirely with inline SVG filters using two primitives:
feTurbulence — generates a procedural noise texture (Perlin or fractal noise). The baseFrequency and numOctaves attributes control the scale and complexity of the noise.
feDisplacementMap — uses the noise texture as a displacement map to warp the source graphic’s pixels, simulating the irregular edge bleed of real dye on fabric.
Here is the filter as it appears on the Projects page cards:
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<filter id={`noise-${id}`}>
<feTurbulence
type="fractalNoise"
baseFrequency="0.02"
numOctaves="3"
/>
<feDisplacementMap
in="SourceGraphic"
scale="30"
/>
</filter>
<rect
width="100%"
height="100%"
fill="white"
filter={`url(#noise-${id})`}
opacity="0.3"
/>
</svg>
Each card uses a unique filter id (e.g. noise-1, noise-2, noise-3) to avoid SVG filter ID collisions when multiple cards are rendered. The project detail modal uses a separate "modal-noise" filter with a higher scale="50" for a more dramatic displacement, and the Skills canvas uses "canvas-noise" with scale="50" and mix-blend-overlay for a color-blending effect.
| Filter usage | baseFrequency | numOctaves | scale |
|---|
| Project card overlay | 0.02 | 3 | 30 |
| Project modal panel | 0.01 | 4 | 50 |
| Skills canvas | 0.05 | 3 | 50 |
| Contact page success burst | 0.01 | 3 | 100 |
mix-blend-mode Layering
mix-blend-mode is central to how colors interact across overlapping layers. Dyed in the Wool uses four blend modes:
| Tailwind utility | CSS value | Where used |
|---|
mix-blend-multiply | multiply | Background blobs — darkens where colors overlap to simulate dye soaking into fabric |
mix-blend-overlay | overlay | SVG noise filters, grain overlay — increases contrast in midtones while letting highlights/shadows show through |
mix-blend-difference | difference | Nav header — inverts colors against the page content, keeping white text legible on any background |
mix-blend-screen | screen | Hero headline SVG gradient overlay — brightens text for a luminous color effect |
The header’s mix-blend-difference is particularly important: because the nav sits fixed over all page content, its white text and indicator need to stay readable regardless of whether the page behind it is light or dark.
Grain Overlay
A fixed full-viewport div applies a subtle paper texture across all pages using an inline SVG data URI noise filter at near-zero opacity:
// Inside Layout — persistent across all routes
<div
className="fixed inset-0 pointer-events-none z-40 opacity-[0.03] mix-blend-overlay"
style={{
backgroundImage: `url("data:image/svg+xml,
<svg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'>
<filter id='noiseFilter'>
<feTurbulence
type='fractalNoise'
baseFrequency='0.65'
numOctaves='3'
stitchTiles='stitch'
/>
</filter>
<rect width='100%' height='100%' filter='url(#noiseFilter)' />
</svg>")`,
}}
/>
Key details:
opacity-[0.03] — almost invisible at 3% opacity; it adds texture without visibly tinting the page.
mix-blend-overlay — blends the noise into underlying colors rather than sitting on top as a flat grey veil.
stitchTiles="stitch" — makes the noise tile seamlessly so there are no visible seams if the browser repeats the background.
pointer-events-none — the overlay is purely decorative and does not intercept mouse or touch events.
z-40 — sits above page content (z-10) but below the nav header (z-50) and cursor (z-[100]).
animate-blob Keyframe
The pulsing, blurry colored circles on the Home page background are powered by a custom animate-blob Tailwind keyframe defined in the Tailwind config. The compiled output reveals the full animation:
@keyframes blob {
0% { transform: translate(0px, 0px) scale(1); }
33% { transform: translate(30px, -50px) scale(1.1); }
66% { transform: translate(-20px, 20px) scale(0.9); }
to { transform: translate(0px, 0px) scale(1); }
}
.animate-blob {
animation: blob 7s infinite;
}
Three blobs run simultaneously on the Home page, each offset by an animationDelay style prop (2s and 4s) so they drift out of sync with each other. Combined with filter blur-3xl, mix-blend-multiply, and low opacity, the result is a slowly shifting, color-blending background reminiscent of a lava lamp or ink diffusing through water.
// Home page background blobs
<div className="absolute top-1/4 left-1/4 w-64 h-64 bg-dye-light
rounded-full mix-blend-multiply filter blur-3xl opacity-30 animate-blob" />
<div className="absolute top-1/3 right-1/4 w-72 h-72 bg-dye-magenta
rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-blob"
style={{ animationDelay: "2s" }} />
<div className="absolute bottom-1/4 left-1/3 w-80 h-80 bg-dye-ocean
rounded-full mix-blend-multiply filter blur-3xl opacity-30 animate-blob"
style={{ animationDelay: "4s" }} />