/**
 * All tunables for the ink brush reveal effect in one place — deliberately
 * NOT admin-configurable (per explicit product decision); developers tune
 * these constants directly. Admin only manages the overlay/reveal images
 * (SignatureEventCard) — nothing here.
 */
export const BRUSH_CONFIG = {
  /** Base stamp radius (px, before velocity scaling). */
  minRadius: 16,
  /** How much pointer speed (px/frame) grows the next stamp's radius. */
  velocityRadiusMultiplier: 0.5,
  /** Hard ceiling so a fast flick never produces a giant blob. */
  maxRadiusClamp: 70,
  /** Per-stamp size jitter, ±8% (davidwhyte.com-style: subtle, not per the earlier ±28% "premium ink" pass). */
  scaleVariation: 0.08,
  /** Per-stamp opacity jitter — each stamp's base alpha is randomized within [opacityJitterMin, 1]. */
  opacityJitterMin: 0.85,

  // --- Pointer physics (inertia) ---
  // Semi-implicit Euler spring, not a flat lerp: the brush accelerates toward
  // the pointer and *keeps moving briefly after the pointer stops* (slight
  // overshoot-then-settle) — see pointerPhysics.ts. `stiffness` is the
  // lerp-like "catch-up rate" (spec target 0.12–0.18); `damping` controls
  // how much velocity carries over frame-to-frame (the "inertia" itself).
  pointerStiffness: 0.9,
  pointerDamping: 0.5,
  /** Frame-to-frame smoothing of the derived speed value (used for radius/spacing) so it doesn't jitter with raw per-frame noise. */
  velocitySmoothing: 0.15,

  // --- Stroke behavior ---
  /** Stamps spawn by distance traveled, not by elapsed time. Threshold = current stamp radius × 2 × this fraction (~25–35% of diameter) — naturally denser at low speed (small radius) and sparser at high speed (large radius), no separate speed lookup needed. */
  stampSpacingFraction: 0.3,
  /** Minimum smoothed speed (px/frame) required to keep spawning stamps. Below this, the trailing spring position is just residual creep toward a now-stale target, not a real stroke — without this floor, a slow/high-damping spring would keep laying stamps in the last direction of travel instead of letting the reveal fade and close up in place. */
  minSpawnSpeed: 0.4,
  /** Random per-stamp rotation jitter around the stroke-direction angle (radians, ±10°). */
  rotationJitterRad: (10 * Math.PI) / 180,
  /** Small random per-stamp position offset (px) off the exact stroke point — avoids a mechanically-perfect center line. */
  positionJitterPx: 4,

  /** Full stamp lifetime before it's fully gone. */
  stampLifetimeMs: 1300,
  /** Random per-stamp lifetime variance (±fraction) so stamps along a stroke don't all close in the same start-to-end order — some linger longer, some close sooner, for a more natural/random-feeling recovery instead of a visible sweeping wave. */
  lifetimeVariation: 0.35,
  /** How long a stamp takes to grow to full size. */
  growInMs: 200,
  /** Fraction of lifetime (0-1) at which fade-out begins. */
  fadeOutStart: 0.35,
  /** Fixed-size object pool — bounds memory and avoids per-frame allocation. */
  poolSize: 96,
  /** Continuous subtle rotational wobble over a stamp's life, layered on top of its (already-jittered) base rotation — keeps the mark feeling "alive", kept small so it doesn't fight the ±10° spawn jitter. */
  wobbleAmount: 0.05,
  wobbleSpeed: 0.01,
  /** Subtle breathing/pulsation of scale over a stamp's life. */
  scaleWobbleAmount: 0.06,
  scaleWobbleSpeed: 0.006,

  /** Blob silhouette: number of path control points. */
  points: 14,
  /** Fine-grained per-point jitter (rock-like noise) — most of the organic character comes from the two noise harmonics below. */
  irregularity: 0.18,
  /** Two layered sine harmonics perturbing the radius by angle — a coarse "ink blob" wave plus a finer ripple, which reads as organic/flowing rather than a jittery random polygon. */
  noiseAmplitude1: 0.22,
  noiseFrequency1: 2,
  noiseAmplitude2: 0.1,
  noiseFrequency2: 5,
  /** Soft edge feather (px) — applied once per frame to the whole accumulated stamp mask (not per-stamp) so it stays cheap regardless of how many stamps are active. Roughly 20–30% of a typical stamp's radius. */
  featherBlurPx: 14,
  /** devicePixelRatio cap — avoids over-rendering on very high-DPI screens. */
  dprCap: 2,

  // --- No-cursor devices (touch-primary: `(hover: none)`) ---
  // There's no hovering pointer to trigger the effect passively, so it
  // "auto-plays" — a virtual pointer wanders to random points on its own,
  // reusing the exact same spring/spacing/stamp logic as a real pointer.
  /** Random delay range (ms) between auto-wander target changes. */
  autoWanderMinDelayMs: 1200,
  autoWanderMaxDelayMs: 3200,
} as const;
