/**
 * Notibar v3 — Frontend stylesheet.
 *
 * Visual language ported 1:1 from v2.1.9 (assets/frontend/css/notibar.css).
 * The slide-down + fade-in entrance was the "appearance effect" v2 users
 * expect; v3 wires the same two-layer animation:
 *
 *   .njt-nofi-container-content      → opacity 0 → 1 (visibility hidden → visible)
 *   .njt-nofi-notification-bar      → translateY(-100%) → translateY(0)
 *
 *   Trigger: JS adds `.njt-nofi-visible` to the container-content node.
 *
 * Architecture:
 *  - #njt-notibar-slot           : outer JS-managed wrapper (no styling).
 *  - .njt-nofi-container         : position/z-index layer (data-position attr).
 *  - .njt-nofi-container-content : opacity transition layer.
 *  - .njt-nofi-notification-bar  : translateY transition layer + flex row.
 *
 * Typo alias `.njt-nofi-content-deskop` kept for one minor version.
 *
 * @since 3.0.0
 */

/* ==========================================================================
   Position layer
   ========================================================================== */

.njt-nofi-container {
  z-index: 10000;
  width: 100%;
  top: 0;
  left: 0;
}

.njt-nofi-container[data-position='fixed'],
.njt-nofi-container:not([data-position]) {
  position: fixed;
}

.njt-nofi-container[data-position='absolute'] {
  position: absolute;
}

/* Bottom placement (Pro) — pin to the bottom edge instead of the top. */
.njt-nofi-container[data-placement='bottom'] {
  top: auto;
  bottom: 0;
}

/* ==========================================================================
   Container content — hidden until JS adds .njt-nofi-visible
   ----------------------------------------------------------------------------
   Switched from CSS transitions to a @keyframes animation. Transitions
   require the browser to *detect* a property change between paints, and
   for innerHTML-injected nodes that detection is fragile — browsers can
   coalesce the initial and final state into a single paint, producing the
   "blank then appear" flash. Keyframes play unconditionally from `from`
   to `to` once their trigger class lands, no detection needed.
   ========================================================================== */

.njt-nofi-container-content {
  opacity: 0;
  pointer-events: none;
}

.njt-nofi-container-content.njt-nofi-visible {
  opacity: 1;
  pointer-events: auto;
}

/* ==========================================================================
   Notification bar — translateY transition (slide-down from above)
   ========================================================================== */

.njt-nofi-notification-bar {
  position: relative;
  display: flex;
  align-items: center;
  padding: 0 10px;
  width: 100%;
  box-sizing: border-box;
  transform: translateY( -100% );
  /* Inline CSS custom props set by renderBarHTML(). */
  background: var( --njt-bar-bg, #9af4cf );
  color: var( --njt-bar-color, #1919cf );
}

/* Keyframe entrance — plays when .njt-nofi-visible lands on the parent.
   `both` fill-mode keeps the bar at translateY(0) opacity:1 after the
   animation completes (otherwise it'd snap back to the initial state). */
@keyframes njt-nofi-slide-in {
  from {
    opacity: 0;
    transform: translateY( -100% );
  }
  to {
    opacity: 1;
    transform: translateY( 0 );
  }
}

.njt-nofi-container-content.njt-nofi-visible .njt-nofi-notification-bar {
  animation: njt-nofi-slide-in 0.4s cubic-bezier( 0.16, 1, 0.3, 1 ) both;
}

/* Bottom placement entrance — slide UP from below instead of down from above.
   Overrides the initial transform + the animation name; duration/easing/fill
   carry over from the base rule above. */
.njt-nofi-container[data-placement='bottom'] .njt-nofi-notification-bar {
  transform: translateY( 100% );
}

@keyframes njt-nofi-slide-in-bottom {
  from {
    opacity: 0;
    transform: translateY( 100% );
  }
  to {
    opacity: 1;
    transform: translateY( 0 );
  }
}

.njt-nofi-container-content.njt-nofi-visible
  .njt-nofi-container[data-placement='bottom'] .njt-nofi-notification-bar {
  animation-name: njt-nofi-slide-in-bottom;
}

/* Collapsed state (toggle mode — per-bar via sessionStorage). */
.njt-nofi-container-content.njt-nofi-collapsed .njt-nofi-content {
  display: none;
}

/* ==========================================================================
   Content blocks (desktop + mobile) — centered, margin:auto for distribution
   ========================================================================== */

.njt-nofi-content {
  width: 100%;
  margin: auto;
  padding: 10px 50px;
  box-sizing: border-box;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  /* display set per variant below; justify-content set via inline style by renderBarHTML(). */
}

.njt-nofi-content-desktop {
  display: flex;
}

.njt-nofi-content-mobile {
  display: none;
}

/* Typo alias: v2 users may reference .njt-nofi-content-deskop.
 * @deprecated 3.0.0 — remove in v3.1. */
.njt-nofi-content-deskop {
  display: flex;
}

/* Legacy v2 typo classes — keep as no-op selectors so child-theme custom CSS
 * targeting them still hooks. @deprecated 3.0.0 — remove in v3.1. */
.diplay-device-deskop,
.diplay-device-mobile {
  /* intentionally empty */
}

/* ==========================================================================
   Text + button
   ========================================================================== */

.njt-nofi-text {
  color: inherit;
}

.njt-nofi-button {
  min-width: fit-content;
}

/* shadcn-style CTA: 6px radius, medium weight, color-darken hover/active (no
   scale), keyboard focus ring in the button's own color. bg + color +
   font-weight are set via inline style by renderBarHTML(); the inline
   --njt-btn-bg var feeds the focus outline. */
.njt-nofi-button-text {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  padding: 8px 16px;
  border-radius: 6px;
  font-weight: 500;
  /* hover/active darken via filter; bg is set inline and never animates. */
  transition: filter 0.15s ease;
}

.njt-nofi-button-text:hover {
  filter: brightness( 0.92 );
}

.njt-nofi-button-text:active {
  filter: brightness( 0.88 );
}

.njt-nofi-button-text:focus-visible {
  outline: 2px solid var( --njt-btn-bg, #1919cf );
  outline-offset: 2px;
}

/* ==========================================================================
   Close / Toggle buttons — flex children at the right edge
   ----------------------------------------------------------------------------
   25x25 circle, semi-opaque dark bg, sits on the right via flex (the
   centred .njt-nofi-content uses margin:auto so the close gets pushed right
   without needing absolute positioning).
   ========================================================================== */

.njt-nofi-close,
.njt-nofi-toggle {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 25px;
  height: 25px;
  border: none;
  background: #0000002e;
  border-radius: 50%;
  cursor: pointer;
  color: inherit;
  padding: 0;
  transition: transform 0.5s, background 0.2s ease;
}

.njt-nofi-close:hover,
.njt-nofi-toggle:hover {
  transform: scale( 1.1 );
}

.njt-nofi-close:focus,
.njt-nofi-toggle:focus,
.njt-nofi-close:focus-visible,
.njt-nofi-toggle:focus-visible {
  outline: 2px solid #4a90e2;
  outline-offset: 2px;
}

.njt-nofi-close-icon {
  pointer-events: none;
  width: 11px;
  height: 11px;
}

/* When the bar is collapsed via toggle mode, rotate the arrow 45° to hint
   the inverse "expand" action (matches v2 .njt-nofi-display-toggle icon). */
.njt-nofi-container-content.njt-nofi-collapsed .njt-nofi-toggle {
  transform: rotate( 45deg );
}

.njt-nofi-container-content.njt-nofi-collapsed .njt-nofi-toggle:hover {
  transform: rotate( 45deg ) scale( 1.1 );
}

/* ==========================================================================
   Navigation arrows — manual prev/next (Pro rotation)
   ----------------------------------------------------------------------------
   Injected by the rotation controller into .njt-nofi-notification-bar, which is
   position:relative. Arrows are absolute full-height zones pinned to the bar's
   left/right edges, with a chevron that follows the bar text color via
   currentColor. The .njt-nofi-has-nav marker (added only when arrows render)
   reserves content gutter space and nudges the close/toggle button inboard so
   nothing overlaps.
   ========================================================================== */

/* Unobtrusive full-height edge zones (lightbox / gallery-slider style): each
   arrow is a tall transparent click area pinned to the bar's far left/right
   edge — no visible button, border, or fill. Only the chevron shows, dim by
   default and brightening on hover, with a faint edge wash to hint clickability. */
.njt-nofi-nav {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: transparent !important;
  color: inherit !important;
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.2s ease, background 0.2s ease;
  z-index: 2;
}

.njt-nofi-nav-prev {
  left: 0;
}

.njt-nofi-nav-next {
  right: 0;
}

.njt-nofi-nav:hover,
.njt-nofi-nav:focus-visible {
  opacity: 1;
}

/* Faint directional wash on hover — hints the zone without a visible button. */
.njt-nofi-nav-prev:hover {
  background: linear-gradient( to right, rgba( 127, 127, 127, 0.16 ), transparent );
}

.njt-nofi-nav-next:hover {
  background: linear-gradient( to left, rgba( 127, 127, 127, 0.16 ), transparent );
}

.njt-nofi-nav:focus-visible {
  /* Inset ring — the zone hugs the bar edge, so an outset ring would sit
     outside the bar (and be clipped during the carousel slide). */
  outline: 2px solid #4a90e2;
  outline-offset: -3px;
}

.njt-nofi-nav:focus {
  outline: none;
}

.njt-nofi-nav-icon {
  pointer-events: none;
  width: 22px;
  height: 22px;
}

/* Gutters so text/buttons never sit under the edge zones. */
.njt-nofi-has-nav .njt-nofi-content {
  padding-left: 52px;
  padding-right: 52px;
}

/* Keep the close/toggle button clear of the right-hand edge zone (48px wide).
   When the close button is disabled this matches nothing — harmless. */
.njt-nofi-has-nav .njt-nofi-close,
.njt-nofi-has-nav .njt-nofi-toggle {
  margin-right: 52px;
}

/* --------------------------------------------------------------------------
   Horizontal carousel slide on MANUAL prev/next (not auto-rotate, which keeps
   its vertical slide-down). The whole bar slides — so bars with different
   background colors transition cleanly. .njt-nofi-container clips the off-
   screen bar (gated by the direction class) so no horizontal scrollbar appears;
   initial/auto renders carry no direction class, so the vertical entrance is
   untouched. animation-name override uses !important to beat the base + bottom-
   placement slide rules regardless of selector specificity.
   -------------------------------------------------------------------------- */
.njt-nofi-nav-slide-next .njt-nofi-container,
.njt-nofi-nav-slide-prev .njt-nofi-container {
  overflow: hidden;
}

@keyframes njt-nofi-bar-in-right {
  from {
    opacity: 0;
    transform: translateX( 100% );
  }
  to {
    opacity: 1;
    transform: translateX( 0 );
  }
}

@keyframes njt-nofi-bar-in-left {
  from {
    opacity: 0;
    transform: translateX( -100% );
  }
  to {
    opacity: 1;
    transform: translateX( 0 );
  }
}

.njt-nofi-container-content.njt-nofi-visible.njt-nofi-nav-slide-next
  .njt-nofi-notification-bar {
  animation-name: njt-nofi-bar-in-right !important;
}

.njt-nofi-container-content.njt-nofi-visible.njt-nofi-nav-slide-prev
  .njt-nofi-notification-bar {
  animation-name: njt-nofi-bar-in-left !important;
}

@media only screen and (max-width: 480px) {
  .njt-nofi-nav {
    width: 40px;
  }

  .njt-nofi-nav-icon {
    width: 20px;
    height: 20px;
  }

  .njt-nofi-has-nav .njt-nofi-content {
    padding-left: 44px;
    padding-right: 44px;
  }

  .njt-nofi-has-nav .njt-nofi-close,
  .njt-nofi-has-nav .njt-nofi-toggle {
    margin-right: 44px;
  }
}

/* ==========================================================================
   WP admin bar offset
   ========================================================================== */

.admin-bar .njt-nofi-container[data-position='fixed'],
.admin-bar .njt-nofi-container[data-position='absolute'] {
  top: 32px;
}

@media screen and (max-width: 782px) {
  .admin-bar .njt-nofi-container[data-position='fixed'],
  .admin-bar .njt-nofi-container[data-position='absolute'] {
    top: 46px;
  }
}

/* ≤600px: WP core switches #wpadminbar to position:absolute, so it scrolls
   away with the page while a fixed bar stays pinned at top:46px behind a
   dead gap. The static 46px above is kept as the correct PRE-SCROLL state;
   mobile-admin-bar-offset.js clamps the fixed bar's inline top to
   max(0, adminBarHeight - scrollY) as the user scrolls. */

/* Bottom placement ignores the admin-bar top offset — it pins to the bottom
   edge. Declared after the rules above so it wins at equal specificity. */
.admin-bar .njt-nofi-container[data-placement='bottom'] {
  top: auto;
  bottom: 0;
}

/* ==========================================================================
   Mobile responsive — ≤480px
   ========================================================================== */

@media only screen and (max-width: 480px) {
  .njt-nofi-content {
    padding: 10px 20px;
    /* flex-wrap inherited from base rule — keeps the button on its own line
       when text+button can't fit on one line. */
  }

  /* Hide the desktop block ONLY when a separate mobile block was rendered
     (marker class .njt-nofi-has-mobile, emitted by render-bar.js when
     content.mobileSeparate is true). Without this guard, bars without a
     separate mobile content section render blank on screens <=480px. */
  .njt-nofi-has-mobile .njt-nofi-content-desktop {
    display: none;
  }

  .njt-nofi-content-mobile {
    display: flex;
  }
}

/* ==========================================================================
   Customizer partial edit shortcuts (preserved from v2).
   ========================================================================== */

.customize-partial-edit-shortcuts-shown
  .njt-nofi-container
  .customize-partial-edit-shortcut-button {
  left: 5px;
  top: 10px;
}

.customize-partial-edit-shortcuts-shown
  .njt-nofi-container
  .customize-partial-edit-shortcut {
  position: inherit;
}

.njt-nofi-container .customize-partial-refreshing {
  opacity: 1;
  transition: opacity 0.25s;
  cursor: progress;
}

/* ==========================================================================
   Reduced-motion override — disable transitions & slide-down.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .njt-nofi-close,
  .njt-nofi-toggle,
  .njt-nofi-button-text,
  .njt-nofi-nav {
    transition: none !important;
  }

  /* Skip slide-down AND the manual-nav horizontal slide — bar appears in its
     final state immediately. The nav-slide selectors are listed at full
     specificity so they beat the !important animation-name override above. */
  .njt-nofi-notification-bar,
  .njt-nofi-container-content.njt-nofi-visible.njt-nofi-nav-slide-next
    .njt-nofi-notification-bar,
  .njt-nofi-container-content.njt-nofi-visible.njt-nofi-nav-slide-prev
    .njt-nofi-notification-bar {
    transform: none !important;
    animation: none !important;
  }
}
