/* ── GRIP application form (JetFormBuilder #2423) — exact copy of the site's Elementor form ── */
/* Every value measured on /open-application/ (getBoundingClientRect + getComputedStyle, 2026-09-01) */
.grip-apply { font-family: inherit; color: #3A3468; max-width: 779px; } /* width of the reference column; inside a popup the popup decides */
/* the only heading of the form. «Apply now» underneath was dropped - it
repeated the button the popup was opened with; the kicker keeps the site's
own blue (Kirill, 2026-09-02) */
.grip-apply__kicker { font-family: var(--font-family-heading, inherit); font-size: 14px; font-weight: 900;
text-transform: uppercase; color: #090142; line-height: 21px; margin: 0 0 28px; }
/* rows: 24px rhythm, same as .elementor-field-group */
.grip-apply .jet-form-builder { display: block; }
.grip-apply .jet-form-builder-row { margin: 0 0 24px; padding: 0; }
.grip-apply .wp-block-columns { display: flex; gap: 16px; margin: 0 0 24px; padding: 0; }
.grip-apply .wp-block-columns .wp-block-column { flex: 1 1 0; min-width: 0; margin: 0; }
.grip-apply .jet-form-builder-row, .grip-apply .jet-form-builder__field-wrap { max-width: 100%; }
.grip-apply .wp-block-columns .jet-form-builder-row { margin-bottom: 0; }
/* label: 16px, lh 17.6, padding-bottom 8 → 25.6px to the field (reference: 25) */
.grip-apply .jet-form-builder__label { display: block; padding: 0 0 8px; margin: 0; line-height: 1.1; }
.grip-apply .jet-form-builder__label-text { font-size: 16px; font-weight: 400; line-height: 1.1; color: #3A3468; }
.grip-apply .jet-form-builder__required { color: #F90130; margin-left: 4px; font-weight: 400; }
/* fields: #ECECEC, no border, 4px radius, 47px tall, 6px 16px padding */
.grip-apply input.jet-form-builder__field:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
.grip-apply select.jet-form-builder__field,
.grip-apply textarea.jet-form-builder__field {
display: block; width: 100%; box-sizing: border-box; background: #ECECEC; border: 0; border-radius: 4px;
padding: 6px 16px; height: 47px; min-height: 47px; font-size: 16px; line-height: 1.4; color: #3A3468; font-family: inherit; margin: 0; }
.grip-apply textarea.jet-form-builder__field { height: 102px; min-height: 102px; resize: vertical; }
.grip-apply select.jet-form-builder__field { padding-right: 44px; appearance: none; -webkit-appearance: none;
background-image: url("data:image/svg+xml;utf8,");
background-repeat: no-repeat; background-position: right 16px center; }
/* focus ring drawn INSIDE the field: an outline is painted outside the box and
gets clipped by the popup edge on the first and last column (2026-09-02) */
/* tag + class: the plugin has its own :focus rule with the same shape and
wins on specificity, leaving a transparent ring (measured 2026-09-02) */
.grip-apply input.jet-form-builder__field:focus,
.grip-apply select.jet-form-builder__field:focus,
.grip-apply textarea.jet-form-builder__field:focus { outline: none; box-shadow: inset 0 0 0 2px #3A3468 !important; }
.grip-apply .jet-form-builder__field::placeholder { color: transparent; }
/* the only field that shows its placeholder — it carries the date format */
.grip-apply input[name="birth_date"]::placeholder { color: #9a96b8; }
/* Yes / No: 24px rows, no gap, 13px radio */
.grip-apply .checkradio-wrap.jet-form-builder__fields-group { display: block; padding: 0; margin: 0; }
.grip-apply .radio-wrap.jet-form-builder__field-wrap { display: block; height: 24px; margin: 0; }
.grip-apply .jet-form-builder__field-label.for-radio { display: inline-flex; align-items: center; gap: 5px; height: 24px;
font-size: 16px; line-height: 17.6px; font-weight: 400; color: #3A3468; cursor: pointer; margin: 0; }
.grip-apply .jet-form-builder__field-label.for-radio span { font-size: 16px; line-height: 17.6px; color: #3A3468; }
.grip-apply input[type="radio"].jet-form-builder__field { width: 13px; height: 13px; margin: 0; accent-color: #3A3468; flex: 0 0 13px; }
/* CV: as in the reference — a slim 22px file input on grey, no padding; drop zone and hint hidden */
.grip-apply .jet-form-builder-file-upload__content { display: none; }
.grip-apply .jet-form-builder-file-upload__fields { background: #ECECEC; border-radius: 0; padding: 0; height: 22px; display: flex; align-items: center; }
.grip-apply input[type="file"].jet-form-builder__field { width: 100%; height: 22px; padding: 0; margin: 0; font-size: 16px; color: #3A3468; background: transparent; border: 0; }
.grip-apply .jet-form-builder-file-upload__files:not(:empty) { margin-top: 6px; }
.grip-apply .jet-form-builder-file-upload__file { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.grip-apply .jet-form-builder__desc, .grip-apply .jet-form-builder-file-upload + .jet-form-builder__desc, .grip-apply small { display: none; }
/* consent — compact, same font */
/* 🔴 the wrapper class is `checkboxes-wrap`, with an "es" - `checkbox-wrap`
matches nothing (cost an hour on 2026-09-02). Anchor on `.for-checkbox`. */
.grip-apply .jet-form-builder__field-label.for-checkbox { display: inline-flex; align-items: flex-start; gap: 8px; font-size: 14px; line-height: 1.4; color: #3A3468; }
/* the consent checkbox has no label of its own (the text lives in the option),
so the required asterisk is appended to that text instead */
.grip-apply .jet-form-builder__field-label.for-checkbox span::after { content: ' *'; color: #F90130; }
.grip-apply input[type="checkbox"].jet-form-builder__field { width: 13px; height: 13px; margin: 2px 0 0; accent-color: #3A3468; flex: 0 0 13px; }
/* button: the reference's visible colour is #090142 (::after over #3A3468); red on hover (::before) */
.grip-apply .jet-form-builder__submit-wrap { margin: 0; }
.grip-apply .jet-form-builder__submit { display: inline-block; background: #090142; color: #fff; border: 0; border-radius: 3px; padding: 16px 32px;
height: 47px; font-size: 15px; font-weight: 500; line-height: 15px; cursor: pointer; font-family: inherit; transition: background .25s; }
.grip-apply .jet-form-builder__submit:hover { background: #F90130; }
/* while the request is in flight: dimmed, with a spinner instead of a hover */
.grip-apply .jet-form-builder__submit.is-sending,
.grip-apply .jet-form-builder__submit[disabled] {
opacity: .75; cursor: progress; background: #090142;
display: inline-flex; align-items: center; gap: 10px; }
.grip-apply .jet-form-builder__submit.is-sending::before {
content: ""; width: 14px; height: 14px; border-radius: 50%;
border: 2px solid rgba(255,255,255,.35); border-top-color: #fff;
animation: grip-spin .7s linear infinite; }
@keyframes grip-spin { to { transform: rotate(360deg); } }
/* messages. The plugin's default is a full-width box with a 1px border and 20px
of padding, centred - it reads as a system alert. The site's own forms show a
quiet line with a check mark, so we match that (Kirill, 2026-09-02). */
.grip-apply .jet-form-builder-messages-wrap { margin-top: 16px; font-size: 14px; }
.grip-apply .jet-form-builder-message {
margin: 0; padding: 0; border: 0; text-align: left;
display: flex; align-items: flex-start; gap: 8px; line-height: 1.45; }
.grip-apply .jet-form-builder-message--success { color: #2a7d3f; }
.grip-apply .jet-form-builder-message--success::before {
content: "✓"; font-weight: 700; line-height: 1.45; }
.grip-apply .jet-form-builder-message--error { color: #F90130; }
.grip-apply .jet-form-builder__field-error, .grip-apply .error-message { color: #F90130; font-size: 13px; margin-top: 4px; }
@media (max-width: 640px) { .grip-apply .wp-block-columns { flex-direction: column; gap: 24px; } .grip-apply__title { font-size: 30px; } }
/* GRIP application form - date mask (DD-MM-YYYY).
The plugin's own mask is unusable: mask_type is a free string with no enum,
so JetFormBuilder takes whatever you pass for the mask itself and prints it
into the field ('default' rendered as def_ult, 2026-09-02). Dashes are typed
in by this script instead.
RULES FOR EDITING THIS FILE - it is inlined into page content by WordPress:
1. No ampersands. WP rewrites every "and" operator into an HTML entity and
the script dies with "Invalid or unexpected token" (found 2026-09-02:
12 occurrences turned into entities). Use nested ifs instead.
2. ASCII only - no dashes, quotes or letters outside ASCII.
3. Delegated listeners on document: a popup may inject the form at any time. */
(function () {
if (window.__gripDateMask) { return; } /* the block can appear twice on a page */
window.__gripDateMask = true;
var SEL = '.grip-apply input[name="birth_date"]';
function setup(el) {
if (el.dataset.gripMask) { return; }
el.dataset.gripMask = '1';
el.setAttribute('maxlength', '10'); /* DD-MM-YYYY = 10 characters */
el.setAttribute('inputmode', 'numeric');
el.setAttribute('title', 'Use DD-MM-YYYY, for example 14-03-1994');
}
function format(digits) {
var out = digits.slice(0, 2);
if (digits.length > 2) { out += '-' + digits.slice(2, 4); }
if (digits.length > 4) { out += '-' + digits.slice(4, 8); }
return out;
}
function isReal(value) {
var m = /^(\d{2})-(\d{2})-(\d{4})$/.exec(value);
if (!m) { return false; }
var d = +m[1], mo = +m[2], y = +m[3];
var now = new Date().getFullYear();
if (mo 12) { return false; }
if (d < 1) { return false; }
if (y now - 15) { return false; } /* nobody applies at 14 */
var dt = new Date(y, mo - 1, d); /* catches 31-02 and friends */
if (dt.getDate() !== d) { return false; }
if (dt.getMonth() !== mo - 1) { return false; }
return true;
}
function match(el) {
if (!el) { return false; }
if (!el.matches) { return false; }
return el.matches(SEL);
}
document.addEventListener('input', function (e) {
var el = e.target;
if (!match(el)) { return; }
setup(el);
var atEnd = el.selectionStart === el.value.length;
el.value = format(el.value.replace(/\D/g, '').slice(0, 8));
if (atEnd) { el.setSelectionRange(el.value.length, el.value.length); }
});
/* Plausibility, not validation: the CRM drops what it cannot read anyway.
This just catches the obvious typo while the person is still on the page. */
document.addEventListener('blur', function (e) {
var el = e.target;
if (!match(el)) { return; }
var bad = false;
if (el.value) { if (!isReal(el.value)) { bad = true; } }
el.setCustomValidity(bad ? 'Please enter a real date as DD-MM-YYYY' : '');
el.style.boxShadow = bad ? 'inset 0 0 0 2px #F90130' : '';
}, true);
var list = document.querySelectorAll(SEL);
for (var i = 0; i < list.length; i++) { setup(list[i]); }
})();
/* GRIP application form - "sending" state on the submit button.
The request is not instant (the CRM writes several rows), and a form that
looks frozen makes people click twice or leave. Same editing rules as above:
no ampersands, ASCII only, delegated on document. */
(function () {
if (window.__gripSubmitState) { return; }
window.__gripSubmitState = true;
function restore(btn) {
if (!btn.dataset.gripBusy) { return; }
btn.disabled = false;
btn.classList.remove('is-sending');
if (btn.tagName === 'INPUT') { btn.value = btn.dataset.gripLabel; }
else { btn.textContent = btn.dataset.gripLabel; }
delete btn.dataset.gripBusy;
}
document.addEventListener('submit', function (e) {
var form = e.target;
if (!form.closest) { return; }
if (!form.closest('.grip-apply')) { return; }
var btn = form.querySelector('.jet-form-builder__submit');
if (!btn) { return; }
if (btn.dataset.gripBusy) { return; }
btn.dataset.gripLabel = btn.tagName === 'INPUT' ? btn.value : btn.textContent;
btn.dataset.gripBusy = '1';
btn.classList.add('is-sending');
btn.disabled = true;
if (btn.tagName === 'INPUT') { btn.value = 'Sending...'; }
else { btn.textContent = 'Sending...'; }
/* Back to normal as soon as the plugin renders any message - on success
the form is replaced anyway, on failure the person must be able to retry. */
var wrap = form.closest('.grip-apply');
var seen = new MutationObserver(function () {
if (wrap.querySelector('.jet-form-builder-message')) { restore(btn); seen.disconnect(); }
});
seen.observe(wrap, { childList: true, subtree: true });
setTimeout(function () { restore(btn); seen.disconnect(); }, 20000);
}, true);
})();