/*
 * notch — STRUCTURE. Copy verbatim.
 *
 * A Dynamic-Island-style pill that floats out of the top-centre of a stage and
 * blooms live content in and out of itself. This file is geometry, layout and
 * the content-compensation transitions only — every colour, shadow and timing
 * resolves through a --sp-notch-* token defined in notch.tokens.css (the skin).
 *
 * The animated NUMERIC values (width, height, corner radii, left) are written
 * inline by notch.js every frame — they are spring-driven, so they are not
 * CSS-transitioned here. What CSS owns is the pill's static look, the press
 * scale, and the blur/opacity/scale/offset the content compensates with while
 * the container resizes underneath it.
 *
 * Faithful web port of ~/Projects/NotchKit (SwiftPM). The native original seats
 * the pill into a real hardware notch; on the web the stage stands in for the
 * screen and the pill sits at its top edge.
 */

/* ---- host: a full-width, zero-height anchor pinned to the stage top -------- */
.sp-notch {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 0;
  z-index: var(--sp-notch-z, 60);
  pointer-events: none;                 /* the pill itself re-enables hit-testing */
  font-family: var(--font-ui, system-ui, sans-serif);
  letter-spacing: var(--tracking-ui, -0.15px);
  -webkit-font-smoothing: antialiased;
}

/* ---- the pill -------------------------------------------------------------- */
/* width / height / left / border-radius are set inline by JS each frame.       */
.sp-notch__pill {
  position: absolute;
  top: 0;
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--sp-notch-surface, #000);
  color: var(--sp-notch-ink, #fff);
  overflow: hidden;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  box-shadow: var(--sp-notch-shadow, 0 10px 30px rgba(0, 0, 0, 0.35));
  /* the press scale and the expand shadow are the only non-spring animations;
     both ride the Soft Product motion tokens, never an invented curve. */
  transform: scale(var(--sp-notch-press, 1));
  transform-origin: top center;
  transition:
    transform var(--dur-instant, 150ms) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
    box-shadow var(--dur-quick, 200ms) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1));
  will-change: width, height, transform;
}

.sp-notch__pill.is-pressed { --sp-notch-press: 1.04; }
.sp-notch__pill.is-expanded {
  box-shadow: var(--sp-notch-shadow-float, 0 18px 50px rgba(0, 0, 0, 0.5));
  cursor: default;
}

/* the 1px hairline ring, drawn inside the clip so it tracks the corner radii.
   On a dark wallpaper this stroke is what keeps a black pill legible. */
.sp-notch__pill::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid var(--sp-notch-stroke, rgba(255, 255, 255, 0.14));
  pointer-events: none;
}

/* ---- content layer --------------------------------------------------------- */
/* Absolutely fills the pill so the container can resize without pushing it.
   The entering/leaving states below ARE CSS-driven: while JS springs the frame,
   the content compensates with blur + opacity + scale + offset. --sp-notch-swap
   is set by JS to the preset's openResponse so calm presets bloom slower. */
.sp-notch__content {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  padding: 0 12px;
  min-width: 0;
  transform-origin: center center;
  will-change: opacity, filter, transform;
}
.sp-notch__content--expanded {
  align-items: stretch;
  justify-content: flex-start;
  padding: 14px 16px;
  transform-origin: top center;
}

/* Island compensation (native: blur 40 compact / 20 expanded, scale 0.4×0.6,
   compact holds opacity 1, expanded fades to 0). The horizontal/vertical
   offsets are computed from the live footprint by JS and fed in as vars. */
@keyframes sp-notch-bloom {
  from {
    opacity: var(--sp-notch-from-opacity, 1);
    filter: blur(var(--sp-notch-blur, 40px));
    transform:
      translate(var(--sp-notch-off-x, 0px), var(--sp-notch-off-y, 0px))
      scale(var(--sp-notch-scale-x, 0.4), var(--sp-notch-scale-y, 0.6));
  }
  to { opacity: 1; filter: blur(0); transform: none; }
}
@keyframes sp-notch-retract {
  from { opacity: 1; filter: blur(0); transform: none; }
  to {
    opacity: var(--sp-notch-from-opacity, 1);
    filter: blur(var(--sp-notch-blur, 40px));
    transform:
      translate(var(--sp-notch-off-x, 0px), var(--sp-notch-off-y, 0px))
      scale(var(--sp-notch-scale-x, 0.4), var(--sp-notch-scale-y, 0.6));
  }
}
.sp-notch__content.is-entering {
  animation: sp-notch-bloom var(--sp-notch-swap, 0.5s) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)) both;
}
.sp-notch__content.is-leaving {
  animation: sp-notch-retract var(--sp-notch-swap, 0.5s) var(--ease-in, cubic-bezier(0.4, 0, 1, 1)) both;
}
/* refresh-in-place (same activity updating) gets a soft dip, no retract */
.sp-notch__content.is-updating {
  animation: sp-notch-update var(--sp-notch-swap, 0.5s) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)) both;
}
@keyframes sp-notch-update {
  0%   { opacity: 1; filter: blur(0); }
  45%  { opacity: 0.55; filter: blur(6px); }
  100% { opacity: 1; filter: blur(0); }
}

/* ---- generic content slots (used by any host markup) ----------------------- */
.sp-notch__leading {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--sp-notch-art, 22px);
  height: var(--sp-notch-art, 22px);
  border-radius: var(--radius-nav, 8px);
  background: var(--sp-notch-accent-soft, rgba(59, 130, 246, 0.18));
  color: var(--sp-notch-accent, #3b82f6);
}
.sp-notch__leading svg { width: 60%; height: 60%; }

.sp-notch__text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.sp-notch__title {
  font: 500 var(--text-sm, 13px) / 1.25 var(--font-ui, system-ui, sans-serif);
  letter-spacing: var(--tracking-ui, -0.15px);
  color: var(--sp-notch-ink, #fff);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sp-notch__subtitle {
  font: 400 var(--text-xs, 12px) / 1.25 var(--font-ui, system-ui, sans-serif);
  color: var(--sp-notch-ink-muted, rgba(255, 255, 255, 0.62));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* trailing flourish — an equalizer by default, any glyph works */
.sp-notch__trailing { flex: none; margin-left: auto; display: flex; align-items: flex-end; gap: 2px; height: 14px; }
.sp-notch__bar {
  width: 3px;
  border-radius: var(--radius-pill, 9999px);
  background: var(--sp-notch-accent, #3b82f6);
  animation: sp-notch-eq 0.9s var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)) infinite alternate;
}
.sp-notch__bar:nth-child(1) { height: 40%; animation-delay: -0.2s; }
.sp-notch__bar:nth-child(2) { height: 100%; animation-delay: -0.5s; }
.sp-notch__bar:nth-child(3) { height: 65%; animation-delay: -0.35s; }
@keyframes sp-notch-eq { from { transform: scaleY(0.35); } to { transform: scaleY(1); } }

/* thin progress rail along the pill's bottom edge */
.sp-notch__progress {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: var(--sp-notch-progress, 0%);
  background: var(--sp-notch-accent, #3b82f6);
  transition: width var(--dur-quick, 200ms) var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}

/* expanded layout helpers */
.sp-notch__expanded { display: flex; flex-direction: column; gap: 10px; width: 100%; min-width: 0; }
.sp-notch__expanded-head { display: flex; align-items: center; gap: 12px; min-width: 0; }
.sp-notch__expanded-art {
  flex: none;
  width: var(--sp-notch-art-lg, 56px);
  height: var(--sp-notch-art-lg, 56px);
  border-radius: var(--radius-card, 16px);
  background: var(--sp-notch-accent-soft, rgba(59, 130, 246, 0.18));
  color: var(--sp-notch-accent, #3b82f6);
  display: grid;
  place-items: center;
}
.sp-notch__expanded-title {
  font: 500 var(--text-md, 14px) / 1.2 var(--font-ui, system-ui, sans-serif);
  color: var(--sp-notch-ink, #fff);
}
.sp-notch__expanded-sub {
  font: 400 var(--text-sm, 13px) / 1.3 var(--font-ui, system-ui, sans-serif);
  color: var(--sp-notch-ink-muted, rgba(255, 255, 255, 0.62));
}
.sp-notch__controls { display: flex; align-items: center; justify-content: center; gap: 22px; color: var(--sp-notch-ink, #fff); }
.sp-notch__controls button {
  appearance: none; border: 0; background: none; padding: 4px; color: inherit;
  cursor: pointer; display: grid; place-items: center;
}
.sp-notch__controls button:focus-visible { outline: 2px solid var(--sp-notch-accent, #3b82f6); outline-offset: 2px; border-radius: var(--radius-pill, 9999px); }

/* The whole pill can be faded by JS (empty notch → opacity 0). JS writes the
   value; this just keeps the fade smooth on the fade spring. */
.sp-notch__pill.is-hidden { visibility: hidden; }

/* ---- reduced motion -------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .sp-notch__pill { transition: none; }
  .sp-notch__content.is-entering,
  .sp-notch__content.is-leaving,
  .sp-notch__content.is-updating { animation-duration: 0.01ms; }
  .sp-notch__bar { animation: none; height: 70%; }
  .sp-notch__progress { transition: none; }
}
