
@import 'tokens';

// respond-to($bp) — mobile-first min-width media query
// Usage: @include respond-to('tablet') { ... }
@mixin respond-to($bp) {
  @media (min-width: #{map-get($breakpoints, $bp)}) {
    @content;
  }
}

// visually-hidden — accessible hide (screen-reader only)
@mixin visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

// focus-ring — consistent keyboard focus ring
@mixin focus-ring {
  outline: 2px solid var(--color-gold);
  outline-offset: 2px;
}

// ── Overlay pattern — shared by image-text-banner, tab-component, testimonials
@mixin image-overlay-base {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

@mixin overlay-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
}

@mixin overlay-gradient($start: 42.075%, $end: 112.89%) {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0) $start, #000 $end);
  z-index: 1;
  pointer-events: none;
}

@mixin overlay-content {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

// slider-nav-btn — shared carousel prev/next button interaction states.
// Used by gallery, testimonials, tab-component, tab-component-2, drawer-lodge nav
// buttons. Component files still own size, icon sizing/element, gap, and the
// resting (prev dimmer than next) opacity via their own --prev/--next modifiers.
@mixin slider-nav-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, opacity 0.2s ease;

  &:hover {
    background-color: var(--color-gold);
    color: var(--color-white);
    opacity: 1;
  }

  &:active {
    background-color: var(--color-gold-dark);
    color: var(--color-white);
    opacity: 1;
  }

  &:focus-visible {
    outline: 2px solid var(--color-gold);
    outline-offset: 2px;
  }

  &.swiper-button-disabled {
    opacity: 0.35;
    pointer-events: none;
  }
}

// slider-breakout — container-aligned heading/controls, full-bleed-right slider
// track. Used by testimonials-slider, tab-component-2-slider, gallery__mobile-slider.
// Apply to the slider element itself; the component root also needs an
// unconditional `overflow: hidden` (or `clip`) so the bled content doesn't cause
// a horizontal scrollbar — add that separately per component (not part of this
// mixin, since some components already have their own root overflow rule).
//
// Below 1200px: cancel .container's 16px inset (main.scss:115 — a literal,
// not var(--space-4), due to the token collision noted there and below).
// At/above 1200px: .container's padding is 0 there — its own max-width instead
// creates a growing auto-margin gutter, (100vw - var(--container-max)) / 2 wide
// on each side — cancel that instead so the track always reaches the true
// viewport edge, not just wherever overflow:visible happens to let a card spill.
@mixin slider-breakout {
  overflow: visible; // let slides spill past this element's own box, to the right only

  // Literal, matching .container's own literal 16px (main.scss) — var(--space-4)
  // would resolve to 4px here due to the booking-widget token collision (see
  // main.scss's .container rule and _mailchimp.scss for the full writeup),
  // which would under-cancel .container's padding and leave the track short
  // of the true viewport edge below 1200px.
  margin-right: -1rem; // -16px, matches .container's padding below 1200px

  @media (min-width: 75rem) { // 1200px
    margin-right: calc(-1 * (100vw - var(--container-max)) / 2);
  }

  // At 1920px+ Bootstrap's xxxl tier widens .container to 1800px (see
  // $container-max-widths in main.scss), so --container-max (1200px) is no
  // longer the width the auto-margin gutter is measured from. Left uncorrected,
  // the calc above cancels a 1200px-based gutter that is (1800 - 1200) / 2 =
  // 300px larger than the real one, pushing the track's right edge that far
  // PAST the viewport — Swiper then sizes its own max translate to that
  // oversized box, so the final slide can never scroll fully into view (it
  // stops ~240px short at 1920px). Measure from the real container width for
  // this tier instead.
  //
  // 1800px is written as a literal rather than reusing --container-max because
  // that token is also the max-width cap for footer/accordion/newsletter-form,
  // which must stay at 1200px at every width — only .container's own Bootstrap
  // tier widens here.
  @include respond-to('wide') { // 1920px — matches main.scss's xxxl tier
    margin-right: calc(-1 * (100vw - 112.5rem) / 2); // 112.5rem = 1800px
  }
}

// body-text — shared paragraph typography (16/24 mobile → 18/32 desktop)
// used by content-only-intro__body, image-and-content__body p, image-text-banner__body,
// footer__cta-subtitle, accordion__content. Pass a color for on-dark contexts.
@mixin body-text($color: var(--color-text-secondary)) {
  font-family: var(--font-body);
  font-size: var(--fs-base);   // 16px mobile
  font-weight: 400;
  line-height: var(--lh-base); // 24px mobile
  color: $color;

  @include respond-to('desktop') {
    font-size: var(--fs-lg);   // 18px desktop
    line-height: var(--lh-lg); // 32px desktop
  }
}

// display-heading — shared section-title/h1/h2 typography (30px mobile → 48px
// desktop, Playfair Display, weight 400). This is the project's single most
// duplicated heading pattern — content-only-intro, image-and-content, footer
// CTA, newsletter-form-adjacent, tab-component(-2), image-text-banner, and the
// standalone .section-title utility (_sections.scss) all use this exact spec.
// Components on a dark/image background override only `color` after the
// @include. --ls-hero is the project's single "-2%" display letter-spacing
// token (confirmed at both 72px hero and 48px section-title — -0.02em is
// -0.96px at 48px, same value every component previously hardcoded).
@mixin display-heading($color: var(--color-gold-dark)) {
  font-family: var(--font-display);
  font-size: var(--fs-display-sm);      // 30px mobile
  font-weight: 400;
  line-height: var(--lh-display-sm);
  letter-spacing: 0;
  color: $color;
  margin: 0;

  @include respond-to('desktop') {
    font-size: var(--fs-display-lg);    // 48px
    line-height: var(--lh-display-lg);
    letter-spacing: var(--ls-hero);     // -0.02em (-0.96px at 48px)
  }
}

// eyebrow-text — shared small-label/overline typography. Two mobile sizes
// exist in the design (16px content-only-intro-style / 18px image-and-content
// -style) but both converge on the same 20px/600/uppercase desktop value —
// pass the mobile tier that matches the component; uppercase and weight are
// the only mobile properties that vary by usage, so both are parameters too.
@mixin eyebrow-text($mobile-size: var(--fs-base), $mobile-weight: 500, $mobile-lh: var(--lh-base), $uppercase: true) {
  font-family: var(--font-body);
  font-size: $mobile-size;
  font-weight: $mobile-weight;
  line-height: $mobile-lh;
  margin: 0;

  @if $uppercase {
    text-transform: uppercase;
  } @else {
    text-transform: none;
  }

  @include respond-to('desktop') {
    font-size: var(--fs-xl);    // 20px
    font-weight: 600;
    line-height: var(--lh-xl);
  }
}

// prose-link — standard text link inside body copy / RTE content. Never a
// button — matches the existing text-link convention (testimonial-card__more,
// image-and-content__tcs): underlined, gold-dark, gold on hover/focus.
@mixin prose-link {
  color: var(--color-gold-dark);
  text-decoration: underline;
  text-underline-offset: 2px;

  &:hover,
  &:focus-visible {
    color: var(--color-gold);
  }

  &:focus-visible {
    outline: 2px solid var(--color-gold);
    outline-offset: 2px;
  }
}

// news-pagination — shared tx_news pagination treatment (vendor
// Partials/List/Pagination.html: <ul class="f3-widget-paginator"> with plain
// <li>/<li class="current">/<li class="next"> — no sflg override, and this
// markup+class is only ever used by tx_news, confirmed via a repo-wide
// grep). Reused identically by news-list-view and news-content-intro-list so
// both tx_news layouts get the same simple pill-number pagination instead of
// the unstyled default <ul> bullet list.
@mixin news-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2); // 8px
  list-style: none;
  margin: var(--space-6) 0 0; // 24px above, separating from the last article
  padding: 0;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;

  li {
    display: flex;
  }

  li a,
  li.current {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  // Page numbers — plain link, pill highlight only on hover/current.
  li:not(.next):not(.previous) {
    a,
    &.current {
      min-width: 32px;
      height: 32px;
      padding-inline: var(--space-1); // 4px, only matters once digits > 1
      border-radius: var(--radius-full);
      color: var(--color-text-secondary);
      text-decoration: none;
    }

    a:hover,
    a:focus-visible {
      background-color: var(--color-pampas);
      color: var(--color-text-primary);
    }

    &.current {
      background-color: var(--color-brand);
      color: var(--color-white);
      font-weight: 600;
    }
  }

  // Prev/next — icon-only chevrons (same family as icon-fa-reg-chevron-left/
  // right.svg used by testimonials/gallery/tab-component nav, recolored to
  // gold-dark to match this pagination's own link color). The vendor
  // partial's text ("previous"/"next") is kept in the DOM for screen readers
  // via font-size:0 rather than display:none — visually replaced, not removed.
  li.previous a,
  li.next a {
    width: 32px;
    height: 32px;
    padding: 0;
    font-size: 0;
    border-radius: var(--radius-full);
    color: var(--color-gold-dark);
    text-decoration: none;

    &::before {
      content: '';
      display: block;
      width: 20px;
      height: 20px;
      background-repeat: no-repeat;
      background-position: center;
      background-size: contain;
    }

    &:hover,
    &:focus-visible {
      background-color: var(--color-pampas);
    }
  }

  li.previous a::before {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3e%3cpath d='M13.6008 19.1523L7.32307 12.6003C7.13861 12.3808 7.0625 12.1751 7.0625 12.0003C7.0625 11.8254 7.13857 11.5899 7.29179 11.4315L13.5695 4.87946C13.8833 4.55054 14.404 4.53982 14.7318 4.85482C15.0618 5.16768 15.0725 5.69036 14.7564 6.01745L9.02501 12.0003L14.785 18.014C15.1011 18.3397 15.0904 18.8636 14.7604 19.1766C14.4339 19.4917 13.9128 19.4814 13.6008 19.1523Z' fill='%23956019'/%3e%3c/svg%3e");
  }

  li.next a::before {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3e%3cpath d='M10.3995 4.84871L16.6772 11.4007C16.8304 11.5593 16.9065 11.7648 16.9065 11.9695C16.9065 12.1742 16.8304 12.3799 16.6772 12.5383L10.3995 19.0903C10.0857 19.4193 9.56497 19.43 9.2372 19.115C8.9072 18.8021 8.89649 18.2791 9.21256 17.9523L14.9726 11.9386L9.21354 5.98665C8.89747 5.66094 8.90819 5.13705 9.23819 4.82403C9.566 4.50894 10.0875 4.51991 10.3995 4.84871Z' fill='%23956019'/%3e%3c/svg%3e");
  }

  a:focus-visible {
    outline: 2px solid var(--color-gold);
    outline-offset: 2px;
  }
}

// news-item-media — shared image treatment for tx_news listing items that
// show a preview image (news-list-view .article, news-content-intro-item).
// Matches the site's existing image styling elsewhere (drawer, tab-component-2,
// gallery): radius-xs corners, object-fit: cover, fixed aspect ratio so list
// rows stay aligned regardless of the source image's own dimensions.
@mixin news-item-media {
  width: 100%;
  border-radius: var(--radius-xs);
  overflow: hidden;

  a,
  span,
  picture {
    display: block;
  }

  img {
    display: block;
    width: 100%;
    height: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
  }
}
