/* Chrome runtime CSS — keyframes + utility classes.
 * Previously injected by system/chrome/inject-keyframes.js via
 * document.createElement('style'). Extracted to this external file
 * so CSP style-src can drop 'unsafe-inline' per NKSC ZAP hardening
 * 2026-06-19. inject-keyframes.js is now a no-op (kept for the legacy
 * SSChrome.SS_CHROME_CSS export — some test probes read it).
 */
@keyframes ssz-shimmer { from { background-position: 0 0; } to { background-position: 64px 0; } }
.ssz-stripe-anim { background-size: 64px 100% !important; animation: ssz-shimmer 8s linear infinite; }
.ssz-stripe-anim:hover { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  /* Global motion reset: neutralise EVERY keyframe animation + transition
     (not just stripes). transition-duration alone never touched the
     animation property, so entrance/loop animations (toasts, modals,
     command palette, skeleton shimmer, scan line, blink, mount/tab fades)
     kept playing. iteration-count:1 stops infinite loops; .01ms duration
     makes entrances effectively instant. */
  .ssz-stripe-anim, .ssz-wipe { animation: none !important; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
.ssz-blink { animation: sszBlink 1s steps(2) infinite; }
@keyframes sszBlink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }

/* Logout wipe — hi-vis stripe sweeps L→R across the viewport just before
   window.location.replace('Login.html'). Defined here so EVERY page
   (not just Portal) gets the same farewell flourish when any UserMenu
   fires its logout. The Portal dropdown still triggers it the same way. */
@keyframes ssz-wipe { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }
.ssz-wipe { animation: ssz-wipe .55s cubic-bezier(.7, 0, .3, 1) forwards; }

/* UserMenu pill positioning — used by every module's top-right corner.
   Desktop: sits 220 px to the LEFT of QuickToggles (which itself is at
   right:16). Mobile (≤640 px wide): the QuickToggles row + UserMenu
   pill don't fit on one line, so the menu drops below QuickToggles
   (top:56 ≈ 16 + 32 px QuickToggle height + 8 px gap) and hugs the
   right edge. Class form replaces an identical inline style
   repeated across 20 module files. */
.ssz-usermenu-pos { position: fixed; top: 16px; right: 220px; z-index: 1000; }
.ssz-usermenu-name { display: inline; }
@media (max-width: 640px) {
  /* Top row shared with QuickToggles: avatar+logout-icon only,
     no name label (still in tooltip via title/aria-label) so the
     pill stops eating into the brand header. UserMenu pill width
     drops from ~120 px → ~70 px, fits next to QuickToggles at
     right:16 with the menu offset to right:170 (enough clearance
     from the 3 toggles, which use ~150 px). */
  .ssz-usermenu-pos { top: 16px; right: 170px; }
  .ssz-usermenu-name { display: none; }
}

@keyframes ssChromePulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes sszSpin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
@keyframes sszExpand { from { opacity: 0; max-height: 0; } to { opacity: 1; max-height: 2000px; } }

/* Command palette */
@keyframes sszCpFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes sszCpSlide {
  from { opacity: 0; transform: translateY(-12px) scale(.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

/* Modal */
@keyframes sszModalIn {
  from { opacity: 0; transform: scale(.96); }
  to { opacity: 1; transform: scale(1); }
}
@keyframes sszModalBackdropIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Unified page-entrance stagger — PageShell tags its content container
   .ssz-stagger; each top-level section rises into place in sequence so a
   module "composes in" on load instead of snapping. TRANSFORM-ONLY (no
   opacity) on purpose: a non-painting context (backgrounded tab, capture
   sandbox) freezes the animation timeline, and an opacity-from-0 reveal
   would then hold content invisible. Animating only translateY means the
   worst case is content resting a few px low but fully VISIBLE; when the
   page actually paints it animates up, staggered. PageShell also drops the
   class after the window (one-shot + clears any lingering transform).
   The reduced-motion reset above neutralises duration AND delay. */
@keyframes sszSectionIn {
  from { transform: translateY(10px); }
  to { transform: none; }
}
.ssz-stagger > *:not([data-ss-overlay]) {
  animation: sszSectionIn .5s cubic-bezier(.22,.61,.36,1) both;
}
.ssz-stagger > *:nth-child(1) { animation-delay: 0s; }
.ssz-stagger > *:nth-child(2) { animation-delay: .04s; }
.ssz-stagger > *:nth-child(3) { animation-delay: .08s; }
.ssz-stagger > *:nth-child(4) { animation-delay: .12s; }
.ssz-stagger > *:nth-child(5) { animation-delay: .16s; }
.ssz-stagger > *:nth-child(6) { animation-delay: .2s; }
.ssz-stagger > *:nth-child(7) { animation-delay: .24s; }
.ssz-stagger > *:nth-child(8) { animation-delay: .28s; }
.ssz-stagger > *:nth-child(n+9) { animation-delay: .32s; }

/* Native <button> background reset — browsers paint a bare <button> with a
   UA grey (ButtonFace / #f0f0f0). It's invisible on light themes but shows
   as a glaring light pill — with near-illegible light text — in dark mode.
   Any button that doesn't set its own background (ghost / icon buttons that
   rely on a CSS :hover tint) used to leak it. Neutralise to transparent so
   a missing background can never break dark-mode contrast; every styled
   button overrides this trivially. System-wide guarantee, not per-module. */
button { background-color: transparent; }

/* Keyboard focus ring — keyboard users must always see where focus is.
   Box-shadow is the load-bearing indicator because many inputs ship with
   inline outline:none (inline styles beat outline in the cascade, but not
   box-shadow). Hi-vis orange reads clearly on both light and dark themes
   (and is on-brand). Scoped to :focus-visible so mouse clicks stay clean. */
*:focus-visible {
  outline: 2px solid #FF6B00;
  outline-offset: 2px;
  box-shadow: 0 0 0 3px rgba(255, 107, 0, 0.4);
}

/* Breadcrumb back-links — make the clickable trail levels obvious on hover. */
.ssz-crumb { transition: color .12s; }
.ssz-crumb:hover { color: #FF6B00 !important; text-decoration: underline; }

/* Offscreen-skip utility — content-visibility:auto lets the browser skip
   layout/paint for chunks scrolled out of view (big win for long lists as
   they grow with real data). contain-intrinsic-size:auto remembers the
   real size after first render, so there's no scrollbar jump. Apply to
   repeated list rows / date groups. */
.ssz-cv { content-visibility: auto; contain-intrinsic-size: auto 240px; }

/* Same offscreen-skip applied to every direct child of a list container —
   add className="ssz-cv-list" to a vertical list wrapper and each row/card
   gets content-visibility automatically (no per-item wrapper / edit). For
   simple column lists only; tables (<tr>) and multi-column grids don't take
   content-visibility cleanly. */
.ssz-cv-list > * { content-visibility: auto; contain-intrinsic-size: auto 72px; }

/* Performance / reduced-effects mode — toggled via the synced reduceFx
   pref (Settings → Darstellung → Animationen off). Drops the two heaviest
   always-on GPU costs: backdrop-filter blur (every glass pill / nav / modal)
   and the 8s infinite stripe shimmer, and makes all animations instant.
   Purely visual — nothing functional changes, so it's a safe speed lever. */
html.ssz-fx-off .ssz-stripe-anim { animation: none !important; }
html.ssz-fx-off *, html.ssz-fx-off *::before, html.ssz-fx-off *::after {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  animation-duration: .01ms !important;
  animation-delay: 0s !important;
  animation-iteration-count: 1 !important;
  transition-duration: .01ms !important;
}

/* QuickToggles — at very small viewports, nudge into the corner but keep
   full size (never scale down: that shrinks the tap targets below the
   comfortable touch minimum). */
@media (max-width: 480px) {
  .ssz-quick-toggles {
    top: 12px !important;
    right: 12px !important;
  }
}
