diff --git a/odoo-community-developers/admin/index.html b/odoo-community-developers/admin/index.html
index af99f25..13144e3 100644
--- a/odoo-community-developers/admin/index.html
+++ b/odoo-community-developers/admin/index.html
@@ -350,8 +350,9 @@
0 / 70
-
-
+
+
+ 0 / 230
@@ -727,6 +728,8 @@
var FOCUS_TOTAL = 15;
var FOCUS_MAX = 5;
var FOCUS_MAX_CHARS = 70;
+ // The description is capped at 230 characters, same as the public application form.
+ var DESC_MAX_CHARS = 230;
var LANG_FIELDS = [["english", "English"], ["german", "German"], ["spanish", "Spanish"]];
// Country VALUE FORMAT — what the Country select sends to the webhook.
// "code" → the ISO 3166-1 alpha-2 code, e.g. "DE" (default)
@@ -874,6 +877,11 @@
if (focusInput && focusCount) {
focusCount.textContent = focusInput.value.length + " / " + FOCUS_MAX_CHARS;
}
+ var descInput = document.getElementById("adDescription");
+ var descCount = document.getElementById("adDescriptionCount");
+ if (descInput && descCount) {
+ descCount.textContent = descInput.value.length + " / " + DESC_MAX_CHARS;
+ }
}
function loadRecord() {
@@ -1001,6 +1009,17 @@
focusInput.addEventListener("input", refreshCount);
refreshCount();
}
+ var descInput = document.getElementById("adDescription");
+ var descCount = document.getElementById("adDescriptionCount");
+ if (descInput && descCount) {
+ var refreshDescCount = function () {
+ var n = descInput.value.length;
+ descCount.textContent = n + " / " + DESC_MAX_CHARS;
+ descCount.setAttribute("data-over", n > DESC_MAX_CHARS ? "1" : "0");
+ };
+ descInput.addEventListener("input", refreshDescCount);
+ refreshDescCount();
+ }
refreshFocus(form);
form.addEventListener("submit", function (event) {
diff --git a/odoo-community-developers/index.html b/odoo-community-developers/index.html
index 5c2eac1..8e8b7dc 100644
--- a/odoo-community-developers/index.html
+++ b/odoo-community-developers/index.html
@@ -4,10 +4,10 @@
Hire an Odoo Developer for Your Project
-
+
-
+
@@ -429,7 +429,22 @@
.dev-links a {
color: var(--brass-deep);
}
- /* A card with no published contact says so — it never shows an empty space. */
+ /* The "Ask question anonymously" trigger — added by script only while its route is
+ set. Styled as a link so it sits in the links row where the mailto chip was. */
+ .dev-links button {
+ font: inherit;
+ padding: 0;
+ border: 0;
+ background: none;
+ color: var(--brass-deep);
+ text-decoration: underline;
+ cursor: pointer;
+ }
+ .dev-links button:focus-visible {
+ outline: 3px solid var(--brass-deep);
+ outline-offset: 2px;
+ }
+ /* A card with no contact route of any kind says so — it never shows an empty space. */
.dev-contact-none {
margin: 0;
font-size: 0.82rem;
@@ -437,6 +452,99 @@
color: var(--ink-soft);
}
+ /* ---- The ask-a-question modal (ships dark; opened only when wired) ---- */
+ .contact-modal[hidden] {
+ display: none;
+ }
+ .contact-modal {
+ position: fixed;
+ inset: 0;
+ z-index: 60;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 1rem;
+ background: rgba(13, 27, 46, 0.72);
+ }
+ .contact-modal-card {
+ position: relative;
+ width: 100%;
+ max-width: 520px;
+ background: var(--ivory);
+ border: 1px solid var(--line-brass);
+ border-radius: var(--radius-lg);
+ padding: 1.5rem 1.6rem 1.3rem;
+ box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
+ max-height: 92vh;
+ overflow: auto;
+ }
+ .contact-modal-card h3 {
+ font-family: Marcellus, Georgia, serif;
+ font-weight: 400;
+ font-size: 1.25rem;
+ margin: 0 0 0.4rem;
+ color: var(--midnight);
+ }
+ .contact-modal-lede {
+ font-size: 0.86rem;
+ line-height: 1.65;
+ color: var(--ink-soft);
+ margin: 0 0 0.9rem;
+ }
+ .contact-modal-close {
+ position: absolute;
+ top: 0.6rem;
+ right: 0.7rem;
+ background: transparent;
+ border: 0;
+ font-size: 1.4rem;
+ line-height: 1;
+ cursor: pointer;
+ color: var(--ink-soft);
+ padding: 0.2rem 0.4rem;
+ }
+ .contact-modal-close:focus-visible {
+ outline: 3px solid var(--brass-deep);
+ outline-offset: 2px;
+ }
+ .contact-modal .form-field {
+ display: flex;
+ flex-direction: column;
+ gap: 0.35rem;
+ margin-bottom: 0.8rem;
+ }
+ .contact-modal .form-field label {
+ font-size: 0.8rem;
+ font-weight: 600;
+ color: var(--midnight);
+ }
+ .contact-modal .form-field input,
+ .contact-modal .form-field textarea {
+ font-family: Inter, sans-serif;
+ font-size: 0.9rem;
+ padding: 0.6rem 0.7rem;
+ border-radius: var(--radius);
+ border: 1px solid var(--line);
+ background: #fff;
+ color: var(--ink);
+ width: 100%;
+ }
+ .contact-modal-to {
+ font-size: 0.85rem;
+ color: var(--ink);
+ margin: 0 0 0.8rem;
+ }
+ /* The apply modal's card is wider than the question modal: the apply form is a
+ two-column grid. Card stays ivory, so the form reads the same moved or inline. */
+ .apply-modal-card {
+ max-width: 760px;
+ }
+ /* A "Get listed" trigger: centred under the copy it belongs to. */
+ .dir-cta {
+ text-align: center;
+ margin: 1.75rem auto 0;
+ }
+
/* The three forms */
.dir-forms {
max-width: 860px;
@@ -850,6 +958,79 @@
gap: 0.4rem;
}
}
+
+ /* ---- Best Practices accordion (page-scoped, additive). Reuses the house FAQ card
+ and "+/-" marker; items are full-width, single column. Exclusivity comes from the
+ native attribute, with a small JS fallback in the page script. All
+ items are CLOSED on load — nothing carries `open`. ---- */
+ .bp-lede {
+ max-width: 760px;
+ margin: 0 0 1.5rem;
+ font-size: 0.9rem;
+ line-height: 1.7;
+ color: var(--ink-soft);
+ }
+ .bp-list {
+ display: grid;
+ gap: 0.75rem;
+ max-width: 900px;
+ }
+ .bp-item {
+ background: var(--ivory);
+ border: 1px solid var(--line);
+ border-radius: var(--radius-lg);
+ padding: 0.35rem 1.25rem;
+ box-shadow: var(--shadow-rest);
+ transition: box-shadow 0.25s;
+ }
+ .bp-item[open],
+ .bp-item:hover {
+ box-shadow: var(--shadow-hover);
+ }
+ .bp-item summary {
+ cursor: pointer;
+ list-style: none;
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 0.9rem 0;
+ font-family: Marcellus, Georgia, serif;
+ font-size: 1rem;
+ color: var(--midnight);
+ }
+ .bp-item summary::-webkit-details-marker {
+ display: none;
+ }
+ .bp-item summary::after {
+ content: "+";
+ font-family: Inter, sans-serif;
+ font-size: 1.25rem;
+ line-height: 1;
+ color: var(--brass);
+ flex-shrink: 0;
+ transition: transform 0.25s;
+ }
+ .bp-item[open] summary::after {
+ content: "\2212";
+ }
+ .bp-item summary:focus-visible {
+ outline: 2px solid var(--brass);
+ outline-offset: 3px;
+ border-radius: var(--radius);
+ }
+ .bp-q {
+ flex: 1;
+ min-width: 0;
+ }
+ .bp-a {
+ font-size: 0.9rem;
+ line-height: 1.7;
+ color: var(--ink-soft);
+ padding: 0 0 1rem;
+ }
+ .bp-a p:last-child {
+ margin-bottom: 0;
+ }
+
+