/* ===== MH Can't find what you're looking for — tab + modal (self-contained) ===== */ document.addEventListener("DOMContentLoaded", () => { if (!document.body.classList.contains("ex-a-5377939")) return; const MODAL_ID = "cant-find-contact"; const STYLE_ID = "cant-find-styles"; const form = document.querySelector(".contact-form.cant-find-form"); // Needs the EvoX contact form on the page; also guards against running twice if (!form || document.getElementById(MODAL_ID)) return; /* ---------- 1. CSS ---------- */ const css = ` .cant-find-wrapper, #cant-find-contact { --cf-accent: var(--evo-btn-default-bg, #f02427); --cf-dark: var(--evo-brand-default, #111111); --cf-accent-ring: rgba(240, 36, 39, 0.15); --cf-border: #d2d2cc; --cf-muted: #c8c8c4; --cf-text: #3d3d3a; } @supports (color: color-mix(in srgb, red 50%, transparent)) { .cant-find-wrapper, #cant-find-contact { --cf-accent-ring: color-mix(in srgb, var(--cf-accent) 15%, transparent); } } /* Tab */ .cant-find-wrapper { position: fixed; left: 0; top: 50%; z-index: 99; transform: translate(-30px, -50%); transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1); } .cant-find-wrapper.is-intro { transform: translate(-100%, -50%); } .cant-find-wrapper:hover, .cant-find-wrapper:has(.cant-find-tab:focus-visible) { transform: translate(0, -50%); } /* Rotated 180deg: CSS left = visual right, so border/radius/shadow are flipped */ .cant-find-tab { display: flex; align-items: flex-end; gap: 12px; padding: 20px 16px 20px 12px; writing-mode: vertical-rl; transform: rotate(180deg); background: var(--cf-dark); color: #ffffff; line-height: 1.2; text-decoration: none; border-left: 4px solid var(--cf-accent); border-radius: 12px 0 0 12px; box-shadow: -4px -6px 18px rgba(0, 0, 0, 0.25); } .cant-find-tab:hover, .cant-find-tab:focus { color: #ffffff; text-decoration: none; } .cant-find-tab:focus-visible { outline: 3px solid var(--cf-accent); outline-offset: 2px; } .cant-find-tab__icon { display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: 20px; height: 20px; border-radius: 50%; background: var(--cf-accent); color: #ffffff; transform: rotate(90deg) translateY(2px); } .cant-find-tab__text { display: flex; flex-direction: column; gap: 3px; } .cant-find-tab__hint { font-size: 11px; font-weight: 500; letter-spacing: 0.02em; color: var(--cf-muted); } .cant-find-tab__title { font-size: 15px; font-weight: 700; letter-spacing: 0.01em; } /* Modal shell */ #cant-find-contact .modal-dialog { width: auto; max-width: 520px; margin: 6vh auto; padding: 0 12px; } #cant-find-contact .modal-content { border: 0; border-radius: 14px; overflow: hidden; box-shadow: 0 24px 60px rgba(0, 0, 0, 0.4); } #cant-find-contact .cf-modal__header { display: flex; align-items: center; gap: 14px; padding: 20px 20px 20px 24px; background: var(--cf-dark); color: #ffffff; border-bottom: 4px solid var(--cf-accent); } #cant-find-contact .cf-modal__header::before, #cant-find-contact .cf-modal__header::after { display: none; } #cant-find-contact .cf-modal__badge { display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: 44px; height: 44px; border-radius: 10px; background: var(--cf-accent); color: #ffffff; } #cant-find-contact .cf-modal__title { flex: 1; min-width: 0; margin: 0; padding: 0; background: none; font-size: 20px; font-weight: 700; line-height: 1.2; text-align: left; color: #ffffff; } #cant-find-contact .cf-modal__close { display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: 44px; height: 44px; padding: 0; background: transparent; border: 1px solid #3a3a3a; border-radius: 10px; color: #ffffff; cursor: pointer; transition: background-color 0.15s; } #cant-find-contact .cf-modal__close:hover { background: #262626; } #cant-find-contact .cf-modal__close:focus-visible { outline: 3px solid var(--cf-accent); outline-offset: 2px; } #cant-find-contact .cf-modal__body { padding: 20px 24px 24px; } #cant-find-contact .cf-modal__intro { margin: 0 0 16px; font-size: 14px; line-height: 1.55; color: var(--cf-text); } #cant-find-contact .cf-modal__intro b { color: var(--cf-dark); } /* Form */ #cant-find-contact .form-group { margin: 0 0 14px; } #cant-find-contact .cf-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; } #cant-find-contact .cf-fields > * { grid-column: 1 / -1; margin: 0; } #cant-find-contact .cf-fields > .cf-half { grid-column: auto; } #cant-find-contact label { display: block; margin: 0 0 6px; font-size: 13px; font-weight: 600; color: var(--cf-dark); } #cant-find-contact .checkbox label, #cant-find-contact .radio label { display: inline; font-weight: 400; } #cant-find-contact input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]), #cant-find-contact select, #cant-find-contact textarea { width: 100%; max-width: 100%; height: 44px; box-sizing: border-box; padding: 0 12px; border: 1px solid var(--cf-border); border-radius: 8px; background: #ffffff; color: var(--cf-dark); font: inherit; font-size: 15px; box-shadow: none; transition: border-color 0.15s, box-shadow 0.15s; } #cant-find-contact textarea { height: auto; min-height: 96px; padding: 10px 12px; resize: vertical; } #cant-find-contact input:focus, #cant-find-contact select:focus, #cant-find-contact textarea:focus { outline: none; border-color: var(--cf-accent); box-shadow: 0 0 0 4px var(--cf-accent-ring); } #cant-find-contact input::placeholder, #cant-find-contact textarea::placeholder { color: #8a8a85; } #cant-find-contact [type="submit"], #cant-find-contact .btn-primary { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; height: 50px; margin-top: 4px; padding: 0 20px; border: 0; border-radius: 10px; background: var(--cf-accent); color: #ffffff; font: inherit; font-size: 18px; font-weight: 700; text-shadow: none; box-shadow: none; cursor: pointer; transition: filter 0.15s; } #cant-find-contact button[type="submit"]::after { content: ""; width: 18px; height: 18px; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat; } #cant-find-contact [type="submit"]:hover, #cant-find-contact .btn-primary:hover { filter: brightness(0.92); color: #ffffff; } #cant-find-contact [type="submit"]:focus-visible, #cant-find-contact .btn-primary:focus-visible { outline: 3px solid var(--cf-dark); outline-offset: 2px; } /* Responsive */ @media only screen and (max-width: 767px) { #cant-find-contact input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]), #cant-find-contact select, #cant-find-contact textarea { font-size: 16px; } } @media only screen and (max-width: 600px) { #cant-find-contact .modal-dialog { margin: 12px auto; } #cant-find-contact .cf-modal__header { padding: 16px 16px 16px 18px; gap: 12px; } #cant-find-contact .cf-modal__badge { width: 38px; height: 38px; } #cant-find-contact .cf-modal__title { font-size: clamp(1.05rem, 4.5vw, 1.25rem); } #cant-find-contact .cf-modal__body { padding: 18px; } } @media only screen and (max-width: 500px) { .cant-find-wrapper { transform: translate(-21px, -50%); } .cant-find-tab { gap: 8px; padding: 14px 12px 14px 8px; } .cant-find-tab__icon { width: 22px; height: 22px; } .cant-find-tab__icon svg { width: 12px; height: 12px; } .cant-find-tab__hint { font-size: 10px; } .cant-find-tab__title { font-size: 13px; } #cant-find-contact .cf-fields { grid-template-columns: minmax(0, 1fr); } #cant-find-contact .cf-fields > .cf-half { grid-column: 1 / -1; } } @media only screen and (max-width: 400px) { #cant-find-contact .cf-modal__badge { display: none; } } @media (prefers-reduced-motion: reduce) { .cant-find-wrapper, #cant-find-contact input, #cant-find-contact textarea, #cant-find-contact select { transition: none; } }`; if (!document.getElementById(STYLE_ID)) { const style = document.createElement("style"); style.id = STYLE_ID; style.textContent = css; document.head.append(style); } /* ---------- 2. Icons ---------- */ const searchIcon = ``; const boxIcon = ``; const closeIcon = ``; /* ---------- 3. Modal (Bootstrap 3 markup) ---------- */ document.body.insertAdjacentHTML( "beforeend", `
`, ); const modal = document.getElementById(MODAL_ID); /* ---------- 4. Move the EvoX contact form into the modal ---------- */ modal.querySelector(".modal-body").append(form); form.classList.remove("hide"); // Pair short single-input fields two per row (skipped if the form already uses a Bootstrap grid) const groups = form.querySelectorAll(".form-group"); const usesBootstrapGrid = form.querySelector(".row, [class*='col-']") !== null; if (groups.length && !usesBootstrapGrid) { const container = groups[0].parentElement; container.classList.add("cf-fields"); const shortInput = "input[type='text'], input[type='email'], input[type='tel'], input[type='number'], input:not([type])"; groups.forEach((group) => { if (group.parentElement !== container) return; const fields = group.querySelectorAll( "input:not([type='hidden']):not([type='checkbox']):not([type='radio']):not([type='submit']), select, textarea", ); if (fields.length === 1 && fields[0].matches(shortInput)) { group.classList.add("cf-half"); } }); // Odd one out in a run of half-width fields goes full width let run = []; const flushRun = () => { if (run.length % 2) run[run.length - 1].classList.remove("cf-half"); run = []; }; Array.from(container.children).forEach((child) => { if (child.matches("input[type='hidden'], script, .hide, [hidden]")) return; if (child.classList.contains("cf-half")) { run.push(child); } else { flushRun(); } }); flushRun(); } /* ---------- 5. Tab ---------- */ // Remove any old static tab left in the page so there's only one document.querySelectorAll(".cant-find-wrapper").forEach((el) => el.remove()); document.body.insertAdjacentHTML( "beforeend", ``, ); const wrapper = document.querySelector(".cant-find-wrapper"); setTimeout(() => wrapper.classList.remove("is-intro"), 800); /* ---------- 6. Focus first field on open (Bootstrap 3 fires this via jQuery) ---------- */ if (window.jQuery) { window.jQuery(modal).on("shown.bs.modal", () => { const firstField = form.querySelector("textarea, input:not([type='hidden']):not([type='checkbox']):not([type='radio']), select"); if (firstField) firstField.focus(); }); // Bootstrap returns focus to the tab on close, which kept it slid out. // For mouse/touch users drop that focus; keyboard users keep it. const tab = wrapper.querySelector(".cant-find-tab"); let openedWithPointer = false; tab.addEventListener("pointerdown", () => { openedWithPointer = true; }); tab.addEventListener("keydown", () => { openedWithPointer = false; }); window.jQuery(modal).on("hidden.bs.modal", () => { if (!openedWithPointer) return; // Bootstrap focuses the trigger after this handler runs, so wait a tick setTimeout(() => tab.blur(), 0); }); } }); /* ===== End ===== */