/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

/* Cartridge Light @font-face lives in layouts/_cartridge_font.html.erb (Propshaft does not rewrite CSS url() paths). */

/* ── Retro CRT effects ── */

/* Scanline overlay — applied to selected surfaces (hero, detail backdrop) */
.crt-scanlines {
  position: relative;
}
.crt-scanlines::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    transparent 0px,
    transparent 2px,
    rgba(0, 0, 0, 0.22) 2px,
    rgba(0, 0, 0, 0.22) 3px
  );
  pointer-events: none;
  z-index: 1;
  mix-blend-mode: multiply;
}

/* Phosphor glow for buttons and accent elements */
.crt-glow {
  box-shadow:
    0 0 12px rgba(6, 182, 212, 0.3),
    0 0 30px rgba(6, 182, 212, 0.1);
}
.crt-glow:hover {
  box-shadow:
    0 0 16px rgba(6, 182, 212, 0.45),
    0 0 40px rgba(6, 182, 212, 0.15);
}

/* Warm CRT text glow */
.crt-text-glow {
  text-shadow:
    0 0 10px rgba(6, 182, 212, 0.5),
    0 0 30px rgba(6, 182, 212, 0.2);
}

/* Header "TVISART" wordmark. The cyan→fuchsia→amber gradient is set with Tailwind
   utilities in the layout; this adds only what Tailwind can't express: a phosphor
   glow dialed down for header-size text, plus the two mirror-image T alternates
   that bookend the word — lead T ss01 (bar points right), final T ss02 (bar points
   left), both angled inward. */
.crt-wordmark { text-shadow: 0 0 8px rgba(6, 182, 212, 0.35), 0 0 20px rgba(6, 182, 212, 0.12); }
.crt-wordmark-t-lead { font-feature-settings: "ss01" 1; }
.crt-wordmark-t-tail { font-feature-settings: "ss02" 1; }

/* One-shot scanline sweep — the "tuning in" moment on show pages */
@keyframes crt-sweep-down {
  0%   { top: -2%; opacity: 0; }
  12%  { opacity: 1; }
  92%  { opacity: 1; }
  100% { top: 102%; opacity: 0; }
}

.crt-sweep-line {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  background: linear-gradient(to bottom, transparent, rgba(103, 232, 249, 0.75), transparent);
  box-shadow: 0 0 22px rgba(103, 232, 249, 0.45);
  pointer-events: none;
  z-index: 3;
  animation: crt-sweep-down 1.6s ease-out 0.2s 1 both;
}

@media (prefers-reduced-motion: reduce) {
  .crt-sweep-line {
    animation: none;
    display: none;
  }
}

/* Broadcast channel strip — labeled segments with hairline dividers.
   Dividers come from a 1px flex `gap` revealing the border-color set on the
   parent's background. This way wrapped rows don't leave an orphan left-border
   on the first cell of a new line. */
.channel-strip {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 1px;
  border: 1px solid var(--color-crt-border, #2a2935);
  border-radius: 4px;
  background-color: var(--color-crt-border, #2a2935);
  overflow: hidden;
}

.channel-strip__cell {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.85rem;
  line-height: 1;
  background: rgba(17, 16, 22, 0.72);
  backdrop-filter: blur(6px);
}

.channel-strip__label {
  font-family: ui-monospace, monospace;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: rgba(103, 232, 249, 0.9);
}

.channel-strip__value {
  font-family: ui-monospace, monospace;
  font-size: 13px;
  font-weight: 600;
  color: rgb(243, 244, 246);
}

/* Broadcast panel language for signed-in views */
.crt-panel {
  position: relative;
  border: 1px solid rgba(42, 41, 53, 0.95);
  border-radius: 0.375rem;
  background: rgba(31, 30, 39, 0.88);
  overflow: hidden;
}

.crt-panel::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: linear-gradient(90deg, rgba(103, 232, 249, 0.95), rgba(217, 70, 239, 0.9));
  pointer-events: none;
}

.crt-panel-fuchsia::before {
  background: linear-gradient(90deg, rgba(217, 70, 239, 0.95), rgba(103, 232, 249, 0.75));
}

.crt-panel-amber::before {
  background: linear-gradient(90deg, rgba(251, 191, 36, 0.95), rgba(103, 232, 249, 0.7));
}

.crt-kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: ui-monospace, monospace;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(103, 232, 249, 0.92);
}

.crt-kicker::before {
  content: "";
  display: block;
  width: 1.5rem;
  height: 1px;
  background: linear-gradient(90deg, rgba(103, 232, 249, 0.9), rgba(103, 232, 249, 0.15));
}

.crt-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  border: 1px solid rgba(55, 65, 81, 0.8);
  border-radius: 9999px;
  background: rgba(17, 16, 22, 0.62);
  padding: 0.3rem 0.75rem;
  font-size: 0.75rem;
  color: rgb(229, 231, 235);
}

.crt-chip-muted {
  color: rgb(156, 163, 175);
}

.crt-chip-mono {
  font-family: ui-monospace, monospace;
  letter-spacing: 0.04em;
}

.crt-divider {
  height: 1px;
  background: linear-gradient(90deg, rgba(103, 232, 249, 0.28), rgba(42, 41, 53, 0.95) 35%, rgba(42, 41, 53, 0.95) 65%, rgba(217, 70, 239, 0.24));
}

/* ── Section rail (sticky in-page nav for long detail pages) ── */

/* Tailwind has no utility for either scrollbar property. */
.no-scrollbar {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.no-scrollbar::-webkit-scrollbar {
  display: none;
}

/* Fade the cut-off edges so the rail reads as scrollable rather than clipped.
   The controller toggles the data attributes as the list scrolls, so an edge
   only dims when something is actually hidden past it. */
.section-rail__viewport::before,
.section-rail__viewport::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1.75rem;
  pointer-events: none;
  opacity: 0;
  transition: opacity 150ms ease;
  z-index: 1;
}

.section-rail__viewport::before {
  left: 0;
  background: linear-gradient(90deg, rgba(17, 16, 22, 0.95), transparent);
}

.section-rail__viewport::after {
  right: 0;
  background: linear-gradient(270deg, rgba(17, 16, 22, 0.95), transparent);
}

.section-rail[data-overflow-start="true"] .section-rail__viewport::before,
.section-rail[data-overflow-end="true"] .section-rail__viewport::after {
  opacity: 1;
}

/* The pills are built by the section-nav controller rather than a template,
   so their styling lives here alongside the other JS-constructed elements. */
.section-rail__pill {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border: 1px solid transparent;
  border-radius: 9999px;
  padding: 0.32rem 0.8rem;
  font-family: ui-monospace, monospace;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  color: rgb(156, 163, 175);
  transition: color 150ms ease, background-color 150ms ease, border-color 150ms ease;
}

.section-rail__pill:hover {
  color: rgb(255, 255, 255);
  border-color: rgba(42, 41, 53, 0.95);
  background: rgba(31, 30, 39, 0.9);
}

.section-rail__pill:focus-visible {
  outline: 2px solid rgba(103, 232, 249, 0.7);
  outline-offset: 2px;
}

.section-rail__pill[aria-current="location"] {
  color: rgb(165, 243, 252);
  border-color: rgba(103, 232, 249, 0.35);
  background: rgba(103, 232, 249, 0.12);
}

.section-rail__count {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: rgba(156, 163, 175, 0.85);
}

.section-rail__pill[aria-current="location"] .section-rail__count {
  color: rgba(165, 243, 252, 0.75);
}

/* Both consume offsets the section-nav controller measures at runtime; the
   fallbacks keep anchors usable before it connects. */
.section-anchor {
  scroll-margin-top: var(--section-rail-offset, 7rem);
}

.section-aside {
  top: var(--section-rail-offset, 7rem);
}

/* ── Calibration module (rate-shows progress) ── */

.calibration-segment {
  background: rgba(107, 114, 128, 0.18);
  border: 1px solid rgba(107, 114, 128, 0.32);
  transition: background 220ms ease, border-color 220ms ease, box-shadow 280ms ease;
}

.calibration-segment.is-lit {
  background: rgba(6, 182, 212, 0.95);
  border-color: rgba(103, 232, 249, 0.55);
}

.calibration-segment.is-peak {
  background: rgba(232, 121, 249, 1);
  border-color: rgba(240, 171, 252, 0.75);
  box-shadow: 0 0 8px rgba(232, 121, 249, 0.45);
}

@keyframes calibration-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

.calibration-dot-online {
  animation: calibration-pulse 1.8s ease-in-out infinite;
}

/* Recommendation skeleton shimmer */
@keyframes shimmer {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

.recommendation-shimmer {
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.04) 40%,
    rgba(255, 255, 255, 0.06) 50%,
    rgba(255, 255, 255, 0.04) 60%,
    transparent 100%
  );
  animation: shimmer 2s ease-in-out infinite;
}

/* Recommendation reveal transition */
.recommendation-reveal {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s ease-out, transform 0.5s ease-out;
}

.recommendation-reveal.reveal-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ── Verdict meter (thumbs down / meh / up) ── */

.verdict-meter {
  display: inline-flex;
  gap: 0.4rem;
  align-items: center;
}

.verdict-meter__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 0.5rem;
  border: 1px solid rgba(107, 114, 128, 0.35);
  background: rgba(17, 16, 22, 0.55);
  color: rgba(229, 231, 235, 0.55);
  transition: transform 120ms ease, background 160ms ease, border-color 160ms ease, color 160ms ease, box-shadow 160ms ease;
  cursor: pointer;
}

.verdict-meter__btn svg {
  width: 22px;
  height: 22px;
}

.verdict-meter--lg .verdict-meter__btn {
  width: 52px;
  height: 52px;
}
.verdict-meter--lg .verdict-meter__btn svg {
  width: 26px;
  height: 26px;
}

.verdict-meter__btn:hover {
  border-color: rgba(203, 213, 225, 0.55);
  color: rgb(229, 231, 235);
  background: rgba(31, 30, 39, 0.9);
}

.verdict-meter__btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(103, 232, 249, 0.6);
}

.verdict-meter__btn.is-active {
  transform: scale(1.05);
}

.verdict-meter__btn--down.is-active {
  background: rgba(248, 113, 113, 0.18);
  border-color: rgba(252, 165, 165, 0.85);
  color: rgb(252, 165, 165);
  box-shadow: 0 0 10px rgba(248, 113, 113, 0.35);
}

.verdict-meter__btn--meh.is-active {
  background: rgba(148, 163, 184, 0.18);
  border-color: rgba(203, 213, 225, 0.75);
  color: rgb(226, 232, 240);
}

.verdict-meter__btn--up.is-active {
  background: rgba(34, 211, 238, 0.18);
  border-color: rgba(103, 232, 249, 0.85);
  color: rgb(165, 243, 252);
  box-shadow: 0 0 12px rgba(34, 211, 238, 0.4);
}

/* ── Chat markdown typography ── */

.chat-markdown p {
  margin-bottom: 0.5em;
}
.chat-markdown p:last-child {
  margin-bottom: 0;
}

.chat-markdown strong {
  font-weight: 600;
}
.chat-markdown em {
  font-style: italic;
}

.chat-markdown h1, .chat-markdown h2, .chat-markdown h3 {
  font-weight: 600;
  margin-top: 0.75em;
  margin-bottom: 0.25em;
}
.chat-markdown h1:first-child,
.chat-markdown h2:first-child,
.chat-markdown h3:first-child {
  margin-top: 0;
}

.chat-markdown ul, .chat-markdown ol {
  margin: 0.5em 0;
  padding-left: 1.5em;
}
.chat-markdown ul {
  list-style-type: disc;
}
.chat-markdown ol {
  list-style-type: decimal;
}
.chat-markdown li {
  margin-bottom: 0.25em;
}
.chat-markdown li:last-child {
  margin-bottom: 0;
}

.chat-markdown code {
  font-family: ui-monospace, monospace;
  font-size: 0.85em;
  padding: 0.15em 0.35em;
  border-radius: 0.25rem;
  background: rgba(255, 255, 255, 0.08);
}
.chat-markdown pre {
  margin: 0.5em 0;
  padding: 0.75em;
  border-radius: 0.5rem;
  background: rgba(0, 0, 0, 0.3);
  overflow-x: auto;
}
.chat-markdown pre code {
  background: none;
  padding: 0;
}

.chat-markdown a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Assistant bubble links */
.chat-markdown a {
  color: #67e8f9; /* cyan-300 */
}
.chat-markdown a:hover {
  color: #a5f3fc; /* cyan-200 */
}

/* User bubble overrides */
.chat-markdown.user-markdown a {
  color: rgba(255, 255, 255, 0.9);
}
.chat-markdown.user-markdown code {
  background: rgba(255, 255, 255, 0.15);
}

/* ── Editorial markdown typography ── */
/* Used for rendered descriptions and SEO articles on detail / lander pages.
   Bigger rhythm than .chat-markdown — meant to read like editorial copy in a
   crt-panel, not chat bubbles. */

.prose-crt {
  color: rgb(229, 231, 235); /* gray-200 */
  font-size: 1rem;
  line-height: 1.7;
}

.prose-crt p {
  margin-bottom: 1em;
}
.prose-crt p:last-child {
  margin-bottom: 0;
}

.prose-crt strong {
  color: white;
  font-weight: 600;
}
.prose-crt em {
  font-style: italic;
}

.prose-crt h2,
.prose-crt h3 {
  color: white;
  font-family: var(--font-display, "Cartridge", ui-monospace, monospace);
  font-weight: 600;
  line-height: 1.25;
  margin-top: 1.5em;
  margin-bottom: 0.5em;
}
.prose-crt h2 { font-size: 1.5rem; }
.prose-crt h3 { font-size: 1.25rem; }
.prose-crt :is(h2, h3):first-child { margin-top: 0; }

.prose-crt ul,
.prose-crt ol {
  margin: 1em 0;
  padding-left: 1.5em;
}
.prose-crt ul { list-style-type: disc; }
.prose-crt ol { list-style-type: decimal; }
.prose-crt li { margin-bottom: 0.4em; }
.prose-crt li:last-child { margin-bottom: 0; }

.prose-crt hr {
  border: 0;
  border-top: 1px solid var(--color-crt-border, #2a2935);
  margin: 1.5em 0;
}

/* Links match .chat-markdown so the app teaches one "this is clickable" visual. */
.prose-crt a {
  color: #67e8f9; /* cyan-300 */
  text-decoration: underline;
  text-underline-offset: 2px;
}
.prose-crt a:hover {
  color: #a5f3fc; /* cyan-200 */
}

/* List markers borrow the kicker's cyan to tie editorial copy to the rest
   of the CRT vocabulary. ▸ instead of a disc reads as a chevron pointer
   without sacrificing scan-ability. */
.prose-crt li::marker {
  color: rgba(103, 232, 249, 0.85); /* cyan-300, kicker-matched */
  font-weight: 600;
}
.prose-crt ul > li::marker {
  content: "▸  ";
}
.prose-crt ol > li::marker {
  font-variant-numeric: tabular-nums;
}

/* Blockquotes are rare here; quiet fuchsia rail + italic, in the same hue
   family as crt-panel-fuchsia but at lower intensity. */
.prose-crt blockquote {
  margin: 1.25em 0;
  padding: 0.25em 0 0.25em 1em;
  border-left: 3px solid rgba(232, 121, 249, 0.6); /* fuchsia-400 @ 60% */
  color: rgb(243, 232, 255); /* fuchsia-50, slightly lifted from gray-200 */
  font-style: italic;
}

/* ── Collapsible panels ──
   `<details class="crt-collapsible">` collapses on small screens for quick scanning
   and always renders fully on lg+. Content stays in the DOM in both states so
   search engines and screen readers always see it. */

.crt-collapsible > summary {
  list-style: none;
  cursor: pointer;
}

.crt-collapsible > summary::-webkit-details-marker {
  display: none;
}

@media (min-width: 1024px) {
  .crt-collapsible > summary {
    cursor: default;
  }
  .crt-collapsible > summary .crt-collapsible__chevron {
    display: none;
  }
  /* Force content visible on desktop regardless of open state. The first
     selector covers legacy browsers; ::details-content covers Chrome 131+
     which wraps non-summary children in a UA pseudo-element. */
  .crt-collapsible > *:not(summary) {
    display: block !important;
    content-visibility: visible !important;
  }
  .crt-collapsible::details-content {
    display: block !important;
    content-visibility: visible !important;
    overflow: visible !important;
  }
}

/* Show cards scrollbar */
.show-cards {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.1) transparent;
}
.show-cards::-webkit-scrollbar {
  height: 4px;
}
.show-cards::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 2px;
}

/* Prevent show card links from inheriting chat-markdown link styles */
a.show-card,
a.show-card:hover {
  text-decoration: none;
  color: inherit;
}

/* ── Star rating ── */

.star-meter {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.star-meter--lg {
  gap: 4px;
}

.star-meter label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 2px;
  cursor: pointer;
  border-radius: 2px;
}

.star-meter svg {
  width: 22px;
  height: 22px;
  color: rgba(107, 114, 128, 0.55);
  transition: color 120ms ease, filter 180ms ease, transform 120ms ease;
}

.star-meter--lg svg {
  width: 30px;
  height: 30px;
}

.star-meter label:has(input:checked) svg,
.star-meter label:has(~ label input:checked) svg {
  color: rgb(250, 204, 21);
}

.star-meter label[data-rating="5"]:has(input:checked) svg {
  filter: drop-shadow(0 0 6px rgba(251, 191, 36, 0.7));
}

.star-meter:hover label svg {
  color: rgba(107, 114, 128, 0.55);
  filter: none;
}

.star-meter label:hover svg,
.star-meter label:has(~ label:hover) svg {
  color: rgb(250, 204, 21);
}

.star-meter label[data-rating="5"]:hover svg {
  filter: drop-shadow(0 0 6px rgba(251, 191, 36, 0.7));
}

.star-meter label:hover svg {
  transform: scale(1.08);
}

.star-meter label:focus-within {
  outline: 1px solid rgba(103, 232, 249, 0.6);
  outline-offset: 2px;
}

/* ── Tuning deck (onboarding rate-shows) ── */

.tuning-deck-wrap {
  position: relative;
}

.tuning-deck__burst-layer {
  position: absolute;
  inset: -1rem;
  z-index: 200;
  overflow: visible;
  pointer-events: none;
}

.tuning-deck__stack {
  position: relative;
  display: grid;
  grid-template-areas: "deck";
}

.tuning-deck__stack .tuning-deck__card {
  grid-area: deck;
  width: 100%;
  transform-origin: top center;
  transition:
    transform 0.35s cubic-bezier(0.33, 1, 0.68, 1),
    opacity 0.28s ease-out,
    filter 0.28s ease-out,
    box-shadow 0.28s ease-out;
  will-change: transform, opacity;
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.75);
}

.tuning-deck__stack .tuning-deck__card--back {
  filter: brightness(0.55) saturate(0.7);
  box-shadow: 0 10px 22px -16px rgba(0, 0, 0, 0.6);
}

.tuning-deck__stack .tuning-deck__card--back .tuning-deck__card-meta {
  visibility: hidden;
}

.tuning-deck__stack .tuning-deck__card--done {
  display: none !important;
}

@keyframes tuning-fly-up-right {
  to {
    transform: translate(120%, -45%) rotate(12deg) scale(0.92);
    opacity: 0;
  }
}

@keyframes tuning-fly-up-left {
  to {
    transform: translate(-120%, -45%) rotate(-12deg) scale(0.92);
    opacity: 0;
  }
}

@keyframes tuning-fly-down {
  to {
    transform: translate(0, 120%) scale(0.94);
    opacity: 0;
  }
}

@keyframes tuning-fly-up {
  to {
    transform: translate(0, -130%) scale(0.9);
    opacity: 0;
  }
}

.tuning-deck__card--exit-up-right {
  animation: tuning-fly-up-right 0.32s cubic-bezier(0.4, 0, 0.2, 1) forwards;
  box-shadow: 0 0 24px rgba(34, 211, 238, 0.35);
}

.tuning-deck__card--exit-up-left {
  animation: tuning-fly-up-left 0.32s cubic-bezier(0.4, 0, 0.2, 1) forwards;
  box-shadow: 0 0 24px rgba(248, 113, 113, 0.35);
}

.tuning-deck__card--exit-down {
  animation: tuning-fly-down 0.32s cubic-bezier(0.4, 0, 0.2, 1) forwards;
  filter: grayscale(0.4);
}

.tuning-deck__card--exit-up {
  animation: tuning-fly-up 0.32s cubic-bezier(0.4, 0, 0.2, 1) forwards;
  box-shadow: 0 0 18px rgba(148, 163, 184, 0.25);
}

@media (prefers-reduced-motion: reduce) {
  .tuning-deck__card {
    transition: none;
  }
  .tuning-deck__card--exit-up-right,
  .tuning-deck__card--exit-up-left,
  .tuning-deck__card--exit-down,
  .tuning-deck__card--exit-up {
    animation: none;
  }
}

/* Signal strength horizontal bar */
.signal-bar__track {
  position: relative;
  height: 0.5rem;
  border-radius: 9999px;
  background: rgba(31, 41, 55, 0.85);
  border: 1px solid rgba(55, 65, 81, 0.7);
  overflow: hidden;
}

.signal-bar__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
  border-radius: 9999px;
  background: linear-gradient(90deg, rgb(6, 182, 212), rgb(217, 70, 239));
  box-shadow: 0 0 12px rgba(217, 70, 239, 0.35);
  transition: width 0.45s cubic-bezier(0.33, 1, 0.68, 1);
}

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

/* Deck verdict row */
.verdict-meter--deck {
  display: inline-flex;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: center;
  gap: 0.6rem;
}

.verdict-meter--deck .verdict-meter__btn {
  width: 52px;
  height: 52px;
}

.verdict-meter--deck .verdict-meter__btn svg {
  width: 26px;
  height: 26px;
}


/* Streak glow tiers */
.calibration-streak--glow-1 {
  box-shadow: 0 0 12px rgba(103, 232, 249, 0.22);
  border-color: rgba(103, 232, 249, 0.35);
}

.calibration-streak--glow-2 {
  box-shadow: 0 0 18px rgba(217, 70, 239, 0.28);
  border-color: rgba(232, 121, 249, 0.45);
}

.calibration-streak--glow-3 {
  box-shadow: 0 0 22px rgba(232, 121, 249, 0.42);
  border-color: rgba(253, 186, 255, 0.55);
}

/* Burst particles */
.burst-particle {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 5px;
  height: 5px;
  margin: -2.5px 0 0 -2.5px;
  border-radius: 9999px;
  background: linear-gradient(135deg, rgba(103, 232, 249, 0.95), rgba(217, 70, 239, 0.9));
  opacity: 0.9;
  animation: burst-fly 0.65s cubic-bezier(0.2, 0.9, 0.3, 1) forwards;
  animation-delay: var(--burst-delay, 0ms);
  pointer-events: none;
}

@keyframes burst-fly {
  to {
    transform: translate(var(--burst-tx, 0px), var(--burst-ty, -40px)) scale(0.2);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .burst-particle {
    animation: none;
    opacity: 0;
  }
}
