/*
 * Sorivelo global focus and motion (handoff section 11).
 *
 * Loaded on every page shell, right after tokens.css. Unlike the rest of
 * static/sv/ this file styles plain elements, so it stays small and careful:
 *
 * Focus: every interactive element shows a 2px --focus outline with a 2px
 * offset when focused from the keyboard (:focus-visible). The selector sits
 * in :where(), so it has no specificity: Bootstrap's own focus rings on the
 * old pages (.btn, .form-control...) still win there, and an sv- component
 * that needs a different focus look (inputs: border plus --focus-halo) just
 * writes its own :focus-visible rule. Never remove a focus style without
 * putting another one in its place. Containers focused from script
 * (tabindex="-1", a sheet or dialog panel) get no ring; widgets that move
 * focus with arrow keys (tabs, switches, menu items, options) do.
 *
 * Motion: with prefers-reduced-motion, spinners and shimmers stand still,
 * every other animation in a redesigned page (.sv-app) or on an sv- element
 * jumps to its end, and --motion-fast drops to 0.01ms. So:
 * - Transitions and animations in static/sv/ take their duration from a
 *   --motion-* token, never a literal (a Go test checks this).
 * - Build animations so the resting style is the final look ("animate
 *   from"); then they stay correct with motion off.
 * - Durations become 0.01ms rather than none, so transitionend and
 *   animationend still fire for code that waits on them.
 */

/* Focus ring on every interactive element */
:where(
  a[href],
  area[href],
  button,
  input:not([type="hidden"]),
  select,
  textarea,
  summary,
  iframe,
  [contenteditable]:not([contenteditable="false"]),
  [tabindex]:not([tabindex="-1"]),
  [role="button"],
  [role="link"],
  [role="tab"],
  [role="switch"],
  [role="checkbox"],
  [role="radio"],
  [role="menuitem"],
  [role="menuitemcheckbox"],
  [role="menuitemradio"],
  [role="option"],
  [role="treeitem"],
  [role="gridcell"]
):focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

/*
 * Text for screen readers only, such as "Loading…" next to skeleton bars
 * (which are aria-hidden) or a label a sighted reader gets from the layout.
 */
.sv-visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/*
 * Spinner: a ring in the current text color with one bright quarter. Put it
 * before the verb in a busy button ("Saving") with aria-hidden="true"; the
 * button carries aria-busy. 14px by default, the button size.
 */
.sv-spinner {
  display: inline-block;
  flex: none;
  box-sizing: border-box;
  width: 14px;
  height: 14px;
  border: 2px solid color-mix(in srgb, currentColor 40%, transparent);
  border-top-color: currentColor;
  border-radius: var(--radius-pill);
  vertical-align: middle;
  animation: sv-spin var(--motion-spin) linear infinite;
}

.sv-spinner-lg {
  width: 20px;
  height: 20px;
}

@keyframes sv-spin {
  to { transform: rotate(360deg); }
}

/*
 * Shimmer: a loading bar with a moving highlight, for AI work in progress
 * ("Reading ..."). Plain skeletons (static, --skeleton) are a separate
 * component. Set its width inline or with a layout class.
 */
.sv-shimmer {
  display: block;
  height: 10px;
  border-radius: var(--radius-tile-sm);
  background: linear-gradient(90deg, var(--hairline-soft) 0%, var(--shimmer-highlight) 50%, var(--hairline-soft) 100%);
  background-size: 200% 100%;
  animation: sv-shimmer var(--motion-shimmer) linear infinite;
}

@keyframes sv-shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  /* Transitions that use the token finish at once */
  :root {
    --motion-fast: 0.01ms;
  }

  /* Spinners and shimmers stop (the old pages' Bootstrap spinner too) */
  .sv-spinner,
  .sv-shimmer,
  .spinner-border {
    animation: none;
  }

  /* Any other animation in the redesign jumps to its end */
  .sv-app,
  .sv-app *,
  .sv-app *::before,
  .sv-app *::after,
  [class^="sv-"],
  [class*=" sv-"],
  [class^="sv-"]::before,
  [class*=" sv-"]::before,
  [class^="sv-"]::after,
  [class*=" sv-"]::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}
