/* apps/tinkyspeak/public/css/mic-affordance.css
 *
 * 2026-05-28 v2 (Luke caught: "putting random micorphoen buttons is
 * not helpful we need teh ciophoens buttons to have teh ebst ux
 * alined with what tehre connected to right nwo its just throw teh
 * micophine"). The v1 mic was a sibling flex-item next to every
 * input — looked thrown, didn't visually belong to the field it
 * triggered, drifted on different parent layouts.
 *
 * v2 rewires placement so the mic is INSIDE the input's host
 * region, top-right corner. The input gets right-padding so text
 * never collides with the icon. The mic is now small + understated
 * by default (transparent), and reveals chrome only on hover/focus
 * /listening — so the input wins the eye first, and the mic is
 * there when wanted.
 *
 * Visual contract (all states):
 *   • Default (idle)  — 26 × 26 circle, transparent, soft gray icon
 *   • Hover           — white pill w/ subtle shadow lift
 *   • Focus           — same as hover + brand-blue outline ring
 *   • Listening       — red gradient halo (pulse), mic icon → dot
 *   • Denied          — amber pill, mic icon, tooltip explains
 *   • Error           — gray pill w/ ×
 *
 * LABEL: PILOT-READY.
 */

/* ─── Host wrapper ────────────────────────────────────────────────
 * mic-affordance.js adds .mic-aff-host to the IMMEDIATE PARENT of
 * any decorated input. We set position: relative there so absolute
 * children anchor correctly, and add right-padding to direct text
 * inputs/textareas so the mic doesn't overlap the typed text.
 *
 * The host has many shapes in the wild (toolbar div, form-group,
 * fieldset, raw <main>). We only target DIRECT input/textarea
 * children to keep the padding effect surgical.
 */
.mic-aff-host {
  position: relative;
}
/* 2026-05-30 — mic is now inline (its own slot), so it no longer
 * overlaps the input's text. The old padding-right:40px hack is
 * removed; the input keeps its natural width. */

/* ─── The mic itself ──────────────────────────────────────────────
 * Absolute-positioned inside the host so it visually "belongs" to
 * the input, not as a thrown sibling. top-right corner works for
 * both text inputs (vertically centered within their natural
 * height) AND textareas (sticks to top-right while the textarea
 * grows downward).
 */
/* 2026-05-30 (Luke: "mics stuck inside Build buttons"). The mic used
 * to be position:absolute against the input's PARENT. When that parent
 * is a flex row that also holds a submit button (e.g. the "Build a
 * board" input + Build button), "right of the host" landed ON the
 * button. Fixed: the mic is now an INLINE button that takes its own
 * slot immediately next to the input — it can never overlap a sibling
 * button. For a flex row it renders [input][🎤][Build]. */
.mic-aff {
  position: static;
  flex: 0 0 auto;
  align-self: center;
  vertical-align: middle;
  width: 30px;
  height: 30px;
  margin: 0 4px;
  padding: 0;
  /* 2026-05-30 (Luke: "put a box around them so it reads as a button").
     At rest the mic now shows a visible bordered box + light fill +
     subtle shadow so it clearly looks pressable — not an invisible icon
     that only appears on hover. Rounded-rect ("box") rather than a bare
     circle. */
  /* 2026-05-30 (Luke: "still missing the boxes") — the hairline gray
     border on white was too faint to read as a button against white
     inputs. Stronger border + a light-gray fill so each mic clearly
     looks like a pressable chip. */
  border: 1.5px solid #AEB6C6;
  border-radius: 8px;
  background: #EEF1F6;
  box-shadow: 0 1px 2px rgba(12, 21, 48, 0.12);
  color: #3A3A4A;
  cursor: pointer;
  font: 400 14px/1 -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
  transition: background 140ms ease, color 140ms ease,
              border-color 140ms ease, box-shadow 140ms ease,
              transform 120ms ease;
}
/* (Single-line vertical-centering is now handled by align-self:center
   in the inline flow — the old absolute top:50% override is removed so
   it doesn't translate a static element off-center.) */

/* Hover / focus reveal the chrome so the user knows it's actionable. */
.mic-aff:hover {
  background: #FFFFFF;
  color: #1A1A2E;
  border-color: rgba(12, 21, 48, 0.14);
  box-shadow: 0 2px 6px rgba(12, 21, 48, 0.10);
}
.mic-aff:focus-visible {
  outline: none;
  border-color: #1976D2;
  background: #FFFFFF;
  color: #1A1A2E;
  box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.16);
}
.mic-aff__icon {
  display: inline-block;
  line-height: 1;
  font-size: 13px;
  pointer-events: none;
}

/* ─── Listening ───────────────────────────────────────────────── */
.mic-aff[data-mic-state="listening"] {
  background: linear-gradient(180deg, #FCA5A5 0%, #EF4444 100%);
  color: #FFFFFF;
  border-color: #DC2626;
  box-shadow:
    0 0 0 3px rgba(239, 68, 68, 0.22),
    0 2px 6px rgba(239, 68, 68, 0.38);
  animation: micPulse 1.2s ease-in-out infinite;
}
.mic-aff[data-mic-state="listening"] .mic-aff__icon::before {
  content: "●";
  font-size: 11px;
  letter-spacing: 0.04em;
  color: #FFFFFF;
}
.mic-aff[data-mic-state="listening"] .mic-aff__icon {
  font-size: 0;
}
@keyframes micPulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.22), 0 2px 6px rgba(239, 68, 68, 0.38); }
  50%      { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0.10), 0 2px 6px rgba(239, 68, 68, 0.32); }
}

/* ─── Denied ──────────────────────────────────────────────────── */
.mic-aff[data-mic-state="denied"] {
  background: linear-gradient(180deg, #FCD34D 0%, #F59E0B 100%);
  color: #78350F;
  border-color: #D97706;
  cursor: not-allowed;
}
.mic-aff[data-mic-state="denied"]:hover {
  transform: none;
}
.mic-aff-host[data-mic-target="input"] .mic-aff[data-mic-state="denied"]:hover {
  transform: translateY(-50%);
}

/* ─── Error ───────────────────────────────────────────────────── */
.mic-aff[data-mic-state="error"] {
  background: #F1F5F9;
  color: #475569;
  border-color: rgba(12, 21, 48, 0.18);
}
.mic-aff[data-mic-state="error"] .mic-aff__icon::before {
  content: "✕";
  font-size: 11px;
  color: #475569;
}
.mic-aff[data-mic-state="error"] .mic-aff__icon {
  font-size: 0;
}

/* ─── Tight buttons that don't visually belong to a text input ──
 * Some legacy host patterns wrap an input that's NOT a direct
 * child (input nested in a span). We still position the mic top-
 * right inside the host — but skip the padding override (no
 * direct child to pad). Visually still works because the host's
 * own padding usually clears the icon.
 */
.mic-aff-host:not(:has(> input)):not(:has(> textarea)) > .mic-aff {
  /* Inline now — nothing to override. Kept as a no-op anchor for the
     comment above. */
  transform: none;
}

/* ─── Reduced motion ──────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .mic-aff,
  .mic-aff[data-mic-state="listening"] {
    animation: none !important;
    transition: none !important;
  }
}
