/* MODULE: css/tactile.css — CONTROLS ARE OBJECTS.
   Loaded after phase6.css. Depends on the light variables published by
   src/light.js (--sh-x/--sh-y/--sh-blur/--ao-*/--hl-*/--light-tint).

   ── The correction this file makes ──────────────────────────────────────
   phase6.css flattened everything, and that was half right. Look at
   docs/reference/braun-receiver-panel.jpg: the PANEL is flat matte and the
   DIAL FACE is flat — but the CONTROLS are objects. Domed cream buttons with
   soft shading, real ambient-occlusion shadows pooled underneath, knurled
   dark knobs, and exactly one red button on the whole panel.

   So: flat where Braun is flat, dimensional where Braun is dimensional.

   ── Why this is not the dated look ─────────────────────────────────────
   Web 2.0 skeuomorphism = hard bevels, tight offset drop shadows, glossy
   specular streaks, inset white top-lines. All still banned.
   This is soft-diffuse rendering = broad gentle shading across a dome, a
   large low-opacity contact shadow, no gloss, no rim light, no bevel.
   The difference is entirely in the softness and the physical plausibility
   of the light, and the light here is real: it moves with the time of day.
   ======================================================================== */

/* Fallbacks so the file is correct before light.js boots, and stays correct
   if a user has JS-driven lighting turned off. */
:root {
  --sh-x: 0px;
  --sh-y: 2.4px;
  --sh-blur: 9px;
  --sh-alpha: 0.16;
  --ao-blur: 3px;
  --ao-alpha: 0.22;
  --hl-x: 4%;
  --hl-y: -22%;
  --hl-alpha: 0.78;
  --light-tint: rgb(255 250 242);
  --light-tint-a: 0.07;
}

/* ── 1. THE DOMED KEY ────────────────────────────────────────────────────
   A key is a gently convex part sitting in the panel. Three things describe
   it, and nothing else is permitted:
     · a broad soft highlight on the lit face of the dome
     · a soft ambient-occlusion shadow pooled where it meets the panel
     · a cast shadow thrown away from the light
   No bevel. No inset white line. No gloss. */
.btn,
.chip,
.segmented__key,
.set-danger__btn {
  position: relative;
  border: 0 !important;
  border-radius: 10px !important;
  background-color: var(--key-face, var(--ramp-050)) !important;

  /* The dome. A large soft radial highlight offset toward the light, mixed
     with the light's own colour temperature. */
  background-image: radial-gradient(
    118% 118% at calc(50% + var(--hl-x)) calc(50% + var(--hl-y)),
    color-mix(in oklab, var(--light-tint) calc(var(--hl-alpha) * 100%), transparent) 0%,
    transparent 62%
  ) !important;

  box-shadow:
    /* contact shadow — where the part meets the panel */
    0 1px var(--ao-blur) rgba(46, 40, 30, var(--ao-alpha)),
    /* cast shadow — thrown away from the light source */
    var(--sh-x) var(--sh-y) var(--sh-blur) rgba(46, 40, 30, var(--sh-alpha)),
    /* the part's own edge, so it reads as moulded rather than drawn */
    0 0 0 0.5px rgba(46, 40, 30, 0.11) !important;

  transition:
    box-shadow 130ms cubic-bezier(0.2, 0, 0.2, 1),
    transform 130ms cubic-bezier(0.2, 0, 0.2, 1),
    background-color 130ms linear;
}

/* Round keys stay round — the ET66's and the receiver's are circles. */
.btn--icon,
.btn--round {
  border-radius: 50% !important;
}

/* Pressed: the part travels DOWN into the panel. The cast shadow collapses
   because there is no longer a gap to cast across, the contact shadow tightens,
   and the highlight dims because the dome has tilted away from the light.
   That is what pressing a real key looks like. */
.btn:active,
.chip:active,
.segmented__key:active,
.set-danger__btn:active {
  transform: translateY(1px) !important;
  box-shadow:
    0 0.5px 1.5px rgba(46, 40, 30, calc(var(--ao-alpha) + 0.08)),
    0 0 0 0.5px rgba(46, 40, 30, 0.14),
    inset 0 1px 2px rgba(46, 40, 30, 0.09) !important;
  background-image: radial-gradient(
    118% 118% at calc(50% + var(--hl-x)) calc(50% + var(--hl-y)),
    color-mix(in oklab, var(--light-tint) calc(var(--hl-alpha) * 62%), transparent) 0%,
    transparent 62%
  ) !important;
}

/* ── 2. THE ONE RED KEY ──────────────────────────────────────────────────
   The receiver panel has exactly one: `fm`. Ours is `start`. Same treatment,
   different pigment — a red part is still a part, lit by the same room. */
.btn--primary,
.btn--lg.btn--primary {
  --key-face: var(--signal-key);
  color: var(--on-signal) !important;
  background-image: radial-gradient(
    118% 118% at calc(50% + var(--hl-x)) calc(50% + var(--hl-y)),
    rgba(255, 255, 255, calc(var(--hl-alpha) * 0.3)) 0%,
    transparent 64%
  ) !important;
  box-shadow:
    0 1px var(--ao-blur) rgba(46, 40, 30, calc(var(--ao-alpha) + 0.06)),
    var(--sh-x) var(--sh-y) var(--sh-blur) rgba(46, 40, 30, calc(var(--sh-alpha) + 0.04)),
    0 0 0 0.5px rgba(120, 30, 6, 0.34) !important;
}

/* Quiet controls have no body, so they get no light. */
.btn--quiet,
.btn--plain {
  background-image: none !important;
  box-shadow: none !important;
}

/* ── 3. THE SEGMENTED SELECTOR ───────────────────────────────────────────
   A row of keys in a recessed channel. The channel is cut INTO the panel, so
   it gets an inset shadow at its top lip; the selected key rises out of it. */
.segmented {
  background-color: var(--ramp-250) !important;
  border-radius: 12px !important;
  padding: 3px !important;
  gap: 3px !important;
  box-shadow:
    inset 0 1px 2px rgba(46, 40, 30, 0.16),
    inset 0 0 0 0.5px rgba(46, 40, 30, 0.08) !important;
}
.segmented__key {
  background-color: transparent !important;
  background-image: none !important;
  box-shadow: none !important;
  border: 0 !important;
  border-radius: 9px !important;
}
.segmented__key[aria-selected="true"],
.segmented__key[aria-pressed="true"],
.segmented__key.is-active {
  background-color: var(--ramp-050) !important;
  color: var(--ink) !important;
  background-image: radial-gradient(
    118% 118% at calc(50% + var(--hl-x)) calc(50% + var(--hl-y)),
    color-mix(in oklab, var(--light-tint) calc(var(--hl-alpha) * 80%), transparent) 0%,
    transparent 66%
  ) !important;
  box-shadow:
    0 1px var(--ao-blur) rgba(46, 40, 30, var(--ao-alpha)),
    var(--sh-x) var(--sh-y) calc(var(--sh-blur) * 0.6) rgba(46, 40, 30, var(--sh-alpha)),
    0 0 0 0.5px rgba(46, 40, 30, 0.1) !important;
}
/* The indicator lamp is a lens, not a dot — tiny, domed, self-coloured. */
.segmented__led {
  background-image: radial-gradient(
    circle at 34% 28%,
    color-mix(in oklab, white 52%, var(--signal)) 0%,
    var(--signal) 58%
  ) !important;
  box-shadow: 0 0 0 0.5px rgba(120, 30, 6, 0.3) !important;
}

/* ── 4. THE PANEL STAYS FLAT ─────────────────────────────────────────────
   This is the half of phase6 that was right and must survive. A Braun front
   panel is one flat matte colour; only the parts on it are dimensional. */
.chassis,
.panel,
.module,
.tt-module,
.tt-panel {
  background-image: none !important;
}

/* ── 5. FIELDS ARE CUT INTO THE PANEL ────────────────────────────────────
   Recessed, so the light does the opposite of a key: shadow at the top lip. */
.field,
input[type="text"],
input[type="search"] {
  background-color: var(--ramp-100) !important;
  border-radius: 8px !important;
  box-shadow:
    inset 0 1.5px 3px rgba(46, 40, 30, 0.13),
    inset 0 0 0 0.5px rgba(46, 40, 30, 0.09) !important;
}

/* ── 6. GRAPHITE ─────────────────────────────────────────────────────────
   Same object, dark material. Shadows go deeper and the highlight is the only
   thing describing the form, so it carries slightly more of the work. */
[data-theme="graphite"] .btn,
[data-theme="graphite"] .chip,
[data-theme="graphite"] .segmented__key[aria-selected="true"] {
  box-shadow:
    0 1px var(--ao-blur) rgba(0, 0, 0, calc(var(--ao-alpha) + 0.3)),
    var(--sh-x) var(--sh-y) var(--sh-blur) rgba(0, 0, 0, calc(var(--sh-alpha) + 0.24)),
    0 0 0 0.5px rgba(0, 0, 0, 0.5) !important;
}
[data-theme="graphite"] .segmented {
  box-shadow:
    inset 0 1px 3px rgba(0, 0, 0, 0.6),
    inset 0 0 0 0.5px rgba(0, 0, 0, 0.4) !important;
}
[data-theme="graphite"] .field,
[data-theme="graphite"] input[type="text"] {
  box-shadow:
    inset 0 1.5px 3px rgba(0, 0, 0, 0.55),
    inset 0 0 0 0.5px rgba(0, 0, 0, 0.4) !important;
}

/* ── 7. REDUCED MOTION ───────────────────────────────────────────────────
   The light still moves — it is information, not decoration, and it moves far
   too slowly to trigger anyone. What stops is the press travel. */
@media (prefers-reduced-motion: reduce) {
  .btn,
  .chip,
  .segmented__key {
    transition: none !important;
  }
  .btn:active,
  .chip:active,
  .segmented__key:active {
    transform: none !important;
  }
}

/* ── 8. FORCED COLOURS ───────────────────────────────────────────────────
   Under a high-contrast OS theme, none of this survives and none of it should. */
@media (forced-colors: active) {
  .btn,
  .chip,
  .segmented__key,
  .field {
    background-image: none !important;
    box-shadow: none !important;
    border: 1px solid ButtonText !important;
  }
}
