Skip to main content

PrivacyCurtain

Location: src/components/PrivacyCurtain.jsx

Overview

PrivacyCurtain is a gentle overlay that appears when the user has been idle, dimming the screen to protect their privacy. It is not a lock screen -- it is a curtain being drawn. Any interaction (mouse move, click, key press, touch) dismisses it immediately.

The component uses the usePrivacyCurtain hook for idle detection and user preferences (style, timeout). A fade-in/fade-out animation provides a smooth transition.

Relevant Invariants

  • Invariant #14: "Privacy Is Infrastructure" -- The privacy curtain is a systemic protection, not an opt-in feature.
  • Invariant #1: "Participation Is Always Voluntary" -- The curtain is non-punitive; any interaction resumes the session.

Props

This component takes no props. All configuration comes from the usePrivacyCurtain hook.

Key Behaviors

  • Idle Detection: The usePrivacyCurtain hook monitors user activity and triggers the curtain after the configured idle timeout.
  • Animated Transition: Uses CSS transitions with a 500ms fade. The component mounts (visible) before the transition class (animating) is applied on the next animation frame.
  • Dismiss on Interaction: The overlay responds to onClick, onMouseMove, onKeyDown, and onTouchStart events to dismiss the curtain.
  • Accessibility: Marked with role="presentation" and aria-hidden="true" since it is a visual overlay, not interactive content.
  • Style Variants: The preferences.style value from the hook controls the CSS class applied (e.g., privacy-curtain--default).
  • Moon Icon: Displays a custom SVG moon icon to represent rest/quiet, reinforcing the non-punitive tone.

Usage

import PrivacyCurtain from '@/components/PrivacyCurtain';

// Typically rendered at the app root level
<PrivacyCurtain />
  • The usePrivacyCurtain hook at src/hooks/usePrivacyCurtain.js manages idle detection and preferences.
  • The component has its own CSS file at src/components/PrivacyCurtain.css.

Last updated: 2026-02-07