/*
 * First Light — the cyclorama world for House Lofi Radio.
 *
 * The surface is not lit; the surface IS the light. Four clock registers
 * cross-fade as the listener's day passes. The mood cue sets a gel over them.
 * Everything here is gradients, so the idle page costs approximately nothing.
 */

@font-face {
  font-family: "Archivo";
  src: url(/assets/archivo-variable-latin-88ee190246153ce582cf46bc0dd464e07641e442e07ef9a365e0a6cfceb1dca5.woff2) format("woff2-variations");
  font-weight: 400 700;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
}

:root {
  --ink: #07070a;
  --cobalt: #1b4fd8;
  --rose: #ff5c8a;
  --gold: #ffc93d;
  --bone: #f2efe9;

  /* Palette law: each of the wheel's five cores owns one hue, used nowhere else
   * in the system, so the palette teaches the wheel. Theatre gels, not pastels:
   * saturated enough to read as a wash when one becomes the day's cue. */
  --e-happy: #f0b429;
  --e-sad: #4d9fe6;
  --e-angry: #ff5a3c;
  --e-fearful: #8a6be0;
  --e-disgusted: #4fbf86;

  /* The gel the mood cue sets. Neutral until a cue is called. */
  --gel: transparent;
  --gel-strength: 0;

  /* Horizon drift, nudged once a minute by the cyc controller. */
  --horizon: 24vh;

  --rule: rgba(242, 239, 233, 0.24);
  --dim: rgba(242, 239, 233, 0.74);
}

/* ---------------------------------------------------------------- shell -- */

html {
  background: var(--ink);
  color-scheme: dark;
}

body.first-light {
  margin: 0;
  min-height: 100svh;
  background: var(--ink);
  color: var(--bone);
  font-family: "Archivo", system-ui, sans-serif;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Browser surfaces belong to the design too. */
::selection {
  background: var(--gold);
  color: var(--ink);
}
body.first-light {
  caret-color: var(--gold);
  scrollbar-color: rgba(242, 239, 233, 0.28) transparent;
  scrollbar-width: thin;
}
:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 1px;
}
a {
  color: inherit;
  text-underline-offset: 0.28em;
  text-decoration-thickness: 1px;
}

/* ------------------------------------------------------------------ cyc -- */

.cyc {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--ink);
}

.cyc__register {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 6s cubic-bezier(0.16, 1, 0.3, 1);
}

.cyc__register[data-active] {
  opacity: 1;
}

/* Night: depthless black, one thin cobalt horizon. */
.cyc__register--night {
  background:
    radial-gradient(
      130% 13% at 50% calc(100% - var(--horizon) + 6vh),
      rgba(27, 79, 216, 0.5) 0%,
      rgba(27, 79, 216, 0.14) 38%,
      transparent 70%
    ),
    linear-gradient(to top, #0c1030 0%, #07070a 46%, #05050a 100%);
}

/* First light: rose gathering over a cobalt band. */
.cyc__register--sunrise {
  background:
    radial-gradient(
      118% 15% at 44% calc(100% - var(--horizon)),
      rgba(255, 201, 61, 0.78) 0%,
      rgba(255, 92, 138, 0.5) 30%,
      transparent 64%
    ),
    linear-gradient(to top, #3a1f4a 0%, #1b2a6b 34%, #0a0d24 74%, #07070a 100%);
}

/* Day: the cobalt field at its most luminous, gold held high. */
.cyc__register--day {
  background:
    radial-gradient(
      124% 16% at 52% calc(100% - var(--horizon)),
      rgba(255, 201, 61, 0.72) 0%,
      rgba(255, 155, 47, 0.34) 30%,
      transparent 70%
    ),
    radial-gradient(
      130% 56% at 54% calc(100% - var(--horizon) - 6vh),
      rgba(27, 79, 216, 0.5) 0%,
      transparent 74%
    ),
    linear-gradient(to top, #3f5db0 0%, #1b3f8f 26%, #10214d 64%, #070b1c 100%);
}

/* Sunset: gold low, rose gathering, violet above. */
.cyc__register--sunset {
  background:
    radial-gradient(
      122% 16% at 54% calc(100% - var(--horizon)),
      rgba(255, 201, 61, 0.86) 0%,
      rgba(255, 92, 138, 0.56) 28%,
      transparent 64%
    ),
    linear-gradient(to top, #4a1f3a 0%, #2a1450 32%, #100a26 70%, #07070a 100%);
}

/* The gel: the mood cue's colour, washed over whatever the clock is doing. */
.cyc__gel {
  position: absolute;
  inset: 0;
  background: var(--gel);
  opacity: var(--gel-strength);
  mix-blend-mode: soft-light;
  transition: opacity 3s ease, background-color 3s ease;
}

.cyc__grain {
  position: absolute;
  inset: 0;
  opacity: 0.16;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(/%23n)'/%3E%3C/svg%3E");
}

@media (prefers-reduced-motion: reduce) {
  .cyc__register,
  .cyc__gel {
    transition: none;
  }
}

/* ---------------------------------------------------------------- stage -- */

.stage {
  position: relative;
  z-index: 1;
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: 2rem;
  padding: clamp(1.25rem, 3vw, 2.5rem);
  max-width: 1600px;
  margin: 0 auto;
}

/* --------------------------------------------------------------- lettering */

.plot {
  font-stretch: 78%;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 0.6875rem;
  line-height: 1;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}

.plot--lit {
  color: var(--bone);
}

.num {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

/* ------------------------------------------------------------- head rule -- */

.rule {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.75rem 1.5rem;
  padding-bottom: 0.875rem;
  border-bottom: 1px solid var(--rule);
}

.rule__name {
  font-stretch: 74%;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.9375rem;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

/* The cyclorama mark, sitting on the wordmark's own baseline. */
.rule__mark {
  width: 1.5em;
  height: 1.5em;
  flex: none;
  color: var(--gold);
  overflow: visible;
}

.rule__span {
  margin-left: auto;
  display: flex;
  gap: 1.25rem;
  align-items: baseline;
}

/* ------------------------------------------------------------------ now -- */

.now {
  display: grid;
  gap: 2.25rem;
  justify-items: start;
  max-width: 34ch;
}

.now__title {
  font-stretch: 82%;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 0.94;
  font-size: clamp(2.25rem, 7vw, 5rem);
  margin: 0;
  text-wrap: balance;
  overflow-wrap: anywhere;

  /* Real YouTube titles run long and decorative. Three lines, then cut. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.now__state {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

.now__lamp {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--dim);
  flex: none;
}

.is-playing .now__lamp {
  background: var(--gold);
  box-shadow: 0 2px 12px rgba(255, 201, 61, 0.7);
}
.is-loading .now__lamp {
  background: var(--rose);
  animation: pulse 1.4s ease-in-out infinite;
}
/* The lamp is blown, not coloured. It borrowed an emotion hue before, which
 * broke the palette law now that the wheel is the only place those hues live. */
.is-error .now__lamp {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--dim);
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.28; }
}

@media (prefers-reduced-motion: reduce) {
  .is-loading .now__lamp { animation: none; }
}

/* -------------------------------------------------------------- controls -- */

.transport {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.key {
  appearance: none;
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 2px;
  color: var(--bone);
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease;
}

.key:hover:not(:disabled) {
  background: rgba(242, 239, 233, 0.1);
  border-color: rgba(242, 239, 233, 0.42);
}

.key:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.key--wide {
  width: auto;
  padding-inline: 1.25rem;
  gap: 0.625rem;
  grid-auto-flow: column;
}

.key[aria-pressed="true"] {
  background: rgba(255, 201, 61, 0.16);
  border-color: var(--gold);
  color: var(--gold);
}

.key svg {
  width: 18px;
  height: 18px;
  stroke-width: 1.5;
}

/* ----------------------------------------------------------------- scrub -- */

/* The timeline and the keys are one instrument, so they sit tight together and
 * take their separation from the title above. */
.board {
  display: grid;
  gap: 1.125rem;
  width: 100%;
  min-width: 0;
}

.scrub {
  display: grid;
  gap: 0.5rem;
  min-width: 0;
}

.scrub__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin: 0;
}

/*
 * Same hairline and same 3px thumb as the channel faders, because it is the
 * same desk. What separates it: the played part is filled. A fader shows how
 * loud, this shows how far, and the fill is the only honest way to say that
 * at a glance from across a room.
 */
.scrub__bar {
  --played: 0%;
  appearance: none;
  width: 100%;
  height: 22px;
  background: transparent;
  cursor: pointer;
  display: block;
}

.scrub__bar:disabled {
  cursor: default;
  opacity: 0.4;
}

.scrub__bar::-webkit-slider-runnable-track {
  height: 1px;
  background: linear-gradient(
    to right,
    var(--bone) var(--played),
    var(--rule) var(--played)
  );
}

.scrub__bar::-webkit-slider-thumb {
  appearance: none;
  width: 3px;
  height: 22px;
  margin-top: -10.5px;
  background: var(--bone);
  border-radius: 0;
}

.scrub__bar::-moz-range-track {
  height: 1px;
  background: var(--rule);
}

.scrub__bar::-moz-range-progress {
  height: 1px;
  background: var(--bone);
}

.scrub__bar::-moz-range-thumb {
  width: 3px;
  height: 22px;
  background: var(--bone);
  border: 0;
  border-radius: 0;
}

/* -------------------------------------------------------------- channels -- */

/* One column at every width: the rail is narrow and two columns overflow. */
.channels {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: 1fr;
}

.channel {
  display: grid;
  gap: 0.625rem;
}

.channel__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}

/* Level and kill sit together at the right of the head, as on a desk. */
.channel__meta {
  display: flex;
  align-items: baseline;
  gap: 0.875rem;
}

/*
 * The control reserves the thumb's full height so it can never ride up into
 * the label row; the hairline is drawn on the track, not on the element.
 */
.channel input[type="range"] {
  appearance: none;
  width: 100%;
  height: 22px;
  background: transparent;
  cursor: pointer;
  display: block;
}

.channel input[type="range"]::-webkit-slider-runnable-track {
  height: 1px;
  background: var(--rule);
}

.channel input[type="range"]::-webkit-slider-thumb {
  appearance: none;
  width: 3px;
  height: 22px;
  margin-top: -10.5px;
  background: var(--bone);
  border-radius: 0;
}

.channel input[type="range"]::-moz-range-track {
  height: 1px;
  background: var(--rule);
}

.channel input[type="range"]::-moz-range-thumb {
  width: 3px;
  height: 22px;
  background: var(--bone);
  border: 0;
  border-radius: 0;
}

.channel__note {
  font-size: 0.6875rem;
  line-height: 1.5;
  color: var(--dim);
  letter-spacing: 0.01em;
  margin: 0;
}

/* ---------------------------------------------------------------- source -- */

/*
 * YouTube's player stays visibly present at a real size. Its developer
 * policies prohibit obscuring player attribution, and hiding it is exactly
 * the shortcut this category takes. Here it reads as the booth's source
 * monitor, which is honest and native to the world.
 */
.source {
  position: absolute;
  left: -9999px;
  top: 0;
  width: 320px;
  height: 180px;
  pointer-events: none;
}



/* ------------------------------------------------------------------- cue -- */

.cue {
  display: grid;
  gap: 1.25rem;
}

.cue--lead {
  border-bottom: 1px solid var(--rule);
  padding-bottom: 1.5rem;
}

.cue__ask {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.875rem 1.25rem;
}

.cue__question {
  font-stretch: 80%;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: clamp(1rem, 2.4vw, 1.375rem);
  margin: 0;
}

.cue__panel {
  display: grid;
  gap: 1.5rem;
  padding: 1.5rem 0 0.5rem;
  border-top: 1px solid var(--rule);
}

/* Skipped and switched-off are resting states, not prompts. They sit back so
 * the footer stops asking for attention once the user has answered it. */
.cue__ask--quiet {
  color: var(--dim);
  margin: 0;
}

.cue__steps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  margin: 0;
}

/* Tracks are capped, not fluid. Step 3 offers only two words, and on 1fr they
 * would each stretch to half the stage and stop reading as the same control
 * the five cores were. The plate is the same size on every step. */
.wheel {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 200px));
  justify-content: start;
  gap: 0.5rem;
  max-width: 900px;
  padding: 0;
  margin: 0;
  border: 0;
}

.wheel legend {
  padding: 0;
  margin-bottom: 0.875rem;
}

.feeling {
  appearance: none;
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 2px;
  color: var(--bone);
  padding: 0.75rem 0.875rem;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  cursor: pointer;
  text-align: left;
  font: inherit;
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-stretch: 82%;
  font-weight: 600;
  transition: border-color 0.18s ease, background-color 0.18s ease;
}

.feeling:hover {
  background: rgba(242, 239, 233, 0.08);
  border-color: rgba(242, 239, 233, 0.4);
}

.feeling__gel {
  width: 12px;
  height: 12px;
  border-radius: 1px;
  background: var(--hue);
  flex: none;
}

.feeling[aria-pressed="true"] {
  border-color: var(--hue);
  background: color-mix(in srgb, var(--hue) 16%, transparent);
}

.cue__set {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
}

/* Project convention: a CTA goes full width on mobile. Only the cue's two,
 * the transport keys are icon targets and stay as they are. */
@media (max-width: 39.99rem) {
  .cue .key--wide {
    width: 100%;
  }
}

.cue__summary {
  font-stretch: 80%;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: clamp(1.25rem, 3vw, 1.75rem);
  margin: 0;
}

.link {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--dim);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 0.3em;
  position: relative;
}

/*
 * Stencil caps at 11px are a 12px tap target. The hit area is grown with a
 * pseudo-element so a thumb can find it without the type getting bigger and
 * the rules moving.
 */
.link::after {
  content: "";
  position: absolute;
  inset: -0.625rem -0.5rem;
}

/*
 * `font: inherit` above resets the button's user-agent font, and because it
 * lands after .plot at the same specificity it takes the stencil size with it.
 * Every .link.plot control was rendering larger than the label beside it.
 */
.link.plot {
  font-stretch: 78%;
  font-weight: 600;
  letter-spacing: 0.16em;
  font-size: 0.6875rem;
  line-height: 1;
}

.link:hover {
  color: var(--bone);
}

/* A lit control on the desk. The word changes too; colour never carries it. */
.link[aria-pressed="true"] {
  color: var(--gold);
}

/* ---------------------------------------------------------------- aside -- */

.plate {
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 1rem 1.125rem;
  display: grid;
  gap: 0.625rem;
  max-width: 34ch;
}

/* The teaser is a printed note on the wall, not another framed panel. The rule
 * above it is what makes it a section of the rail rather than a loose caption
 * hanging off the channels. */
.plate--bare {
  border: 0;
  border-top: 1px solid var(--rule);
  border-radius: 0;
  padding: 1.25rem 0 0;
  gap: 0.75rem;
}

.plate p {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--dim);
}

/*
 * The one place on the page that is selling something, so it is the one label
 * that steps out of the 11px stencil rank the channel heads share. Gold is
 * already this desk's word for live; the heading borrows it rather than
 * inventing a second accent.
 */
/* Scoped under .plate: the generic `.plate p` rule below carries an element
 * selector and would otherwise take back both the size and the colour. */
.plate p.plate__head {
  margin: 0;
  font-stretch: 76%;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.875rem;
  line-height: 1;
  color: var(--gold);
}

.plate__list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.5rem;
}

.plate__list li {
  position: relative;
  padding-left: 1.0625rem;
  font-size: 0.75rem;
  line-height: 1.35;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-stretch: 82%;
  color: var(--dim);
}

/* Drawn from the same square the wheel's gel chip uses, at tick size. */
.plate__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.45em;
  width: 4px;
  height: 4px;
  background: currentColor;
}

/* The number is the line people look for, so it is the lit one. */
.plate__list li.plate__price {
  color: var(--bone);
  font-weight: 700;
}

.plate__list li.plate__price::before {
  background: var(--gold);
}

/* --------------------------------------------------------------- layout -- */

.deck {
  display: grid;
  gap: 2.5rem;
  grid-template-columns: 1fr;
  min-width: 0;
}

.deck__side {
  display: grid;
  gap: 1.75rem;
  justify-items: start;
  min-width: 0;
}

/*
 * The subject sits low against the wall and the light is left to run above it.
 * The upper field is the cyclorama, not an accident of vertical centring.
 */
@media (min-width: 60rem) {
  .stage {
    gap: 2.5rem;
  }
  .deck {
    grid-template-columns: minmax(0, 1fr) minmax(260px, 320px);
    gap: 4rem;
    align-items: stretch;
  }
  .now {
    align-self: end;
    padding-bottom: 1rem;
  }
  .deck__side {
    align-self: start;
  }
}

/* The sign-off. Quiet enough that an eight-hour tab never notices it, present
   enough to be read once. */
.sign {
  border-top: 1px solid var(--rule);
  padding-top: 1rem;
}

.sign p {
  margin: 0;
}

.sign__heart {
  font-size: 0.875em;
  vertical-align: baseline;
}

[hidden] {
  display: none !important;
}

/* -------------------------------------------------------------- waitlist -- */

/* Premium waiting list. Borrows the .key border and colour so the field sits
   with the transport controls rather than looking like a browser default. */
.waitlist {
  display: grid;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.waitlist input[type="email"] {
  appearance: none;
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 2px;
  color: var(--bone);
  font: inherit;
  padding: 0.5rem 0.625rem;
  width: 100%;
  min-width: 0;
}

.waitlist input[type="email"]::placeholder {
  color: rgba(242, 239, 233, 0.35);
}

.waitlist input[type="email"]:focus-visible {
  outline: none;
  border-color: var(--gold);
}

/* Full width on the rail, which is narrow at every breakpoint. */
.waitlist .key--wide {
  width: 100%;
}

.waitlist__note {
  margin-top: 0.625rem;
}

/* ----------------------------------------------------------------- gauge -- */

/* The strength fader on step 4 of the check-up. Same vocabulary as the two
   channel faders: hairline track, square cap, no radius. What differs is that
   it wears the day's hue, set inline by the controller, so the control reads as
   part of the feeling just chosen rather than as a generic amount. */
.gauge {
  display: grid;
  gap: 1rem;
  margin-top: 1.25rem;

  /* .wheel is a grid of 200px option cells. Left in one cell the fader comes out
     a couple of hundred pixels wide; span the row instead. Capped, because a
     fader running the full width of a desktop is harder to place, not easier:
     ten notches across 28rem sit roughly a thumb-width apart. */
  grid-column: 1 / -1;
  width: 100%;
  max-width: 28rem;
}

/* The option cells are capped at 200px so five feelings sit in a readable row.
   While the fader is showing there are no options in the wheel at all, so that
   cap only starves the fader: on a phone the grid is a single 200px column and
   the notches end up 20px apart, tighter than a thumb. Drop the cap for the one
   state that is not a row of options. */
.wheel:has(.gauge:not([hidden])) {
  grid-template-columns: minmax(0, 1fr);
}

/* Tabular figures so 1 and 10 do not shift the readout as it counts. */
.gauge__read {
  font-size: clamp(3rem, 12vw, 5rem);
  line-height: 0.9;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.04em;
  color: var(--hue, var(--bone));
  transition: color 0.3s ease;
}

@media (prefers-reduced-motion: reduce) {
  .gauge__read { transition: none; }
}

.gauge__fader {
  position: relative;
  display: grid;
  gap: 0.5rem;
}

.gauge__input {
  appearance: none;
  width: 100%;
  height: 22px;
  background: transparent;
  cursor: pointer;
  display: block;
  margin: 0;
}

/* The filled part stops at the cap rather than running under and past it. */
.gauge__input::-webkit-slider-runnable-track {
  height: 1px;
  background:
    linear-gradient(to right, var(--hue, var(--bone)) 0 var(--fill, 50%),
                    var(--rule) var(--fill, 50%) 100%);
}

.gauge__input::-webkit-slider-thumb {
  appearance: none;
  width: 3px;
  height: 22px;
  margin-top: -10.5px;
  background: var(--hue, var(--bone));
  border-radius: 0;
}

.gauge__input::-moz-range-track {
  height: 1px;
  background: var(--rule);
}

.gauge__input::-moz-range-progress {
  height: 1px;
  background: var(--hue, var(--bone));
}

.gauge__input::-moz-range-thumb {
  width: 3px;
  height: 22px;
  background: var(--hue, var(--bone));
  border: 0;
  border-radius: 0;
}

.gauge__input:focus-visible {
  outline: none;
}

.gauge__input:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 1px var(--ink), 0 0 0 3px var(--hue, var(--bone));
}

.gauge__input:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 1px var(--ink), 0 0 0 3px var(--hue, var(--bone));
}

/* Ten marks, so the scale reads as ten discrete notches rather than as a
   continuous amount. Inset by half a cap at each end so the outer marks sit
   under the cap at its travel limits instead of past them. */
.gauge__ticks {
  display: flex;
  justify-content: space-between;
  margin-inline: 1.5px;
}

.gauge__ticks span {
  width: 1px;
  height: 4px;
  background: var(--rule);
}

.gauge__ends {
  display: flex;
  justify-content: space-between;
  margin: 0;
  color: var(--dim);
}
