/* Replaces Webflow's IX2 runtime.
 *
 * Loaded AFTER the three Webflow stylesheets and kept separate from them —
 * those stay byte-identical to the export, which is what makes the parity
 * numbers mean anything.
 *
 * Values are taken from docs/interactions.md, which was extracted from the
 * IX2 payload in the exported bundle rather than eyeballed. 12 of the 39
 * original events target elements that no longer exist and are deliberately
 * not reproduced here.
 */

/* ── Pattern 1: card hover-reveal ───────────────────────────────────────────
 * IX2 set .direct-link to opacity 0 as an "initial state", which Webflow also
 * inlines onto the element. The inline style outranks any class rule, so the
 * hover state has to be !important to reach it — the alternative is stripping
 * an attribute the live DOM has, which would trade a real difference for a
 * cosmetic one. Fade is 100ms in and out, per the action list. */
.direct-link {
  transition: opacity 100ms;
}
.resource_item:hover .direct-link,
.blog_item:hover .direct-link,
.email-ad-wrapper:hover .direct-link {
  opacity: 1 !important;
}

/* Respect the OS setting; IX2 never did. */
@media (prefers-reduced-motion: reduce) {
  .direct-link { transition: none; }
}

/* ── Email popup ────────────────────────────────────────────────────────────
 * Webflow ships `.modal.is-email-popup { display: none }` and never opens it —
 * the live site has a close animation and no trigger anywhere. components/
 * EmailPopup.tsx adds one and toggles this class; the markup itself stays
 * exactly as Webflow emits it. */
.modal.is-email-popup.is-open {
  display: flex;
  animation: ft-popup-in 200ms ease both;
}
@keyframes ft-popup-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* The fade lives in an animation on the OPEN state, not in an opacity on the
 * base rule. Setting opacity:0 on the closed modal is invisible — it is
 * display:none either way — but it shows up as a computed-style difference
 * against live, and a verification tool that reports a difference nobody
 * caused is a tool people stop reading. */
@media (prefers-reduced-motion: reduce) {
  .modal.is-email-popup.is-open { animation: none; }
}

/* ── Resource quick-view modal ──────────────────────────────────────────────
 * Webflow ships `.modal.is-item` closed and opened it with jQuery. Same class
 * toggle, same shell, different implementation — see components/ResourceModal.tsx. */
.modal.is-item.is-open {
  display: flex;
  animation: ft-modal-in 250ms ease both;
}
@keyframes ft-modal-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .modal.is-item.is-open { animation: none; }
}

/* ── Mobile menu ────────────────────────────────────────────────────────────
 * Ours, not Webflow's. That nav is data-collapse="none", so its hamburger is
 * display:none at every width and About / Sponsor / Submit are unreachable
 * below 767px on the live site. Nothing to preserve, so this is built rather
 * than transplanted — and it is the only place the rebuild deliberately
 * departs from the original's appearance.
 *
 * Scoped to <= 767px, so nothing above that breakpoint can move. */

@media screen and (max-width: 767px) {
  /* Webflow's own button, un-hidden. Reusing it keeps the header markup
     identical to live and it already has three bars shaped for a morph. */
  .navbar_menu-button {
    display: flex !important;
    align-items: center;
    justify-content: center;
    /* 44px is the smallest reliable touch target. */
    min-width: 44px;
    min-height: 44px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .navbar_menu-button:focus-visible {
    outline: 2px solid #0f172a;
    outline-offset: 2px;
    border-radius: 8px;
  }

  /* Bars morph into a cross. Transform only — never height or margin — so the
     whole thing stays on the compositor. */
  .menu-icon_line-top,
  .menu-icon_line-bottom,
  .menu-icon_line-middle {
    transition: transform 260ms cubic-bezier(0.32, 0.72, 0, 1),
                opacity 160ms ease;
    transform-origin: center;
  }
  /* 8px, measured: the bars sit at y=28, 36 and 44, so each outer bar travels
     exactly one gap to meet at the centre. Guessing 6px left the X open. */
  .ft-menu-open .menu-icon_line-top    { transform: translateY(8px) rotate(45deg); }
  .ft-menu-open .menu-icon_line-bottom { transform: translateY(-8px) rotate(-45deg); }
  /* The middle BAR, not its inner span — hiding the inner left the full-width
     bar drawn straight through the X. */
  .ft-menu-open .menu-icon_line-middle { opacity: 0; transform: scaleX(0.2); }
}

/* Panel. Present above 767px too but never openable there — the trigger is
   hidden — so it costs nothing and avoids a second breakpoint to keep in sync. */
.ft-menu {
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  visibility: hidden;
}
.ft-menu.is-open { pointer-events: auto; visibility: visible; }

.ft-menu__scrim {
  position: absolute;
  inset: 0;
  width: 100%;
  border: 0;
  padding: 0;
  background: rgba(15, 23, 42, 0.28);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 280ms cubic-bezier(0.32, 0.72, 0, 1);
  cursor: default;
}
.ft-menu.is-open .ft-menu__scrim { opacity: 1; }

.ft-menu__panel {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.25rem;
  /* Respects notches and home indicators. */
  padding: max(6rem, env(safe-area-inset-top) + 5rem) 2.5rem
           max(3rem, env(safe-area-inset-bottom) + 2rem);
  background: #fffffc;
  overflow-y: auto;
  overscroll-behavior: contain;
  opacity: 0;
  transform: translateY(-8px) scale(0.995);
  transition: opacity 300ms cubic-bezier(0.32, 0.72, 0, 1),
              transform 320ms cubic-bezier(0.32, 0.72, 0, 1);
}
.ft-menu.is-open .ft-menu__panel { opacity: 1; transform: none; }

.ft-menu__nav { display: flex; flex-direction: column; }

.ft-menu__link,
.ft-menu__cta {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.6rem 0;
  font-family: 'Uncut Sans', sans-serif;
  font-size: 2rem;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: #0f172a;
  text-decoration: none;
  /* Links arrive after the panel, staggered by an inline delay. */
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 320ms cubic-bezier(0.32, 0.72, 0, 1),
              transform 320ms cubic-bezier(0.32, 0.72, 0, 1);
}
.ft-menu.is-open .ft-menu__link,
.ft-menu.is-open .ft-menu__cta { opacity: 1; transform: none; }

/* Closing runs with no stagger — a reversed cascade reads as hesitation. */
.ft-menu:not(.is-open) .ft-menu__link,
.ft-menu:not(.is-open) .ft-menu__cta { transition-delay: 0ms !important; }

.ft-menu__link:focus-visible,
.ft-menu__cta:focus-visible {
  outline: 2px solid #0f172a;
  outline-offset: 4px;
  border-radius: 4px;
}

.ft-menu__badge {
  font-size: 0.75rem;
  line-height: 1;
  letter-spacing: 0;
  color: #617187;
  transform: translateY(-0.6em);
}

.ft-menu__cta {
  margin-top: 1.75rem;
  font-size: 1.125rem;
  align-self: flex-start;
  padding: 0.75rem 1.25rem;
  border-radius: 100px;
  background: #fde89e;
}

/* The page behind must not scroll while the panel is up. */
.ft-menu-open, .ft-menu-open body { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .ft-menu__scrim,
  .ft-menu__panel,
  .ft-menu__link,
  .ft-menu__cta,
  .menu-icon_line-top,
  .menu-icon_line-bottom,
  .menu-icon_line-middle-inner {
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
  }
  .ft-menu__panel { transform: none; }
}

/* The header floats above the sheet while it is open, so the hamburger — now
   an X — stays tappable. A full-screen panel that hides its own close control
   is the classic version of this mistake. */
.ft-menu-open .navbar_component {
  position: relative;
  z-index: 9999;
  background: #fffffc;
}
/* The panel starts below the header rather than behind it, so the links never
   slide under the logo on the way in. */
@media screen and (max-width: 767px) {
  .ft-menu__panel { padding-top: max(7.5rem, env(safe-area-inset-top) + 6.5rem); }
}
