Bezier

If ease-in-out feels too rigid, it’s usually because the acceleration and deceleration are too symmetrical and “standard.” For a modern, premium feel—often described as “soft” or “organic”—you want a cubic-bezier that stays slow for longer at the start or has a much more dramatic “cushion” at the end.
Here are a few bezier options to make your transitions feel more sophisticated:

  1. The “Soft & Modern” (Exponential)
    This is the gold standard for UI. It starts very subtly and spends more time in the slowing-down phase, which feels more natural to the human eye.
  1. The “Elegant Slide” (Quartic)
    If you want it to feel even “thicker” and more deliberate, this curve is steeper in the middle but very soft on the edges.
  1. The “Smooth Entrance” (Out-Focused)
    If the transition is for something appearing or moving into view, you might want to ditch the “In” part of “In-Out” and focus on a very soft landing.

Building your own CSS framework is the perfect place to codify these. Instead of relying on the browser’s defaults, you can create a “motion system” that gives your projects a signature feel—much like how Apple or Google have a distinct “weight” to their UI.
For your Standard framework, I’d suggest a tiered approach. Instead of naming them by their math (like “Quartic”), name them by their intent.
🏗️ Proposed “Standard” Motion Tokens
If you’re using CSS variables (which fits the minimalist/modern vibe of your projects), you could set them up like this:
:root {
/* The “Snappy” – for small icons or toggles (Short duration) */
—ease-snappy: cubic-bezier(0.2, 0, 0, 1);

/* The “Standard” – for general UI transitions (Your 0.5s sweet spot) */
—ease-standard: cubic-bezier(0.4, 0, 0.2, 1);

/* The “Soft” – for large modals or overlays (The “softest” feel) */
—ease-soft: cubic-bezier(0.16, 1, 0.3, 1);

/* The “Emphasis” – has a tiny bit of weight/anticipation */
—ease-emphasis: cubic-bezier(0.34, 1.56, 0.64, 1);
}

Why this fits a “Digital Garden” / Slow Web aesthetic:

For buttons and links, you generally want to move away from the 0.5s duration. In UI design, interaction feedback needs to feel “instant” to be satisfying. If a button takes half a second to change color, it feels like the website is lagging behind the user’s intent.
Here is how you can structure the “Standard” feel for micro-interactions:
⚡ The “Reactive” Hover (Buttons & Links)
For these, you want a very fast entrance and a slightly slower “settle” when the mouse leaves.

.stnd-button {
transition:
background-color 0.2s cubic-bezier(0.25, 1, 0.5, 1),
transform 0.15s cubic-bezier(0.25, 1, 0.5, 1);
}

.stnd-button:active {
transform: scale(0.98); /* Tiny physical feedback */
}

🎨 The “Standard” Link Underline
Since you like the Slow Web and minimalist aesthetics, you might be using those nice text-decoration or border-bottom transitions.
To make a link feel “softer” without being slow:

a:hover {
text-decoration-color: rgba(0,0,0,1);
transition: text-decoration-color 0.15s ease-out; /* Snappy Fade In */
}

🛠️ In your Framework
I’d recommend adding a specific variable for these “micro” moments. It keeps your digital garden feeling alive but disciplined.

Intent Variable Name Value Recommended Duration
Reaction —ease-react cubic-bezier(0.2, 1, 0.4, 1) 0.15s
Exit —ease-out-soft cubic-bezier(0.4, 0, 1, 1) 0.3s

Note: If you apply a 0.5s ease to a button hover, it might feel “mushy.” Try dropping the duration for hovers while keeping your custom bezier—you’ll get that “softness” you’re looking for without losing the responsiveness.

Would you like me to help you write a small CSS utility class or a Sass/PostCSS mixin to handle these entrance/exit transitions automatically for your framework?

Yes, 100%. Transitioning from value-based variables (like —ease-slow) to semantic-based variables (like —ease-interaction) is exactly what separates a generic utility library from a professional design system.
In a framework like Standard, semantic variables act as the “API” for your UI. If you decide later that 0.5s is too slow for all buttons, you change it in one place without hunting for every 0.5s instance in your codebase.
Here is how I would suggest structuring your semantic layers:
🏗️ The Three-Layer System

  1. Primitive Tokens (The Math)
    These are your raw ingredients. You don’t use these directly in your components; they just store the “shapes” of the motion.
    :root {
    /* Shapes */
    —ease-shape-soft: cubic-bezier(0.4, 0, 0.2, 1);
    —ease-shape-snappy: cubic-bezier(0.2, 1, 0.4, 1);
    —ease-shape-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);

/* Durations */
—duration-instant: 100ms;
—duration-fast: 200ms;
—duration-standard: 350ms;
—duration-slow: 500ms;
}

  1. Semantic Tokens (The Intent)
    This is what you actually use in your CSS. It describes what the animation is doing, not how long it is.
    :root {
    /* Interaction (Buttons, Links, Toggles) */
    —ease-interaction: var(—duration-fast) var(—ease-shape-snappy);

/* Feedback (Success/Error states, validation) */
—ease-feedback: var(—duration-standard) var(—ease-shape-bounce);

/* Layout (Sidebars, expanding cards, Digital Garden navigation) */
—ease-surface: var(—duration-slow) var(—ease-shape-soft);

/* Enter/Exit (Modals, tooltips) */
—ease-enter: var(—duration-fast) ease-out;
—ease-exit: var(—duration-standard) ease-in;
}

  1. Component Application
    Now your components are incredibly clean and descriptive.
    .stnd-button {
    transition: all var(—ease-interaction);
    }

.stnd-sidebar {
transition: transform var(—ease-surface);
}

🧩 Why this works for your projects

@media (prefers-reduced-motion: reduce) {
:root {
—duration-fast: 0ms;
—duration-standard: 0ms;
—duration-slow: 0ms;
}
}

💡 A “Standard” Tip
Since you are using pnpm and likely building this as a package, you could even export these as CSS Custom Media or a Tailwind config extension.
Would you like me to help you generate a full “Motion” CSS file with these semantic variables to drop into your @stnd monorepo?

Are you absolutely sure?

This action cannot be undone.