/*
 * Craftis Hero Slider — frontend styles.
 * Colors/fonts fall back to the theme's design tokens (craftis-dynamic.css)
 * via var(), matching craftis-custom-theme-design-spec.md §5 Section 1.
 */

.craftis-hero-slider {
  position: relative;
  width: 100%;
  overflow: hidden;
}

/*
 * Clip-path morph wipe: a single diagonal edge sweeps across the WHOLE
 * slide in one continuous motion, revealing the incoming slide from
 * underneath — no separate curtain elements, no per-panel split. Both
 * the outgoing and incoming slide are stacked via position:absolute
 * (Swiper's own slide positioning is bypassed for this effect — see
 * craftisInitClipWipeSlider() in hero-slider.js), so there's always a
 * fully-rendered slide visible beneath the animating clip-path; the
 * diagonal edge only ever reveals real content, never a blank gap.
 *
 * Direction: sweeps from the trailing corner to the leading corner in
 * the direction of travel (bottom-left -> top-right on "next", mirrored
 * on "prev"), driven by JS toggling .is-active on the entering slide's
 * clip-path is-active class.
 */
.craftis-hero-slider--clip-wipe,
.craftis-hero-slider--clip-wipe .swiper-wrapper {
  min-height: calc(100vh + 200px);
}

.craftis-hero-slider--clip-wipe .craftis-hero-slider__slide {
  position: absolute;
  inset: 0;
  transition: clip-path 0.9s cubic-bezier(0.65, 0, 0.35, 1);
  clip-path: polygon(0% 100%, 0% 100%, 0% 100%, 0% 100%);
  will-change: clip-path;
}

.craftis-hero-slider--clip-wipe .craftis-hero-slider__slide.is-active {
  clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
  z-index: 2;
}

.craftis-hero-slider--clip-wipe .craftis-hero-slider__slide.is-outgoing {
  transition: none;
  clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
  z-index: 1;
}

.craftis-hero-slider__slide {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh + 200px);
}

@media (min-width: 768px) {
  .craftis-hero-slider__slide {
    flex-direction: row;
  }
}

.craftis-hero-slider__panel {
  flex: 1 1 50%;
  display: flex;
  align-items: center;
  position: relative;
  padding: 60px 0;
}

@media (max-width: 767px) {
  .craftis-hero-slider__panel {
    padding-top: 170px;
    padding-bottom: 80px;
  }

  /*
   * On mobile the two panels stack (flex-direction:column, see
   * .craftis-hero-slider__slide above) and split min-height 50/50 by
   * default — the text panel ends up noticeably shorter than the image
   * below it once its own top/bottom padding is subtracted. Giving it a
   * larger flex-basis than the image panel gives the heading/description/
   * button more visible room before the image panel starts.
   */
  .craftis-hero-slider__panel--text {
    flex: 1 1 62%;
  }

  .craftis-hero-slider__panel--image {
    flex: 1 1 38%;
  }
}

/*
 * Text panel background: solid #f9f9f9 base + a muted dotted-canvas
 * pattern (repeating radial-gradient dots, no image asset needed). The
 * dots themselves light up following the cursor in a full 30-stop
 * rainbow instead of one flat color — two stacked layers:
 *   ::before - permanently-muted gray dot grid (the base pattern)
 *   ::after  - a 30-stop conic-gradient rainbow, dot-masked with the
 *              SAME grid as ::before (so only actual dot positions show
 *              color, not a solid wash) AND spotlight-masked to a
 *              cursor-following circle via mask-composite: intersect —
 *              only dots inside that circle are ever visible.
 * --mx/--my are set live by craftisInitDotSpotlight() in hero-slider.js
 * on mousemove; with no JS (or before the first mousemove) the
 * spotlight mask defaults off-panel via --mx/--my below, so nothing
 * lights up until the cursor actually enters.
 */
.craftis-hero-slider__panel--text {
  justify-content: flex-start;
  position: relative;
  overflow: hidden;
  background-color: #f9f9f9;
  --mx: -9999px;
  --my: -9999px;
  --craftis-dot-rainbow: conic-gradient(
    from 0deg,
    #f22424 0%,
    #f24d24 3%,
    #f27624 7%,
    #f29f24 10%,
    #f2c924 13%,
    #f2f224 17%,
    #c9f224 20%,
    #9ff224 23%,
    #76f224 27%,
    #4df224 30%,
    #24f224 33%,
    #24f24d 37%,
    #24f276 40%,
    #24f29f 43%,
    #24f2c9 47%,
    #24f2f2 50%,
    #24c9f2 53%,
    #249ff2 57%,
    #2476f2 60%,
    #244df2 63%,
    #2424f2 67%,
    #4d24f2 70%,
    #7624f2 73%,
    #9f24f2 77%,
    #c924f2 80%,
    #f224f2 83%,
    #f224c9 87%,
    #f2249f 90%,
    #f22476 93%,
    #f2244d 97%,
    #f22424 100%
  );
}

.craftis-hero-slider__panel--text::before,
.craftis-hero-slider__panel--text::after,
.craftis-hero-slider__dot-glow {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.craftis-hero-slider__panel--text::before {
  z-index: 0;
  background-image: radial-gradient(
    rgba(43, 43, 40, 0.1) 1.5px,
    transparent 1.5px
  );
  background-size: 22px 22px;
}

/*
 * Two identical rainbow-dot layers, same gradient + same two-part mask
 * (dot grid intersected with the cursor spotlight circle):
 *   .craftis-hero-slider__dot-glow - a real element (not a pseudo-
 *     element, since each element only gets two: ::before/::after, both
 *     already spoken for) rendered UNDER the crisp layer, blurred, so
 *     each lit dot gets a soft halo in its OWN color — filter: blur()
 *     naturally glows in whatever colors are present under it, unlike
 *     drop-shadow() which needs one flat shadow color and can't sample
 *     per-pixel hue.
 *   ::after - the crisp, unblurred dots on top.
 */
.craftis-hero-slider__dot-glow {
  z-index: 0;
  background-image: var(--craftis-dot-rainbow);
  -webkit-mask-image:
    radial-gradient(black 1.5px, transparent 1.5px),
    radial-gradient(circle 140px at var(--mx) var(--my), #000 0%, transparent 100%);
  -webkit-mask-size: 22px 22px, 100% 100%;
  -webkit-mask-composite: source-in;
  mask-image:
    radial-gradient(black 1.5px, transparent 1.5px),
    radial-gradient(circle 140px at var(--mx) var(--my), #000 0%, transparent 100%);
  mask-size: 22px 22px, 100% 100%;
  mask-composite: intersect;
  opacity: 0.9;
  filter: blur(4px);
  transition: opacity 0.3s ease;
}

.craftis-hero-slider__panel--text::after {
  z-index: 0;
  background-image: var(--craftis-dot-rainbow);
  -webkit-mask-image:
    radial-gradient(black 1.5px, transparent 1.5px),
    radial-gradient(circle 140px at var(--mx) var(--my), #000 0%, transparent 100%);
  -webkit-mask-size: 22px 22px, 100% 100%;
  -webkit-mask-composite: source-in;
  mask-image:
    radial-gradient(black 1.5px, transparent 1.5px),
    radial-gradient(circle 140px at var(--mx) var(--my), #000 0%, transparent 100%);
  mask-size: 22px 22px, 100% 100%;
  mask-composite: intersect;
  opacity: 0.9;
  transition: opacity 0.3s ease;
}

.craftis-hero-slider__panel--text .craftis-hero-slider__content {
  position: relative;
  z-index: 1;
}

.craftis-hero-slider__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 20px;
  width: 100%;
  max-width: 480px;
  /*
	 * Left edge lines up with .craftis-container's left edge (theme's
	 * global container gutter) even though this panel is only the left
	 * half of the viewport, not the full width — same formula
	 * mixins.container uses: gutter, or the container's own left margin
	 * on ultra-wide screens once the container hits its max-width and
	 * stops growing.
	 */
  margin-left: max(
    20px,
    calc((100vw - var(--container-width, 1320px)) / 2 + 20px)
  );
  padding-right: 20px;
}

@media (min-width: 768px) {
  .craftis-hero-slider__content {
    margin-left: max(
      40px,
      calc((100vw - var(--container-width, 1320px)) / 2 + 40px)
    );
    /* padding-right: 40px; */
  }
}

.craftis-hero-slider__panel--image {
  background-color: var(--color-bg-warm-2, #edece8);
  background-size: cover;
  background-position: center;
  justify-content: center;
}

.craftis-hero-slider__panel--image::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: #000;
  opacity: 0;
  pointer-events: none;
}

.craftis-hero-slider__eyebrow {
  color: var(--color-text-muted, #6e6e6c);
}

.craftis-hero-slider__title {
  font-family: var(--font-heading, "Metropolis"), sans-serif;
  font-weight: var(--font-heading-weight, 300);
  font-size: 3rem;
  line-height: 1.15;
  margin: 0;
  color: var(--color-text, #2b2b28);
}

/* Highlighted word/phrase inside the title (class-hero-slider.php's
 * render_title_with_highlight()) — Runethia calligraphy accent font,
 * color/size overridable via the widget's Style tab controls. */
.craftis-highlight-word {
  font-family: "Runethia", cursive;
  font-weight: 400;
}

/*
 * Content entrance animation: eyebrow, title, description, and CTA fade
 * up in a staggered cascade whenever their slide becomes .is-active —
 * the same class craftisInitClipWipeSlider() (hero-slider.js) toggles on
 * slide change — instead of just appearing instantly the moment the
 * clip-path wipe uncovers them. Starts hidden/offset by default so a
 * freshly-revealed slide's text always re-plays the animation, not just
 * on first load.
 */
.craftis-hero-slider--clip-wipe .craftis-hero-slider__eyebrow,
.craftis-hero-slider--clip-wipe .craftis-hero-slider__title,
.craftis-hero-slider--clip-wipe .craftis-hero-slider__description,
.craftis-hero-slider--clip-wipe .craftis-hero-slider__cta {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s cubic-bezier(0.25, 0.1, 0.25, 1), transform 0.7s cubic-bezier(0.25, 0.1, 0.25, 1);
}

.craftis-hero-slider--clip-wipe .craftis-hero-slider__slide.is-active .craftis-hero-slider__eyebrow {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.35s;
}

.craftis-hero-slider--clip-wipe .craftis-hero-slider__slide.is-active .craftis-hero-slider__title {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.45s;
}

.craftis-hero-slider--clip-wipe .craftis-hero-slider__slide.is-active .craftis-hero-slider__description {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.55s;
}

.craftis-hero-slider--clip-wipe .craftis-hero-slider__slide.is-active .craftis-hero-slider__cta {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.65s;
}

.craftis-hero-slider__description {
  font-family: var(--font-body, "Jost"), sans-serif;
  font-weight: 400;
  font-size: 1.0625rem;
  line-height: 1.7;
  margin: 0;
  max-width: 42ch;
  color: var(--color-text-muted, #6e6e6c);
}

.craftis-hero-slider__price-badge {
  position: absolute;
  bottom: 40px;
  right: 40px;
  width: 90px;
  height: 90px;
  border-radius: 50%;
  background-color: var(--color-accent-sage, #8fa089);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading, "Metropolis"), sans-serif;
  font-size: 1.125rem;
}

.craftis-hero-slider__social {
  position: absolute;
  left: 20px;
  top: 50%;
  transform: translateY(-50%) rotate(-90deg);
  transform-origin: left center;
  display: flex;
  gap: 24px;
  z-index: 5;
}

.craftis-hero-slider__social-link {
  text-transform: uppercase;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  color: inherit;
}

.craftis-hero-slider__nav {
  position: absolute;
  right: 20px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  z-index: 5;
}

.craftis-hero-slider__nav--bottom {
  position: absolute;
  right: auto;
  left: 50%;
  top: auto;
  bottom: 24px;
  transform: translateX(-50%) rotate(0deg);
  flex-direction: row;
}

/*
 * Bottom-right of content panel: nav sits inside the TEXT panel's own
 * whitespace (left half on desktop), not the image panel — unlike
 * --edges (positioned relative to the whole slider, landing on the
 * image side) this is offset from the slider's horizontal center so it
 * stays within the text column's own right edge/bottom padding.
 */
.craftis-hero-slider__nav--content-corner {
  position: absolute;
  left: auto;
  right: 20px;
  top: auto;
  bottom: 40px;
  transform: none;
  flex-direction: row;
}

/*
 * Above the panel-stacking breakpoint (panels sit side by side, text on
 * the left), pull the nav in from the slider's right edge to the text
 * panel's own right edge (50% + its padding) so it stays over the text
 * panel's whitespace instead of the image.
 */
@media (min-width: 768px) {
  .craftis-hero-slider__nav--content-corner {
    right: calc(50% + 20px);
  }
}

.craftis-hero-slider__prev,
.craftis-hero-slider__next {
  text-transform: uppercase;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  background: none;
  border: 0;
  cursor: pointer;
  color: inherit;
  writing-mode: vertical-rl;
}

.craftis-hero-slider__nav--bottom .craftis-hero-slider__prev,
.craftis-hero-slider__nav--bottom .craftis-hero-slider__next,
.craftis-hero-slider__nav--content-corner .craftis-hero-slider__prev,
.craftis-hero-slider__nav--content-corner .craftis-hero-slider__next {
  writing-mode: horizontal-tb;
}

.craftis-hero-slider__line {
  width: 1px;
  height: 40px;
  background-color: currentColor;
  opacity: 0.4;
}

.craftis-hero-slider__cta {
  margin-top: 8px;
}
