New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

idle-escalation

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

idle-escalation

A focus ring that deepens in color, then thickens, while a focused field sits idle. Helps users who freeze re-focus and users who look away find their place.

latest
Source
npmnpm
Version
1.0.0
Version published
Maintainers
1
Created
Source

Idle Escalation

A focus ring that gets stronger the longer a field sits idle.

When a user clicks into a field and does not start typing, the focus ring starts as a light, soft tone of your primary color. Every 2 seconds it gains saturation until it reaches full color. If the user still has not typed, the outline then thickens by 0.5 px every 2 seconds, four times. The moment they type, it goes back to calm. No popups, sounds or shaking.

Created by Joseph Brendan, founder of Dev and Design HQ, 2026.

Read the full specification

Why this exists

Idle Escalation exists to help the user. It helps two kinds of people.

  • Users who freeze or stare. They click a field, then their mind drifts or they get stuck. The growing ring pulls their attention back to the field, so they can start typing what they came to enter.
  • Users who look away. They check their phone, open another tab, or switch to another window. When they come back, the strong ring shows exactly where they were. No scrolling. No searching.

People rarely give a screen their full attention. Research by Gloria Mark at UC Irvine found that people now stay on one screen for about 47 seconds, on average, before switching. A 2015 study from Florida State University found that just receiving a phone notification, without touching the phone, breaks focus about as much as using the phone. A normal focus ring looks the same after 2 seconds as after 2 minutes. Idle Escalation changes that.

See SPEC.md, Section 2 for the full problem statement and sources.

How it works

Time idleStepPhaseRing
0 s1ColorLight, soft tone at 2 px (already visible)
2 s2ColorStronger tone, 2 px
4 s3ColorStronger again, 2 px
6 s4ColorFull primary color, 2 px
8 s5WidthFull color, 2.5 px
10 s6WidthFull color, 3 px
12 s7WidthFull color, 3.5 px
14 s8WidthFull color, 4 px, hint text appears. Holds here.

Typing resets to step 1 at 2 px. Leaving the field clears it. Switching to another tab, window or app pauses the timer, and on return the ring jumps to full color so the spot is easy to find.

Quick start

1. Add the files

<link rel="stylesheet" href="src/idle-escalation.css">
<script src="src/idle-escalation.js" defer></script>

2. Mark your fields

<label for="email">Email address</label>
<input id="email" type="email"
       data-idle-escalation
       data-ie-hint="email-hint"
       aria-describedby="email-hint">
<p id="email-hint" class="ie-hint">Example: ada@example.com</p>

3. Start it

<script>
  document.addEventListener('DOMContentLoaded', function () {
    IdleEscalation.init();
  });
</script>

4. Use your brand colors

Replace the four tones in src/idle-escalation.css:

:root {
  --ie-step-1: #8a85f0; /* softest, must reach 3:1 contrast */
  --ie-step-2: #6b63eb;
  --ie-step-3: #5b52e8;
  --ie-step-4: #4f46e5; /* peak, your full primary color */
}

Options

OptionData attributeDefaultWhat it does
delaydata-ie-delay2000Milliseconds between steps. Minimum 1000.
colorStepsdata-ie-color-steps4Steps in the color phase, including the soft start.
widthStepsdata-ie-width-steps4Steps in the width phase. 0 turns it off.
widthIncrementdata-ie-width-increment0.5Pixels added per width step (0.25 to 1).
returnBoostdata-ie-return-boosttrueJump to full color when the user returns from another tab or app.
watchPausesdata-ie-watch-pausesfalseAlso escalate after the user pauses mid-typing.
(hint)data-ie-hintnoneID of hint text to show at the peak.

Add the class ie-halo to a field for a soft halo during the color phase.

// Set options for every field at once
IdleEscalation.init(document, { delay: 3000, widthIncrement: 0.5 });

// Or attach to one field
const ie = new IdleEscalation(document.getElementById('email'), { delay: 2500 });
ie.destroy(); // remove it later

Events

Each field fires idleescalation:step when its step changes. Use it to measure the pattern.

field.addEventListener('idleescalation:step', (e) => {
  console.log(e.detail); // { step: 6, steps: 8, phase: 'width', widthAdded: 1, peak: false }
});

Accessibility

  • Step 1 always meets 3:1 contrast, so focus is visible from the start (WCAG 2.4.7 and 1.4.11).
  • The width phase means color is not the only signal. Users who cannot tell tones apart still see the ring grow.
  • The ring is an outline, so a thicker ring never moves the field or the page.
  • The ring never blinks, pulses or loops. It stops at the peak.
  • Reduced motion: steps change instantly with no easing.
  • Forced colors (Windows High Contrast): the system focus color takes over.
  • Hint text is linked with aria-describedby, so screen reader users hear it right away.

Full details in SPEC.md, Section 8.

Rules for a true Idle Escalation

  • It exists to help the user return to the field, never to pressure them.
  • The soft start is still clearly visible.
  • Color deepens first. Width grows only after full color.
  • Each step is stronger than the last. Width grows by 1 px or less per step, 4 px at most in total.
  • It stops at the peak. No loops, blinking or pulsing.
  • Any input resets it.
  • No sound, vibration, shaking or popups. Nothing on the page moves.

Project files

idle-escalation/
├── README.md                  You are here
├── SPEC.md                    Full specification and research
├── DEFENSIVE-PUBLICATION.md   Public technical disclosure
├── LICENSE                    MIT License
├── CITATION.cff               How to cite this work
├── CHANGELOG.md               Version history
├── src/
│   ├── idle-escalation.js     Reference implementation
│   └── idle-escalation.css    Styles and color tokens
└── demo/
    └── index.html             Live demo

Credit

Idle Escalation is free to use in any product, commercial or personal. If you write about it, teach it, or ship it in a design system, please credit it as:

Idle Escalation, an interaction pattern by Joseph Brendan (Founder, Dev and Design HQ), 2026.

The specification is shared under CC BY 4.0. The code is shared under the MIT License.

Contributing

Ideas, bug reports and test results are welcome. If you run an A/B test with this pattern, please open an issue and share what you found, good or bad.

Author

Joseph Brendan Founder, Dev and Design HQ devdesignhq.com · LinkedIn

Keywords

idle-escalation

FAQs

Package last updated on 01 Oct 2026

Related posts