№ 012

Inertia Core

A precision slider whose weight you can see — a champagne slug lags behind the handle as you drag.

Version
1.0.0
Download
345 KB · 5 files
Added
Oct 26, 2026
Built with
HTML, CSS, JS
Needs
Google Fonts
Tags
slider, inertia, physics

Usage

Copy inertia-core.css and inertia-core.js (and assets/, if there is one) into your project, then:

  new InertiaCore(element, {
    value: 0.64,             // 0..1
    label: 'OUTPUT',
    titanium: 'assets/titanium.jpg',
    graphite: 'assets/graphite.jpg',
    onChange(value) {},
  })

A precision slider whose weight you can see: a champagne slug sits in a window through the titanium
handle. The handle tracks the pointer exactly; the slug has inertia, so it lags behind as you drag,
swaps sides when you reverse, and settles back to centre with one small, heavily damped movement.
The value always follows the gesture directly — only the slug is simulated.

Source

/* Inertia Core — a precision slider. Laid out on a 560-unit-wide grid (--u), so it scales as one piece
   with the width of its container. */

.ic {
  --ic-ink: #d9d4cb;
  --ic-ink-dim: #8f8b84;
  --ic-champagne-lt: #f3dfc4;
  --ic-champagne: #d2b08a;
  --ic-champagne-dk: #8a6a4b;
  --ic-titanium: none;
  --ic-graphite: none;
  --ic-font: "Inter", "Helvetica Neue", Arial, sans-serif;

  container-type: inline-size;
  position: relative;
  width: 100%;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.ic *,
.ic *::before,
.ic *::after {
  box-sizing: border-box;
}

.ic-stage {
  --u: calc(100cqw / 560);
  position: relative;
  width: 100%;
  height: calc(var(--u) * 116);
  cursor: pointer;
  touch-action: none;
}

/* ── housing ── */

.ic-housing {
  position: absolute;
  inset: 0;
  border-radius: calc(var(--u) * 7);
  /* the matte graphite, softened toward a warm mid-grey */
  background: linear-gradient(rgba(74, 74, 71, 0.72), rgba(64, 64, 62, 0.78)), var(--ic-graphite) center / 100% auto, #444542;
  box-shadow:
    inset 0 0 0 calc(var(--u) * 1) rgba(255, 255, 255, 0.07),    /* machined outer rim */
    inset 0 calc(var(--u) * 0.8) 0 rgba(255, 255, 255, 0.12),   /* fine highlight on the top edge */
    inset 0 calc(var(--u) * -1) calc(var(--u) * 1.5) rgba(0, 0, 0, 0.35),
    0 calc(var(--u) * 1.5) calc(var(--u) * 2) rgba(40, 36, 30, 0.22),
    0 calc(var(--u) * 10) calc(var(--u) * 18) rgba(40, 36, 30, 0.2);
}

.ic-label,
.ic-value,
.ic-end {
  position: absolute;
  font: 400 calc(var(--u) * 8.5) / 1 var(--ic-font);
  letter-spacing: 0.3em;
  color: var(--ic-ink);
  white-space: nowrap;
}

.ic-label {
  left: calc(var(--u) * 26);
  top: calc(var(--u) * 15);
}

.ic-value {
  right: calc(var(--u) * 25);
  margin-right: -0.3em;
  top: calc(var(--u) * 15);
  font-variant-numeric: tabular-nums;
}

.ic-end {
  top: calc(var(--u) * 96);
  font-size: calc(var(--u) * 7.5);
  letter-spacing: 0.18em;
  color: var(--ic-ink-dim);
}

.ic-min { left: calc(var(--u) * 24); }
.ic-max { right: calc(var(--u) * 22); margin-right: -0.18em; }

/* recessed channel with a soft machined rim */
.ic-slot {
  position: absolute;
  left: calc(var(--u) * 22.5);
  right: calc(var(--u) * 27);
  top: calc(var(--u) * 36);
  height: calc(var(--u) * 37);
  border-radius: calc(var(--u) * 4);
  background: linear-gradient(#161616, #222223 60%, #262627);
  box-shadow:
    0 0 0 calc(var(--u) * 1.2) #3c3d3d,
    0 calc(var(--u) * 1.4) 0 calc(var(--u) * 1.2) rgba(255, 255, 255, 0.07),
    inset 0 calc(var(--u) * 3) calc(var(--u) * 4) rgba(0, 0, 0, 0.6);
}

/* the empty run of track, right of the handle */
.ic-groove {
  position: absolute;
  left: calc(var(--u) * 6);
  right: calc(var(--u) * 6);
  top: calc(var(--u) * 13);
  height: calc(var(--u) * 11);
  border-radius: calc(var(--u) * 2);
  background: #2c2c2d;
  box-shadow: inset 0 calc(var(--u) * 1) calc(var(--u) * 1.5) rgba(0, 0, 0, 0.5), 0 calc(var(--u) * 0.6) 0 rgba(255, 255, 255, 0.04);
}

/* the champagne rod, from the left end up to the handle */
.ic-rail {
  position: absolute;
  left: calc(var(--u) * 7.5);
  top: calc(var(--u) * 17);
  height: calc(var(--u) * 3.2);
  border-radius: calc(var(--u) * 1.6);
  background: linear-gradient(var(--ic-champagne-lt), var(--ic-champagne) 55%, var(--ic-champagne-dk));
  box-shadow: 0 calc(var(--u) * 1) calc(var(--u) * 1.5) rgba(0, 0, 0, 0.55);
}

.ic-scale {
  position: absolute;
  inset: 0;
}

.ic-tick {
  position: absolute;
  top: calc(var(--u) * 85);
  width: calc(var(--u) * 0.7);
  height: calc(var(--u) * 4);
  margin-left: calc(var(--u) * -0.35);
  background: #77746f;
}

.ic-tick.is-major {
  top: calc(var(--u) * 83);
  height: calc(var(--u) * 7);
  background: #a9a59e;
}

/* ── handle: a titanium carriage with a window through its centre ── */

.ic-handle {
  position: absolute;
  left: 0;
  top: calc(var(--u) * 14);
  width: calc(var(--u) * 49);
  height: calc(var(--u) * 81);
  border-radius: calc(var(--u) * 2.4);
  background:
    linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0) 18%, rgba(0, 0, 0, 0) 58%, rgba(0, 0, 0, 0.42)),
    linear-gradient(rgba(120, 106, 88, 0.32), rgba(120, 106, 88, 0.32)),   /* warm gunmetal tint */
    var(--ic-titanium) center / cover,
    #9a968f;
  background-blend-mode: normal, multiply, normal;
  box-shadow:
    inset 0 calc(var(--u) * 1) 0 rgba(255, 255, 255, 0.75),        /* fine highlight across the top edge */
    inset calc(var(--u) * 1) 0 0 rgba(255, 255, 255, 0.22),
    inset calc(var(--u) * -1) 0 0 rgba(0, 0, 0, 0.25),
    inset 0 calc(var(--u) * -1.6) 0 rgba(0, 0, 0, 0.45),           /* chamfer on the lower edge */
    0 calc(var(--u) * 1) calc(var(--u) * 1) rgba(0, 0, 0, 0.5),
    0 calc(var(--u) * 6) calc(var(--u) * 9) rgba(0, 0, 0, 0.45);
  outline: none;
  cursor: grab;
}

.is-dragging .ic-handle { cursor: grabbing; }

.ic-handle:focus-visible {
  box-shadow:
    0 0 0 calc(var(--u) * 1.5) #1f1f1f,
    0 0 0 calc(var(--u) * 3) var(--ic-champagne),
    inset 0 calc(var(--u) * 1) 0 rgba(255, 255, 255, 0.75),
    0 calc(var(--u) * 6) calc(var(--u) * 9) rgba(0, 0, 0, 0.45);
}

/* two machined grooves above and below the window */
.ic-handle::before,
.ic-handle::after {
  content: "";
  position: absolute;
  left: 50%;
  width: calc(var(--u) * 10);
  height: calc(var(--u) * 21);
  margin-left: calc(var(--u) * -5);
  background:
    linear-gradient(to right,
      rgba(0, 0, 0, 0.6) 0 calc(var(--u) * 1.6), rgba(255, 255, 255, 0.5) 0 calc(var(--u) * 2.3), transparent 0 calc(var(--u) * 7),
      rgba(0, 0, 0, 0.6) 0 calc(var(--u) * 8.6), rgba(255, 255, 255, 0.5) 0 calc(var(--u) * 9.3), transparent 0);
}

.ic-handle::before { top: calc(var(--u) * 6); }
.ic-handle::after { bottom: calc(var(--u) * 6); }

.ic-window {
  position: absolute;
  left: calc(var(--u) * 5.5);
  right: calc(var(--u) * 5.5);
  top: calc(var(--u) * 33);
  height: calc(var(--u) * 15);
  border-radius: calc(var(--u) * 2);
  background: linear-gradient(#0c0c0c, #1b1b1b);
  box-shadow:
    inset 0 calc(var(--u) * 1.6) calc(var(--u) * 2) rgba(0, 0, 0, 0.9),
    0 calc(var(--u) * 0.8) 0 rgba(255, 255, 255, 0.35),
    0 calc(var(--u) * -0.8) 0 rgba(0, 0, 0, 0.35);
  overflow: hidden;
}

/* the weight: a small solid champagne slug */
.ic-core {
  position: absolute;
  left: 50%;
  top: calc(var(--u) * 2);
  width: calc(var(--u) * 17);
  height: calc(var(--u) * 11);
  margin-left: calc(var(--u) * -8.5);
  border-radius: calc(var(--u) * 1.6);
  background:
    repeating-linear-gradient(to right, rgba(70, 48, 28, 0.28) 0 calc(var(--u) * 0.5), transparent 0 calc(var(--u) * 2.2)) center / calc(100% - var(--u) * 6) 100% no-repeat,
    linear-gradient(var(--ic-champagne-lt), #e2c49f 30%, var(--ic-champagne) 55%, var(--ic-champagne-dk));
  box-shadow:
    inset 0 calc(var(--u) * 0.6) 0 rgba(255, 255, 255, 0.6),
    inset 0 calc(var(--u) * -0.8) 0 rgba(60, 40, 22, 0.5),
    0 0 calc(var(--u) * 2) rgba(0, 0, 0, 0.8);
}
All 5 files in the zip
  • assets/graphite.jpg
  • assets/titanium.jpg
  • index.html
  • inertia-core.css
  • inertia-core.js