/* Generated from ui/components/dial/dial.css by tools/sync-ui.py — do not edit.
   Edit the source and re-run the script; validate_ui.py fails on a
   copy that has drifted from it. */
/* The dial — the turned cap, the dish it sits in, the lit bead and the scale.
 *
 * Shared because more than one thing wears this machine's face. It was two
 * copies of the same rules, and the site's copy still had the colours written
 * out where the app had moved to tokens: linear-gradient(94deg, #363029 …)
 * against var(--dial-face). Same dial, one of them a month behind.
 *
 * Needs: ui/tokens.css, for --dial-well, --dial-face, --dial-lip, --dial-tick,
 * --dial-tick-lit, --control-edge, --lens-catch, --tune and --lit-rgb; and
 * --type-xs, --leading-flush and --tracking-sm for the scale legends.
 * Plus --ease, --motion-fast and --motion-slower for the cap and the ring.
 *
 * Does not include where the dial sits. The app places it inside a knob module
 * and the site drops it into a row, and a component that decided that for both
 * would be a layout rather than a part. Each consumer positions .dial-wrap
 * itself.
 */

/* Out of the flow entirely, pinned against the left edge of the .knob row —
   see the note on .knob above for why it is not a grid cell. */
.dial-wrap {
  /* --dial sizes the whole module; the cap and the tick ring are fractions of
     it, so one value scales a knob without a second set of rules.
     The default lives in the fallback, NOT as a declaration here: declaring it
     on this element makes it the element's own value, which beats anything
     inherited — so every --dial set on a parent was silently ignored and every
     knob rendered at 116px whatever it was told. */
  width: var(--dial, 116px);
  height: var(--dial, 116px);
  --cap: calc(var(--dial, 116px) * .5);
  /* How far the dish reaches past the cap, all the way round. */
  --dish: 11px;
  /* The lit bead and how far in from the cap's edge it sits. Variables rather
     than fixed, because a cap twice the size wants a bead you can still read
     across the room — held at 4px it turns into a speck. */
  --bead: 4px;
  --bead-inset: 8px;
  /* And the ticks always clear it.
     Derived, not declared. This was a fraction of --dial while the dish is a
     fraction of --cap plus a fixed ring — so every context that tuned the cap
     moved the two relative to one another, and the ring ended up sitting on
     the dish's rim on the fascia and inside it everywhere else. Only the
     untouched default happened to be right. Off the dish, the ticks are
     engraved on flat panel, which is where a scale belongs. */
  --tick-r: calc(var(--cap) / 2 + var(--dish) + 5px);
  /* Where it sits is the consumer's: the app hangs it inside a knob
     module, the site drops it into a row. A component that decided
     that for both would be a layout rather than a part. */
}

/* The dish. Wider than the collar and fading out, so the panel appears to
   slope inward rather than to have a hole punched in it. */
.dial-wrap::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--cap) + var(--dish) * 2);
  height: calc(var(--cap) + var(--dish) * 2);
  margin: calc((var(--cap) + var(--dish) * 2) / -2) 0 0 calc((var(--cap) + var(--dish) * 2) / -2);
  border-radius: 50%;
  /* Raked left to right rather than lit from below: the left wall of the
     dish faces away from the light, the right wall catches it. */
  background: var(--dial-well);
  box-shadow:
    inset 0 2px 5px rgba(0, 0, 0, .5),
    inset 0 -2px 4px rgba(255, 255, 255, .04),
    0 1px 0 rgba(255, 255, 255, .025);
  pointer-events: none;
}

.dial-min { left: 9px;  bottom: 9px; }

.dial-max { right: 9px; bottom: 9px; }

.dial-mid { top: 0; left: 50%; transform: translateX(-50%); }

.dial {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--cap);
  height: var(--cap);
  margin: calc(var(--cap) / -2) 0 0 calc(var(--cap) / -2);
  border-radius: 50%;
  border: 0;
  background: var(--dial-face);
  /* The lit top lip belongs to the cap itself, not to having been touched.
     Without it the resting cap is a dark inset along its foot and nothing
     along its head, which is the shading of something pressed in — so the knob
     sat there looking held down, and gained the lip the first time it took
     focus, which read as it popping back out. A cap is raised; that is what a
     cap is. */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .14),
    inset 0 -3px 7px rgba(0, 0, 0, .45),
    0 3px 7px rgba(0, 0, 0, .55);
  cursor: ns-resize;
  touch-action: none;
  transition: box-shadow var(--motion-fast) var(--ease);
}

/* A hairline between the dish and the collar, so the two dark rings have an
   edge rather than bleeding into one another. Held flat across the top half
   and lifted only through the bottom, which is the one place light reaches
   into a depression. */
.dial::before {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1px solid transparent;
  background: var(--dial-lip) border-box;
  -webkit-mask:
    linear-gradient(#000 0 0) padding-box exclude,
    linear-gradient(#000 0 0);
  mask:
    linear-gradient(#000 0 0) padding-box exclude,
    linear-gradient(#000 0 0);
  pointer-events: none;
}

/* The collar: one flat colour all the way round, and the darkest element on
   the knob. Grading it light-at-the-bottom made it compete with the cap for
   attention and read as a second, brighter ring. */
.dial::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 4px solid var(--control-edge);
  pointer-events: none;
}

.dial.turning {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .16),
    inset 0 -4px 8px rgba(0, 0, 0, .55),
    0 3px 7px rgba(0, 0, 0, .55),
    0 0 0 1px rgba(var(--lit-rgb), 0.18);
}

/* The lit edge of the cap. It has to be a masked gradient ring rather than an
   offset inset shadow: offsetting a shadow inside a circle makes a crescent
   that is thick at one side and tapers to nothing at the other, which fades by
   shape. This holds 1px all the way round and fades by alpha instead. */
.dial-rim {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid transparent;
  background:
    linear-gradient(158deg,
      rgba(255, 255, 255, .16) 0%,
      rgba(255, 255, 255, .07) 26%,
      rgba(255, 255, 255, 0) 56%) border-box;
  -webkit-mask:
    linear-gradient(#000 0 0) padding-box exclude,
    linear-gradient(#000 0 0);
  mask:
    linear-gradient(#000 0 0) padding-box exclude,
    linear-gradient(#000 0 0);
  pointer-events: none;
}

/* The pointer is a single lit bead now. No mask is needed without a rectangle
   to clip, and leaving overflow:hidden on would have cropped the bead's glow
   at the cap's edge — a light should spill. */
.dial-mark {
  position: absolute;
  inset: 0;
  transform: rotate(var(--angle, 0deg));
  pointer-events: none;
}

/* The bead: small, lit the way the readouts are. */
.dial-mark::after {
  transition: background var(--motion-slower) var(--ease), box-shadow var(--motion-slower) var(--ease);

  content: "";
  position: absolute;
  left: 50%;
  top: var(--bead-inset);
  width: var(--bead);
  height: var(--bead);
  margin-left: calc(var(--bead) / -2);
  border-radius: 50%;
  background: var(--lens-catch), var(--tune);
  /* The same bloom the seven-segment readouts carry, so the lit parts of the
     panel all glow alike. */
  box-shadow:
    inset 0 -1px 0 rgba(255, 255, 255, .2),
    0 0 7px rgba(var(--lit-rgb), .55),
    0 0 14px rgba(var(--lit-rgb), .25);
}

.dial-input {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;   /* focusable by keyboard, invisible to the cursor */
}

/* Every engraved value on a dial. All three share this rule: a figure added to
   knob.js and not added here comes out static, full size and in the page's own
   face, which is how the quarters looked on their first outing. */
.dial-min, .dial-mid, .dial-max {
  position: absolute;
  /* 8.5px before the typescale, and the only half-pixel size in the kit. It
     bought nothing: Silkscreen and Work Sans both anti-alias at every size, so
     8.5 was not landing on a grid that 9 misses. line-height was also set
     twice here, identically. */
  font-size: var(--type-xs);
  font-weight: 500;
  line-height: var(--leading-flush);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 0 rgba(0, 0, 0, .8);
}

